From f3cd4eb92472dd1094f61d188803b4b58ec54908 Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:19:17 -0600 Subject: [PATCH 01/10] binary now spits out a tsv file for tracker purposes, im awesome --- .gitignore | 4 ++ embed/linux/triage/firewall.sh | 0 triage/firewall_linux.go | 38 +++++++++++- triage/firewall_windows.go | 102 ++++++++++++++++++++++++++++++++- triage/main.go | 77 +++++++++++++++++++++++-- triage/network_info.go | 78 ++++++++++++++++--------- triage/os_version_linux.go | 8 ++- triage/os_version_windows.go | 24 +++++++- triage/users_linux.go | 23 +++++--- triage/users_windows.go | 71 ++++++++++++++++++++++- util/run_script.go | 5 +- 11 files changed, 378 insertions(+), 52 deletions(-) mode change 100644 => 100755 embed/linux/triage/firewall.sh diff --git a/.gitignore b/.gitignore index b6d5261..9fe8afd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +#ide stuff +*.idea +.idea/ + # Binaries for programs and plugins *.exe *.exe~ diff --git a/embed/linux/triage/firewall.sh b/embed/linux/triage/firewall.sh old mode 100644 new mode 100755 diff --git a/triage/firewall_linux.go b/triage/firewall_linux.go index c823f88..195da00 100644 --- a/triage/firewall_linux.go +++ b/triage/firewall_linux.go @@ -1,7 +1,39 @@ package triage -import "github.com/UT-CTF/landschaft/util" +import ( + "fmt" + "os" + "os/exec" + "strings" -func runFirewallTriage() { - util.RunAndPrintScript("triage/firewall.sh") + "github.com/UT-CTF/landschaft/util" +) + +func runFirewallTriage() string { + result := util.RunAndPrintScript("triage/firewall.sh") + "\t" + + if strings.Contains(result, "No supported firewall") { + result = "No Firewall!\t" + } + + result += getDomainInfo() + "\t" + + return result +} + +func getDomainInfo() string { + // Check 1: sssd.conf + content, err := os.ReadFile("/etc/sssd/sssd.conf") + if err == nil { + fmt.Println("sssd.conf") + return strings.TrimSpace(string(content)) + } + + // Check 2: realm list (if available) + out, err := exec.Command("realm", "list").Output() + if err == nil && len(out) > 0 { + return strings.TrimSpace(string(out)) + } + + return "Not Domain Jointed" } diff --git a/triage/firewall_windows.go b/triage/firewall_windows.go index 86d78f7..4df2ad9 100644 --- a/triage/firewall_windows.go +++ b/triage/firewall_windows.go @@ -1,9 +1,107 @@ package triage import ( + "fmt" + "os/exec" + "strings" + "github.com/UT-CTF/landschaft/util" ) -func runFirewallTriage() { - util.RunAndPrintScript("triage/firewall.ps1") +func runFirewallTriage() string { + result := parseFirewall(util.RunAndPrintScript("triage/firewall.ps1")) + "\t" + result += getDomainStatus() + "\t" + return result +} + +func parseFirewall(result string) string { + lines := strings.Split(result, "\n") + + type iface struct { + name string + alias string + category string + } + + var interfaces []iface + profileEnabled := make(map[string]bool) + profileState := make(map[string]string) + profilePolicy := make(map[string]string) + currentProfile := "" + + for _, line := range lines { + trimmed := strings.TrimSpace(line) + + // skip header lines + if strings.HasPrefix(trimmed, "Name") || strings.HasPrefix(trimmed, "----") || trimmed == "" { + continue + } + + // interface lines - 3 fields + fields := strings.Fields(trimmed) + if len(fields) == 3 && !strings.HasPrefix(trimmed, "Profile:") && !strings.HasSuffix(trimmed, "Settings:") && !strings.HasPrefix(trimmed, "State") && !strings.HasPrefix(trimmed, "Firewall") { + interfaces = append(interfaces, iface{fields[0], fields[1], fields[2]}) + continue + } + + // Profile: X - Enabled/Disabled + if strings.HasPrefix(trimmed, "Profile:") { + parts := strings.Split(trimmed, " - ") + profileName := strings.TrimSpace(strings.TrimPrefix(parts[0], "Profile:")) + if len(parts) > 1 { + profileEnabled[profileName] = strings.TrimSpace(parts[1]) == "Enabled" + } + continue + } + + // X Profile Settings: + if strings.HasSuffix(trimmed, "Profile Settings:") { + currentProfile = strings.TrimSuffix(trimmed, " Profile Settings:") + continue + } + + if currentProfile != "" { + if strings.HasPrefix(trimmed, "State") { + profileState[currentProfile] = strings.TrimSpace(strings.TrimPrefix(trimmed, "State")) + } + if strings.HasPrefix(trimmed, "Firewall Policy") { + profilePolicy[currentProfile] = strings.TrimSpace(strings.TrimPrefix(trimmed, "Firewall Policy")) + } + } + } + + var parts []string + for _, i := range interfaces { + enabled := "Disabled" + if profileEnabled[i.category] { + enabled = "Enabled" + } + state := profileState[i.category] + policy := profilePolicy[i.category] + parts = append(parts, fmt.Sprintf("%s - %s - %s (%s; State %s; Firewall Policy: %s)", + i.name, i.alias, i.category, enabled, state, policy)) + } + + return strings.Join(parts, "; ") +} + +func getDomainStatus() string { + out, err := exec.Command("wmic", "computersystem", "get", "domain").Output() + if err != nil { + return "Not Domain Joined" + } + + lines := strings.Split(strings.TrimSpace(string(out)), "\n") + for _, line := range lines { + line = strings.TrimSpace(line) + if line == "" || line == "Domain" { + continue + } + if line == "WORKGROUP" { + return "Not Domain Joined" + } + return line + } + + return "Not Domain Joined" } diff --git a/triage/main.go b/triage/main.go index 79c46b4..7895ceb 100644 --- a/triage/main.go +++ b/triage/main.go @@ -2,17 +2,86 @@ package triage import ( "fmt" + "os" + "os/exec" + "runtime" + "strings" "github.com/UT-CTF/landschaft/util" ) func Run() { + file, err := os.Create("triage.tsv") + if err != nil { + fmt.Println("Error creating csv file:", err) + } + fmt.Println(util.TitleColor.Render("Network")) - runNetworkTriage() + + if _, err := file.Write([]byte(runNetworkTriage())); err != nil { + // ignore error + } + fmt.Println(util.TitleColor.Render("Users & Groups")) - runUsersTriage() + + if _, err := file.Write([]byte(runUsersTriage())); err != nil { + // ignore error + } + fmt.Println(util.TitleColor.Render("OS Version")) - runOSVersionTriage() + + if _, err := file.Write([]byte(runOSVersionTriage())); err != nil { + // ignore error + } + fmt.Println(util.TitleColor.Render("Firewall")) - runFirewallTriage() + + if _, err := file.Write([]byte(runFirewallTriage())); err != nil { + // ignore error + } + + errF := file.Close() + if errF != nil { + + } + + openOrCopyFile(file.Name()) + +} + +func openOrCopyFile(filename string) { + if runtime.GOOS == "windows" { + println("\nOpen " + filename + " in notepad to copy to sheets") + err := exec.Command("notepad.exe", filename).Start() + if err != nil { + err := exec.Command("explorer.exe", filename).Start() + if err != nil { + println(err.Error()) + return + } + } + return + } + + // Linux - install and use xclip + err := exec.Command("sudo", "apt-get", "install", "-y", "xclip").Run() + if err != nil { + println("\nCannot install xclip! must use xclip or xsel to copy to sheets") + println(err.Error()) + return + } + + data, err := os.ReadFile(filename) + if err != nil { + fmt.Println("Error reading file:", err) + return + } + + cmd := exec.Command("xclip", "-selection", "clipboard") + cmd.Stdin = strings.NewReader(string(data)) + cmd.Run() + + println("\n\n ****** Triage copied to clipboard ******") + println("\n\n Triage saved to " + filename + ". To copy:") + println("\n\tcat " + filename + " | xclip -selection clipboard\n\n") } diff --git a/triage/network_info.go b/triage/network_info.go index 12d92f2..6eac54a 100644 --- a/triage/network_info.go +++ b/triage/network_info.go @@ -9,12 +9,14 @@ import ( "github.com/charmbracelet/log" ) -func runNetworkTriage() { +func runNetworkTriage() string { var hostname = getAndPrintHostname() - printDNSName(hostname) - printIPAddrs() - printNetstat() + var csv = hostname + "\t" + csv = csv + printDNSName(hostname) + "\t" + csv = csv + printIPAddrs() + "\t" + csv = csv + printNetstat() fmt.Println() + return csv } func getAndPrintHostname() string { @@ -27,31 +29,35 @@ func getAndPrintHostname() string { return hostname } -func printDNSName(hostname string) { +func printDNSName(hostname string) string { + var result string addrs, err := net.LookupHost(hostname) if err != nil { fmt.Println("error looking up hostname") - return + return "err" } for _, addr := range addrs { names, err := net.LookupAddr(addr) if err != nil { - return + return "N/A" } for _, name := range names { if name == "localhost" { continue } fmt.Printf("FQDN for %s: %s\n", addr, name) + result = result + addr + ": " + name + ", " } } + return result } -func printIPAddrs() { +func printIPAddrs() string { + var result string var interfaces, err = net.Interfaces() if err != nil { log.Error("Failed to get network interfaces", "err", err) - return + return "err" } for _, iface := range interfaces { // skip loopback address @@ -62,14 +68,14 @@ func printIPAddrs() { var addrs, ipErr = iface.Addrs() if ipErr != nil { log.Error("Failed to get IP addresses", "err", ipErr) - return + return "err" } var ipv4Addrs, ipv6Addrs []string for _, addr := range addrs { ipNet, ok := addr.(*net.IPNet) if !ok { log.Error("Failed to cast address to IPNet", "addr", addr) - return + return "err" } if ipNet.IP.To4() != nil { ipv4Addrs = append(ipv4Addrs, ipNet.IP.String()) @@ -77,61 +83,77 @@ func printIPAddrs() { ipv6Addrs = append(ipv6Addrs, ipNet.IP.String()) } } - printAddrs(ipv4Addrs, " IPv4 Addresses:") - printAddrs(ipv6Addrs, " IPv6 Addresses:") + result = printAddrs(ipv4Addrs, " IPv4 Addresses:") + result = result + "\t" + printAddrs(ipv6Addrs, " IPv6 Addresses:") + return result } + return result } -func printAddrs(list []string, msg string) { +func printAddrs(list []string, msg string) string { + var result string if len(list) > 0 { fmt.Println(" ", msg) for _, ip := range list { fmt.Println(" -", ip) + result = result + ip + ", " } } + return result } -func printSockets(title string, sockets []netstat.SockTabEntry) { +func printSockets(title string, sockets []netstat.SockTabEntry) string { + var result = "" if len(sockets) > 0 { - fmt.Println(title) + fmt.Print(title) for _, e := range sockets { if e.State.String() == "LISTEN" && !e.LocalAddr.IP.IsLoopback() { fmt.Printf("%s %s %d %s\n", e.LocalAddr.String(), e.State.String(), e.UID, e.Process) + result += fmt.Sprintf("%s %s %d %s;", e.LocalAddr.String(), e.State.String(), e.UID, e.Process) } } } + + if len(result) == 0 { + result = "NONE" + } + + return result + "\t" } -func printNetstat() { +func printNetstat() string { + var result string // Get TCP IPv4 sockets tcpSocks, err := netstat.TCPSocks(netstat.NoopFilter) if err != nil { fmt.Print(err) - return + result += "err" + } else { + result += printSockets("\nTCP IPv4 Sockets:", tcpSocks) } - printSockets("\nTCP IPv4 Sockets:", tcpSocks) - // Get UDP IPv4 sockets udpSocks, err := netstat.UDPSocks(netstat.NoopFilter) if err != nil { fmt.Print(err) - return + result += "err" + } else { + result += printSockets("\nUDP IPv4 Sockets:", udpSocks) } - printSockets("\nUDP IPv4 Sockets:", udpSocks) - // Get TCP IPv6 sockets tcp6Socks, err := netstat.TCP6Socks(netstat.NoopFilter) if err != nil { fmt.Print(err) - return + result += "err" + } else { + result += printSockets("\nTCP IPv6 Sockets:", tcp6Socks) } - printSockets("\nTCP IPv6 Sockets:", tcp6Socks) - // Get UDP IPv6 sockets udp6Socks, err := netstat.UDP6Socks(netstat.NoopFilter) if err != nil { fmt.Print(err) - return + result += "err" + } else { + result += printSockets("\nUDP IPv6 Sockets:", udp6Socks) } - printSockets("\nUDP IPv6 Sockets:", udp6Socks) + return result } diff --git a/triage/os_version_linux.go b/triage/os_version_linux.go index f3172f0..6cf92ab 100644 --- a/triage/os_version_linux.go +++ b/triage/os_version_linux.go @@ -7,22 +7,26 @@ import ( "strings" ) -func runOSVersionTriage() { +func runOSVersionTriage() string { file, err := os.Open("/etc/os-release") if err != nil { fmt.Println("Error reading OS release:", err) - return + return "err" } defer file.Close() + var result string scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() parts := strings.Split(line, "=") if parts[0] == "NAME" { + result += strings.Trim(parts[1], `"`) + "\t" fmt.Println("OS:", strings.Trim(parts[1], `"`)) } else if parts[0] == "VERSION" { fmt.Println("Version:", strings.Trim(parts[1], `"`)) + result += strings.Trim(parts[1], `"`) + "\t" } } + return result } diff --git a/triage/os_version_windows.go b/triage/os_version_windows.go index 6b49f1a..dfe8d39 100644 --- a/triage/os_version_windows.go +++ b/triage/os_version_windows.go @@ -1,9 +1,29 @@ package triage import ( + "fmt" + "strings" + "github.com/UT-CTF/landschaft/util" ) -func runOSVersionTriage() { - util.RunAndPrintScript("triage/os_version.ps1") +func runOSVersionTriage() string { + return parseOSVersion(util.RunAndPrintScript("triage/os_version.ps1")) + "\t" +} + +func parseOSVersion(result string) string { + lines := strings.Split(result, "\n") + var osName, osVersion string + + for _, line := range lines { + line = strings.TrimSpace(line) + if strings.HasPrefix(line, "OS Name:") { + osName = strings.TrimSpace(strings.TrimPrefix(line, "OS Name:")) + } + if strings.HasPrefix(line, "OS Version:") { + osVersion = strings.TrimSpace(strings.TrimPrefix(line, "OS Version:")) + } + } + + return fmt.Sprintf("%s\t%s", osName, osVersion) } diff --git a/triage/users_linux.go b/triage/users_linux.go index aaca756..a9f831d 100644 --- a/triage/users_linux.go +++ b/triage/users_linux.go @@ -9,9 +9,12 @@ import ( "github.com/UT-CTF/landschaft/util" ) -func runUsersTriage() { - printUsers() - printGroups() +func runUsersTriage() string { + csv := printUsers() + csv += "\t" + csv += printGroups() + csv += "\t" + return csv } type user struct { @@ -27,11 +30,11 @@ type group struct { users []string } -func printUsers() { +func printUsers() string { file, err := os.Open("/etc/passwd") if err != nil { fmt.Println("Error reading /etc/passwd:", err) - return + return "err" } defer file.Close() scanner := bufio.NewScanner(file) @@ -52,20 +55,23 @@ func printUsers() { } // convert to [][]string + var result string userListStr := make([][]string, len(userList)) for i, u := range userList { userListStr[i] = []string{u.name, u.uid, u.gid, u.shell} + result += fmt.Sprintf("%s,%s,%s,%s; ", u.name, u.uid, u.gid, u.shell) } t := util.StyledTable().Rows(userListStr...) fmt.Println(t.Render()) + return result } -func printGroups() { +func printGroups() string { file, err := os.Open("/etc/group") if err != nil { fmt.Println("Error reading /etc/group:", err) - return + return "err" } defer file.Close() @@ -90,11 +96,14 @@ func printGroups() { } // convert to [][]string + var result string groupListStr := make([][]string, len(groupList)) for i, g := range groupList { groupListStr[i] = []string{g.name, g.gid, strings.Join(g.users, ",")} + result += fmt.Sprintf("%s,%s,%s; ", g.name, g.gid, strings.Join(g.users, ";")) } t := util.StyledTable().Headers("group", "gid", "users").Rows(groupListStr...) fmt.Println(t.Render()) + return result } diff --git a/triage/users_windows.go b/triage/users_windows.go index 11f3029..1250506 100644 --- a/triage/users_windows.go +++ b/triage/users_windows.go @@ -1,9 +1,76 @@ package triage import ( + "fmt" + "strings" + "github.com/UT-CTF/landschaft/util" ) -func runUsersTriage() { - util.RunAndPrintScript("triage/users.ps1") +func runUsersTriage() string { + return parseUsersAndGroups(util.RunAndPrintScript("triage/users.ps1")) + "\t" + +} + +func parseUsersAndGroups(result string) string { + lines := strings.Split(result, "\n") + var enabled, disabled []string + var enabledCount, disabledCount string + current := "" + inGroups := false + + groups := make(map[string][]string) + var groupOrder []string + currentGroup := "" + + for _, line := range lines { + line = strings.TrimSpace(line) + + if line == "Groups:" { + inGroups = true + continue + } + if line == "" || line == "--------------------------------------------------" || line == "Users:" { + continue + } + + if !inGroups { + if strings.HasPrefix(line, "Enabled Local Users") { + current = "enabled" + enabledCount = strings.TrimPrefix(line, "Enabled Local Users ") + continue + } + if strings.HasPrefix(line, "Disabled Local Users") { + current = "disabled" + disabledCount = strings.TrimPrefix(line, "Disabled Local Users: ") + continue + } + if current == "enabled" { + enabled = append(enabled, line) + } else if current == "disabled" { + disabled = append(disabled, line) + } + } else { + if strings.Contains(line, "(") && strings.Contains(line, ")") && !strings.Contains(line, "\\") { + currentGroup = line + groupOrder = append(groupOrder, currentGroup) + groups[currentGroup] = []string{} + } else if currentGroup != "" { + groups[currentGroup] = append(groups[currentGroup], line) + } + } + } + + var groupParts []string + for _, g := range groupOrder { + groupParts = append(groupParts, fmt.Sprintf("%s: %s", g, strings.Join(groups[g], ", "))) + } + + return fmt.Sprintf("Enabled Local Users %s: %s; Disabled Local Users: %s: %s\t%s", + enabledCount, + strings.Join(enabled, ", "), + disabledCount, + strings.Join(disabled, ", "), + strings.Join(groupParts, "; "), + ) } diff --git a/util/run_script.go b/util/run_script.go index c77ef5e..021e4dd 100644 --- a/util/run_script.go +++ b/util/run_script.go @@ -7,14 +7,15 @@ import ( "github.com/charmbracelet/log" ) -func RunAndPrintScript(scriptPath string, args ...string) { +func RunAndPrintScript(scriptPath string, args ...string) string { fmt.Println("Executing " + scriptPath) scriptOut, err := embed.ExecuteScript(scriptPath, false, args...) if err != nil { log.Error("Failed to execute script", "script", scriptPath, "err", err) - return + return "err" } fmt.Println(scriptOut) + return scriptOut } func RunAndRedirectScript(scriptPath string, args ...string) { From 036967aeac2c04e2821c9d958b34ab3ee92abaf7 Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:58:53 -0600 Subject: [PATCH 02/10] hi --- triage/main.go | 48 ++++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/triage/main.go b/triage/main.go index 7895ceb..d5650a7 100644 --- a/triage/main.go +++ b/triage/main.go @@ -3,8 +3,7 @@ package triage import ( "fmt" "os" - "os/exec" - "runtime" + "path/filepath" "strings" "github.com/UT-CTF/landschaft/util" @@ -45,43 +44,24 @@ func Run() { } - openOrCopyFile(file.Name()) + printCopyInstructions() } -func openOrCopyFile(filename string) { - if runtime.GOOS == "windows" { - println("\nOpen " + filename + " in notepad to copy to sheets") - err := exec.Command("notepad.exe", filename).Start() - if err != nil { - err := exec.Command("explorer.exe", filename).Start() - if err != nil { - println(err.Error()) - return - } - } - return - } +func printCopyInstructions() { + sshConn := os.Getenv("SSH_CONNECTION") + fields := strings.Fields(sshConn) + serverUser := os.Getenv("USER") + serverIP := "" + if len(fields) >= 3 { - // Linux - install and use xclip - err := exec.Command("sudo", "apt-get", "install", "-y", "xclip").Run() - if err != nil { - println("\nCannot install xclip! must use xclip or xsel to copy to sheets") - println(err.Error()) - return - } - - data, err := os.ReadFile(filename) - if err != nil { - fmt.Println("Error reading file:", err) - return + serverIP = fields[2] } - cmd := exec.Command("xclip", "-selection", "clipboard") - cmd.Stdin = strings.NewReader(string(data)) - cmd.Run() + exePath, _ := os.Executable() + tsvPath := filepath.Join(filepath.Dir(exePath), "triage.tsv") - println("\n\n ****** Triage copied to clipboard ******") - println("\n\n Triage saved to " + filename + ". To copy:") - println("\n\tcat " + filename + " | xclip -selection clipboard\n\n") + fmt.Println("To copy to clipboard:") + fmt.Printf("\tIf your host is linux: ssh %s@%s \"cat %s\" | xclip -selection clipboard\n", serverUser, serverIP, tsvPath) + fmt.Printf("\tIf your host is windows: ssh %s@%s \"cat %s\" | clip.exe\n", serverUser, serverIP, tsvPath) } From 242e6e3ac958f5ceb81dca39ebd65aa06f67cead Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Thu, 19 Feb 2026 01:33:19 -0600 Subject: [PATCH 03/10] tsv fix --- triage/firewall_linux.go | 7 ++++++- triage/firewall_windows.go | 20 +++++++++++--------- triage/main.go | 12 +++++++++--- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/triage/firewall_linux.go b/triage/firewall_linux.go index 195da00..24ee923 100644 --- a/triage/firewall_linux.go +++ b/triage/firewall_linux.go @@ -10,7 +10,12 @@ import ( ) func runFirewallTriage() string { - result := util.RunAndPrintScript("triage/firewall.sh") + "\t" + result := util.RunAndPrintScript("triage/firewall.sh") + result = strings.ReplaceAll(result, "\n", " ") + result = strings.ReplaceAll(result, "\r", "") + result = strings.Join(strings.Fields(result), " ") + result = strings.ReplaceAll(result, "=", "") + result += "\t" if strings.Contains(result, "No supported firewall") { result = "No Firewall!\t" diff --git a/triage/firewall_windows.go b/triage/firewall_windows.go index 4df2ad9..75bcfdc 100644 --- a/triage/firewall_windows.go +++ b/triage/firewall_windows.go @@ -32,19 +32,12 @@ func parseFirewall(result string) string { for _, line := range lines { trimmed := strings.TrimSpace(line) - // skip header lines - if strings.HasPrefix(trimmed, "Name") || strings.HasPrefix(trimmed, "----") || trimmed == "" { + if strings.HasPrefix(trimmed, "Name") || strings.HasPrefix(trimmed, "----") || trimmed == "" || strings.HasPrefix(trimmed, "Interfaces:") { continue } - // interface lines - 3 fields fields := strings.Fields(trimmed) - if len(fields) == 3 && !strings.HasPrefix(trimmed, "Profile:") && !strings.HasSuffix(trimmed, "Settings:") && !strings.HasPrefix(trimmed, "State") && !strings.HasPrefix(trimmed, "Firewall") { - interfaces = append(interfaces, iface{fields[0], fields[1], fields[2]}) - continue - } - // Profile: X - Enabled/Disabled if strings.HasPrefix(trimmed, "Profile:") { parts := strings.Split(trimmed, " - ") profileName := strings.TrimSpace(strings.TrimPrefix(parts[0], "Profile:")) @@ -54,7 +47,6 @@ func parseFirewall(result string) string { continue } - // X Profile Settings: if strings.HasSuffix(trimmed, "Profile Settings:") { currentProfile = strings.TrimSuffix(trimmed, " Profile Settings:") continue @@ -63,11 +55,21 @@ func parseFirewall(result string) string { if currentProfile != "" { if strings.HasPrefix(trimmed, "State") { profileState[currentProfile] = strings.TrimSpace(strings.TrimPrefix(trimmed, "State")) + continue } if strings.HasPrefix(trimmed, "Firewall Policy") { profilePolicy[currentProfile] = strings.TrimSpace(strings.TrimPrefix(trimmed, "Firewall Policy")) + continue } } + + // interface line - last field is category, second to last is alias, rest is name + if len(fields) >= 3 { + category := fields[len(fields)-1] + alias := fields[len(fields)-2] + name := strings.Join(fields[:len(fields)-2], " ") + interfaces = append(interfaces, iface{name, alias, category}) + } } var parts []string diff --git a/triage/main.go b/triage/main.go index d5650a7..238d6b2 100644 --- a/triage/main.go +++ b/triage/main.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" "strings" "github.com/UT-CTF/landschaft/util" @@ -54,14 +55,19 @@ func printCopyInstructions() { serverUser := os.Getenv("USER") serverIP := "" if len(fields) >= 3 { - serverIP = fields[2] } exePath, _ := os.Executable() tsvPath := filepath.Join(filepath.Dir(exePath), "triage.tsv") + catCmd := "cat" + if runtime.GOOS == "windows" { + catCmd = "type" + serverUser = os.Getenv("USERNAME") + } + fmt.Println("To copy to clipboard:") - fmt.Printf("\tIf your host is linux: ssh %s@%s \"cat %s\" | xclip -selection clipboard\n", serverUser, serverIP, tsvPath) - fmt.Printf("\tIf your host is windows: ssh %s@%s \"cat %s\" | clip.exe\n", serverUser, serverIP, tsvPath) + fmt.Printf("\tIf your host is linux: ssh %s@%s \"%s %s\" | xclip -selection clipboard\n", serverUser, serverIP, catCmd, tsvPath) + fmt.Printf("\tIf your host is windows: ssh %s@%s \"%s %s\" | clip.exe\n\n\n", serverUser, serverIP, catCmd, tsvPath) } From 366e054ecb9b4b1b1a2875bcf663ff46ae340eda Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Thu, 19 Feb 2026 20:09:38 -0600 Subject: [PATCH 04/10] ameya is picky --- triage/domain_info.go | 55 ++++++++++++++++++++++++++++++++++++++ triage/firewall_linux.go | 22 --------------- triage/firewall_windows.go | 33 +++++++---------------- triage/main.go | 4 +++ triage/network_info.go | 36 +++++++++++++++---------- triage/users_linux.go | 8 +++--- triage/users_windows.go | 13 ++++----- 7 files changed, 102 insertions(+), 69 deletions(-) create mode 100644 triage/domain_info.go diff --git a/triage/domain_info.go b/triage/domain_info.go new file mode 100644 index 0000000..b955bfb --- /dev/null +++ b/triage/domain_info.go @@ -0,0 +1,55 @@ +package triage + +import ( + "fmt" + "os" + "os/exec" + "runtime" + "strings" +) + +func getDomainInfo() string { + if runtime.GOOS == "windows" { + return getDomainInfoWindows() + "\t" + } else { + return getDomainInfoLinux() + "\t" + } +} + +func getDomainInfoLinux() string { + // Check 1: sssd.conf + content, err := os.ReadFile("/etc/sssd/sssd.conf") + if err == nil { + fmt.Println("sssd.conf") + return strings.TrimSpace(string(content)) + } + + // Check 2: realm list (if available) + out, err := exec.Command("realm", "list").Output() + if err == nil && len(out) > 0 { + return strings.TrimSpace(string(out)) + } + + return "Not Domain Jointed" +} + +func getDomainInfoWindows() string { + out, err := exec.Command("wmic", "computersystem", "get", "domain").Output() + if err != nil { + return "Not Domain Joined" + } + + lines := strings.Split(strings.TrimSpace(string(out)), "\n") + for _, line := range lines { + line = strings.TrimSpace(line) + if line == "" || line == "Domain" { + continue + } + if line == "WORKGROUP" { + return "Not Domain Joined" + } + return line + } + + return "Not Domain Joined" +} diff --git a/triage/firewall_linux.go b/triage/firewall_linux.go index 24ee923..162711c 100644 --- a/triage/firewall_linux.go +++ b/triage/firewall_linux.go @@ -1,9 +1,6 @@ package triage import ( - "fmt" - "os" - "os/exec" "strings" "github.com/UT-CTF/landschaft/util" @@ -21,24 +18,5 @@ func runFirewallTriage() string { result = "No Firewall!\t" } - result += getDomainInfo() + "\t" - return result } - -func getDomainInfo() string { - // Check 1: sssd.conf - content, err := os.ReadFile("/etc/sssd/sssd.conf") - if err == nil { - fmt.Println("sssd.conf") - return strings.TrimSpace(string(content)) - } - - // Check 2: realm list (if available) - out, err := exec.Command("realm", "list").Output() - if err == nil && len(out) > 0 { - return strings.TrimSpace(string(out)) - } - - return "Not Domain Jointed" -} diff --git a/triage/firewall_windows.go b/triage/firewall_windows.go index 75bcfdc..b63c855 100644 --- a/triage/firewall_windows.go +++ b/triage/firewall_windows.go @@ -2,7 +2,6 @@ package triage import ( "fmt" - "os/exec" "strings" "github.com/UT-CTF/landschaft/util" @@ -10,7 +9,6 @@ import ( func runFirewallTriage() string { result := parseFirewall(util.RunAndPrintScript("triage/firewall.ps1")) + "\t" - result += getDomainStatus() + "\t" return result } @@ -75,35 +73,24 @@ func parseFirewall(result string) string { var parts []string for _, i := range interfaces { enabled := "Disabled" + check := false if profileEnabled[i.category] { enabled = "Enabled" + check = true } state := profileState[i.category] policy := profilePolicy[i.category] - parts = append(parts, fmt.Sprintf("%s - %s - %s (%s; State %s; Firewall Policy: %s)", - i.name, i.alias, i.category, enabled, state, policy)) - } - return strings.Join(parts, "; ") -} + if check { + parts = append(parts, fmt.Sprintf("%s - %s \n\t%s - %s \n\tState %s \n\tFirewall Policy: %s", + i.name, i.alias, i.category, enabled, state, policy)) + } else { + parts = append(parts, fmt.Sprintf("%s - %s \n\t%s - %s", + i.name, i.alias, i.category, enabled)) + } -func getDomainStatus() string { - out, err := exec.Command("wmic", "computersystem", "get", "domain").Output() - if err != nil { - return "Not Domain Joined" } - lines := strings.Split(strings.TrimSpace(string(out)), "\n") - for _, line := range lines { - line = strings.TrimSpace(line) - if line == "" || line == "Domain" { - continue - } - if line == "WORKGROUP" { - return "Not Domain Joined" - } - return line - } + return "\"" + strings.Join(parts, "\n\n ") + "\"" - return "Not Domain Joined" } diff --git a/triage/main.go b/triage/main.go index 238d6b2..04e12a9 100644 --- a/triage/main.go +++ b/triage/main.go @@ -40,6 +40,10 @@ func Run() { // ignore error } + if _, err := file.Write([]byte(getDomainInfo())); err != nil { + // ignore error + } + errF := file.Close() if errF != nil { diff --git a/triage/network_info.go b/triage/network_info.go index 6eac54a..e259b21 100644 --- a/triage/network_info.go +++ b/triage/network_info.go @@ -36,20 +36,25 @@ func printDNSName(hostname string) string { fmt.Println("error looking up hostname") return "err" } + var check = false for _, addr := range addrs { names, err := net.LookupAddr(addr) if err != nil { return "N/A" } for _, name := range names { - if name == "localhost" { + if name == "localhost" || addr == "127.0.1.1" || addr == "127.0.0.1" { continue } fmt.Printf("FQDN for %s: %s\n", addr, name) - result = result + addr + ": " + name + ", " + result = result + addr + ": " + name + "\n" + check = true } } - return result + if !check { + return "N/A" + } + return "\"" + result + "\"" } func printIPAddrs() string { @@ -83,11 +88,14 @@ func printIPAddrs() string { ipv6Addrs = append(ipv6Addrs, ipNet.IP.String()) } } - result = printAddrs(ipv4Addrs, " IPv4 Addresses:") - result = result + "\t" + printAddrs(ipv6Addrs, " IPv6 Addresses:") - return result + temp := printAddrs(ipv4Addrs, " IPv4 Addresses:") + "\n\n" + if len(temp) > 2 { + result += iface.Name + temp + } + //result = result + "\t" + printAddrs(ipv6Addrs, " IPv6 Addresses:") + printAddrs(ipv6Addrs, " IPv6 Addresses:") } - return result + return "\"" + result + "\"" } func printAddrs(list []string, msg string) string { @@ -96,7 +104,7 @@ func printAddrs(list []string, msg string) string { fmt.Println(" ", msg) for _, ip := range list { fmt.Println(" -", ip) - result = result + ip + ", " + result += fmt.Sprintf("\n\t%s", ip) } } return result @@ -109,7 +117,7 @@ func printSockets(title string, sockets []netstat.SockTabEntry) string { for _, e := range sockets { if e.State.String() == "LISTEN" && !e.LocalAddr.IP.IsLoopback() { fmt.Printf("%s %s %d %s\n", e.LocalAddr.String(), e.State.String(), e.UID, e.Process) - result += fmt.Sprintf("%s %s %d %s;", e.LocalAddr.String(), e.State.String(), e.UID, e.Process) + result += fmt.Sprintf("%d\t%s\n", e.LocalAddr.Port, e.Process) } } } @@ -118,7 +126,7 @@ func printSockets(title string, sockets []netstat.SockTabEntry) string { result = "NONE" } - return result + "\t" + return "\"" + result + "\"\t" } func printNetstat() string { @@ -143,17 +151,17 @@ func printNetstat() string { tcp6Socks, err := netstat.TCP6Socks(netstat.NoopFilter) if err != nil { fmt.Print(err) - result += "err" + //result += "err" } else { - result += printSockets("\nTCP IPv6 Sockets:", tcp6Socks) + printSockets("\nTCP IPv6 Sockets:", tcp6Socks) } // Get UDP IPv6 sockets udp6Socks, err := netstat.UDP6Socks(netstat.NoopFilter) if err != nil { fmt.Print(err) - result += "err" + //result += "err" } else { - result += printSockets("\nUDP IPv6 Sockets:", udp6Socks) + printSockets("\nUDP IPv6 Sockets:", udp6Socks) } return result } diff --git a/triage/users_linux.go b/triage/users_linux.go index a9f831d..629b6fd 100644 --- a/triage/users_linux.go +++ b/triage/users_linux.go @@ -59,12 +59,12 @@ func printUsers() string { userListStr := make([][]string, len(userList)) for i, u := range userList { userListStr[i] = []string{u.name, u.uid, u.gid, u.shell} - result += fmt.Sprintf("%s,%s,%s,%s; ", u.name, u.uid, u.gid, u.shell) + result += fmt.Sprintf("%s (UID: %s, GID: %s, Shell: %s) \n", u.name, u.uid, u.gid, u.shell) } t := util.StyledTable().Rows(userListStr...) fmt.Println(t.Render()) - return result + return "\"" + result + "\"" } func printGroups() string { @@ -100,10 +100,10 @@ func printGroups() string { groupListStr := make([][]string, len(groupList)) for i, g := range groupList { groupListStr[i] = []string{g.name, g.gid, strings.Join(g.users, ",")} - result += fmt.Sprintf("%s,%s,%s; ", g.name, g.gid, strings.Join(g.users, ";")) + result += fmt.Sprintf("%s (GID: %s) - %s\n\n ", g.name, g.gid, strings.Join(g.users, ", ")) } t := util.StyledTable().Headers("group", "gid", "users").Rows(groupListStr...) fmt.Println(t.Render()) - return result + return "\"" + result + "\"" } diff --git a/triage/users_windows.go b/triage/users_windows.go index 1250506..94fdf73 100644 --- a/triage/users_windows.go +++ b/triage/users_windows.go @@ -63,14 +63,15 @@ func parseUsersAndGroups(result string) string { var groupParts []string for _, g := range groupOrder { - groupParts = append(groupParts, fmt.Sprintf("%s: %s", g, strings.Join(groups[g], ", "))) + groupParts = append(groupParts, fmt.Sprintf("%s \n\t%s", g, strings.Join(groups[g], "\n\t"))) } - return fmt.Sprintf("Enabled Local Users %s: %s; Disabled Local Users: %s: %s\t%s", + return fmt.Sprintf("\"Enabled Local Users%s \n\t%s\n"+ + "\nDisabled Local Users %s: \n\t%s\"", enabledCount, - strings.Join(enabled, ", "), + strings.Join(enabled, "\n\t"), disabledCount, - strings.Join(disabled, ", "), - strings.Join(groupParts, "; "), - ) + strings.Join(disabled, "\n\t"), + ) + "\t" + fmt.Sprintf("\"%s\"", strings.Join(groupParts, "\n\n")) + } From 0319efc0308e80ad5998a9be827c668868326c91 Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Fri, 20 Feb 2026 01:18:21 -0600 Subject: [PATCH 05/10] combined os name and version + moved the order of execution --- triage/main.go | 14 ++++++-------- triage/network_info.go | 9 ++++----- triage/os_version_linux.go | 6 +++--- triage/os_version_windows.go | 4 ++-- triage/users_linux.go | 2 +- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/triage/main.go b/triage/main.go index 04e12a9..89d59e9 100644 --- a/triage/main.go +++ b/triage/main.go @@ -18,19 +18,17 @@ func Run() { fmt.Println(util.TitleColor.Render("Network")) - if _, err := file.Write([]byte(runNetworkTriage())); err != nil { - // ignore error - } + hostname, csv := runNetworkTriage() - fmt.Println(util.TitleColor.Render("Users & Groups")) + fmt.Println(util.TitleColor.Render("OS Version")) - if _, err := file.Write([]byte(runUsersTriage())); err != nil { + if _, err := file.Write([]byte(hostname + "\t" + runOSVersionTriage() + "\t" + csv)); err != nil { // ignore error } - fmt.Println(util.TitleColor.Render("OS Version")) + fmt.Println(util.TitleColor.Render("Users & Groups")) - if _, err := file.Write([]byte(runOSVersionTriage())); err != nil { + if _, err := file.Write([]byte(runUsersTriage())); err != nil { // ignore error } @@ -72,6 +70,6 @@ func printCopyInstructions() { } fmt.Println("To copy to clipboard:") - fmt.Printf("\tIf your host is linux: ssh %s@%s \"%s %s\" | xclip -selection clipboard\n", serverUser, serverIP, catCmd, tsvPath) + fmt.Printf("\tIf your host is linux: ssh %s@%s \"%s %s\" | xclip -selection clipboard\n\n", serverUser, serverIP, catCmd, tsvPath) fmt.Printf("\tIf your host is windows: ssh %s@%s \"%s %s\" | clip.exe\n\n\n", serverUser, serverIP, catCmd, tsvPath) } diff --git a/triage/network_info.go b/triage/network_info.go index e259b21..a6ee0ce 100644 --- a/triage/network_info.go +++ b/triage/network_info.go @@ -9,14 +9,13 @@ import ( "github.com/charmbracelet/log" ) -func runNetworkTriage() string { - var hostname = getAndPrintHostname() - var csv = hostname + "\t" - csv = csv + printDNSName(hostname) + "\t" +func runNetworkTriage() (string, string) { + hostname := getAndPrintHostname() + csv := printDNSName(hostname) + "\t" csv = csv + printIPAddrs() + "\t" csv = csv + printNetstat() fmt.Println() - return csv + return hostname, csv } func getAndPrintHostname() string { diff --git a/triage/os_version_linux.go b/triage/os_version_linux.go index 6cf92ab..88aced8 100644 --- a/triage/os_version_linux.go +++ b/triage/os_version_linux.go @@ -21,12 +21,12 @@ func runOSVersionTriage() string { line := scanner.Text() parts := strings.Split(line, "=") if parts[0] == "NAME" { - result += strings.Trim(parts[1], `"`) + "\t" + result += strings.Trim(parts[1], `"`) + "\n" fmt.Println("OS:", strings.Trim(parts[1], `"`)) } else if parts[0] == "VERSION" { fmt.Println("Version:", strings.Trim(parts[1], `"`)) - result += strings.Trim(parts[1], `"`) + "\t" + result += strings.Trim(parts[1], `"`) } } - return result + return "\"" + result + "\"" } diff --git a/triage/os_version_windows.go b/triage/os_version_windows.go index dfe8d39..0dfaec1 100644 --- a/triage/os_version_windows.go +++ b/triage/os_version_windows.go @@ -8,7 +8,7 @@ import ( ) func runOSVersionTriage() string { - return parseOSVersion(util.RunAndPrintScript("triage/os_version.ps1")) + "\t" + return parseOSVersion(util.RunAndPrintScript("triage/os_version.ps1")) } func parseOSVersion(result string) string { @@ -25,5 +25,5 @@ func parseOSVersion(result string) string { } } - return fmt.Sprintf("%s\t%s", osName, osVersion) + return fmt.Sprintf("\"%s\n%s\"", osName, osVersion) } diff --git a/triage/users_linux.go b/triage/users_linux.go index 629b6fd..a394a87 100644 --- a/triage/users_linux.go +++ b/triage/users_linux.go @@ -100,7 +100,7 @@ func printGroups() string { groupListStr := make([][]string, len(groupList)) for i, g := range groupList { groupListStr[i] = []string{g.name, g.gid, strings.Join(g.users, ",")} - result += fmt.Sprintf("%s (GID: %s) - %s\n\n ", g.name, g.gid, strings.Join(g.users, ", ")) + result += fmt.Sprintf("%s (GID: %s) - %s\n\n", g.name, g.gid, strings.Join(g.users, ", ")) } t := util.StyledTable().Headers("group", "gid", "users").Rows(groupListStr...) From 4343f68116df4f0069af17daf3d180a886742c7b Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Fri, 20 Feb 2026 01:34:21 -0600 Subject: [PATCH 06/10] combined tcp and udp --- triage/network_info.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/triage/network_info.go b/triage/network_info.go index a6ee0ce..71d1bbc 100644 --- a/triage/network_info.go +++ b/triage/network_info.go @@ -125,7 +125,7 @@ func printSockets(title string, sockets []netstat.SockTabEntry) string { result = "NONE" } - return "\"" + result + "\"\t" + return result } func printNetstat() string { @@ -136,7 +136,7 @@ func printNetstat() string { fmt.Print(err) result += "err" } else { - result += printSockets("\nTCP IPv4 Sockets:", tcpSocks) + result += "## TCP ##\n" + printSockets("\nTCP IPv4 Sockets:", tcpSocks) } // Get UDP IPv4 sockets udpSocks, err := netstat.UDPSocks(netstat.NoopFilter) @@ -144,7 +144,7 @@ func printNetstat() string { fmt.Print(err) result += "err" } else { - result += printSockets("\nUDP IPv4 Sockets:", udpSocks) + result += "\n## UDP ##\n" + printSockets("\nUDP IPv4 Sockets:", udpSocks) } // Get TCP IPv6 sockets tcp6Socks, err := netstat.TCP6Socks(netstat.NoopFilter) @@ -162,5 +162,5 @@ func printNetstat() string { } else { printSockets("\nUDP IPv6 Sockets:", udp6Socks) } - return result + return "\"" + result + "\"\t" } From a8e2565edcfcb68cd536dc270dfbe4ae99354277 Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Fri, 20 Feb 2026 01:53:51 -0600 Subject: [PATCH 07/10] added os conf --- triage/os_version_windows.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/triage/os_version_windows.go b/triage/os_version_windows.go index 0dfaec1..14a6782 100644 --- a/triage/os_version_windows.go +++ b/triage/os_version_windows.go @@ -13,7 +13,7 @@ func runOSVersionTriage() string { func parseOSVersion(result string) string { lines := strings.Split(result, "\n") - var osName, osVersion string + var osName, osVersion, osConf string for _, line := range lines { line = strings.TrimSpace(line) @@ -23,7 +23,11 @@ func parseOSVersion(result string) string { if strings.HasPrefix(line, "OS Version:") { osVersion = strings.TrimSpace(strings.TrimPrefix(line, "OS Version:")) } + + if strings.HasPrefix(line, "OS Configuration:") { + osConf = strings.TrimSpace(strings.TrimPrefix(line, "OS Configuration:")) + } } - return fmt.Sprintf("\"%s\n%s\"", osName, osVersion) + return fmt.Sprintf("\"%s\n%s\n\n%s\"", osName, osVersion, osConf) } From e5db6e6857e1a6b4f04abd59754736d30b82a75b Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Fri, 20 Feb 2026 02:04:50 -0600 Subject: [PATCH 08/10] user format --- triage/users_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triage/users_linux.go b/triage/users_linux.go index a394a87..e05a895 100644 --- a/triage/users_linux.go +++ b/triage/users_linux.go @@ -59,7 +59,7 @@ func printUsers() string { userListStr := make([][]string, len(userList)) for i, u := range userList { userListStr[i] = []string{u.name, u.uid, u.gid, u.shell} - result += fmt.Sprintf("%s (UID: %s, GID: %s, Shell: %s) \n", u.name, u.uid, u.gid, u.shell) + result += fmt.Sprintf("%s (%s, %s, %s) \n", u.name, u.uid, u.gid, u.shell) } t := util.StyledTable().Rows(userListStr...) From 0da62766f6580d6c70c2815fe34714fbe6376fac Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:11:35 -0600 Subject: [PATCH 09/10] file structure change --- triage/domain_info.go | 55 ----------------------------------- triage/domain_info_linux.go | 25 ++++++++++++++++ triage/domain_info_windows.go | 24 +++++++++++++++ 3 files changed, 49 insertions(+), 55 deletions(-) delete mode 100644 triage/domain_info.go create mode 100644 triage/domain_info_linux.go create mode 100644 triage/domain_info_windows.go diff --git a/triage/domain_info.go b/triage/domain_info.go deleted file mode 100644 index b955bfb..0000000 --- a/triage/domain_info.go +++ /dev/null @@ -1,55 +0,0 @@ -package triage - -import ( - "fmt" - "os" - "os/exec" - "runtime" - "strings" -) - -func getDomainInfo() string { - if runtime.GOOS == "windows" { - return getDomainInfoWindows() + "\t" - } else { - return getDomainInfoLinux() + "\t" - } -} - -func getDomainInfoLinux() string { - // Check 1: sssd.conf - content, err := os.ReadFile("/etc/sssd/sssd.conf") - if err == nil { - fmt.Println("sssd.conf") - return strings.TrimSpace(string(content)) - } - - // Check 2: realm list (if available) - out, err := exec.Command("realm", "list").Output() - if err == nil && len(out) > 0 { - return strings.TrimSpace(string(out)) - } - - return "Not Domain Jointed" -} - -func getDomainInfoWindows() string { - out, err := exec.Command("wmic", "computersystem", "get", "domain").Output() - if err != nil { - return "Not Domain Joined" - } - - lines := strings.Split(strings.TrimSpace(string(out)), "\n") - for _, line := range lines { - line = strings.TrimSpace(line) - if line == "" || line == "Domain" { - continue - } - if line == "WORKGROUP" { - return "Not Domain Joined" - } - return line - } - - return "Not Domain Joined" -} diff --git a/triage/domain_info_linux.go b/triage/domain_info_linux.go new file mode 100644 index 0000000..f9cc735 --- /dev/null +++ b/triage/domain_info_linux.go @@ -0,0 +1,25 @@ +package triage + +import ( + "fmt" + "os" + "os/exec" + "strings" +) + +func getDomainInfo() string { + // Check 1: sssd.conf + content, err := os.ReadFile("/etc/sssd/sssd.conf") + if err == nil { + fmt.Println("sssd.conf") + return strings.TrimSpace(string(content)) + "\t" + } + + // Check 2: realm list (if available) + out, err := exec.Command("realm", "list").Output() + if err == nil && len(out) > 0 { + return strings.TrimSpace(string(out)) + "\t" + } + + return "Not Domain Jointed" + "\t" +} diff --git a/triage/domain_info_windows.go b/triage/domain_info_windows.go new file mode 100644 index 0000000..7865ba0 --- /dev/null +++ b/triage/domain_info_windows.go @@ -0,0 +1,24 @@ +package triage + +import "os/exec" + +func getDomainInfo() string { + out, err := exec.Command("wmic", "computersystem", "get", "domain").Output() + if err != nil { + return "Not Domain Joined" + "\t" + } + + lines := strings.Split(strings.TrimSpace(string(out)), "\n") + for _, line := range lines { + line = strings.TrimSpace(line) + if line == "" || line == "Domain" { + continue + } + if line == "WORKGROUP" { + return "Not Domain Joined" + "\t" + } + return line + "\t" + } + + return "Not Domain Joined" + "\t" +} From b14110d1ab98194c60f89735bb74a0921caed93b Mon Sep 17 00:00:00 2001 From: thankgod4rob <189082078+thankgod4rob@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:17:43 -0600 Subject: [PATCH 10/10] real push, the last one was fake --- triage/domain_info_windows.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/triage/domain_info_windows.go b/triage/domain_info_windows.go index 7865ba0..06dd70e 100644 --- a/triage/domain_info_windows.go +++ b/triage/domain_info_windows.go @@ -1,6 +1,9 @@ package triage -import "os/exec" +import ( + "os/exec" + "strings" +) func getDomainInfo() string { out, err := exec.Command("wmic", "computersystem", "get", "domain").Output()