SQL注入詳細講解概括-GET注入、POST注入、HEAD注入


SQL注入詳細講解概括-GET注入、POST注入、HEAD注入

1、SQL注入流程

2、GET注入

3、POST注入

4、HEAD注入


一、SQL注入流程

  1、SQL注入流程

  · 尋找注入點—與數據庫交互的地方,比如登錄框,搜索框、URL地址欄、登陸界面、留言板等等

  · 判斷是否存在注入點,判斷數據庫類型,確定注入方法

  · 構造特殊語句,查詢數據庫數據

二、GET注入

  1、What is GET注入

  要搞懂GET注入之前,先搞懂什么是GET傳參。

  GET傳參:用戶輸入的內容參數會被傳到地址欄(URL欄),是通過GET的方式進行傳參

  · 特點:傳參內容可見,傳參長度有限,標識“?”,輸入的內容會可能被url編碼

  GET注入:通過GET傳參的方式,傳輸惡意語句,進行SQL注入

  

   2、如何進行GET注入

  一般情況判斷為傳參方式為GET傳參方式,首先進行GET注入測試,判斷是否存在GET注入

  如何判斷是否存在GET注入:要想知道是否存在,首先搞原理,弄清楚是如何發生的

  簡單說,原本程序要執行的代碼拼接了用戶輸入的數據然后執行,就是本來用戶輸入的數據是要被查詢的,但是被數據庫當作代碼執行

  OK,AND,只需知道輸入的數據有沒有被數據庫當作代碼,可以判斷存不存在注入點

  AND,用戶輸入的數據一定不是輸入everying都行的,如果用戶隨便輸入的數據都被當做代碼執行,那么這個網站就失去了它的功能,這是網站開發者不允許的

  SO,要輸入什么數據才能被判斷是否存在注入點呢

  先來看一段代碼 

$query  = "SELECT first_name, last_name FROM users WHERE user_id = $id

用戶輸入參數傳入$id  

來輸入1  >>>>  $id=1    >>> sql語句就變成了下面這樣
$query  = "SELECT first_name, last_name FROM users WHERE user_id = 1

ok,look look 現在數據庫收到的數據是這樣的,,
SELECT first_name, last_name FROM users WHERE user_id = 1

AND,輸入什么能夠讓數據庫執行一些別的操作
思考ing time(3min)

當然是數據庫語言了,,,試一試  or  怎么樣 
ok,, >>>  1 or 1=1 >>> $id=1 or 1=1

SELECT first_name, last_name FROM users WHERE user_id = 1 or 1=1

輸入的內容當作代碼執行了  //這個叫做整形閉合

    在來看一段,這次 把變量用引號引起來,用單引號or用雙引號,是不一樣的破解方法

$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"
上面雙引號里的是要被傳入數據庫執行的

first,輸入的數據被傳入$id這個變量

ok,那么輸入一個 1	,$id=1  and 此語句就變成了:

SELECT first_name, last_name FROM users WHERE user_id = '1'

那么要怎么做才能變成輸入的數據變成代碼執行呢?
思考ing  time(5min)

ok,無論輸入什么數據他都在引號里,那輸入的數據就沒有任何意義對吧,
那就來突破引號,如何突破

,,look here 》》 1' or 1=1 '  》》 $id=1' or 1=1 '   拼接試一試

SELECT first_name, last_name FROM users WHERE user_id = '1' or 1=1 ''
FUCK,,有問題了,,不一樣了    //這個叫做單引號閉合

那么再來思考一個問題,當變量用雙引號引起來怎么辦,不是沒用引號,也不是單引號
思考ing time(2min)

ok,easy 那就用雙引號破解唄

SELECT first_name, last_name FROM users WHERE user_id = "$id"

look here 》》》 1" or 1=1 " 》》》 $id=1" or 1=1 "

SELECT first_name, last_name FROM users WHERE user_id = "1" or 1=1 ""

success,easy //這個叫做雙引號閉合

  OK,上面是能看到后端代碼的,哪個網站願意讓你看到他的后端代碼,It won't

  AND,看不到源碼,怎么進行注入呢

  so easy , 通過傳入的惡意代碼,觀察頁面情況 ,是否正常等,來判斷是否存在注入點,確定注入方法

  首先我們找到傳參點,進行注入 嘗試 ,首先判斷閉合類型

  SQL語句的閉合類型:整型閉合、單引號閉合、雙引號閉合、單引號加括號、雙引號加括號

  · 整形閉合 

