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
92 每月下载量
在 2 crates 中使用
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