免杀对抗------第一百六十五天
安全工具篇&Go魔改二开&Fscan扫描&FRP代理&特征消除&新增扩展&打乱HASH
安全工具 - Goland-FRP魔改二开&特征消除
- FRP是一种快速的反向代理,允许你将位于NAT或防火墙后的本地服务器暴露在互联网上。目前它支持 TCP 和 UDP ,以及 HTTP 和 HTTPS 协议,使请求可以通过域名转发到内部服务,也是内网常用的内网穿透工具。
- 下载地址:https://github.com/fatedier/frp
- 同样,这玩意下载下就全部被杀,所以我们还是需要魔改,把源码拖到本地,然后通过make进行编译,这里因为Kali上自带make,所以尽量是放到Kali上编译:
bash
make -f Makefile.cross-compiles

-
但是这种直接编译的还是没啥用,因为这个frp是流量转发工具,所以除了对一些特征进行更改之外,还需要对流量特征进行更改
-
比如在
pkg/msg/msg.go文件中把传输的数据特征改掉:


-
然后在
pkg/util/net/tls.go文件中将FRPTLSHeadByte改掉:

-
版本特征也可以改掉,在
pkg/util/version/version.go文件中:

-
这样改动之后对免杀有一定的效果,在这个基础上也可以进行加壳、加保护、加签名、降低熵值等等操作
-
当然这个只是治标不治本的方法,一些较强的杀软或者是EDR设备还是过不了,因此还是需要更深层的改动,但这里我们也不深入改了,有兴趣的可以根据这篇文章自己下去尝试:【神兵利器】手把手教你魔改frp
安全工具 - Goland-FScan魔改二开&特征消除
工具混淆
- fscan是一款内网综合扫描工具,方便一键自动化、全方位漏扫扫描,体积小、扫描快、功能多,因此在内网扫描当中非常受欢迎。
- 下载地址:Releases · shadow1ng/fscan
- 但是这个工具已经是被杀毒软件杀得不要不要的,所以我们需要对其进行免杀处理,和之前一样,我们可以从如下方面入手:
- 对EXE成品:
- 加签名、加壳、加保护、降低熵值等等
- 转换为二进制/dll文件通过Loader加载调用
- 对源码:
- 重新编译
- 修改源码逻辑
- 重新写一个新的工具
- 对EXE成品:
- 那我们这里就从简单到难,首先看看重新编译的效果,这个的主要目的就是改变文件的哈希值,将文件源代码下载下来之后,用goland打开(记得关杀毒),执行如下命令编译:
bash
go build -ldflags="-s -w" -trimpath main.go

- 但是自己编译出来的目前也是直接被杀,因此我们可以更进一步通过DLL加载调用,加载器代码如下:
c
#include <stdio.h>
#include <windows.h>
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;
}
- go启动代码如下:
go
package main
import "C"
import (
"fmt"
"time"
"github.com/wjlin0/fscan/Plugins"
"github.com/wjlin0/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("[*] 扫描结束,耗时: %s\n", t)
}
func main() {}
- 然后通过如下命令分别编译加载器和启动代码:
bash
gcc -o fscan_loader.exe main.c
go build -buildmode=c-shared -o fscan.dll main.go
-
运行
fscan_loader.exe就可以调用fscan工具了:

-
这个可以过火绒、DF,但是卡巴过不了,然后这里引用的库是
github.com/wjlin0/fscan/Plugins,这个不是官方的库,如果引用官方的库可能就会杀 -
这里如果要用最新版可以直接fork到自己的仓库然后改一下依赖即可
新增PoC
-
在fscan中是有一些常见Web PoC扫描的,在
/WebScan/pocs目录下,如果我们想引入一些最新的漏洞PoC可以自己新增:

-
这里就不再演示了,怎么编写yml的PoC之前的课程也讲到过,写完之后重新打包即可:
bash
go build -buildmode=c-shared -o fscan.dll ./main.go
- 对于其他的非Web模块的漏洞,可以在
/Plugins目录下新增其他的插件或者漏洞扫描模块,比如这里我们新增一个zookeeper未授权连接的探测功能,首先在该目录下创建ZookeeperConn.go文件:
go
package Plugins
import (
"fmt"
"strings" "time"
"github.com/samuel/go-zookeeper/zk"
"github.com/shadow1ng/fscan/Common"
)
func ZookeeperScan(info *Common.HostInfo) error {
// Trim inputs
info.Host = strings.TrimSpace(info.Host)
info.Ports = strings.TrimSpace(info.Ports)
var addresses []string
if info.Ports == "" {
// default zookeeper port
addresses = append(addresses, fmt.Sprintf("%s:%d", info.Host, 2181))
} else if strings.Contains(info.Ports, ",") {
ports := strings.Split(info.Ports, ",")
for _, port := range ports {
p := strings.TrimSpace(port)
if p == "" {
continue
}
addresses = append(addresses, fmt.Sprintf("%s:%s", info.Host, p))
}
} else {
addresses = append(addresses, fmt.Sprintf("%s:%s", info.Host, info.Ports))
}
conn, err := ZookeeperConn(addresses, time.Duration(Common.Timeout)*time.Second)
if err != nil {
errlog := fmt.Sprintf("[-] Zookeeper %v:%v connect failed, %v", info.Host, info.Ports, err)
Common.LogError(errlog)
return err
}
defer conn.Close()
// 检查根节点是否存在,作为未授权访问的判断依据
exists, _, err := conn.Exists("/")
if err != nil {
errlog := fmt.Sprintf("[-] Zookeeper %v:%v check unauthorized failed, %v", info.Host, info.Ports, err)
Common.LogError(errlog)
return err
}
if exists {
result := fmt.Sprintf("[+] Zookeeper %v:%v unauthorized", info.Host, info.Ports)
Common.LogSuccess(result)
_ = Common.SaveResult(&Common.ScanResult{
Time: time.Now(),
Type: Common.VULN,
Target: fmt.Sprintf("%s:%s", info.Host, info.Ports),
Status: "vulnerable",
Details: map[string]interface{}{"service": "zookeeper", "vulnerability": "unauthorized-access"},
})
}
return nil
}
func ZookeeperConn(addresses []string, timeout time.Duration) (*zk.Conn, error) {
conn, _, err := zk.Connect(addresses, timeout)
if err != nil {
return nil, fmt.Errorf("connect to Zookeeper failed: %v", err)
}
return conn, nil
}
- 如果是旧版,按小迪的流程注册插件即可,如果是新版,只需要在
/Core/Registry.go文件中添加如下代码即可:
go
Common.RegisterPlugin("zookeeperconn", Common.ScanPlugin{
Name: "ZookeeperConn",
Ports: []int{2181},
ScanFunc: Plugins.ZookeeperScan,
Types: []string{Common.PluginTypeService},
})
- 因为是测试未授权,所有不需要在
/Core/Config.go中添加暴力破解的账户以及密码 - 然后我们在
/Common/Ports.go文件的var MainPorts里面加入2181端口,运行如下命令进行扫描探测:
bash
fscan.exe -h <IP>

- 可以看到这里能够成功发现了zookeeper的未授权访问漏洞,所以我们如果想增加一些服务漏洞扫描或者其他插件功能就可以在这里自行添加