作者:expsky

最近,我们的网络监测设备中发现了revslider.zip文件,解压后的两个php文件mil.php,pbot.php都经过了编码处理,非常可疑。搜索revslider关键字能找到freebuf上的一篇文章《RevSlider插件漏洞导致大量WordPress网站被黑》,进一步确认了猜测,于是对这两个php文件进行了分析。

1

一、pbot.php

通常的webshell木马,顾名思义就是操作界面是web网页,通过http协议进行通讯,能远程执行shell命令。而该木马利用的是IRC协议进行通讯,操作界面是IRC聊天客户端软件,除了同样能够执行shell命令外,还能接收其他更多的远程控制命令(后面会看到)。

什么是IRC木马?

IRC是Internet Relay Chat的英文缩写,是应用层的即时通讯协议。特点是小而美,原理非常简单,用户运行基于IRC协议的客户端软件,连接上IRC服务器,就可以开始聊天了。与传统的webshell比,IRC木马远控的过程就是和肉鸡“聊天”的过程,有更多优势:

可以使用任意的IRC聊天软件来进行远程控制,操作界面更加友好

木马功能更加强大,除了执行shell命令外,可以执行更多的远控命令,而且扩展起来方便,易于维护

在一个聊天窗口,同时控制多台肉鸡(与多个肉鸡“聊天”)

如下是两个常见的IRC聊天软件:mIRC, XChat

mirc xchat

这个IRC php木马实现了基本的IRC通讯协议,木马运行后连接到了irc.mildnet.net这台IRC服务器,并进入预先设置好的私有频道(群),身在某个角落的木马作者用任意IRC客户端软件加入到相同的频道(群)。可以想象成这样一个画面,一个聊天群里有很多成员,除了木马作者外,其他成员都是被控制的肉鸡,作者可以@任何肉鸡,与它聊天,聊天的内容就是提前设置的远控命令,告诉肉鸡要做什么,肉鸡完成任务后再给作者回复结果。

IRC协议简介

IRC详细的协议比较多,这里介绍下最主要的

客户端与服务器之间通讯传递的是一条条的IRC消息,IRC消息是纯文本格式,一条IRC消息最长不超过512字节,以\r\n标志结束

一条IRC消息由三个部分组成,前缀、命令字、参数,以空格分开,其中前缀和参数不是必须的部分,命令字是IRC协议的核心,一共有几十个命令字。命令字有两种表示类型,一种是大写的带英文含义的字符串(如NICK),一种是纯数字(如433)

前缀 命令 参数 结尾符
: xxx!name@freebuf.com NICK expsky \r\n
上面是一条IRC消息,应该能猜出意思就是,告诉服务器我把自己的昵称修改为了expsky

IRC全部英文命令字:

