Files
Sigma-C2/server/server.go
2025-07-11 14:06:11 +02:00

171 lines
4.4 KiB
Go

package main
import (
"crypto/tls"
"crypto/x509"
"flag"
"fmt"
"log"
"net"
"os"
"os/signal"
"syscall"
)
// Default operator listener
var defaultServerAddr = "0.0.0.0:8080"
// Default agent listeners' addresses
var defaultListenSSLaddr = []string{"192.168.1.4"}
var defaultListenSSLport = "8443"
var defaultListenHTTPSaddr = []string{"192.168.1.4"}
var defaultListenHTTPSport = "8880"
var defaultListenDNSaddr = []string{"192.168.1.4"}
var defaultListenDNSport = "8553"
var defaultListenTCPaddr = []string{"192.168.1.4"}
var defaultListenTCPport = "8888"
// To store server's password
var serverPass *string
var serverHashedPass string
// Developer mode
var DevelMode bool
// Certificates
var serverCertPath = "certificates/server.crt"
var serverKeyPath = "certificates/server.key"
var caCertPath = "certificates/ca.crt"
// Global, as will be shared
var tlsConfig *tls.Config
func main() {
// log.SetFlags(log.Ltime | log.Lshortfile)
log.SetFlags(log.Ltime)
// Handle signals for graceful shutdown
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
// Load avaialbe modules from directory
InitModules()
go func() {
<-stop
log.Println("Shutting down server gracefully...")
os.Exit(0)
}()
// Parse arguments
serverPass = flag.String("p", "", "Password for operator authentication")
serverAddr := flag.String("ip", defaultServerAddr, "IP address and port to listen for operators")
flag.BoolVar(&DevelMode, "devel", false, "Developer mode")
flag.Parse()
// Check if pass is provided
if *serverPass == "" {
log.Println("Usage: server.exe -p <password>")
return
}
log.Println("Server password set.")
// Store hashed server password
serverHashedPass = HashPassword(serverPass)
// Load CA certificate
caCert, err := os.ReadFile(caCertPath)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Load our CA cert for mTLS
caCertPool := x509.NewCertPool()
if !caCertPool.AppendCertsFromPEM(caCert) {
log.Fatal("Failed to append CA certificate to pool")
}
// Load certificates
cert, err := tls.LoadX509KeyPair(serverCertPath, serverKeyPath)
if err != nil {
fmt.Println("Error loading certificates:", err)
return
}
// Init TLS context
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
ClientCAs: caCertPool,
ClientAuth: tls.RequireAndVerifyClientCert, // Client cert will be requested and verified
}
// Skip cert verifications if developing or debugging
if DevelMode {
log.Print("Skipping mTLS in devel mode")
tlsConfig.ClientAuth = tls.NoClientCert
}
// Goroutines
// Start default operator listener
go ListenForOperator(tlsConfig, serverAddr)
// Start default agent listeners
if DevelMode {
StartAgentListener("tcp", defaultListenTCPaddr, defaultListenTCPport, "default_TCP", nil)
StartAgentListener("ssl", defaultListenSSLaddr, defaultListenSSLport, "default_SSL", nil)
StartAgentListener("https", defaultListenHTTPSaddr, defaultListenHTTPSport, "default_HTTPS", nil)
StartAgentListener("dns", defaultListenDNSaddr, defaultListenDNSport, "default_DNS", nil)
}
select {}
}
// Start listening for operators
func ListenForOperator(tlsConfig *tls.Config, serverAddr *string) {
// Start listening for operators
listener, err := tls.Listen("tcp", *serverAddr, tlsConfig)
if err != nil {
log.Fatalf("Error starting operator server: %v", err)
return
}
defer listener.Close()
// Accept connection via go routine
for {
operatorConn, err := listener.Accept()
if err != nil {
debugLog("Error accepting connection: %v", err)
continue
}
go HandleOperatorConnection(operatorConn)
}
}
// Log operator's connection, authenticate and start parsing commands
func HandleOperatorConnection(operatorConn net.Conn) {
defer func() {
debugLog("Operator connection closed from: %s", operatorConn.RemoteAddr())
debugLog("\n")
operatorConn.Close()
}()
// Authenticate operator
operatorID, authenticated := AuthenticateOperator(operatorConn, serverHashedPass)
if !authenticated {
debugLog("Authentication failed")
return
}
// Update dynamic tab completion right after operator connects
UpdateListenersTabCompletion()
UpdateAgentsTabCompletion()
// Handle operator commands after successful authentication
ParseOperatorCommands(operatorConn, operatorID)
}