1
SELECT  FROM  admin  WHERE  id=1;   //整形閉合

  模擬注入

  ?id=1'   =>  報錯

  ?id=1''  =>  報錯

  判斷為整形閉合

  · 單引號閉合 

1
SELECT  FROM  admin  WHERE  id=‘1’;  //單引號閉合

  模擬注入

  ?id=1'  =>  報錯

  ?id=1'' =>  正常返回id=1的值

  判斷為單引號或者單引號括號閉合

  任何閉合方式都這樣在沒有遇到相對應的閉合時,都會把這個符號當作一個整體,注釋符也不例外

  再次模擬注入

  ?id=1'-+  =>  無報錯 => 單引號閉合

  ?id=1'-+  =>  報錯  =>  單引號括號閉合

  · 雙引號閉合 

1
SELECT  FROM  admin  WHERE  id= "1" ;  //雙引號閉合

 

  ?id=1'  => 正常返回id=1的值

  ?id=1" => 報錯

  判斷為雙引號閉合或者雙引號括號閉合

  再次模擬注入

  ?id=1"-+  => 無報錯 => 雙引號閉合

  ?id=1"-+ => 報錯  =>  雙引號括號閉合

  · 總結

  判斷閉合類型

  首先嘗試:?id=1'

       ?id=1"

  不報錯 =>  整形閉合

  報錯   =>  單引號報錯 ,雙引號不報錯 => 嘗試 ?id=1'-+  =>  無報錯單引號閉合,報錯單引號加括號閉合

  報錯  =>  單引號不報錯,雙引號報錯  =>  嘗試 ?id=1"-+  =>  無報錯雙引號閉合,報錯雙引號加括號閉合

  

  注入點找到,確定閉合方式開始進行注入攻擊,以DVWA靶場為例

  First,觀察url欄 判斷為GET傳參,先進行正常內容輸入,輸入1 ,看返回結果

  

   第二步,測試是否存在注入,進行惡意語句測試,不知道閉合類型,先從整形閉合開始判斷 1 and 1=1

  

   頁面正常,與id=1 時返回的內容一樣  不確定是否注入成功,因為and 1=1 恆成立 所以還得進行第二次判斷,1 and 1=2

  

   頁面正常,與id=1 時返回的內容一樣,and 1=2 是恆不成立的,如果數據庫執行了代碼那么應該是沒有數據返回的,現在返回了數據,so,不是整形閉合

  ok,既然不是整形閉合,那么去嘗試是不是單引號閉合,輸入   1',,,把錯誤顯示出來了,說明是單引號閉合,既存在注入,又確定是單引號閉合,那么可以進行注入了。AND,我輸入的是1'  為什么url的傳參是1%27,這是因為get傳參會被url編碼,這個引號被url編碼了,HTTP請求GET請求一般要進行URL編碼,為什么呢,這是為了防止URL中的參數和HTTP中的一些參數沖突,導致奇異。

  

  OK,下面開始SQL注入

  First,已經找到注入點,判斷出閉合類型,開始 通過惡意語句來獲取數據庫信息

  第一步,猜解字段數,用到語法:order by  X   當X大於字段數就會顯錯,小於或等於正常返回頁面

  通過order by語句查出當前表有兩個字段,為什么要先查字段數? 思考ing time(1min)

  answer >>>>  因為下面要想查數據庫其他的內容,不可能再用當前表吧,得通過聯合查詢吧,那么聯合查詢的必要條件>>>多個表的字段數必須相同

  

   第二步,判斷顯位,why? 

  answer >>>一個表可能有多個字段,但是我們頁面上看到的可能並不是表的字段的全部,開發者可能頁面內容只輸出指定的那幾個字段,那是不是我們就看不到其他的字段呢,so,頁面顯示並不一定是全部字段。那我們就要判斷出字段顯位,同時也輸出另一個表同樣的顯位,這樣查詢的信息才可能通過 顯位 輸出到頁面。

  HOW?

  answer>>>有的網站,會規定這個顯位,輸出的數據指定是多少,如果開發者指定只能輸出一條數據,那么聯合查詢好像也沒什么作用了,因為聯合查詢是先輸出前面表的數據,我們需要的是后面的表的數據,有遇到難題了。。。思考ing time(2min)

  ok,用聯合查詢,當一個表里沒有查詢到數據,那么不輸出這個表的數據,,,,可不可以,前面的表不輸出數據呢。。of course

  1.111111111111,1,998787,6.37176,90000.88877,,,,這些數據數據庫里可以說是百年不會見吧,那我們去查他,是不是空?? of course

  ok,構建惡意語句>>>> 1.11114434' union select 1,2 #

  

  如上圖,從第一步得知有兩個字段,用來判顯位,兩個字段內容全部顯示,當然這種情況的概率是非常小的

  ok,顯位判斷完畢

  第三步,查詢當前數據庫

  HOW?思考ing time(1min)

  database()函數

