1.1需要回答的问题
1.1.1实验收获与感想
1.我很菜
2.其实东西是很有意思的,当然是在有实验指导书的情况下,去理解其中的逻辑很有趣,也还有一些东西没有很懂
3.我以前没有好好学汇编,我对不起老师,我之后也没有去补学,对不起我买的大书
4.我记忆力真的不好,前一眼看的指令转头就忘
5.虽然我拖延症严重,但是只要开始做我就可以一直学
6.感谢老师详细的指导书,不然我可能没有勇气去做
1.1.2什么是漏洞,漏洞有什么危害
漏洞是,程序中一些考虑不周的部分,还有计算机设计之初没有考虑到的一些容易被利用的问题,以及某种程序语言的局限性。
漏洞的危害有,攻击者非法获取权限,造成网络瘫痪,用户信息泄露,开后门留下安全隐患。
1.2 需要描述的内容
1.2.1相应指令的机器码
- NOP:0x90
- JNE:0x75
- JE:0x74
- JMP:0xEB(8位相对短跳转时) 0xE9(16位相对跳转时) 0xFF(16位/32位绝对跳转时)
- CMP:0x38(目的操作数为8位内存或寄存器,源只能为8位寄存器)
0x39(目的是16位内存单元或者寄存器,源只能为16位寄存器)
0x3A(目的是8位寄存器,源是8位内存单元或者寄存器)
0x3B(目的是8位寄存器,源是8位内存单元或者寄存器)
0x3C(源操作数是8位立即数,目的是AL)
0x3D(源操作数是16位立即数,目的是AX)
2 实验内容
注:更改主机名的方法:进入/etc文件vim hostname(root下)重启即可
不想承认我为截图又重新做了一遍
2.1 直接修改程序机器指令,改变程序执行流程
在码云指导书的末尾附件链接里面找到pwn1.zip,保存到kali虚拟机内
使用objdump -d 文件 | more反汇编,查看几个函数的指令
看到main函数里面的call foo函数的指令是e8 d7 ff ff ff,执行call指令时eip寄存器里面的值是下一条指令的地址80484ba,此时call指令让eip的值+d7ffffff(-41),即跳转到foo函数起始地址8048491,要想调用getShell,则修改eip加的这个值,windows计算器的程序员模式可以计算出应改为c3ffffff
所以修改pwn中的机器指令可以直接调用getShell
编辑pwn2文件(pwn1副本),如果直接在pwn1中操作,之后还需要再解压,在16进制模式下找到/e8d7(需要注意的是e8和d7之间可能有空格,直接搜索/e8d7无结果)
改d7为c3,一定要转换成原格式:%!xxd -r,wq保存后反汇编,可以看到main函数直接调用getShell
运行:
2.2 构造字符串,覆盖返回地址,造成BOF攻击
反汇编pwn可以看到foo函数的汇编指令lea -0x1c(%ebp),%eax,可知预留给字符串的缓冲区为0x1c=28字节,还有ebp存储的4个字节,我们要覆盖这部分以达到跳转到getShell的目的
分析完了之后来验证,下图是我多打了一个1,也就是说理论上最后溢出的为4555四个字节,从下图中的EIP的值可以看出(4和5的ASCII码为34和35)溢出的正是4555(小端存放为0x35353534)
再次用12345678验证存放方式
所以,如果想让程序直接返回到getShell的地址0804847d,则将这个地址覆盖到字符串中,用perl语言将字符串存储到文件(x0a为回车)
2.3 注入Shellcode并执行
准备工作:
设置pwn文件堆栈可执行,关闭地址随机化(execstack要用get-apt install execstack安装)(关闭地址随机化要在root下运行)
构造要注入的payload:Linux下有两种基本构造攻击buf的方法:
- retaddr+nop+shellcode
- nop+shellcode+retaddr(nop作为填充和滑行区,只要猜到的返回地址落在任何nop上,就会滑到shellcode上面)
在gdb调试的时候一定要开两个终端,并且构造的文件里面不能有回车符,配合在ret处设断点一步步找到相关值,就可以找到应该填的地址
为了多熟悉下这个过程,我第二个失败的方法也试过了一遍了,确实不行,但是说实话现在都没看懂为啥
下面是第二个失败的方法的一些过程:
这里构造的字符串是
x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00
进行gdb调试的时候找01020304,然后再一步步往前找到这段字符串开头
再用第一个办法,返回地址放在最前面,仍然用01020304来定位
在另一个终端进行gdb调试
这时候的esp值为0xffffd2ac,再往下指四个字节,跳过返回地址,就能指到shellcode的起始地址,所以ffffd2ac+4为ffffd2b0,故将其替换01020304,
运行: