weather app — hack the box(CVE 2018–12116 ssrf via request splitting)

natnat
3 min readDec 6, 2022

--

index.js file:


const path = require('path');
const fs = require('fs');
const express = require('express');
const router = express.Router();
const WeatherHelper = require('../helpers/WeatherHelper');

let db;

const response = data => ({ message: data });

router.get('/', (req, res) => {
return res.sendFile(path.resolve('views/index.html'));
});

router.get('/register', (req, res) => {
return res.sendFile(path.resolve('views/register.html'));
});

router.post('/register', (req, res) => {

if (req.socket.remoteAddress.replace(/^.*:/, '') != '127.0.0.1') {
return res.status(401).end();
}

let { username, password } = req.body;

if (username && password) {
return db.register(username, password)
.then(() => res.send(response('Successfully registered')))
.catch(() => res.send(response('Something went wrong')));
}

return res.send(response('Missing parameters'));
});

router.get('/login', (req, res) => {
return res.sendFile(path.resolve('views/login.html'));
});

router.post('/login', (req, res) => {
let { username, password } = req.body;

if (username && password) {
return db.isAdmin(username, password)
.then(admin => {
if (admin) return res.send(fs.readFileSync('/app/flag').toString());
return res.send(response('You are not admin'));
})
.catch(() => res.send(response('Something went wrong')));
}

return re.send(response('Missing parameters'));
});

router.post('/api/weather', (req, res) => {
let { endpoint, city, country } = req.body;

if (endpoint && city && country) {
return WeatherHelper.getWeather(res, endpoint, city, country);
}

return res.send(response('Missing parameters'));
});

module.exports = database => {
db = database;
return router;
};

code analysis:

when you login as admin it gives you a flag otherwise it sends you a message ‘you are not admin’

when u check package.json file you can see nodejs version is low (8).

research

i went to node js releases website(https://nodejs.org/en/download/releases/) and checked for when this version was released and then started searching Nodejs 2018 vulnerabilities.

then i started searching for request splitting vulnerability examples to get the idea what the attack would look like and i came across this article which helped me a lot(https://www.rfk.id.au/blog/entry/security-bugs-ssrf-via-request-splitting/). it said “node js version 8 or lower doesn’t escape unicode characters with diacritics.” and the guy used this so he could hack the app with request splitting.

attack

in order to make ssrf via request splitting we have to make post request. this app makes post request on 3 routes: /api/weather, /register, /login and the request must be sent from 127.0.0.1 endpoint otherwise it will give us unauthorized response code.

this post request makes request to endpoint and passes parameters. so we can use this endpoint input to make request to weather app page. now let’s say we make a request, then? …we can’t get flag just by doing that. if you look at source code you can see we can also make post request to /login and /register route, too. we can make post request to /register route but with 127.0.0.1 as a host and change admin’s password using sql query.

sql query for password change:

‘) ON CONFLICT (username) DO UPDATE SET password = ‘passwd123’; —

updates the existing row that conflicts with the row proposed for insertion as its alternative action.

exploit code: (code link: https://github.com/natachikhinashvili/python_exploits/blob/main/htb/request_splitting.py)

I was stuck on this part and this article helped me

https://blog.csdn.net/f_cccc/article/details/116406838

  • %27 — ‘
  • %22 — “
  • \u0120 — (space)
  • \u010D — \r
  • \u010A — \n

log in with your updated password and you get the flag.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Responses (2)

Write a response