test_your_nc1
先checksec题目附件,检测文件的保护机制
bing@bing-virtual-machine:~/pwn$ checksec test
[*] '/home/bing/pwn/test'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
bing@bing-virtual-machine:~/pwn$
代码中:
Relro:Full Relro(重定位表只读)
Relocation Read Only, 重定位表只读。重定位表即.got 和 .plt 两个表。
Stack:No Canary found(能栈溢出)
NX: NX enable(不可执行内存)
Non-Executable Memory,不可执行内存。
PIE: PIE enable(开启ASLR 地址随机化)
Address space layout randomization,地址空间布局随机化。通过将数据随机放置来防止攻击。
用IDA分析题目附件test
按下shift+f12,打开string window
发现/bin/sh
双击/bin/sh, 点击command,右键然后点击Xrefs to,发现/bin/sh的address在main函数里
点击option->general,勾选相应选项可方便看代码,具体如下:
按下f5,发现main函数就是一个简单的system函数.直接调用了/bin/sh,所以根据题目提示直接nc就行.
然后直接打开虚拟机,进入终端,nc题目网址
记得把ip中间的“:”删掉,不然它会截断ip,导致linux系统无法扫描出其host
nc后,输入ls,查找目录文件,发现flag文件
cat flag查找flag
成功!
rip1
checksec
打开题目,下载附件,然后拖入kali中,先checksec一下,可以查看文件类型和linux下的ELF二进制文件的保护机制
1.Canary(栈保护)
这个选项表示栈保护功能有没有开启。
栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行。当启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary。
2.NX/DEP(堆栈不可执行)
NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。
3.PIE/ASLR(地址随机化)
4.Fortify
这个保护机制查了很久都没有个很好的汉语形容,根据我的理解它其实和栈保护都是gcc的新的为了增强保护的一种机制,防止缓冲区溢出攻击。由于并不是太常见,也没有太多的了解。
5.RelRO
设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。
附件分析
我们使用IDA,因为上面查看了是64位,所以打开64位的
main函数有明显的漏洞,gets,又没有栈溢出保护,可以栈溢出
bin/sh
(获取权限的命令,双击找到字符串的地址)
按下shift+f12,打开string window
双击打开
在(command)这一行上右键,选Xrefs to,可以看到哪里引用了这个字符串
来看看fun这个函数
直接是system("/bin/sh")
,非常的好,那么只要通过栈溢出把返回地址改成这个fun函数的地址就行了(0x401186)
算偏移量
看地址算偏移量
我们需要利用gets函数获取一个长字符串覆盖rip来控制程序流到fun()函数
函数的局部变量会存放在他的栈中,那么在main函数中,我们双击s变量,查看s分配了多少空
是15个字节的空间,也就是在main函数的栈帧中,给s划分了一个15字节的存储空间
因为是64位的EIF文件,所以rbp是8个字节
(如果对这一部分不太了解,可以参考这篇文章:
CTF PWN基础知识(寄存器、栈、汇编指令、标志位)详解_rbp rsp寄存器-CSDN博客
)
那么我们还需要8个自己的数据把Caller’s rbp的数据填满(当然在本题中应该是rbp,因为是64位的系统),这样可以溢出进入Return
Address了,所以接下来我们输入Return
Address(返回地址),也就是说,也就是fun函数的地址,地址我们可以看到是0x401186
现在可以构建exp了
写脚本
脚本模板:
from pwn import * #引入pwn库
p = remote(ip, port) # 输入对应的ip地址和端口号来连接其他主机的服务
... # 输入payload来进行操作以拿到程序的shell payload一般等于 偏移量 + 地址
p.interactive() # 反弹shell
本题目脚本:
from pwn import *
p = remote('node5.buuoj.cn', 29467)
p.sendline(b'a' * 15 + p64(0x401186))
p.interactive()
这里在返回地址前要填一个ret的地址,实测0x401198
(fun的ret)、0x401185
(main的ret)、0x4010C0
(deregister_tm_clones的ret)都可以,应该什么ret都可以
具体原因:BUUCTF (PWN) RIP详细分析_buuctf rip pwn 解法-CSDN博客
连远程,cat flag
成功!