#gadget #rop #multi-threading #assembly #stack #finder #instructions

bin+lib ropr

一个快速的线程多任务ROP Gadget查找器。ropper / ropgadget替代品

30个版本

0.2.25 2023年8月13日
0.2.24 2023年5月7日
0.2.23 2022年10月11日
0.2.22 2022年5月26日
0.1.4 2020年9月23日

#2 in #gadget

Download history 22/week @ 2024-04-08 19/week @ 2024-04-15 41/week @ 2024-04-22 34/week @ 2024-04-29 28/week @ 2024-05-06 19/week @ 2024-05-13 20/week @ 2024-05-20 17/week @ 2024-05-27 20/week @ 2024-06-03 23/week @ 2024-06-10 18/week @ 2024-06-17 26/week @ 2024-06-24 39/week @ 2024-07-01 3/week @ 2024-07-08 31/week @ 2024-07-15 9/week @ 2024-07-22

92 每月下载量
2 crates 中使用

MIT/Apache

29KB
780

ropr

ropr是一个快速的线程多任务ROP Gadget查找器

什么是ROP Gadget?

ROP(返回导向编程)Gadget是一些几条汇编指令的小片段,通常以ret指令结束,这些指令作为可执行代码存在于每个二进制文件或库中。这些Gadget可以用于二进制漏洞利用和破坏有漏洞的可执行文件。

当许多ROP Gadget的地址被写入缓冲区时,我们就形成了一个ROP链。如果攻击者可以将栈指针移动到这个ROP链中,则控制权可以完全转移到攻击者手中。

大多数可执行文件都包含足够的Gadget来编写一个图灵完备的ROP链。对于那些不包含的情况,一旦我们知道它们的地址,我们总是可以使用同一地址空间中的动态库,如libc。

使用ROP Gadget的美丽之处在于不需要在任何地方编写新的可执行代码——攻击者可以使用程序中已经存在的代码来实现他们的目标。

如何使用ROP Gadget?

通常,使用ROP Gadget的第一个要求是在缓冲区中写入你的ROP链——这可以是任何可读的缓冲区。只需将你想要使用的每个Gadget的地址写入此缓冲区。如果缓冲区太小,可能没有足够的空间写入一个长的ROP链,因此攻击者应该小心地构造他们的ROP链,使其足够高效,以便适应可用的空间。

下一个要求是能够控制栈——这可以采取栈溢出的形式——允许ROP链直接写入栈指针下方,或者“栈转换”——通常是一个将栈指针移动到ROP链其余部分的单个Gadget。

一旦栈指针位于你的ROP链的起始位置,下一个ret指令将触发Gadget按顺序执行——每个Gadget使用其自己的栈帧中的下一个Gadget作为返回地址。

还可以在ROP链中添加函数指针——注意在ROP链的下一个元素之后提供函数参数。这通常与一个“pop Gadget”结合使用,它将参数从栈中弹出,以便在函数参数之后平滑地转换到下一个Gadget。

如何安装ropr?

  • 需要货物(Rust构建系统)

易于安装

cargo install ropr

应用程序将安装到 ~/.cargo/bin

从源码

git clone https://github.com/Ben-Lichtman/ropr
cd ropr
cargo build --release

生成的二进制文件将位于 target/release/ropr

或者

git clone https://github.com/Ben-Lichtman/ropr
cd ropr
cargo install --path .

应用程序将安装到 ~/.cargo/bin

如何使用ropr?

USAGE:
    ropr [OPTIONS] <BINARY>

ARGS:
    <BINARY>    The path of the file to inspect

OPTIONS:
    -b, --base-pivot               Filters for gadgets which alter the base pointer
    -c, --colour <COLOUR>          Forces output to be in colour or plain text (`true` or `false`)
    -h, --help                     Print help information
    -j, --nojop                    Removes "JOP Gadgets" - these may have a controllable branch,
                                   call, etc. instead of a simple `ret` at the end
    -m, --max-instr <MAX_INSTR>    Maximum number of instructions in a gadget [default: 6]
    -n, --noisy                    Includes potentially low-quality gadgets such as prefixes,
                                   conditional branches, and near branches (will find significantly
                                   more gadgets)
    -p, --stack-pivot              Filters for gadgets which alter the stack pointer
    -r, --norop                    Removes normal "ROP Gadgets"
    -R, --regex <REGEX>            Perform a regex search on the returned gadgets for easy filtering
        --range <RANGE>            Search between address ranges (in hexadecial) eg. `0x1234-0x4567`
        --raw <RAW>                Treats the input file as a blob of code (`true` or `false`)
    -s, --nosys                    Removes syscalls and other interrupts
    -V, --version                  Print version information

例如,如果我想从一个寄存器填充 rax 的值,我可以选择使用正则表达式 ^mov eax, ...;

❯ ropr /usr/lib/libc.so.6 -R "^mov eax, ...;" > /dev/null

==> Found 197 gadgets in 0.118 seconds

现在我可以添加一些过滤器到命令行以获得最高质量的结果

❯ ropr /usr/lib/libc.so.6 -m 2 -j -s -R "^mov eax, ...;"
0x000353e7: mov eax, eax; ret;
0x000788c8: mov eax, ecx; ret;
0x00052252: mov eax, edi; ret;
0x0003ae43: mov eax, edx; ret;
0x000353e6: mov eax, r8d; ret;
0x000788c7: mov eax, r9d; ret;

==> Found 6 gadgets in 0.046 seconds

现在我在地址 0x00052252 有一个很好的 mov gadget 候选

依赖关系

~19–31MB
~465K SLoC