windows下sqli-labs的搭建及學習(POST篇)


windows下sqli-labs的搭建及學習(GET篇):

http://blog.csdn.net/sherlock17/article/details/64454449

Less-11:基於錯誤的_post_單引號_字符型注入

     post型的注入一般都是登錄繞過,測試的方法與get都類似,通過查看源碼我們知道以post方式傳遞的兩個參數是uname和passwd,那么首先來嘗試下單引號

     從這里的報錯中可以知道后台的sql語句應該是select username,password from table where username='$_GET['uname']' and password='$_GET['passwd']' limit 0,1

     而這里之所以報錯是因為加號沒有被轉義,可以換成--%20來注釋后面的limit,然后我們可以構造永真語句繞過登錄

     接着猜字段數

     再試試3,報錯,說明用select查詢的是兩個字段


    於是 用union來爆數據庫名


     依次爆表名,字段

     最后的payload:

     這里還有一個需要注意的地方,username和password的輸入框都可以作為注入點,但是在前一個參數處注入時只能注釋掉后面的語句,而在最后一個參數處注入時既可以注釋也可以閉合,閉合即uname=&passwd=' or 1='1,后一個1前的單引號會與limit前的單引號匹配(閉合)可以正常執行,之所以username那里不能使用閉合,是因為一旦使用后語句將變成:

     select username,password from table where username='$_GET['uname']' or 1=1 and password='$_GET['passwd']' limit 0,1

     這里的and運算符優先級比or高,語句會先執行1=1 and password='$_GET['passwd']',因為我們並不知道正確的password值,故該語句必為flase,且username的值也是flase,兩者進行or運算,其結果也必然是flase


Less-12:基於錯誤的_雙引號_post_字符型_變形注入

     嘗試單引號沒反應,再試試雙引號

     繞過登錄:

     方法同之前一樣,payload:


Less-13:單引號_post_字符型_雙注入_變形注入

     嘗試之前的方法,可以登入但沒有返回用戶信息

     從源碼中可以看到,輸出被注釋了

     於是嘗試雙注入,直接上payload:



Less-14:雙引號_post_字符型_雙注入_變形注入

     把less-13改成雙引號就行了


Less-15:單引號_post_bool型/時間型盲注

     輸入單引號和雙引號出錯但都沒顯示報錯,加入永真式單引號可以登入,但也沒有用戶信息

     嘗試雙注入,仍然沒有用戶信息返回

     查看源碼發現,他將輸出和sql報錯都注釋了,less-13僅注釋了輸出所以可以用雙注入

     這里只能考慮盲注了,因為合法輸入和非法輸入返回的是不同的頁面,所以這里可以用bool盲注,盲注通常都是先確定數據庫名,表名,字段名的長度,然后再匹配內容,如下測試數據庫名的長度



     由此可以確定數據庫名的長度是8,接着來匹配名字的8位字母

     於是可以確定數據庫名的第一個字母是's',按照這個方法逐個去匹配,最好的方式還是寫個腳本,省時省力


Less-16:雙引號_post_bool型/時間型盲注

     輸入uname=&passwd=") or 1=1%23顯示登入,其余的和less-15沒有什么不同,但也可以用來練下時間型盲注,可以構造如下兩種:

     uname=&passwd=") or (ascii(substr((select database()) ,1,1))) >115 or if(1=1, sleep(5), null)%23

     uname=&passwd=") or if(ascii(substr((select database()) ,1,1))>115,1,sleep(5))%23


Less-17:基於錯誤的_post_更新查詢注入

     單雙引號嘗試后,他的畫風始終是這樣子的

     注意到他的提示password reset,估計后台會用到update,於是去翻了下源碼,果然

     他的大概執行過程是接收到username和password后,首先根據username的值查詢數據庫返回username和password,然后再將原有的password值用接收到的值替換掉,這里有一個問題是,username在接收時用了一個自定義的過濾函數check_input(),這個函數首先做了判空處理,合法就截取username的前15個字符,然后是通過get_magic_quotes_gpc()的返回值判斷magic_quotes_gpc的值是on還是off:

     magic_quotes_gpc=on時, 不用對輸入和輸出數據庫的字符串數據作addslashes()和stripslashes()的操作,數據也會正常顯示。

