Skip to content

πŸ›‘οΈ macOS security event monitor with protocol-oriented design and value types - Swift

Notifications You must be signed in to change notification settings

bad-antics/nullsec-swiftsentinel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

NullSec SwiftSentinel

macOS Security Event Monitor written in Swift

Version Language License

Part of the NullSec offensive security toolkit
Discord: discord.gg/killers
Portal: bad-antics.github.io

Overview

SwiftSentinel is a macOS security event monitor that analyzes process, file, network, and authentication events for threats. Built with Swift's protocol-oriented programming, value types, and type-safe enums for robust security analysis.

Swift Features Showcased

  • Protocol-Oriented Design: SecurityEvent, Analyzable, Reportable
  • Enums with Associated Values: Event categories, threat indicators
  • Value Types (Structs): Immutable event objects
  • Generics: Type-safe EventAnalyzer
  • Closures: Rule definitions as first-class functions
  • Pattern Matching: switch with case binding
  • Optionals: Safe nil handling
  • Protocol Extensions: Default implementations

Event Categories

Category Events Detection
Process Spawn, Exec, Exit Shell injection, malware
File Create, Modify, Delete Persistence, exfiltration
Network Connect, Listen, DNS C2 communication
Auth Login, Sudo, TouchID Brute force, privilege escalation
System Kernel, SIP, Gatekeeper System tampering

Security Rules

Rule Severity MITRE Description
Web Shell CRITICAL T1059.004 Shell from web server
C2 Port CRITICAL T1071.001 Known C2 port connection
Recon Tool HIGH T1046 nmap/masscan execution
Sensitive File HIGH T1003.008 /etc/shadow access
Launch Daemon HIGH T1543.001 Persistence mechanism
Privilege Escalation MEDIUM T1548.003 Sudo command
SSH Brute Force MEDIUM T1110.001 Failed SSH attempts

Installation

# Clone
git clone https://github.com/bad-antics/nullsec-swiftsentinel.git
cd nullsec-swiftsentinel

# Build with Swift
swiftc -O SwiftSentinel.swift -o swiftsentinel

# Or run directly
swift SwiftSentinel.swift

Usage

# Run demo mode
./swiftsentinel

# Monitor live events (requires root)
sudo ./swiftsentinel --live

# Filter by event type
./swiftsentinel --filter process,network

# JSON output
./swiftsentinel --json

Options

USAGE:
    swiftsentinel [OPTIONS]

OPTIONS:
    --live           Monitor live events
    --filter         Event types (process,file,network,auth)
    --json           JSON output format
    -v, --verbose    Verbose output

Sample Output

╔══════════════════════════════════════════════════════════════════╗
β•‘       NullSec SwiftSentinel - macOS Security Event Monitor       β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

[Demo Mode]

Analyzing macOS security events...

Processing Events...

  [Process] Event received
  [Process] Event received
  [Process] Event received
  [File] Event received
  [File] Event received
  [Network] Event received
  [Network] Event received
  [Authentication] Event received
  [Authentication] Event received

═══════════════════════════════════════════════════════════════════
                         SECURITY ALERTS
═══════════════════════════════════════════════════════════════════

  [CRITICAL] Shell spawned from web server process
      ID:          PROC-A1B2C3D4
      Source:      EndpointSecurity
      Risk Score:  85/100
      MITRE:       T1059.004
      Remediation: Investigate web server compromise, check for webshells

  [CRITICAL] Connection to known C2 port
      ID:          NET-E5F6G7H8
      Source:      NetworkExtension
      Risk Score:  95/100
      MITRE:       T1071.001
      Remediation: Block connection, investigate process

  [HIGH] Network reconnaissance tool executed
      ID:          PROC-I9J0K1L2
      Source:      EndpointSecurity
      Risk Score:  90/100
      MITRE:       T1046
      Remediation: Investigate suspicious tool execution

  [HIGH] Sensitive file accessed: /etc/shadow
      ID:          FILE-M3N4O5P6
      Source:      EndpointSecurity
      Risk Score:  75/100
      MITRE:       T1003.008
      Remediation: Review access to sensitive file