1.7274972' union select 1,database() #

  

   ok,顯位已經判斷完畢,下面才是剛剛開始

  第三步,對數據庫里的庫,表,字段,數據進行查詢

  HOW?

  First,需要了解數據庫,此靶場的數據庫是MySQL,后續會寫怎么識別數據庫,常見數據庫太多了,Oracle Database甲骨文公司、SQL Server微軟公司、DB2IBM公司、PostgreSQL開源、MySQL開源、Access微軟等等

  mysql在5.0以上版本加入了information_schema這個系統自帶庫,其中保存着關於mysql服務器所維護的其他數據信息,如數據庫名,數據庫的表,表欄的數據類型與訪問權限,,這個庫非常牛,,數據庫所有的 庫,表,字段的位置在這張表里都能找到

  information_scheam這個庫下面有幾個非常重要的表,必須知道的:

  information_schema.schemata  >>> 這個表保存了所有數據庫里的庫的信息

  

  information_schema.tables  >>>  這個表保存了數據庫里所有表的信息

  

 

 

   information_schema.columns  >>> 這個表保存了數據庫里所有的字段信息

  

  AND,,

  column_name 字段名

  table_name 表名

  schema_name 庫名

  OK,基礎知識已簡單了解,怎么取通過這些知識注入呢,

  思考ing  time(5min)

  OK,Time out,,,

  Look here  >>>  上一步知道了聯合查詢,對不對,要查詢數據庫信息需要知道表名呀,現在已經知道了系統自帶庫、自帶表,而且通過這幾張表我們可以得到數據庫任何數據

  OK,那下面就easy了,,,構建惡意語句,先看看,當前庫存在哪些表

1.2223' union select 1,table_name from information_schema.tables where table_schema=database()  #

  >>>

  

 

   OK,當前數據庫下的表's name有已經拿到,,定睛一看,,users,,這個表有點可疑呀,,user什么意思>>用戶   

   SO,我們來看一下users表里有什么東西,來,上惡意代碼

1.2333' union select 1,column_name from information_schema.columns where table_schema=database() and table_name='users'  #  

  >>> 

 

   OK,字段名已經獲取了,是不是有兩個非常重要的數據>>>user  \   password

  SO,獲取user and password 兩個字段的數據   ,,,>>>  惡意代碼,,,上

1.647' union select user,password from dvwa.users #

  >>>

  

 

   WC,NB,信息都出來,藍框時用戶名,綠框時密碼,但仔細一看有點不對,,哪里不對

  password被加密了,MD5加密,,百度搜MD5解密,,把密碼解出來,,so  easy

