-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
utils.go
152 lines (137 loc) · 4.71 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"fmt"
"io"
"math/rand"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"net/url"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
)
func selectRandomOrHardcoded(options []string, method string) []string {
if len(options) == 0 {
logToFile("config.General.LogFile", "No options provided for selection.")
return options
}
if method == "hardcoded" {
return options
}
rand.Seed(time.Now().UnixNano())
return []string{options[rand.Intn(len(options))]}
}
func downloadFile(url, dest string) error {
resp, err := http.Get(url)
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to download HTTP file %s: %v", url, err))
return err
}
defer resp.Body.Close()
out, err := os.Create(dest)
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to create file %s: %v", dest, err))
return err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to copy HTTP file %s: %v", url, err))
}
return err
}
func downloadSMBFile(smbPath, dest string) error {
cmd := exec.Command("powershell", "-Command", fmt.Sprintf("New-PSDrive -Name S -PSProvider FileSystem -Root \\\\%s; Copy-Item S:\\%s -Destination %s; Remove-PSDrive -Name S", smbPath, filepath.Base(dest), dest))
output, err := cmd.CombinedOutput()
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to download SMB file %s: %v, output: %s", smbPath, err, string(output)))
}
return err
}
func downloadNFSFile(nfsPath, dest string) error {
cmd := exec.Command("powershell", "-Command", fmt.Sprintf("New-PSDrive -Name N -PSProvider FileSystem -Root %s; Copy-Item N:\\%s -Destination %s; Remove-PSDrive -Name N", nfsPath, filepath.Base(dest), dest))
output, err := cmd.CombinedOutput()
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to download NFS file %s: %v, output: %s", nfsPath, err, string(output)))
}
return err
}
func downloadSFTPFile(sftpPath, dest, username, password string) error {
config := &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
client, err := ssh.Dial("tcp", sftpPath, config)
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to connect to SFTP server %s: %v", sftpPath, err))
return err
}
defer client.Close()
sftpClient, err := sftp.NewClient(client)
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to create SFTP client %s: %v", sftpPath, err))
return err
}
defer sftpClient.Close()
source, err := sftpClient.Open(filepath.Base(sftpPath))
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to open source SFTP file %s: %v", sftpPath, err))
return err
}
defer source.Close()
output, err := os.Create(dest)
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to create destination file %s: %v", dest, err))
return err
}
defer output.Close()
_, err = io.Copy(output, source)
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to copy SFTP file %s: %v", sftpPath, err))
}
return err
}
func downloadDecoyFiles(config *Config) {
for _, set := range config.DecoyFiles.Sets {
locations := selectRandomOrHardcoded(set.Location, set.SelectionMethod)
targetDirs := selectRandomOrHardcoded(set.TargetDirectory, set.SelectionMethod)
for _, location := range locations {
for _, targetDir := range targetDirs {
filename := filepath.Base(location)
targetPath := filepath.Join(targetDir, filename)
var err error
switch {
case strings.HasPrefix(location, "http"):
err = downloadFile(location, targetPath)
case strings.HasPrefix(location, "smb"):
err = downloadSMBFile(location, targetPath)
case strings.HasPrefix(location, "nfs"):
err = downloadNFSFile(location, targetPath)
case strings.HasPrefix(location, "sftp"):
// Assume SFTP URL format: sftp://username:password@host:port/path
url, parseErr := url.Parse(location)
if parseErr != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to parse SFTP URL %s: %v", location, parseErr))
continue
}
username := url.User.Username()
password, _ := url.User.Password()
err = downloadSFTPFile(url.Host, targetPath, username, password)
default:
logToFile("config.General.LogFile", fmt.Sprintf("Unsupported protocol for decoy file %s", location))
}
if err != nil {
logToFile("config.General.LogFile", fmt.Sprintf("Failed to download decoy file %s: %v", location, err))
} else {
logToFile("config.General.LogFile", fmt.Sprintf("Downloaded decoy file %s", location))
}
}
}
}
}