티스토리 뷰
예전에 과제로 했던 proxy-server 보다도 시간이 오래 걸린거 같다.
뭔가 생각지 않은 상황도 너무 많았고 여타 다른 바이너리와는 다른 부분도 너무 많았다.
심지어 보호기법도 많았다!
NX-Bit, SSP, PIE가 걸려있었고 내부적으로 fork를 쓰는거 같아 Canary와 binary-base의 주소는 바뀌지 않았다.
즉 한번만 구해놓으면 된다는 것인데, 사실 한번구하면 계속 구할 수 있기 때문에 큰 메리트는 아니다.
일단 우리가 알아내야 할 건 총 3가지이다.
랜덤값으로 이루어진 Password, 역시 랜덤한 canary 또 랜덤한 binary-base address.
총 3개를 leak해야 하고 canary와 base address는 기존에 해왔던 방식으로 브루트 포싱했다.
for(bytes_wrong = 0, l = 0; pw[l] && l < password_size; l++) { | |
if(pw[l] != password[l]) { | |
#if 0 | |
char *buf; | |
asprintf(&buf, "[%d] wrong byte (%02x vs %02x)\n", l, | |
password[l], pw[l]); | |
write(58, buf, strlen(buf)); | |
#endif | |
bytes_wrong++; | |
} | |
} | |
// anti bruteforce mechanism. good luck ;> | |
tv.tv_sec = 0; | |
tv.tv_usec = 2500 * bytes_wrong; | |
select(0, NULL, NULL, NULL, &tv); | |
password를 한바이트씩 비교하여 틀리면 bytes_wrong변수가 증가하고
for문이 끝나면 tv_usec을 2500*bytes_wrong으로 대입해준다.
(tv는 timeval struct의 인스턴스이다.
http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/2/gettimeofday)
그리고 select로 tv만큼의 timeout을 설정해준다. (그만큼 지연) 즉 printable한 값들을 한바이트씩 대입해보고
가장 시간이 적게 걸린 값을 가져오면 password를 leak할 수 있다.
시간을 이용한 알고리즘이라 그런지 가끔 오차가 발생핸다.
password를 반복하여 체크하는 반복문을 넣어서 해결했다.
canary는 stack smashing message가 뜨는지 안뜨는지로 판단하면 쉽게 구할 수 있다.
문제는 base address를 구할 애를 먹었는데, write@plt로 아무리 출력해봐도 유효하지 않고
gdb로 봤더니 write 자체가 실행이 되지 않았다. 그 이유는 이 바이너리가 got plt를 약간 이상하게 call하기 때문이다.
현재 got를 기준으로 offset 값을 이용하여 값을 가져온다. 그리고 got는 무조건 ebx에 있어야 한다.
그래서 write@plt나 read@plt를 call하려면 ebx를 .got.plt의 시작주소 (offset 0x00004118)로 지정해 주어야
제대로 실행이 된다.
pop ebx ; ret 가젯이 있으니 지정해주는 건 쉽다.
마지막으로 exploit에서도 이상한 현상이 발생했다. read를 해주고 leave; ret을 하려 했으나
왜인지 첫번째 read가 실행이 안돼서 read를 두번 실행해줬다.
요즘 부쩍 Fake-EBP 기법을 많이 쓰는 것 같다. 뭔가 편하기도 하고 예전에 풀어봤던 문제들은
안써도 될만한 것들 밖에 없어서 그런것 같다.
in leak_password() ...
2 3 5 2 M 5 t 5 6 H C u 3 2 V l
2352M5t56HCu32Vl
Password : 2352M5t56HCu32Vl
in leak_canary() ...
0x0 0x8b 0xc 0x2c
Canary : 0x2c0c8b00
in leak_binary_base() ...
Now base : 0xb7500000L
Now base : 0xb7580000L
Now base : 0xb7600000L
Now base : 0xb7680000L
Now base : 0xb7700000L
Now base : 0xb7780000L
Base address : 0xb779f000L
id
uid=20004 gid=20004 groups=20004
[Finished in 60.7s]
'Pwnable > Fusion' 카테고리의 다른 글
exploit-exercises.com fusion level03 (0) | 2015.11.03 |
---|---|
exploit-exercises.com fusion level02 (0) | 2015.01.03 |
exploit-exercises.com fusion level01 (0) | 2014.12.30 |
exploit-exercises.com fusion level00 (1) | 2014.12.22 |