日常遇到的样本,前两层主要就是解密dll文件,加载,不做分析,从第三层开始
由于程序本身被混淆,尝试使用de4dot效果不明显,字符串全部被加密,所以想试着解一下字符串看看效果
动态调试发现所有字符串调用都在Gn6.O3i()函数内,通过不同的数字来生成字符串
思路一:自己写
看一下解密函数
从360行到3317行,放弃……
思路二:直接调用
既然它是一个dll,那我们就可以写一个程序来调用这个函数不就行了吗
上代码,然后...
失败,找不到该方法
查找原因,是由于该方法被internal修饰,不能够被从外部调用
思路三:
直接从外部调用行不通,那如果在内部加一个类似的调用呢,这就可以用到dnspy的编译功能了,由于Gn6这个类太大,而且被混淆了,直接在它内部加方法很大可能编译失败,所以还是最好自己加一个新的类
编译后,可以看到已经出现刚刚编译进去的文件
随后保存模块
修改一下文件名
因为混淆的原因,会报错
修改以下选项
修改完成后,继续上代码
解密效果如下,可以看到,该模块主要功能为反沙箱,反虚拟机,还有注入
下一层
提取到下一层文件如下,是一个可执行文件了,并且所有字符串同样被加密了
解密函数如下:
经分析知,函数调用的参数(字符串数组下标,字符串所在位置偏移量,字符串长度)
它将所有需要的字符串放在一起并做了异或加密,解密为 字符 xor 下标 xor 170,随后通过偏移位置与字符串长度将其取出
由于它的字符串没有隔断,需要自行控制截断,而字符串数量过大,所有就想直接提取该部分解密函数使用
思路:
在提取前,因为混淆过于严重,先使用de4dot做一下处理,处理后要好看很多,并且一些可能在编译的时候有问题的地方也帮忙做了处理
选择”文件->导出到工程”得到工程文件,然后找到解密函数所在的文件,直接添加现有项到自己要写的代码中,随后修改下报错的地方,同时由于程序需要解密的字符串数组太大,导致在dnspy中显示不全
这段数组可以通过查看文件的16进制直接找到这一段,根据dnspy的提示长度将该段复制出来,替换掉自己工程文件中的这一段
替换
由于每个字符串都是一个函数,函数过多,可以通过遍历该类中所有函数方法的方式来调用每一个函数
解密效果如下:
通过解密出来的字符串与动态调试的一些行为,发现其实该样本为Agent Tesla 木马的变种
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.IO;
namespace dessttrrr
{
class
Program
{
static void Main(string[] args)
{
string path
=
@
"C:\Users\admin1\Desktop\新建文件夹\newDll"
;
/
/
调用dll路径
Assembly assem
=
Assembly.LoadFile(path);
Type
[] tys;
try
{
tys
=
assem.GetTypes();
int
i
=
0
;
string []mystr
=
new string[
10000
];
int
j
=
0
;
foreach (
Type
ty
in
tys)
/
/
遍历查找类名
{
if
(ty.Name
=
=
"Program"
)
{
for
(; i <
10000
;
+
+
i)
{
ConstructorInfo magicConstructor
=
ty.GetConstructor(
Type
.EmptyTypes);
object
magicClassObject
=
magicConstructor.Invoke(new
object
[] { });
/
/
获取一个类实例
object
[] paramertors
=
new
object
[] { i };
/
/
需要传入的参数
MethodInfo[] methods
=
ty.GetMethods();
MethodInfo mi
=
ty.GetMethod(
"getStr"
);
/
/
获取方法
object
aa
=
mi.Invoke(magicClassObject, paramertors);
int
flag
=
String.Compare("", aa.ToString());
if
(flag !
=
0
)
{
int
flag2
=
aa.ToString()[
0
];
/
/
去除乱码
if
(flag2 <
255
)
{
mystr[j]
=
i.ToString()
+
": "
+
aa.ToString()
+
"\n"
;
+
+
j;
}
}
}
File
.WriteAllLines(
"str.txt"
, mystr, Encoding.Default);
}
}
}
catch (ReflectionTypeLoadException ex)
{
/
/
now look at ex.LoaderExceptions
-
this
is
an Exception[], so:
foreach (Exception inner
in
ex.LoaderExceptions)
{
/
/
write details of
"inner"
,
in
particular inner.Message
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.IO;
namespace dessttrrr
{
class
Program
{
static void Main(string[] args)
{
string path
=
@
"C:\Users\admin1\Desktop\新建文件夹\newDll"
;
/
/
调用dll路径
Assembly assem
=
Assembly.LoadFile(path);
Type
[] tys;
try
{
tys
=
assem.GetTypes();
int
i
=
0
;
string []mystr
=
new string[
10000
];
int
j
=
0
;
foreach (
Type
ty
in
tys)
/
/
遍历查找类名
{
if
(ty.Name
=
=
"Program"
)
{
for
(; i <
10000
;
+
+
i)
{
ConstructorInfo magicConstructor
=
ty.GetConstructor(
Type
.EmptyTypes);
object
magicClassObject
=
magicConstructor.Invoke(new
object
[] { });
/
/
获取一个类实例
object
[] paramertors
=
new
object
[] { i };
/
/
需要传入的参数
MethodInfo[] methods
=
ty.GetMethods();
MethodInfo mi
=
ty.GetMethod(
"getStr"
);
/
/
获取方法
object
aa
=
mi.Invoke(magicClassObject, paramertors);
int
flag
=
String.Compare("", aa.ToString());
if
(flag !
=
0
)
{
int
flag2
=
aa.ToString()[
0
];
/
/
去除乱码
if
(flag2 <
255
)
{
mystr[j]
=
i.ToString()
+
": "
+
aa.ToString()
+
"\n"
;
+
+
j;
}
}
}
File
.WriteAllLines(
"str.txt"
, mystr, Encoding.Default);
}
}
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)