漏洞分為系統漏洞和應用漏洞,系統漏洞以二進制漏洞為代表,其挖掘難度較高需要對反匯編和操作系統原理深入理解,而除了系統漏洞以外還有一些應用漏洞,包括不限MySQL,Apache,為代表的Web漏洞,這里我們就挖掘PHP代碼層面的漏洞。
漏洞的挖掘也分為,點對點挖掘漏洞,和分散式挖掘漏洞,這我們主要使用點對點挖掘,在挖掘是我們需要找一些關鍵字,漏洞本身就是兩個條件,可控的函數,和可控的變量。
1.首先打開about.php源代碼,然后 $GET[r] 通過GET的方式接收一個傳遞參數,然后通過使用 addslashes 函數過濾,addslashes函數的作用是轉義,將多余的單引號全部轉義,轉義以后交給llink變量保存結果,然后拼接SQL查詢語句,由於拼接代碼 $llink中存在單引號,那我們需要手動閉合單引號,一旦閉合單引號addslashes函數就起了作用,會自動過濾掉單引號,所以這里無法被繞過。
<?php require 'inc/conn.php'; require 'inc/time.class.php'; $query = "SELECT * FROM settings"; $resul = mysql_query($query) or die('SQL語句有誤:'.mysql_error()); $info = mysql_fetch_array($resul); $llink = addslashes($_GET['r']); $query = "SELECT * FROM nav WHERE link='$llink'"; $resul = mysql_query($query) or die('SQL語句有誤:'.mysql_error()); $navs = mysql_fetch_array($resul); ?>
2.打開另一個 content.php 觀察下方的PHP代碼,雖然有很多處數據庫的操作,但是帶入查詢時都是通過單引號括起來的,並且每一個語句都強制使用addslashes函數進行了不同程度的轉義,這里並沒有可利用的地方。
<?php require 'inc/conn.php'; require 'inc/time.class.php'; $query = "SELECT * FROM settings"; $resul = mysql_query($query) or die('SQL語句有誤:'.mysql_error()); $info = mysql_fetch_array($resul); $id=addslashes($_GET['cid']); $query = "SELECT * FROM content WHERE id='$id'"; $resul = mysql_query($query) or die('SQL語句有誤:'.mysql_error()); $content = mysql_fetch_array($resul); $navid=$content['navclass']; $query = "SELECT * FROM navclass WHERE id='$navid'"; $resul = mysql_query($query) or die('SQL語句有誤:'.mysql_error()); $navs = mysql_fetch_array($resul); //瀏覽計數 $query = "UPDATE content SET hit = hit+1 WHERE id=$id"; @mysql_query($query) or die('修改錯誤:'.mysql_error()); ?> <?php $query=mysql_query("select * FROM interaction WHERE (cid='$id' AND type=1 and xs=1)"); $pinglunzs = mysql_num_rows($query) ?>
3.打開 submit.php 文件,觀察代碼發現這里作者寫遺漏了,這里並沒有過濾函數的過濾,而且都是POST方式傳遞的參數,明顯可以使用POST注入。
<?php session_start(); require 'inc/conn.php'; $type=addslashes($_GET['type']); $name=$_POST['name']; $mail=$_POST['mail']; $url=$_POST['url']; $content=$_POST['content']; $cid=$_POST['cid']; $ip=$_SERVER["REMOTE_ADDR"]; $tz=$_POST['tz']; if ($tz==""){$tz=0;} $jz=$_POST['jz'];
將代碼向下翻,可以看到 SELECT * FROM interaction WHERE( mail = '$mail') 這么一條查詢語句,這條語句雖然 $mail 參數被加了單引號,但是由於沒有進行有效的過濾,所以我們可以通過構建一些SQL語句巧妙地閉合它。
//查詢用戶頭像數據 $query = "SELECT * FROM interaction WHERE( mail = '$mail')"; $result = mysql_query($query) or die('SQL語句有誤:'.mysql_error()); $tx = mysql_fetch_array($result); if (!mysql_num_rows($result)){ $touxiang = mt_rand(1,100); }else{ $touxiang = $tx['touxiang']; }
繼續向下找,同樣的在最下方也發現了存在查詢語句 SELECT * FROM download WHERE( id= $cid) 這個cid參數,也沒有進行合法化的檢查,也是一個SQL注入漏洞。
if ($type==3){ $query = "SELECT * FROM download WHERE( id= $cid)"; $result = mysql_query($query) or die('SQL語句有誤:'.mysql_error()); $wz = mysql_fetch_array($result); $title=$wz['title']; $body ='<div style="border:1px double #06f;">
上方兩處就是這個CMS系統的注入漏洞,雖然mail參數上有單引號,但是並沒有檢查合法化,這里我們只需要將其閉合掉就可以。
這兩個變量我們能夠操作他,因為它帶入到數據庫查詢了,我們只需要把前面的單引號閉合掉。
4.上方的漏洞文件在 /files/submit.php,且文件的開頭都是 $_POST['xxx']; 明顯這是POST注入,這里如果直接使用 http://127.0.0.1/cms/files/submit.php 訪問的話會報錯,原因是包含不到 require 'inc/conn.php'; 這個文件,我們繼續看下主 index.php 是怎么包含的,如下代碼:
<?php error_reporting(0); //關閉錯誤顯示 $file=addslashes($_GET['r']); //接收文件名 $action=$file==''?'index':$file; //判斷為空或者等於index include('files/'.$action.'.php'); //載入相應文件 ?>
如上:首先通過 $_GET['r] 接收一個參數,然后傳遞給file,action 如果為空則等於index,最終包含 files/.action.php,如果要訪問 /files/submit.php 包含以后的寫法是:?r=submit 或者完整寫法 /index.php?r=submit
5.為了方便演示,我們在 submit.php 文件中加入以行打印函數,echo $mail; 打印出mail里面的參數
<?php session_start(); require 'inc/conn.php'; $type=addslashes($_GET['type']); $name=$_POST['name']; $mail=$_POST['mail']; echo $mail; < ------------------------ $url=$_POST['url'];
然后使用火狐瀏覽器的hackBar插件進行POST注入,如下圖注入成功了。
除此之外,login.php 文件中也存在一個注入漏洞 /cms/admin/?r=login ,我們可以直接寫出他的exp ,但是這里沒有地方可以完成回顯,但漏洞是存在的。
直接記下 http://127.0.0.1/cms/admin/?r=login 網址然后,我們打開SQLMAP跑一下。