程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php代碼審計學習之dvwa_sql,php審計dvwa_sql

php代碼審計學習之dvwa_sql,php審計dvwa_sql

編輯:關於PHP編程

php代碼審計學習之dvwa_sql,php審計dvwa_sql


0x00

  由於轉了onenote行列,所以已經好久沒有發表新的隨筆了,但是想想還是非常有必要的,這幾天開始學習php代碼審計,所以先開始發這一些的隨筆吧!

  首先就先通過十大測試平台dvwa開始學習吧,先在這裡帶上參考的大牛鏈接,感謝分享

  1.http://drops.wooyun.org/papers/483

  2.http://www.lxway.com/86980986.htm   is_numeric 函數繞過

  3.http://www.cnblogs.com/Safe3/archive/2008/08/22/1274095.html  字符編碼繞過  寬字節注入

0x01

  這裡先帶入最簡單low級別的php代碼

  

  $id = $_GET['id'];//未作任何過濾,防注入處理
    $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
    $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );

  看到這裡我們可以知道這段代碼其實對id沒有進行處理,導致sql注入漏洞,ok,各種注入都可以,在這裡就不再詳敘了!

0x02

  medium級別,代碼:

  $id=$_GET['id'];
  $id=mysql_real_escape_string($id);//這裡對id進行了轉義的操作
  $getid="SELECTfirst_name,last_nameFROMusersWHEREuser_id=$id";

  mysql_real_escape_string 函數對id參數進行了轉義操作,具體常見的轉義包括

  • ' => \'
  • " => \"
  • \ => \\
  • \n => \\n

  這裡我想應該有2張方法來繞過這個處理:

  1.數值型注入

    由於這個函數主要針對的是字符型特殊字符的處理,這樣我們可以不使用特殊字符來進行注入,即數值注入

  

  構造:1 untion select user,password from users

    由此可以獲得users表中的賬號密碼,當然你會說要是是不知道具體表名列名改怎麼辦?ok,我們可以嘗試使用union bool注入

  構造:1+union+select+1,(select+case+when+char(72)=(select mid(table_name,0,1) from information_schema.tables limit 0,1)+then+2+end) 

    其中char()中的數值需要變換以及limit,這樣子可能會比較花時間,我們可以寫個python腳本(ps:先占個坑),其實用延時注入也同樣可以實現這樣的效果

  2.寬字節注入

  mysql_real_escape_string  對參數進行轉義的方法就是添加一個‘\’,它的url編碼就是%5c ,這樣我們在參數中添加%df%5c%27 ,其中%df%5c為合法的gbk字符

  那麼經過該函數一處理,可以發現會變成%df%5c%5c%27 ,這樣子%df%5c會吞掉一個%5c  變成 一個gbk字符+ \\\' 

  而mysql的轉義符也是'\' 相當於注入了一個單引號

  構造:1%df%5c%27%20||1+--+ 

  同樣的addslashes函數也存在同樣的問題,具體參考文章開始的鏈接

0x02

  high級別的php代碼

$id=$_GET['id'];
$id=stripslashes($id);//剔除參數中的斜槓
$id=mysql_real_escape_string($id);//對id中的特殊字符進行轉義
if(is_numeric($id)){//判斷是否是數值或數值字符串
    ...

  好吧,這樣一來,我覺得還是變得很安全了,前面2個函數對字符型的注入進行了處理,緊接著is_numeric函數則對數值型注入進行了處理。

  然而這樣子仍然可以造成sql注入,不過是二次注入,且限制的條件也比較苛刻但是仍有機會造成注入

  比如執行sql語句

  

  insert into test(type) values($s);   

 

  此時傳入的字符串$s=0x31206f722031  

  這樣看可以知道這是一個16進制數,可以通過該函數的檢測,然後對16進制解碼我們可以發現$s其實實際的值為 ‘1 or 1’ 

  那麼這樣操作數據庫裡會變成什麼樣子

  

  可以看到數據庫將這串16進制數進行了轉碼變成了1 or 1  那麼到時候進行數據庫取值然後不經處理帶入到另一個sql語句中就會造成二次注入.所以我們在寫代碼的時候不能盲目的信任數據庫裡的數據,在取出數據時仍需要進行檢測。

0x03

  sql部分的代碼就分析到這裡,如有不正確的地方,歡迎拍磚!

  下篇准備sql blind :)

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved