2017-01-23 6 views
2

학생들에게 버퍼 오버 플로우 연습을 개발 중입니다. 이런 맥락에서 프로그램의 반환 주소로 임의 바이트를 입력해야하는 경우가 종종 있습니다. 나는 점점 더 복잡한 운동을 개발하는 동안 다음gdb에서 프로그램의 STDIN에 임의의 바이트를 보내는 방법은 무엇입니까?

python -c 'print "A"*8+"\x08\x04\88\72"' | ./program 

처럼 공식화 할 수있는 솔루션을 찾아 낼 때까지, 어려움을 gdb를

#import <stdio.h> 
#import <string.h> 

void func() { 
    char buf[4]; 
    gets(buf); 
} 

int main (int argc, char** argv) { 
    func(); 

    return 0; 
} 

일반적으로 I 실험 :

이 예제를 가정 해결책을 찾는다. 때때로

set {int}address_of_address = new_address 

을 통해 gdb의 반송 주소를 덮어 쓰지 만 파이썬 방식은 그렇지 않습니다. 이것을 디버깅하고 gdb에서 "\ x04"와 같은 바이트를 입력 할 수 있으면 좋을 것입니다. 프로그램이 실행되는 동안 효과를 분석합니다.

이렇게 할 방법이 있습니까?

이 질문은 관련 보이지만 파이썬-방식으로 대답한다 : Sending arbitrary bytes to fgets from stdin

광산은 넘어 : -/

+0

참고로 파이썬이 필요 없으므로'bash'를 사용할 수 있습니다 :'echo $ 'AAAAAAAA \ x08 \ x04 \ 88 \ 72'| ./program' – Barmar

+1

이 방법이 도움이됩니까? http://stackoverflow.com/q/8422259/72178? – ks1322

+0

예. 이것은 매우 도움이됩니다! 그러나 프로그램이 이미 실행 중일 때 임의의 바이트를 입력 할 수있는 방법이 있습니까? –

답변

0

"프로그램이 실행되는 동안"이 문제의 한 부분이다. 다른 하나는 "효과를 분석"하기 위해 미리 중단 점을 설정할 수 있습니다.

GDB의 기본 동작은 동일한 표준 스트림을 사용하여 프로그램을 하위 프로세스로 실행하는 것입니다. 따라서 GDB의 CLI에있는 동안 자식의 표준 입력란에 글을 쓰는 것은 불가능합니다. 왜냐하면 현재로서는 프로그램이 아닌 GDB에서 읽을 수 있기 때문입니다.

가장 간단한 해결책은 tty 해결 방법 (tty 명령 + stty 설정 + /proc/<pid>/fd/{0,1}에 읽기/쓰기)을 사용하는 것입니다. 코드를 테스트 할 수 있고 GDB에서 "호출 가능"하도록하는 것입니다. 그러면 문자열 인수를 함수에 전달하여 테스트하고 디버깅 할 수 있습니다. 예를 들어

:

#include <stdio.h> 
#include <unistd.h> 

void exploitme(char* str) 
{ 
    printf(str); 
} 

int main() 
{ 
    while (1) 
    { 
    char str[10]; 
    fgets(str, sizeof (str), stdin); 
    exploitme(str); 
    } 

    return 0; 
} 

exploitme()은 그것을 사용하는 모든 것이 제대로 초기화되면 호출하는 것이 가능 있도록 제대로 단일 진입 점에 싸여 이용할 경우입니다. 그런 다음 명령을 사용하여 main() 중단 점에 도달하면 (즉, 주 호출자에서 수행되는 C 런타임이 완료 될 때까지) 호출 할 수 있습니다. 당신은 C 문자열 평가를 포함 GDB의 인수 수혜

~/test $ gdb ./a.out                      
(gdb) call exploitme("hello") 
You can't do that without a process to debug. 
(gdb) b main 
Breakpoint 1 at 0x4005ae: file helloworld.c, line 14. 
(gdb) r 
Starting program: /home/julio/test/a.out 

Breakpoint 1, main() at helloworld.c:14 
14   fgets(str, sizeof (str), stdin); 
(gdb) call exploitme("hello") 
(gdb) call exploitme("hello\n") 
hellohello 
(gdb) call exploitme("AAAAAAAA\x08\x04\88\72\n") 
AAAAAAA�: 
(gdb) b exploitme 
Breakpoint 2 at 0x400592: file helloworld.c, line 6. 
(gdb) call exploitme("foo") 
Breakpoint 2, exploitme (str=0x602010 "foo") at helloworld.c:6 
6   printf(str); 
The program being debugged stopped while in a function called from GDB. 
Evaluation of the expression containing the function 
(exploitme) will be abandoned. 
When the function is done executing, GDB will silently stop. 

참고.

다른 (길게 & complexer) 솔루션은 다른 tty 아래에서 프로그램을 실행하여 독립적으로 GDB와 프로그램을 작성할 수 있도록 해줍니다.

0

GDB에서 "\ X04을"이 디버깅하고 처럼 바이트를 입력 할 수 있도록 그것은 프로그램이 실행되는 동안, 당신이 필요 이렇게하려면 효과

를 분석, 좋은 것 콘솔 : 프로그램 stdin에서 바이트를 입력하는 첫 번째 바이트, gdb 디버그 세션에서 두 번째 바이트.

stdin에서 대기하는 것을 멈출 때까지 첫 번째 콘솔에서 프로그램을 먼저 실행할 수 있습니다. 그런 다음 gdb를 두 번째 콘솔에서 실행하고 pid로 프로그램에 연결하십시오. 두 개의 다른 콘솔에서 동시에 디버그하고 바이트를 입력 할 수 있습니다.