ADMIN,AWAY,CNOTICE,CPRIVMSG,CONNECT,DIE,ENCAP,ERROR,<span class="hljs-keyword">HELP</span>,INFO,INVITE,ISON,<span class="hljs-keyword">JOIN</span>,KICK,<span class="hljs-keyword">KILL</span>,KNOCK,LINKS,<span class="hljs-keyword">LIST</span>,LUSERS,<span class="hljs-keyword">MODE</span>,MOTD,<span class="hljs-keyword">NAMES</span>,NAMESX,NICK,<span class="hljs-keyword">NOTICE</span>,OPER,PART,PASS,PING,PONG,PRIVMSG,QUIT,REHASH,RESTART,<span class="hljs-keyword">RULES</span>,<span class="hljs-keyword">SERVER</span>,SERVICE,SERVLIST,SQUERY,SQUIT,SETNAME,SILENCE,STATS,SUMMON,<span class="hljs-keyword">TIME</span>,TOPIC,<span class="hljs-keyword">TRACE</span>,UHNAMES,<span class="hljs-keyword">USER</span>,USERHOST,USERIP,<span class="hljs-keyword">USERS</span>,<span class="hljs-keyword">VERSION</span>,WALLOPS,WATCH,WHO,WHOIS,WHOWAS
`</pre>
IRC全部数字命令字:
<pre>`<span class="hljs-string">"001"</span>: <span class="hljs-string">"welcome"</span>,    <span class="hljs-string">"002"</span>: <span class="hljs-string">"yourhost"</span>,    <span class="hljs-string">"003"</span>: <span class="hljs-string">"created"</span>,    <span class="hljs-string">"004"</span>: <span class="hljs-string">"myinfo"</span>,    <span class="hljs-string">"005"</span>: <span class="hljs-string">"featurelist"</span>,    <span class="hljs-string">"200"</span>: <span class="hljs-string">"tracelink"</span>,    <span class="hljs-string">"201"</span>: <span class="hljs-string">"traceconnecting"</span>,    <span class="hljs-string">"202"</span>: <span class="hljs-string">"tracehandshake"</span>,    <span class="hljs-string">"203"</span>: <span class="hljs-string">"traceunknown"</span>,    <span class="hljs-string">"204"</span>: <span class="hljs-string">"traceoperator"</span>,    <span class="hljs-string">"205"</span>: <span class="hljs-string">"traceuser"</span>,    <span class="hljs-string">"206"</span>: <span class="hljs-string">"traceserver"</span>,    <span class="hljs-string">"207"</span>: <span class="hljs-string">"traceservice"</span>,    <span class="hljs-string">"208"</span>: <span class="hljs-string">"tracenewtype"</span>,    <span class="hljs-string">"209"</span>: <span class="hljs-string">"traceclass"</span>,    <span class="hljs-string">"210"</span>: <span class="hljs-string">"tracereconnect"</span>,    <span class="hljs-string">"211"</span>: <span class="hljs-string">"statslinkinfo"</span>,    <span class="hljs-string">"212"</span>: <span class="hljs-string">"statscommands"</span>,    <span class="hljs-string">"213"</span>: <span class="hljs-string">"statscline"</span>,    <span class="hljs-string">"214"</span>: <span class="hljs-string">"statsnline"</span>,    <span class="hljs-string">"215"</span>: <span class="hljs-string">"statsiline"</span>,    <span class="hljs-string">"216"</span>: <span class="hljs-string">"statskline"</span>,    <span class="hljs-string">"217"</span>: <span class="hljs-string">"statsqline"</span>,    <span class="hljs-string">"218"</span>: <span class="hljs-string">"statsyline"</span>,    <span class="hljs-string">"219"</span>: <span class="hljs-string">"endofstats"</span>,    <span class="hljs-string">"221"</span>: <span class="hljs-string">"umodeis"</span>,    <span class="hljs-string">"231"</span>: <span class="hljs-string">"serviceinfo"</span>,    <span class="hljs-string">"232"</span>: <span class="hljs-string">"endofservices"</span>,    <span class="hljs-string">"233"</span>: <span class="hljs-string">"service"</span>,    <span class="hljs-string">"234"</span>: <span class="hljs-string">"servlist"</span>,    <span class="hljs-string">"235"</span>: <span class="hljs-string">"servlistend"</span>,    <span class="hljs-string">"241"</span>: <span class="hljs-string">"statslline"</span>,    <span class="hljs-string">"242"</span>: <span class="hljs-string">"statsuptime"</span>,    <span class="hljs-string">"243"</span>: <span class="hljs-string">"statsoline"</span>,    <span class="hljs-string">"244"</span>: <span class="hljs-string">"statshline"</span>,    <span class="hljs-string">"250"</span>: <span class="hljs-string">"luserconns"</span>,    <span class="hljs-string">"251"</span>: <span class="hljs-string">"luserclient"</span>,    <span class="hljs-string">"252"</span>: <span class="hljs-string">"luserop"</span>,    <span class="hljs-string">"253"</span>: <span class="hljs-string">"luserunknown"</span>,    <span class="hljs-string">"254"</span>: <span class="hljs-string">"luserchannels"</span>,    <span class="hljs-string">"255"</span>: <span class="hljs-string">"luserme"</span>,    <span class="hljs-string">"256"</span>: <span class="hljs-string">"adminme"</span>,    <span class="hljs-string">"257"</span>: <span class="hljs-string">"adminloc1"</span>,    <span class="hljs-string">"258"</span>: <span class="hljs-string">"adminloc2"</span>,    <span class="hljs-string">"259"</span>: <span class="hljs-string">"adminemail"</span>,    <span class="hljs-string">"261"</span>: <span class="hljs-string">"tracelog"</span>,    <span class="hljs-string">"262"</span>: <span class="hljs-string">"endoftrace"</span>,    <span class="hljs-string">"263"</span>: <span class="hljs-string">"tryagain"</span>,    <span class="hljs-string">"265"</span>: <span class="hljs-string">"n_local"</span>,    <span class="hljs-string">"266"</span>: <span class="hljs-string">"n_global"</span>,    <span class="hljs-string">"300"</span>: <span class="hljs-string">"none"</span>,    <span class="hljs-string">"301"</span>: <span class="hljs-string">"away"</span>,    <span class="hljs-string">"302"</span>: <span class="hljs-string">"userhost"</span>,    <span class="hljs-string">"303"</span>: <span class="hljs-string">"ison"</span>,    <span class="hljs-string">"305"</span>: <span class="hljs-string">"unaway"</span>,    <span class="hljs-string">"306"</span>: <span class="hljs-string">"nowaway"</span>,    <span class="hljs-string">"311"</span>: <span class="hljs-string">"whoisuser"</span>,    <span class="hljs-string">"312"</span>: <span class="hljs-string">"whoisserver"</span>,    <span class="hljs-string">"313"</span>: <span class="hljs-string">"whoisoperator"</span>,    <span class="hljs-string">"314"</span>: <span class="hljs-string">"whowasuser"</span>,    <span class="hljs-string">"315"</span>: <span class="hljs-string">"endofwho"</span>,    <span class="hljs-string">"316"</span>: <span class="hljs-string">"whoischanop"</span>,    <span class="hljs-string">"317"</span>: <span class="hljs-string">"whoisidle"</span>,    <span class="hljs-string">"318"</span>: <span class="hljs-string">"endofwhois"</span>,    <span class="hljs-string">"319"</span>: <span class="hljs-string">"whoischannels"</span>,    <span class="hljs-string">"321"</span>: <span class="hljs-string">"liststart"</span>,    <span class="hljs-string">"322"</span>: <span class="hljs-string">"list"</span>,    <span class="hljs-string">"323"</span>: <span class="hljs-string">"listend"</span>,    <span class="hljs-string">"324"</span>: <span class="hljs-string">"channelmodeis"</span>,    <span class="hljs-string">"329"</span>: <span class="hljs-string">"channelcreate"</span>,    <span class="hljs-string">"331"</span>: <span class="hljs-string">"notopic"</span>,    <span class="hljs-string">"332"</span>: <span class="hljs-string">"currenttopic"</span>,    <span class="hljs-string">"333"</span>: <span class="hljs-string">"topicinfo"</span>,    <span class="hljs-string">"341"</span>: <span class="hljs-string">"inviting"</span>,    <span class="hljs-string">"342"</span>: <span class="hljs-string">"summoning"</span>,    <span class="hljs-string">"346"</span>: <span class="hljs-string">"invitelist"</span>,    <span class="hljs-string">"347"</span>: <span class="hljs-string">"endofinvitelist"</span>,    <span class="hljs-string">"348"</span>: <span class="hljs-string">"exceptlist"</span>,    <span class="hljs-string">"349"</span>: <span class="hljs-string">"endofexceptlist"</span>,    <span class="hljs-string">"351"</span>: <span class="hljs-string">"version"</span>,    <span class="hljs-string">"352"</span>: <span class="hljs-string">"whoreply"</span>,    <span class="hljs-string">"353"</span>: <span class="hljs-string">"namreply"</span>,    <span class="hljs-string">"361"</span>: <span class="hljs-string">"killdone"</span>,    <span class="hljs-string">"362"</span>: <span class="hljs-string">"closing"</span>,    <span class="hljs-string">"363"</span>: <span class="hljs-string">"closeend"</span>,    <span class="hljs-string">"364"</span>: <span class="hljs-string">"links"</span>,    <span class="hljs-string">"365"</span>: <span class="hljs-string">"endoflinks"</span>,    <span class="hljs-string">"366"</span>: <span class="hljs-string">"endofnames"</span>,    <span class="hljs-string">"367"</span>: <span class="hljs-string">"banlist"</span>,    <span class="hljs-string">"368"</span>: <span class="hljs-string">"endofbanlist"</span>,    <span class="hljs-string">"369"</span>: <span class="hljs-string">"endofwhowas"</span>,    <span class="hljs-string">"371"</span>: <span class="hljs-string">"info"</span>,    <span class="hljs-string">"372"</span>: <span class="hljs-string">"motd"</span>,    <span class="hljs-string">"373"</span>: <span class="hljs-string">"infostart"</span>,    <span class="hljs-string">"374"</span>: <span class="hljs-string">"endofinfo"</span>,    <span class="hljs-string">"375"</span>: <span class="hljs-string">"motdstart"</span>,    <span class="hljs-string">"376"</span>: <span class="hljs-string">"endofmotd"</span>,    <span class="hljs-string">"377"</span>: <span class="hljs-string">"motd2"</span>,    <span class="hljs-string">"381"</span>: <span class="hljs-string">"youreoper"</span>,    <span class="hljs-string">"382"</span>: <span class="hljs-string">"rehashing"</span>,    <span class="hljs-string">"384"</span>: <span class="hljs-string">"myportis"</span>,    <span class="hljs-string">"391"</span>: <span class="hljs-string">"time"</span>,    <span class="hljs-string">"392"</span>: <span class="hljs-string">"usersstart"</span>,    <span class="hljs-string">"393"</span>: <span class="hljs-string">"users"</span>,    <span class="hljs-string">"394"</span>: <span class="hljs-string">"endofusers"</span>,    <span class="hljs-string">"395"</span>: <span class="hljs-string">"nousers"</span>,    <span class="hljs-string">"401"</span>: <span class="hljs-string">"nosuchnick"</span>,    <span class="hljs-string">"402"</span>: <span class="hljs-string">"nosuchserver"</span>,    <span class="hljs-string">"403"</span>: <span class="hljs-string">"nosuchchannel"</span>,    <span class="hljs-string">"404"</span>: <span class="hljs-string">"cannotsendtochan"</span>,    <span class="hljs-string">"405"</span>: <span class="hljs-string">"toomanychannels"</span>,    <span class="hljs-string">"406"</span>: <span class="hljs-string">"wasnosuchnick"</span>,    <span class="hljs-string">"407"</span>: <span class="hljs-string">"toomanytargets"</span>,    <span class="hljs-string">"409"</span>: <span class="hljs-string">"noorigin"</span>,    <span class="hljs-string">"411"</span>: <span class="hljs-string">"norecipient"</span>,    <span class="hljs-string">"412"</span>: <span class="hljs-string">"notexttosend"</span>,    <span class="hljs-string">"413"</span>: <span class="hljs-string">"notoplevel"</span>,    <span class="hljs-string">"414"</span>: <span class="hljs-string">"wildtoplevel"</span>,    <span class="hljs-string">"421"</span>: <span class="hljs-string">"unknowncommand"</span>,    <span class="hljs-string">"422"</span>: <span class="hljs-string">"nomotd"</span>,    <span class="hljs-string">"423"</span>: <span class="hljs-string">"noadmininfo"</span>,    <span class="hljs-string">"424"</span>: <span class="hljs-string">"fileerror"</span>,    <span class="hljs-string">"431"</span>: <span class="hljs-string">"nonicknamegiven"</span>,    <span class="hljs-string">"432"</span>: <span class="hljs-string">"erroneusnickname"</span>,    <span class="hljs-string">"433"</span>: <span class="hljs-string">"nicknameinuse"</span>,    <span class="hljs-string">"436"</span>: <span class="hljs-string">"nickcollision"</span>,    <span class="hljs-string">"437"</span>: <span class="hljs-string">"unavailresource"</span>,    <span class="hljs-string">"441"</span>: <span class="hljs-string">"usernotinchannel"</span>,    <span class="hljs-string">"442"</span>: <span class="hljs-string">"notonchannel"</span>,    <span class="hljs-string">"443"</span>: <span class="hljs-string">"useronchannel"</span>,    <span class="hljs-string">"444"</span>: <span class="hljs-string">"nologin"</span>,    <span class="hljs-string">"445"</span>: <span class="hljs-string">"summondisabled"</span>,    <span class="hljs-string">"446"</span>: <span class="hljs-string">"usersdisabled"</span>,    <span class="hljs-string">"451"</span>: <span class="hljs-string">"notregistered"</span>,    <span class="hljs-string">"461"</span>: <span class="hljs-string">"needmoreparams"</span>,    <span class="hljs-string">"462"</span>: <span class="hljs-string">"alreadyregistered"</span>,    <span class="hljs-string">"463"</span>: <span class="hljs-string">"nopermforhost"</span>,    <span class="hljs-string">"464"</span>: <span class="hljs-string">"passwdmismatch"</span>,    <span class="hljs-string">"465"</span>: <span class="hljs-string">"yourebannedcreep"</span>,    <span class="hljs-string">"466"</span>: <span class="hljs-string">"youwillbebanned"</span>,    <span class="hljs-string">"467"</span>: <span class="hljs-string">"keyset"</span>,    <span class="hljs-string">"471"</span>: <span class="hljs-string">"channelisfull"</span>,    <span class="hljs-string">"472"</span>: <span class="hljs-string">"unknownmode"</span>,    <span class="hljs-string">"473"</span>: <span class="hljs-string">"inviteonlychan"</span>,    <span class="hljs-string">"474"</span>: <span class="hljs-string">"bannedfromchan"</span>,    <span class="hljs-string">"475"</span>: <span class="hljs-string">"badchannelkey"</span>,    <span class="hljs-string">"476"</span>: <span class="hljs-string">"badchanmask"</span>,    <span class="hljs-string">"477"</span>: <span class="hljs-string">"nochanmodes"</span>,    <span class="hljs-string">"478"</span>: <span class="hljs-string">"banlistfull"</span>,    <span class="hljs-string">"481"</span>: <span class="hljs-string">"noprivileges"</span>,    <span class="hljs-string">"482"</span>: <span class="hljs-string">"chanoprivsneeded"</span>,    <span class="hljs-string">"483"</span>: <span class="hljs-string">"cantkillserver"</span>,    <span class="hljs-string">"484"</span>: <span class="hljs-string">"restricted"</span>,    <span class="hljs-string">"485"</span>: <span class="hljs-string">"uniqopprivsneeded"</span>,    <span class="hljs-string">"491"</span>: <span class="hljs-string">"nooperhost"</span>,    <span class="hljs-string">"492"</span>: <span class="hljs-string">"noservicehost"</span>,    <span class="hljs-string">"501"</span>: <span class="hljs-string">"umodeunknownflag"</span>,    <span class="hljs-string">"502"</span>: <span class="hljs-string">"usersdontmatch"</span>,
`</pre>
IRC命令解释详见:[List of Internet Relay Chat commands](https://en.wikipedia.org/wiki/List_of_Internet_Relay_Chat_commands)

#### **pbot.php木马利用IRC协议进行通讯过程**

分析前先对编码过的php代码进行解码

![2](http://www.ms509.com/wp-content/uploads/2016/08/2.jpg)

此木马用到的IRC命令字:
<pre class="lang:default decode:true">PASS:设置IRC连接密码

USER:设置username,,hostname,realname

NICK:设置昵称

PING:验证客户端是否存活

MODE:设置IRC连接模式

JOIN:加入频道(频道就类似群的概念)

PRIVMSG:发送私有消息(最常用的IRC命令)

001:成功建立IRC连接后服务器返回的welcome消息 

443:昵称重复</pre>

##### **1)建立IRC连接**
[![3](http://www.ms509.com/wp-content/uploads/2016/08/3.jpg)](http://www.ms509.com/?attachment_id=427)

如上,木马实现IRC协议规定的建立连接握手流程:以PASS,USER,NICK三个IRC命令开始(设置连接密码,用户ID,昵称等信息)
[![4](http://www.ms509.com/wp-content/uploads/2016/08/4.jpg)](http://www.ms509.com/?attachment_id=428)

建立完连接后进入主功能函数main

##### **2)main函数(消息循环)**

IRC连接建立成功后设置连接模式为私有隐藏,加入预先建好的两个远控频道(配置变量中的chan和chan2:即#ccpower和#sianta),频道密码是配置变量里的key即correct

配置参数包含服务器域名,端口,频道名(群名),频道密码,频道模式等信息
<pre>`    <span class="hljs-keyword">var</span> $config = <span class="hljs-keyword">array</span>(<span class="hljs-string">"server"</span> =&gt; <span class="hljs-string">"irc.mildnet.net"</span>, 
        <span class="hljs-string">"port"</span> =&gt; <span class="hljs-string">"7000"</span>, <span class="hljs-string">"pass"</span> =&gt; <span class="hljs-string">""</span>, <span class="hljs-string">"prefix"</span> =&gt; <span class="hljs-string">"pbot"</span>, <span class="hljs-string">"maxrand"</span> =&gt; <span class="hljs-string">"2"</span>, <span class="hljs-string">"chan"</span> =&gt; <span class="hljs-string">"#ccpower"</span>, 
        <span class="hljs-string">"chan2"</span> =&gt; <span class="hljs-string">"#siantar"</span>, <span class="hljs-string">"key"</span> =&gt; <span class="hljs-string">"correct"</span>, <span class="hljs-string">"modes"</span> =&gt; <span class="hljs-string">"+ps"</span>);

