HTB之Weather App
0x01 挑战说明
1 | CHALLENGE DESCRIPTION |
0x02 收集信息
打开页面,没有找到什么可利用的信息。
下载所需的文件,里面有此天气程序的源代码和一个docker容器,我们可以在linux上运行此docker容器,然后在127.0.0.1:1337本地访问,以便测试。

首先要摸清楚该应用程序是如何工作的,才有可能快速找到漏洞所在。
一个个看,首先是helpers/HttpHelpers.js
文件:

此文件有个HttpGet()函数,作用是接收一个url并发起一个请求,然后对返回的数据进行处理。
然后是helpers/WeatherHelpers.js
文件:

此文件定义了一个getWeather
函数,该函数调用了HttpGet(url)
函数,作用是访问了一个api,并接收处理返回的数据,其中有几个变量,endpoint
city
country
,留意这几个变量,看是否可以注入恶意数据。
查看routes/index.js
:
发现代码里面有四条可用路由,我们可以知道这是一个应用了Express的Node.js的应用程序:




查看一下路由/register
的代码:

发现如果想要注册一个用户必须满足两个条件:
- 必须是post请求提交
- post请求必须来自服务器端
留意条件二,说明我们利用SSRF来攻破这个应用,我们需要注意哪些地方可以利用SSRF。
查看路由/login
的代码:

我们可以知道以下几个信息:
- post方式访问
- admin用户登录可以访问
/app/flag
页面,获取flag
这时候,我们就会想到注册一个admin用户,然后登录。但是admin用户很可能已经存在,我们需要继续往下看。
查看/js/
目录里的两个文件:

里面定义了一些常量和调用了上面的getWeather()
函数,跳过。
查看views/database.js
文件:
先看migrate()函数

定义username字段的时候用了UNIQUE,所以用户名不能重复,且在创建该表的时候就已经创建了一个admin用户。密码经过使用了随机的32字节转换成16进制后存放进数据库,所以爆破密码是不现实的。
再看register()
函数:

该函数在使用sql语句的时候,没有使用 “ ?”参数化查询,说明可以我们可以在注册用户的时候实施恶意注入攻击。
再看isAdmin()
函数:

显而易见,该函数的功能是判断登录的时候用户是否admin
,在查询过程中使用了参数化查询,也消除了恶意字符,没有利用价值。
由上面可知,该应用程序的工作逻辑是这样的:
main.js——>调用getWeather()——>getWeather()调用Httpget()并传递参数api,用来发出GET请求。
0x03 思路
我们将采用SSRF攻击该程序,利用点显然在这里。

如何构造一个有效的payload发起请求是关键。
我们可以尝试通过截断字符来发出额外的http请求,而且Node 8的http模块很容易通过Request Splitting受到SSRF的攻击。
1 | 空格 编码为 \u0120 |
0x04 构造Payload
初步构造的url效果为:
1 | GET / HTTP/1.1 |
该payload还无法产生威胁,根据我上面获取到的信息,register()
函数是可以进行SQL注入攻击的,结合SQL攻击。
使username为 admin
password为 1234') ON CONFLICT(username) DO UPDATE SET password = 'admin';--
会产生如下效果:
1 | INSERT INTO users (username, password) VALUES ('admin', 1337') ON CONFLICT(username) DO UPDATE SET password = 'admin';--') |
如果用户名冲突,密码将更新为admin。
我们可以构造如下url:
1 | GET / HTTP/1.1 |
0x05 编写POC
1 | import requests |