═══════════════════════════════════════════════════════════════════

  Summary:
    Events Processed: 9
    Alerts Generated: 8
    Critical:         2
    High:             4
    Medium:           2
    Low:              0

Code Highlights

Protocol-Oriented Design

protocol SecurityEvent {
    var timestamp: Date { get }
    var severity: Severity { get }
    var source: String { get }
    var description: String { get }
    var mitreId: String { get }
}

protocol Analyzable {
    associatedtype Input
    associatedtype Output
    func analyze(_ input: Input) -> Output
}

Enums with Associated Values

enum EventCategory {
    case process(ProcessEvent)
    case file(FileEvent)
    case network(NetworkEvent)
    case authentication(AuthEvent)
    case system(SystemEvent)
}

enum ThreatIndicator {
    case maliciousProcess(name: String, pid: Int)
    case suspiciousFile(path: String, operation: String)
    case c2Communication(ip: String, port: Int)
    case bruteForce(user: String, attempts: Int)
}

Generic Analyzer with Protocol Constraints

struct EventAnalyzer<E: SecurityEvent>: Analyzable {
    typealias Input = E
    typealias Output = Alert?
    
    private let rules: [(E) -> Alert?]
    
    func analyze(_ input: E) -> Alert? {
        for rule in rules {
            if let alert = rule(input) {
                return alert
            }
        }
        return nil
    }
}

Rules as Closures

static let processRules: [(ProcessEvent) -> Alert?] = [
    { event in
        let shells = ["bash", "sh", "zsh"]
        guard shells.contains(event.name),
              event.path.contains("nginx") else {
            return nil
        }
        
        return Alert(
            id: "PROC-\(UUID().uuidString.prefix(8))",
            event: event,
            indicator: .maliciousProcess(name: event.name, pid: event.pid),
            riskScore: 85.0,
            remediation: "Investigate web server compromise"
        )
    }
]

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               SwiftSentinel Architecture                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚   β”‚           Event Sources (Protocols)               β”‚        β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚        β”‚
β”‚   β”‚  β”‚Endpoint β”‚ β”‚Network  β”‚ β”‚Open     β”‚ β”‚Unified  β”‚ β”‚        β”‚
β”‚   β”‚  β”‚Security β”‚ β”‚Extensionβ”‚ β”‚Directoryβ”‚ β”‚Logging  β”‚ β”‚        β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β”‚        β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”˜        β”‚
β”‚           β”‚           β”‚           β”‚           β”‚                β”‚
β”‚           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
β”‚                       β–Ό           β–Ό                            β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚   β”‚       EventCategory (enum with associated)        β”‚        β”‚
β”‚   β”‚  .process(ProcessEvent) | .file(FileEvent)       β”‚        β”‚
β”‚   β”‚  .network(NetworkEvent) | .auth(AuthEvent)       β”‚        β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β”‚                            β”‚                                   β”‚
β”‚                            β–Ό                                   β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚   β”‚      EventAnalyzer<E: SecurityEvent> (Generic)    β”‚        β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚        β”‚
β”‚   β”‚  β”‚  rules: [(E) -> Alert?]  (Closure Array)    β”‚ β”‚        β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚        β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β”‚                            β”‚                                   β”‚
β”‚                            β–Ό                                   β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚   β”‚  Alert           β”‚    β”‚  Reportable      β”‚               β”‚
β”‚   β”‚  (struct)        │───▢│  (protocol)      β”‚               β”‚
β”‚   β”‚  Value Type      β”‚    β”‚  generateReport()β”‚               β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β”‚                                                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why Swift?

Requirement Swift Advantage
Type Safety Protocol constraints, optionals
Performance Value types, zero-cost abstractions
Expressiveness Enums with associated values
Safety Memory safety, bounds checking
Concurrency async/await, actors (Swift 5.5+)
macOS Integration Native Endpoint Security API

License

MIT License - See LICENSE for details.

Related Tools

About

πŸ›‘οΈ macOS security event monitor with protocol-oriented design and value types - Swift

Resources

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages