2017-04-07 8 views
3

이 질문을 조사한 결과 가장 가까운 답을 찾을 수있었습니다. gdb - debugging with piped input (not arguments)GDB에서 처음에 중단 점이 아닌 파이프 된 입력 보내기

나는이 사람이 묻는 것을 정확하게 할 필요가있다. 그러나 나는 이미 프로그램의 일부를 본 후에 입력을 보낼 수 있어야한다.

내가 내 가상 컴퓨터의 포맷 스트링 공격을 수행하려고 해요
#define SECRET1 0x44 
#define SECRET2 0x55 

int main(int argc, char *argv[]) 
{ 
char user_input[100]; 

int *secret; 
int int_input; 
int a, b, c, d; /* other variables, not used here.*/ 

/* The secret value is stored on the heap */ 
secret = (int *) malloc(2*sizeof(int)); 

/* getting the secret */ 
secret[0] = SECRET1; secret[1] = SECRET2; 

printf("The variable secret’s address is 0x%8x (on stack)\n", &secret); 
printf("The variable secret’s value is 0x%8x (on heap)\n", secret); 
printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]); 
printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]); 

printf("Please enter a decimal integer\n"); 
scanf("%d", &int_input); /* getting an input from user */ 

printf("Please enter a string\n"); 
scanf("%s", user_input); /* getting a string from user */ 

/* Vulnerable place */ 
printf(user_input); 
printf("\n"); 

/* Verify whether your attack is successful */ 
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2); 
printf("The new secrets:  0x%x -- 0x%x\n", secret[0], secret[1]); 

return 0; 
} 

GDB

에에서 내가 찾고 있어요 코드입니다. 그렇게하기 위해서, 비밀이 저장되는 주소를 알아야합니다. 이 프로그램은 공격의 성격은 내가 2 scanf와의 입력으로 ASCII가 아닌 16 진수 값을 전송해야이 줄

printf("The variable secret’s address is 0x%8x (on stack)\n", &secret); 
    printf("The variable secret’s value is 0x%8x (on heap)\n", secret); 
    printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]); 
    printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]); 

과 출력을 통해 나에게이 문제를 알려줍니다, 그래서 나는 단순히 입력에게 자신을 입력 할 수 없습니다. 나는

[email protected]:/tmp$ perl -e 'print "5\x0a"; print "\x08\xb0\x04\x08%x.%x.%x.%x.%x.%x.%x";' > /tmp/input 

내가 그때 기억 무작위 내가 실행할 수 있습니다으로 꺼져 환경에서 작동하는 나의 방법을 왔

$gdb ./vul_prog < /tmp/input 

실행, 여기에 펄을 사용하여 내 입력을 설정 이룬 프로그램을 한 번 실행하고 메모리 주소를 확인한 다음 perl 스크립트를 변경하고 간단히 다시 실행하십시오. 그러나 메모리 무작위 화를 사용하면 실행하기 전에 주소가 어디인지 알 수 없기 때문에 입력을 만들고 보내기 전에 주소가 실행된다는 내용의 프로그램 부분을 볼 수 있어야합니다.

여기에서 가장 직관적 인 방식으로 시도했지만 구문 오류가 발생합니다.

Starting program: /home/ramtest/Downloads/vulprog 
The variable secret’s address is 0xbfffefd8 (on stack) 
The variable secret’s value is 0x 804b008 (on heap) 
secret[0]’s address is 0x 804b008 (on heap) 
secret[1]’s address is 0x 804b00c (on heap) 
Please enter a decimal integer 
1 
Please enter a string 

Breakpoint 2, 0x0804858f in main() 
(gdb) c > /tmp/input 
A syntax error in expression, near `> /tmp/input'. 
(gdb) c < /tmp/input 
A syntax error in expression, near `< /tmp/input'. 

은 나를 내가 입력하라는 메시지가 있어요 바로 전에 다음, GDB에서 중단 점을 설정 어떻게 든 입력으로/tmp에/입력 정보를 보낼 수 있습니까?

그렇다면 어떻게해야할까요?

도움을 주시면 감사하겠습니다.

답변

1

run 명령을 사용하면됩니다. 표준 입력 리디렉션와 나는, gdb를하는 /bin/cat를 공급, 그 main()의 파괴에 의해 설명하겠다 :

예 :

$ gdb /bin/cat 
GNU gdb (GDB) Fedora 7.12.1-47.fc25 
[ ... ] 
(gdb) b main 
Breakpoint 1 at 0x1bc0 
(gdb) run </etc/issue 
Starting program: /usr/bin/cat </etc/issue 

Breakpoint 1, 0x0000555555555bc0 in main() 
(gdb) c 
Continuing. 
\S 
Kernel \r on an \m (\l) 

[Inferior 1 (process 18190) exited normally] 
(gdb) 

당신은 gdb 아래 프로그램을 시작 할 수 있어야 직전에 중단 점을 설정 scanf이면 run 빈 파일에서 리다이렉트 된 표준 입력입니다. 그때까지는 프로그램이 표준 입력에서 읽으려고 시도하지 않기 때문에 리다이렉트 된 표준 입력에서 파일 끝 (end-of-file) 조건을 볼 수 없습니다.

브레이크 포인트는 다음

c 

다음, 길이가 0 인 파일에 추가 간단히 진행하고 읽기를 시도해야 실행을, 당신의 페이로드를 준비하고, 메모리 주소를 가지고 있어야 명중 현재 표준 입력에서 사용할 수있는 페이로드입니다.

디버거를 필요로하지 않는 변형 된 방법은 미리 쓰기 위해 열어 둔 명명 된 파이프를 사용하고, 명명 된 파이프에서 리디렉션 된 표준 입력으로이 프로그램을 실행하는 것입니다. 예상 된 결과는 프로그램이 메모리 주소를 인쇄 한 다음 파이프에서 읽을 때 차단합니다. 이 시점에서 페이로드를 준비하고 파이프에 기록 할 수 있습니다.

+0

감사합니다. 시험해 보겠습니다. – vergilEther

+0

매력처럼 작동합니다. 감사! – vergilEther