# WWW2Exec - GOT/PLT {{#include ../../banners/hacktricks-training.md}} ## **基本情報** ### **GOT: グローバルオフセットテーブル** **グローバルオフセットテーブル (GOT)** は、動的リンクバイナリで外部関数の**アドレスを管理するために使用されるメカニズム**です。これらの**アドレスは実行時まで知られない**ため(動的リンクのため)、GOTは**これらの外部シンボルのアドレスを動的に更新する方法**を提供します。 GOTの各エントリは、バイナリが呼び出す可能性のある外部ライブラリのシンボルに対応しています。**関数が最初に呼び出されると、その実際のアドレスは動的リンカーによって解決され、GOTに格納されます**。同じ関数への後続の呼び出しは、GOTに格納されたアドレスを使用し、再度アドレスを解決するオーバーヘッドを回避します。 ### **PLT: プロシージャリンクテーブル** **プロシージャリンクテーブル (PLT)** はGOTと密接に連携し、外部関数への呼び出しを処理するためのトランポリンとして機能します。バイナリが**外部関数を初めて呼び出すと、制御はその関数に関連付けられたPLTのエントリに渡されます**。このPLTエントリは、関数のアドレスがまだ解決されていない場合、動的リンカーを呼び出してアドレスを解決する責任があります。アドレスが解決された後、それは**GOT**に格納されます。 **したがって、** GOTエントリは外部関数または変数のアドレスが解決された後に直接使用されます。**PLTエントリは、動的リンカーを介してこれらのアドレスの初期解決を促進するために使用されます。** ## 実行を取得 ### GOTを確認 GOTテーブルのアドレスを取得するには: **`objdump -s -j .got ./exec`** ![](<../../images/image (121).png>) GEFで**実行可能ファイルを読み込んだ後、GOTにある** **関数**を**見ることができます**: `gef➤ x/20x 0xADDR_GOT` ![](<../../images/image (620) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2) (2).png>) GEFを使用して**デバッグ**セッションを**開始**し、**`got`**を実行してGOTテーブルを表示できます: ![](<../../images/image (496).png>) ### GOT2Exec バイナリ内のGOTには、**関数のアドレスまたは** **PLT**セクションのアドレスが含まれています。この任意の書き込みの目的は、後で実行される関数の**GOTエントリを上書きすること**です。例えば、**`system`** **関数**のPLTの**アドレス**で上書きします。 理想的には、**あなたが制御するパラメータで呼び出される関数のGOTを上書きすることになります**(これにより、system関数に送信されるパラメータを制御できるようになります)。 もし**`system`** **がバイナリで使用されていない場合、system関数はPLTにエントリを持ちません**。このシナリオでは、最初に`system`関数のアドレスを**リーク**し、その後GOTをこのアドレスを指すように上書きする必要があります。 PLTアドレスは**`objdump -j .plt -d ./vuln_binary`**で確認できます。 ## libc GOTエントリ **libcのGOT**は通常、**部分的RELRO**でコンパイルされており、そのアドレスを特定できれば良いターゲットになります([**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html))。 libcの一般的な関数は、**他の内部関数**を呼び出すことがあり、そのGOTはコード実行を得るために上書きされる可能性があります。 [**この技術に関する詳細情報はこちら**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries)を参照してください。 ### **Free2system** ヒープのエクスプロイトCTFでは、チャンクの内容を制御でき、時にはGOTテーブルを上書きすることが一般的です。利用可能なガジェットがない場合にRCEを取得するための簡単なトリックは、`free`のGOTアドレスを`system`を指すように上書きし、チャンク内に`"/bin/sh"`を書き込むことです。このようにして、このチャンクが解放されると、`system("/bin/sh")`が実行されます。 ### **Strlen2system** もう一つの一般的な技術は、**`strlen`**のGOTアドレスを**`system`**を指すように上書きすることです。これにより、この関数がユーザー入力で呼び出されると、文字列`"/bin/sh"`を渡してシェルを取得することが可能になります。 さらに、`puts`がユーザー入力で使用される場合、`strlen`のGOTアドレスを`system`を指すように上書きし、文字列`"/bin/sh"`を渡してシェルを取得することが可能です。**`puts`はユーザー入力で`strlen`を呼び出します**。 ## **One Gadget** {{#ref}} ../rop-return-oriented-programing/ret2lib/one-gadget.md {{#endref}} ## **ヒープからGOTを悪用する** ヒープの脆弱性からRCEを取得する一般的な方法は、ファストビンを悪用することです。これにより、GOTテーブルの一部をファストビンに追加できるため、そのチャンクが割り当てられると、**通常は`free`の関数ポインタを上書きすることが可能になります**。\ その後、`free`を`system`に指し、`/bin/sh\x00`が書き込まれたチャンクを解放すると、シェルが実行されます。 [**ここに例があります**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/chunk_extend_overlapping/#hitcon-trainging-lab13)**。** ## **保護** **フルRELRO**保護は、この種の技術から保護するために、バイナリが起動されるときにすべての関数のアドレスを解決し、その後**GOTテーブルを読み取り専用**にすることを目的としています。 {{#ref}} ../common-binary-protections-and-bypasses/relro.md {{#endref}} ## 参考文献 - [https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite) - [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook) {{#include ../../banners/hacktricks-training.md}}