三、POST注入

  1、What is POST注入

  要搞懂POST注入,先搞懂POST傳參

  POST傳參:用戶輸入的內容被隱藏了起來,地址欄看不到

  特點:傳參內容不可見,傳參長度無限制

  POST注入:通過POST傳參的方式,傳輸惡意語句,進行SQL注入,本質和GET注入是一樣的

  

  如上圖,所示,沒有輸入地方,只有選項框,最重要的一點是,地址欄不可見傳參內容

  WC,這怎么搞,這怎么進行傳參,TMD不按套路來

  那好吧,來搬個救兵吧  >>>>>  BURP  

  BURP來抓個包吧,既然地址欄不能顯示傳參內容,抓包總可以吧

  

 

 

   

 

   OK,,來來來,,傳參內容出現了吧,,

  那就在burp里測試吧

  剩下的步驟就和GET注入一模一樣了,修改傳參內容

   OK,還是判斷閉合類型,這里判斷是整形閉合 >> 判斷字段數 >> 判斷顯位 >> 查詢數據庫數據      so easy

  直接給出結果

 

   OK,很簡單吧,再來一個全自動好不好,用工具Sqlmap來做,不懂原理用工具叫做Very low-end script boy 當我們懂了原理用工具那么我們就是 increase of efficiency

   OK,GET注入 AND  POST注入 到這就差不多了,是不是很簡單,這是最基礎的,一般網站可不會這么容易,講這個只是一個入門,告訴大家SQL注入是如何發生的,從而更好 理解高級的SQL注入,一般網站會做很多防護和過濾,,比如過濾敏感字,像and/or/#/'/"  等等這些敏感字符很容易被網站過濾和攔截,,當然了,防護還有很多高級的防護,破解也有很多高級的破解

 

四、HEAD注入

 

  1、HEAD注入原理

  在傳參的時候,將我們的數據構建在http頭部

 

  利用了php的全局變量$_server獲取用戶的相關信息且將數據存入數據庫,利用updatexml函數輸入sql語句,返回信息

 

  通常HTTP消息包括客戶機向服務器的請求消息和服務器向客戶機的響應消息。這兩種類型的消息由一個起始行,一個或者多個頭域,一個只是頭域結束的空行和可選的消息體組成。HTTP的頭域包括通用頭,請求頭,響應頭和實體頭四個部分。每個頭域由一個域名,冒號(:)和域值三部分組成。域名是大小寫無關的,域值前可以添加任何數量的空格符,頭域可以被擴展為多行,在每行開始處,使用至少一個空格或制表符。

 

  2、PHP超全局變量

 

  超全局變量

 

  php中許多預定義變量都是超全局變量,這意味着它們在一個腳本的全部作用域中都可用  

 

  $_REQUEST(獲取GET/POST/COOKIE)COOKIE在新版本已經無法獲取了
  $_POST(獲取POST傳參)
  $_GET(獲取GET傳參)
  $_COOKIE(獲取COOKIE傳參)
  $_SERVER(包含了諸如頭信息(header)、路徑(path)、以及腳本位置(script locations)等等信息的數組)
  $_SERVER['HTTP_REFERER']獲取referer請求頭數據
  $_SERVER["HTTP_USER_AGENT"]獲取用戶相關信息,包括用戶瀏覽器、操作系統等信息
  $_SERVER["REMOTE_ADDR"]瀏覽網頁的用戶ip

 

  User-Agent:服務器獲取客戶的操作系統,瀏覽器版本等,有些網站中會將獲取的信息存入數據庫中

  Cookie:身份信息、進行 session 跟蹤而儲存在用戶本地終端上的數據,一般會加密.

  X-Forwarded-For:XFF頭,代表客戶端,HTTP的請求端真實的IP,有些網站的防注入功能會記錄請求端真實IP地址並寫入數據庫,修改XXF頭可虛假IP

  Rerferer:瀏覽器告訴WEB 服務器是從哪個頁面鏈接過來的.

  Host:客戶端指定訪問的WEB服務器的域名/IP 地址和端口號

  

  3、updatexml()函數

 

  updatexml() 更新xml文檔的函數

 

  語法:updatexml(目標xml內容,xml文檔路徑,更新xml內容)

 

  OK,這里看上去是去更新了xml文檔,實際上在xml文檔路徑的位置寫了子查詢語句,然后輸入特殊字符,之后因為不符合輸入規則報錯了,其實在報錯的時候已經執行l子查詢語句

 

  【xml文檔路徑 填寫 :0x7e】

 

  concat()是拼接字符串函數

 

updatexml(1,concat(0x7e,(select database()),0x7e),1)

 

  why? 0x7e是16進制,MySQL字符串是支持十六進制的,有個前提:開頭須寫0x ,這就是告訴MySQL下面要開始十六進制了。而7e才是十六進制的內容,7e是個特殊符號,一定不符合路徑規則

 

  OK,今天的就先到這里,斷更了好久,今天多寫點,最后感恩   

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM