由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。
前言
fscan作为一款内网扫描工具,集成了多种功能,包括端口扫描、服务识别、漏洞探测、弱口令检测等,是网络安全专业人士和渗透测试人员常用的工具之一。正因它比较出名,常常被攻击者使用,所以杀软目前已把fscan标记为恶意工具,只要主机上安装了杀软,就会杀掉你上传的fscan工具。那么好用的工具,怎么能轻易放弃它的使用呢?今天就来学习一下fscan免杀吧!
本次fscan的免杀方案主要参考别的师傅的文章有感而来,这位师傅是使用dll劫持技术实现了fscan工具的免杀。而且他拥有一个微软签名的白程序,通过白加黑来执行fscan的dll。但是很可惜文章中没有太多细节,也没有把白程序分享出来(好像是需要加入星球才能获取吧)。作为一个白嫖党,让我花钱不存在的,自己研究一下吧,终于在一系列踩坑后,成功完成了这个fscan工具的免杀,而且无需使用白程序也可以拥有不错的免杀效果。耐心看完这个文章吧,希望对大家有所帮助。
免杀过程
首先我们要把fscan编译成一个dll文件,fscan使用的是go语言,所以需要安装go环境,直接去go官网下载安装即可,把go的bin目录添加到环境变量中,命令行执行go –version检查go环境是否安装成功,成功如下
接着去下载fscan的源代码,项目地址https://github.com/shadow1ng/fscan,因为我之前没有接触过go,所以不太熟悉go的编译,直接在fscan的项目目录下执行go build,命令行直接报错
这是因为网络连接问题,导致无法安装依赖,试了好几种解决方案,最后使用 Go Modules 镜像解决了这个问题。某些可能无法访问 Go 的默认模块代理 proxy.golang.org,所以需要更换镜像,命令行执行go env -w GOPROXY=https://goproxy.cn,direct,使用中国大陆地区的镜像。然后执行go clean -modcache清理模块缓存,再次执行go build命令发现可以成功编译exe文件如下
接着想要把fscan项目编译成dll,需要修改main.go文件,修改后的代码为
package main
import "C"
import (
"fmt"
"time"
"github.com/shadow1ng/fscan/Plugins"
"github.com/shadow1ng/fscan/common"
)
//export DllCanUnloadNow
func DllCanUnloadNow() {}
//export DllGetClassObject
func DllGetClassObject() {}
//export DllRegisterServer
func DllRegisterServer() {}
//export DllUnregisterServer
func DllUnregisterServer() {}
func init() {
start := time.Now()
var Info common.HostInfo
common.Flag(&Info)
common.Parse(&Info)
Plugins.Scan(Info)
t := time.Now().Sub(start)
fmt.Printf("[*] 扫描结束,耗时: %sn", t)
}
func main() {
}
使用命令go build -o fscan.dll -buildmode=c-shared尝试把fscan项目编译成dll,运行再次报错,
把报错信息发给gpt4,它告诉我需要正确配置CGO,使用go env查看CGO相关配置如下
这里CGO_ENABLED=0代表未开启CGO,使用命令set CGO_ENABLED=1,开启CGO再次进行编译,命令行再次报错,报错信息
未找到gcc,go项目编译成dll需要安装gcc,我这里使用 MSYS2安装gcc,访问https://www.msys2.org/,下载文件直接默认安装即可,运行安装好的MSYS2
执行命令pacman -S mingw-w64-x86_64-gcc即可完成gcc安装,安装完成后把MinGW-w64 的安装目录添加到您的环境变量 PATH 中,命令行执行gcc –version,验证gcc是否安装成功,成功如下
执行go build -o fscan.dll -buildmode=c-shared进行编译,终于编译成功如下
注意默认编译的是64位dll,我这里尝试编译了32位dll一直没有成功,也是修改GOARCH=386,重新编译就会提示
有知道怎么解决的师傅可以私信告诉我一下(非常感谢),继续向下,我们现在已经成功编译了一个fscan的64位dll,接下来是要加载dll执行fscan的命令啊,直接使用windows应用程序去加载dll是不行的,原因是fscan本质是一个命令行工具,需要在命令行传递参数来运行,所以我们需要使用控制台应用来加载这个dll才能实现fscan扫描。这是整个免杀的关键点,因为go语言使用gcc编译成的dll是可以被c语言调用加载的,所以直接使用vs创建一个控制台应用
代码如下
int main() {
HMODULE hDLL;
hDLL = LoadLibrary("fscan.dll");
if (hDLL != NULL) {
// 定义函数指针类型
typedef void (*FunctionType)();
// 为每个导出函数创建一个函数指针
FunctionType DllCanUnloadNow = (FunctionType)GetProcAddress(hDLL, "DllCanUnloadNow");
FunctionType DllGetClassObject = (FunctionType)GetProcAddress(hDLL, "DllGetClassObject");
FunctionType DllRegisterServer = (FunctionType)GetProcAddress(hDLL, "DllRegisterServer");
FunctionType DllUnregisterServer = (FunctionType)GetProcAddress(hDLL, "DllUnregisterServer");
// 调用每个函数(如果函数指针非空)
if (DllCanUnloadNow) DllCanUnloadNow();
if (DllGetClassObject) DllGetClassObject();
if (DllRegisterServer) DllRegisterServer();
if (DllUnregisterServer) DllUnregisterServer();
// 卸载 DLL
FreeLibrary(hDLL);
printf("All functions executed successfully.n");
}
else {
printf("Failed to load DLL.n");
}
return 0;
}
这里使用c代码加载了我们生成的dll,之前main.go代码中有个init函数,当dll被加载时就会执行这个函数,从而接受命令行传递的参数进行fscan扫描。将C语言控制台应用编译成64位exe,把exe和dll放在统一目录下,命令行执行fc_loader.exe -h 192.168.233.134,如下
发现fscan已经正常使用一些功能了,但还是报错了,
错误信息“invalid memory address or nil pointer dereference”通常是因为尝试访问或操作一个nil指针。在PortConnect函数中,有一个defer conn.Close()调用,但是在调用Close之前没有检查conn是否为nil。如果common.WrapperTcpWithTimeout函数返回错误,conn可能是nil,这会导致运行时错误。
对portscan.go文件进行修改,替换PortConnect函数,修改后的代码
func PortConnect(addr Addr, respondingHosts chan<- string, adjustedTimeout int64, wg *sync.WaitGroup) {
host, port := addr.ip, addr.port
conn, err := common.WrapperTcpWithTimeout("tcp4", fmt.Sprintf("%s:%v", host, port), time.Duration(adjustedTimeout)*time.Second)
if conn != nil {
defer conn.Close()
}
if err == nil {
address := host + ":" + strconv.Itoa(port)
result := fmt.Sprintf("%s open", address)
common.LogSuccess(result)
wg.Add(1)
respondingHosts <- address
}
}
修改后保存,重新执行go build -o fscan.dll -buildmode=c-shared编译dll,再次在命令行执行fscan扫描,成功完成扫描,如下
免杀测试
360核晶环境
defender环境
火绒环境
vt平台
微步云沙箱
微步会识别dll是恶意的,报毒的引擎只有国外的杀毒,在国内杀软环境下使用完全足够。你想追求完美的话,需要进一步处理fscan源码。
总结
-
1、编译fscan项目为dll时,需要安装好go环境、GCC环境,否则会出现无法编译。
-
2、由于没有64位的命令行白程序,所以自写控制台应用来加载dll实现fscan扫描,师傅们如何手里有64位命令行白程序可以私信我,方便的话也提供给我一个,大家共同学习!
-
考虑到有人可能觉得编译比较麻烦,就把编译好的工具直接分享出来了,公众号回复“
fscan免杀”获取即可。
点击下方名片进入公众号,欢迎关注!
往期推荐
原文始发于微信公众号(随风安全):技术幻影-揭开fscan免杀的面纱