
Um localizador de gadgets ROP multithreaded extremamente rápido™. Alternativa ao ropper / ropgadget (atualmente apenas x86)
ropr é um localizador de gadgets ROP extremamente rápido e multithread
Gadgets ROP (Return Oriented Programming) são pequenos trechos de algumas instruções de assembly que normalmente terminam com uma instrução ret e que já existem como código executável dentro de cada binário ou biblioteca. Esses gadgets podem ser usados para exploração binária e para subverter executáveis vulneráveis.
Quando os endereços de muitos gadgets ROP são escritos em um buffer, formamos uma ROP Chain. Se um atacante conseguir mover o ponteiro de pilha para dentro desta ROP Chain, o controle pode ser completamente transferido para o atacante.
A maioria dos executáveis contém gadgets suficientes para escrever uma ROP Chain Turing-completa. Para aqueles que não têm, sempre se pode usar bibliotecas dinâmicas contidas no mesmo espaço de endereçamento, como a libc, uma vez que conhecemos seus endereços.
A beleza de usar gadgets ROP é que não é necessário escrever nenhum novo código executável em lugar algum - um atacante pode alcançar seu objetivo usando apenas o código que já existe no programa.
Normalmente, o primeiro requisito para usar gadgets ROP é ter um lugar para escrever sua ROP Chain - isso pode ser qualquer buffer legível. Basta escrever os endereços de cada gadget que você deseja usar neste buffer. Se o buffer for muito pequeno, pode não haver espaço suficiente para escrever uma ROP Chain longa, então um atacante deve tomar cuidado para criar sua ROP Chain de forma eficiente o suficiente para caber no espaço disponível.
O próximo requisito é ser capaz de controlar a pilha - isso pode assumir a forma de um estouro de pilha - que permite que a ROP Chain seja escrita diretamente abaixo do ponteiro de pilha, ou um "stack pivot" - que geralmente é um único gadget que move o ponteiro de pilha para o resto da ROP Chain.
Uma vez que o ponteiro de pilha esteja no início da sua ROP Chain, a próxima instrução ret fará com que os gadgets sejam executados em sequência - cada um usando o próximo como seu endereço de retorno em seu próprio quadro de pilha.
Também é possível adicionar ponteiros de função em uma ROP Chain - tomando cuidado para que os argumentos da função sejam fornecidos após o próximo elemento da ROP Chain. Isso é tipicamente combinado com um "pop gadget", que retira os argumentos da pilha para fazer uma transição suave para o próximo gadget após os argumentos da função.
Instalação fácil:
cargo install ropr
a aplicação será instalada em ~/.cargo/bin
A partir do código fonte:
git clone https://github.com/Ben-Lichtman/ropr
cd ropr
cargo build --release
o binário resultante estará localizado em target/release/ropr
Alternativamente:
git clone https://github.com/Ben-Lichtman/ropr
cd ropr
cargo install --path .
a aplicação será instalada em ~/.cargo/bin
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
Por exemplo, se eu estivesse procurando uma maneira de preencher rax com um valor de outro registrador, eu poderia escolher filtrar pela regex ^mov eax, ...;:
❯ ropr /usr/lib/libc.so.6 -R "^mov eax, ...;" > /dev/null
==> Found 197 gadgets in 0.118 seconds
Agora posso adicionar alguns filtros na linha de comando para obter os resultados da mais alta qualidade:
❯ 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
Agora tenho um bom candidato a gadget mov no endereço 0x00052252