如果此時對輸入的數據作了addslashes()處理,那么在輸出的時候就必須使用stripslashes()去掉多余的反斜杠。

     magic_quotes_gpc=off 時,必須使用addslashes()對輸入數據進行處理,但並不需要使用stripslashes()格式化輸出,因為addslashes()並未將反斜杠一起寫入數據庫,只是幫助mysql完成了sql語句的執行。
     最后,他用了ctype_digit()判斷username值的類型是否是數字,是字符就用mysql_real_escape_string對特殊字符進行轉義

      顯然,username這里並不好注入,只有通過弱口令爆破,像是admin之類的,但是他對password的接收沒有做過濾的處理,於是我們可以在這里動手腳

     對於update的注入有幾種思路,我們將他連同insert和delete一起來總結一下:

     1、子查詢注入

     子查詢注入原理即雙注入,對於dateup、delete和insert通常都是結合or的邏輯判斷,本題為例我們對update可以構造如下語句

     獲取數據庫名:

     獲取表名:

     獲取字段名:

     獲取用戶信息;

     這里就 直接放insert和delete的后台語句了,利用原理和構造的語句與update是一樣的:

  1. INSERT INTO users (username, password) VALUES ('admin',' or (SELECT 1 FROM(SELECT count(*),concat((SELECT concat(0x7e,0x27,cast(database() as char),0x27,0x7e) FROM information_schema.tables),floor(rand()*2))x FROM information_schema.tables group by x)a)%23);  

 

  1. DELETE FROM users WHERE id=1 or (SELECT 1 FROM(SELECT count(*),concat((SELECT concat(0x7e,0x27,cast(database() as char),0x27,0x7e) FROM information_schema.tables),floor(rand()*2))x FROM information_schema.tables group by x)a)%23;  

     2、通過name_const():    

     name_const(name,value):返回給定值,當用來產生一個結果集合列時, name_const()促使該列使用給定名稱

     但他的使用范圍受限,只適用於一些數據庫版本高於5.0.12,但又稍舊的版本,像現在的5.7版本就不用想了...然而我用的就是較新的版本,注入只能顯示數據庫的版本信息,想要查詢其他的信息,會顯示Incorrect arguments to NAME_CONST,所以,這里我就不截圖了,直接放payload:

     獲取數據庫:

  1. ' or (SELECT * FROM (SELECT(name_const(database(),1)),name_const(database(),1))a) where username='admin'%23  

     獲取表名:

  1. ' or (SELECT * FROM(SELECT name_const((SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema='security'),1),name_const(( SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema='security'),1))a)%23  

     總的來說,對於update,insert和delete都有一個固定的結構:... or (select * from(select name_const((select ...),1),name_const((select...),1))a) ...

     3、通過updatexml():

     updatexml(xml_target,xpath_expr,new_xml)函數是MYSQL對XML文檔數據進行查詢和修改的XPATH函數,xml_target是目標xml,形式類似於節點目錄,xpath_expr是xml的表達式,new_xml是用來替換的xml,簡單來說就是,用new_xml把xml_target中包含xpath_expr的部分節點(包括xml_target)替換掉,比如,updatexml(<a><b><c>asd</c></b><e></e></a>,'//b',<f>abc</f>)運行結果是<a><f>abc</f><e></e></a>,其中'//b'的斜杠表示不管b節點在哪一層都替換掉,而'/b'則是指在根目錄下替換,此處xml_target的根目錄節點是a

     利用updatexml()獲取數據的固定payload是:... or updatexml(1,concat(0x7e,(...)),0) ....updatexml()的xml_target和new_xml參數隨便設定一個數就行,這里主要讓他報錯

     首先獲取數據庫名

     獲取表名:

     獲取字段名

     獲取用戶信息

     報錯了,百度一下,說是不能先select出同一表中的某些值,再update這個表(在同一語句中),也就是說將select出的結果再通過中間表select一遍,這樣就規避了錯誤,其實之前在子查詢注入中也有用到此方法,同時,還要給多加的一重select賦一個別名

     注意,這個問題只出現於mysql,mssql和Oracle不會出現此問

     最后總結一下payload:or updatexml(1,concat(0x7e,(select * from(select ....)a),0x7e),0)%23

     4、通過extractvalue():

     extractvalue(xml,xpath)函數也是MYSQL5.1以后推出的對XML文檔數據進行查詢和修改的XPATH函數,可一次獲取多個xml中某節點的值,注入時第一個參數隨便給一個數字

     直接上payload:

     payload:or extractvalue(1,concat(0x7e,(select * from(select ....)a),0x7e))%23

Less-18:基於錯誤的_post_用戶代理_頭部注入

      看標題就知道,這道題主要是通過修改User Agent獲取他的報錯信息,之前直接改password的方法肯定是不行了,從源碼可以看出來password和username都進行了過濾

     修改User Agent常用的工具有burp,Live Http Headers,Modify Headers,后兩者都是firefox的插件,其中Live Http Headers貌似因為firefox版本的更新,變得不好用了,尤其是對post數據包的重放,但是也有辦法修復,這里貼一個修復的方法:http://www.cnblogs.com/lcamry/p/5532122.html

     我下面使用的是Modify Headers,首先結合之前的updatexml報錯方法修改他的User-Agent

     然后刷新less-18的頁面就可以看到爆出的數據庫名了


     接着用同樣的方法爆出表名、字段名、用戶信息,但我這里出現了報錯暫時還沒解決,所以采用別的方法,既然這里構成了邏輯判斷,那么就可以用盲注,寫個忙盲注腳本就行


Less-19:基於報錯的_post_referer_頭部注入

     登陸后發現他直接給出了提示:“Your referer is:”

     於是用和之前相同的方法修改referer:

     然后爆表名:

     最后的payload:

 

Less-20:基於報錯的_post_cookie_頭部注入

     換個地方繼續注,直接上payload:

 

Less-21:基於錯誤的_復雜型_字符串_cookie注入

     登錄成功后,發現一個奇怪的地方,我登錄的賬號是admin,但是顯示的cookie不是admin,於是去翻了下源碼

     原來是對cookie中的username做了base64加密,把頁面上顯示的cookie值拿去解密確實是admin

     那么修改cookie的時候就可以把語句先做一次base64的加密,然后再賦給uname,這樣就可以突破了,直接上最后的payload:') union select 1,group_concat(username),group_concat(password) from users#

 

 

Less-22:基於錯誤的_post_雙引號_字符型_cookie注入

     這個和Less-21差別不大,只是')改成"就可以了,下面直接上payload:" union select 1,group_concat(username),group_concat(password) from users#




參考文獻:
http://blog.csdn.net/ysynhtt/article/details/45115849
http://blog.csdn.net/priestmoon/article/details/8016121


免責聲明!

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



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