PHP Tricks
Last updated
Last updated
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)
あなたのウェブアプリ、ネットワーク、クラウドに対するハッカーの視点を得る
実際のビジネスに影響を与える重大で悪用可能な脆弱性を見つけて報告します。 20以上のカスタムツールを使用して攻撃面をマッピングし、特権を昇格させるセキュリティ問題を見つけ、自動化されたエクスプロイトを使用して重要な証拠を収集し、あなたの努力を説得力のある報告書に変えます。
これはphpMyAdminのクッキーにも当てはまります。
クッキー:
場所:
PHPで==
が使用されると、比較が期待通りに動作しない予期しないケースがあります。これは「==」が同じ型に変換された値のみを比較するためであり、比較されるデータの型も同じであることを比較したい場合は===
を使用する必要があります。
PHPの比較表: https://www.php.net/manual/en/types.comparisons.php
"string" == 0 -> True
数字で始まらない文字列は数字と等しい
"0xAAAA" == "43690" -> True
10進数または16進数形式の数字で構成された文字列は、数字が同じであれば他の数字/文字列と比較でき、結果はTrueになります(文字列内の数字は数字として解釈されます)
"0e3264578" == 0 --> True
"0e"で始まり、何かが続く文字列は0と等しい
"0X3264578" == 0X --> True
"0"で始まり、任意の文字(Xは任意の文字)で続き、何かが続く文字列は0と等しい
"0e12334" == "0" --> True
これは非常に興味深いです。なぜなら、場合によっては「0」の文字列入力とそれにハッシュされて比較されるコンテンツを制御できるからです。したがって、「0e」で始まり、任意の文字がない値を提供できれば、比較をバイパスできる可能性があります。この形式のすでにハッシュされた文字列はここで見つけることができます: https://github.com/spaze/hashes
"X" == 0 --> True
文字列内の任意の文字はint 0と等しい
詳細はhttps://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09を参照してください。
型ジャグリングはデフォルトでin_array()
関数にも影響を与えます(厳密な比較を行うには、3番目の引数をtrueに設定する必要があります):
この関数が任意の認証チェック(パスワードの確認など)に使用されている場合、ユーザーが比較の一方を制御できると、パスワードの値として文字列の代わりに空の配列を送信することができ(https://example.com/login.php/?username=admin&password[]=
)、このチェックをバイパスすることができます:
strcasecmp()
でも同じエラーが発生します。
===
が使用されている場合でも、比較が脆弱になる型ジャグリングを引き起こすエラーがある可能性があります。例えば、比較が比較する前にデータを異なる型のオブジェクトに変換している場合:
preg_match()
は ユーザー入力を検証する ために使用できます(それは ブラックリスト の 単語/正規表現 が ユーザー入力 に 存在するか を チェック し、存在しない場合はコードの実行を続けることができます)。
しかし、正規表現の開始を区切る際に preg_match()
は ユーザー入力の最初の行のみをチェック します。したがって、何らかの方法で 複数行 で入力を 送信 できる場合、このチェックをバイパスできる可能性があります。例:
このチェックを回避するには、新しい行をURLエンコードした値を送信する(%0A
)か、JSONデータを送信できる場合は、複数行で送信します:
ここに例があります: https://ramadistra.dev/fbctf-2019-rceservice
(このバイパスは明らかに PHP 5.2.5 で試され、PHP 7.3.15 では動作しませんでした)
preg_match()
に有効な非常に 大きな入力 を送信できれば、処理できなくなり、チェックを バイパス できるようになります。たとえば、JSON をブラックリストにしている場合、次のように送信できます:
From: https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0
Trick from: https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223 and https://mizu.re/post/pong
要するに、この問題はPHPのpreg_*
関数がPCREライブラリに基づいているために発生します。PCREでは、特定の正規表現が多くの再帰呼び出しを使用して一致され、これにより多くのスタックスペースが消費されます。再帰の許可される回数に制限を設定することは可能ですが、PHPではこの制限はデフォルトで100,000であり、スタックに収まる以上の数です。
このStackoverflowスレッドも、問題についてより深く語られている投稿にリンクされています。私たちのタスクは明確でした:
正規表現が100,000回以上の再帰を行うような入力を送信し、SIGSEGVを引き起こし、preg_match()
関数がfalse
を返すようにして、アプリケーションが私たちの入力を悪意のあるものではないと考えさせ、ペイロードの最後に{system(<verybadcommand>)}
のような驚きを投げかけてSSTI --> RCE --> フラグを取得すること :)。
さて、正規表現の用語で言えば、実際には100kの「再帰」を行っているわけではなく、「バックトラッキングステップ」を数えているのです。これはPHPのドキュメントによれば、pcre.backtrack_limit
変数のデフォルトは1,000,000(1M)です。
それを達成するために、'X'*500_001
は100万のバックトラッキングステップ(500k前進と500k後退)を生成します:
もしPHPが別のページにリダイレクトしているが、ヘッダーLocation
が設定された後に**die
またはexit
関数が呼び出されていない**場合、PHPは実行を続け、データをボディに追加します:
Check:
File Inclusion/Path traversalregister_globals: PHP < 4.1.1.1 または誤って設定された場合、register_globals が有効である可能性があります(またはその動作が模倣されています)。これは、グローバル変数のような $_GET に値がある場合、例えば $_GET["param"]="1234" の場合、$param を介してアクセスできることを意味します。したがって、HTTP パラメータを送信することで、コード内で使用される変数を上書きできます。
同じドメインの PHPSESSION クッキーは同じ場所に保存されます。したがって、ドメイン内で 異なるパスで異なるクッキーが使用されている場合、そのパスが 他のパスのクッキーにアクセスするように設定することができます。 この方法で、両方のパスが同じ名前の変数にアクセスする場合、path1 のその変数の値を path2 に適用させることができます。そして、path2 は path1 の変数を有効と見なします(path2 に対応する名前のクッキーを与えることによって)。
マシンの ユーザー名 を持っている場合は、アドレス /~<USERNAME> を確認して、php ディレクトリが有効になっているかどうかを確認します。
この関数は通常、PHP で パスワードからハッシュを生成するため、および ハッシュと比較してパスワードが正しいかどうかを確認するため に使用されます。
サポートされているアルゴリズムは: PASSWORD_DEFAULT
と PASSWORD_BCRYPT
($2y$
で始まります)。注意すべきは、PASSWORD_DEFAULT は頻繁に PASSWORD_BCRYPT と同じであることです。 現在、PASSWORD_BCRYPT には 72 バイトの入力サイズ制限があります。したがって、このアルゴリズムで 72 バイトを超えるものをハッシュしようとすると、最初の 72B のみが使用されます:
このツイッタースレッドから、1000を超えるGETパラメータや1000を超えるPOSTパラメータ、または20ファイルを送信すると、PHPはレスポンスにヘッダーを設定しないことがわかります。
これにより、例えば次のようなコードで設定されているCSPヘッダーをバイパスすることが可能になります:
もしPHPページがエラーを印刷し、ユーザーが提供した入力をエコーしている場合、ユーザーはPHPサーバーに十分に長いコンテンツを印刷させることができ、サーバーがレスポンスにヘッダーを追加しようとするとエラーを投げることになります。 次のシナリオでは、攻撃者がサーバーに大きなエラーを投げさせました。画面で見ると、PHPがヘッダー情報を変更しようとしたとき、できなかったことがわかります(例えば、CSPヘッダーはユーザーに送信されませんでした):
ページを確認してください:
PHP SSRFsystem("ls"); `ls`; shell_exec("ls");
こちらをチェックして、より便利なPHP関数を見つけてください
"replace" 引数でコードを実行するには、少なくとも1つの一致が必要です。 この preg_replace のオプションは PHP 5.5.0 以降非推奨です。
このphp内の関数は、文字列で書かれたコードを実行することを可能にし、真または偽を返す(これに応じて実行を変更する)。通常、ユーザー変数は文字列の中間に挿入される。例えば:
assert("strpos($_GET['page']),'..') === false")
--> この場合、RCEを得るためには次のようにすることができる:
あなたはコードの構文を 壊し、ペイロードを 追加し、そして再び修正する必要があります。"and"や"%26%26"や"|"のような論理演算子を使用できます。"or"や"||"は機能しないことに注意してください。最初の条件が真である場合、私たちのペイロードは実行されません。同様に、";"も機能しません。なぜなら、私たちのペイロードは実行されないからです。
別のオプションは、文字列にコマンドの実行を追加することです:'.highlight_file('.passwd').'
別のオプション(内部コードがある場合)は、実行を変更するためにいくつかの変数を修正することです:$file = "hola"
この関数は、特定の関数を使用してアイテムの配列をソートするために使用されます。 この関数を悪用するには:
You can also use // to comment the rest of the code.
To discover the number of parenthesis that you need to close:
?order=id;}//
: エラーメッセージが表示されます(Parse error: syntax error, unexpected ';'
)。おそらく、1つ以上の括弧が不足しています。
?order=id);}//
: 警告が表示されます。それは正しいようです。
?order=id));}//
: エラーメッセージが表示されます(Parse error: syntax error, unexpected ')' i
)。おそらく、閉じ括弧が多すぎます。
.htaccessをアップロードできる場合、いくつかの設定を行い、コードを実行することさえできます(拡張子が .htaccess のファイルが実行されるように設定すること)。
異なる .htaccess シェルはこちらで見つけることができます。
PHPでenv変数を変更できる脆弱性を見つけた場合(ファイルをアップロードするための別の脆弱性も必要ですが、さらに調査すれば回避できるかもしれません)、この動作を悪用してRCEを取得できます。
LD_PRELOAD
: この環境変数は、他のバイナリを実行する際に任意のライブラリを読み込むことを許可します(ただし、この場合は機能しないかもしれません)。
PHPRC
: PHPに設定ファイルの場所を指示します。通常は php.ini
と呼ばれます。独自の設定ファイルをアップロードできる場合は、PHPRC
を使用してPHPにそれを指し示します。2番目のアップロードファイルを指定する**auto_prepend_file
エントリを追加します。この2番目のファイルには通常のPHPコードが含まれ、PHPランタイムによって他のコードの前に実行されます**。
シェルコードを含むPHPファイルをアップロードします。
1ステップでアップロードしたファイルを実行するようにPHPプリプロセッサに指示する**auto_prepend_file
**ディレクティブを含む2番目のファイルをアップロードします。
PHPRC
変数を2ステップでアップロードしたファイルに設定します。
このチェーンを実行する方法についての詳細は元のレポートから取得できます。
PHPRC - 別のオプション
ファイルをアップロードできない場合、FreeBSDでは**stdin
を含む"ファイル" /dev/fd/0
を使用できます。これは、stdin
に送信されたリクエストの本体**です:
curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'
またはRCEを取得するために、**allow_url_include
**を有効にし、base64 PHPコードを含むファイルを前置きします:
curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'
技術はこのレポートから。
WebサーバーはHTTPリクエストを解析し、http://host/cgi.php?foo=bar
のようなリクエストを実行するPHPスクリプトに渡します(php.exe cgi.php foo=bar
として)。これにより、パラメータの注入が可能になります。これにより、ボディからPHPコードを読み込むために次のパラメータを注入できます:
さらに、PHPの後の正規化により、0xAD文字を使用して"-"パラメータを注入することが可能です。 この投稿からのエクスプロイトの例を確認してください。
この記事では 非常に少ない文字でブレインファック PHP コードを生成するための素晴らしいアイデアを見つけることができます。 さらに、いくつかのチェックをバイパスすることを可能にする関数を実行するための興味深い方法も提案されています:
これらの関数への呼び出しにコードを挿入できるか確認してください(こちらから):
PHPアプリケーションをデバッグしている場合は、/etc/php5/apache2/php.ini
にdisplay_errors = On
を追加してエラープリンティングをグローバルに有効にし、apacheを再起動します: sudo systemctl restart apache2
www.unphp.netを使用してPHPコードをデオブフスケートできます。
PHPラッパーとプロトコルは、システム内の書き込みおよび読み取り保護をバイパスし、妥協することを可能にする場合があります。詳細についてはこのページを確認してください。
phpconfig()
の出力にXdebugが有効であることが表示された場合は、https://github.com/nqxcode/xdebug-exploitを介してRCEを取得することを試みるべきです。
もしページで任意のクラスの新しいオブジェクトを作成できる場合、RCEを取得できるかもしれません。以下のページを確認して学んでください:
PHP - RCE abusing object creation: new $_GET["a"]($_GET["b"])https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
この解説 によると、次のようにして簡単なシェルコードを生成することが可能です:
だから、数字と文字なしで任意のPHPを実行できる場合、次のようなリクエストを送信して、そのペイロードを悪用して任意のPHPを実行できます:
より詳細な説明については、https://ctf-wiki.org/web/php/php/#preg_matchを確認してください。
あなたのウェブアプリ、ネットワーク、クラウドに対するハッカーの視点を得る
実際のビジネスに影響を与える重大で悪用可能な脆弱性を見つけて報告します。 20以上のカスタムツールを使用して攻撃面をマッピングし、特権を昇格させるセキュリティ問題を見つけ、自動化されたエクスプロイトを使用して重要な証拠を収集し、あなたの努力を説得力のある報告書に変えます。
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)