5

调用到的函数(相应IRC协议中的命令JOIN, PRIVMSG, NICK)

[![join](http://www.ms509.com/wp-content/uploads/2016/08/join.png)](http://www.ms509.com/?attachment_id=507)

木马自己的远控命令

上面主要是IRC协议相关的内容,而木马自己的功能,也就是执行各种远程控制命令的代码如下:

(远控命令的发送是通过PRIVMSG IRC命令字发送给木马,以!号开头)

6 7 8

如上,木马自己的远控命令一共有13个,最重要的两个就是eval命令:执行php代码;cmd命令:执行shell命令行

所有命令和功能如下:

reload:退出后重连

safe:获取php的安全模式信息

conback:未实现

dns:域名查询

info:未实现

vuln:获取服务器信息

bot:获取web shell类型

uname:获取PHP系统相关信息

rndnick:设置随机昵称

raw:原始消息发送

eval:执行php代码

cmd:执行shell代码

mati:断开连接

到此,通过一个简单的IRC聊天客户端,连接IRC服务器:irc.mildnet.net;进入预先设置好的私有频道:#ccpower,#siantar(频道密码:correct),就可以像聊QQ一样,和群里的肉鸡”聊天“了,聊天的内容就是上面的13个命令

二、mil.php

压缩包里还有另外一个php文件,这个不是IRC木马,解码后也简单的分析下:

mil.php木马有两个功能

1)执行shell命令

2)上传文件

shangchuan

上面两个form表单是木马的操作界面,这样看不是太清楚,把两个form字符串保存成html文件,用浏览器里打开看就比较清楚了

xuanze

从上面的界面文字以及php里的一些字符串发现不是英文,感觉有点像马来文。由于文字很少,也没进一步考证

htaccess

最后是增加.htaccess配置文件,文件内容又经过了编码处理,估计是配置网马文件的权限,解码后证实一下

PHP