nse

package
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2026 License: MIT Imports: 15 Imported by: 0

README

NSE (Nmap Script Engine) Package

For the current cross-component ownership, deletion, atomic update, and isolated functional-test contract, see NSE catalog consistency.

This package manages NSE scripts in the Sirius Scanner, providing a robust synchronization system between local scripts, a global ValKey store, and Git repositories. The system ensures consistent script management across Docker containers while maintaining script integrity and version control.

Core Components

1. Directory Structure
/opt/sirius/nse/               # Base directory in Docker
├── manifest.json            # Repository list manifest
├── sirius-nse/             # Repository directory
│   ├── manifest.json      # Repository manifest
│   └── scripts/          # NSE scripts directory
│       └── vulners.nse  # Example script
2. Manifest System

The NSE system uses several types of manifests that work together:

  1. Repository List Manifest (manifest.json)

    • Lists all NSE script repositories
    • Example:
    {
      "repositories": [
        {
          "name": "sirius-nse",
          "url": "https://github.com/SiriusScan/sirius-nse.git"
        }
      ]
    }
    
  2. Repository Manifest (<repo>/manifest.json)

    • Source of truth for script definitions
    • Contains script metadata and paths
    • Example:
    {
      "name": "sirius-nse",
      "version": "0.1.0",
      "description": "NSE scripts for Sirius",
      "scripts": {
        "vulners": {
          "name": "vulners",
          "path": "scripts/vulners.nse",
          "protocol": "*"
        }
      }
    }
    
  3. Global Manifests (ValKey)

    • nse:repo-manifest - Global repository list
    • nse:manifest - Global script manifest
    • Take precedence over local manifests
    • Enable cross-container synchronization
  4. Local Manifests (Memory)

    • Working copies in each container
    • Synchronized with global manifests
    • Used for script execution
3. Synchronization System

The sync system follows a priority-based approach:

Global ValKey > Local Files > Built-in Defaults

Key features:

  • Automatic initialization of empty manifests
  • Built-in repository list as fallback
  • Preservation of script content during syncs
  • Proper error handling for missing scripts
  • Atomic updates to prevent partial states
4. ValKey Integration

Key naming convention:

  • nse:repo-manifest - Global repository list storage
  • nse:manifest - Global script manifest storage
  • nse:script:<script_name> - Script content storage

Usage

Basic Initialization
// Create a repo manager with Docker path
repoManager := nse.NewRepoManager("/opt/sirius/nse/sirius-nse", repoURL)

// Create a sync manager
syncManager := nse.NewSyncManager(repoManager, kvStore)

// Synchronize repositories and scripts
err := syncManager.Sync(context.Background())
Script Content Management
// Update script content
err := syncManager.updateScriptContent(ctx, "vulners", &ScriptContent{
    Content: scriptContent,
    Metadata: Metadata{
        Author:      "Author Name",
        Tags:        []string{"vulnerability"},
        Description: "Script description",
    },
    UpdatedAt: time.Now().Unix(),
})

Error Handling

The system implements comprehensive error handling:

  1. ValKey Errors

    • Handles "nil message" errors for missing keys
    • Provides initialization for missing manifests
    • Preserves error context through wrapping
  2. File System Errors

    • Handles missing directories
    • Manages file permissions
    • Provides cleanup for legacy paths
  3. Repository Errors

    • Graceful handling of repository failures
    • Continues processing other repositories on error
    • Clear error messages for troubleshooting
  4. Synchronization Errors

    • Graceful handling of missing scripts
    • Clear error messages for troubleshooting
    • Proper context preservation

Testing

Run the NSE test program to verify the setup:

docker exec -it sirius-engine go run cmd/nse-test/main.go

The test program:

  • Verifies ValKey connectivity
  • Tests repository manifest synchronization
  • Tests script manifest synchronization
  • Validates script content management
  • Checks directory structure
  • Cleans up legacy paths

Best Practices

  1. Docker Environment

    • Always use /opt/sirius/nse as the base path
    • Ensure proper permissions (755 for directories)
    • Clean up legacy directories when found
  2. Repository Management

    • Use the built-in repository list as a fallback
    • Let ValKey repository manifest take precedence
    • Handle repository failures gracefully
  3. Manifest Management

    • Let global manifests take precedence
    • Initialize empty manifests when missing
    • Preserve script metadata during syncs
  4. Error Handling

    • Check ValKey connectivity first
    • Validate paths before operations
    • Log meaningful error messages
  5. Synchronization

    • Always sync before script execution
    • Verify script content after updates
    • Handle missing scripts gracefully

Documentation

Index

Constants

View Source
const (
	// DefaultNSERepoURL is the default Git repository URL for Sirius NSE scripts.
	// Override with the NSE_REPO_URL environment variable.
	DefaultNSERepoURL = "https://github.com/SiriusScan/sirius-nse.git"
	// DefaultNSEBasePath is the default base path where NSE scripts are stored.
	// Override with the NSE_BASE_PATH environment variable.
	DefaultNSEBasePath = "/sirius-nse"
	// ManifestFile is the name of the manifest file
	ManifestFile = "manifest.json"
)
View Source
const (
	ValKeyManifestKey      = templates.KeyNseManifest
	ValKeyRepoManifestKey  = templates.KeyNseRepoManifest
	ValKeyScriptPrefix     = templates.KeyNseScriptPrefix
	ValKeyScriptMetaPrefix = templates.KeyNseScriptMetaPrefix
)

Valkey keys are sourced from the shared go-api/sirius/store/templates package so every producer/consumer agrees on namespacing without having to copy string literals around. Kept as package-level aliases for backwards compatibility with existing call sites in tests.

Variables

View Source
var NSEBasePath = envOrDefault("NSE_BASE_PATH", DefaultNSEBasePath)

NSEBasePath is the base path where NSE scripts are stored.

View Source
var NSERepoURL = envOrDefault("NSE_REPO_URL", DefaultNSERepoURL)

NSERepoURL returns the NSE repository URL from env or the default.

View Source
var ScriptBlacklist = map[string]string{

	"afp-brute":                        "brute",
	"ajp-brute":                        "brute",
	"backorifice-brute":                "brute",
	"cassandra-brute":                  "brute",
	"cics-user-brute":                  "brute",
	"citrix-brute-xml":                 "brute",
	"cvs-brute":                        "brute",
	"cvs-brute-repository":             "brute",
	"deluge-rpc-brute":                 "brute",
	"dicom-brute":                      "brute",
	"dns-brute":                        "brute",
	"domcon-brute":                     "brute",
	"dpap-brute":                       "brute",
	"drda-brute":                       "brute",
	"ftp-brute":                        "brute",
	"http-brute":                       "brute",
	"http-form-brute":                  "brute",
	"http-iis-short-name-brute":        "brute",
	"http-joomla-brute":                "brute",
	"http-proxy-brute":                 "brute",
	"http-wordpress-brute":             "brute",
	"iax2-brute":                       "brute",
	"imap-brute":                       "brute",
	"informix-brute":                   "brute",
	"ipmi-brute":                       "brute",
	"irc-brute":                        "brute",
	"irc-sasl-brute":                   "brute",
	"iscsi-brute":                      "brute",
	"ldap-brute":                       "brute",
	"membase-brute":                    "brute",
	"memcached-brute":                  "brute",
	"metasploit-msgrpc-brute":          "brute",
	"mikrotik-routeros-brute":          "brute",
	"mmouse-brute":                     "brute",
	"mongodb-brute":                    "brute",
	"mqtt-subscribe":                   "brute",
	"ms-sql-brute":                     "brute",
	"mysql-brute":                      "brute",
	"netbus-brute":                     "brute",
	"nexpose-brute":                    "brute",
	"nping-brute":                      "brute",
	"omp2-brute":                       "brute",
	"openvas-otp-brute":                "brute",
	"openlookup-brute":                 "brute",
	"oracle-brute":                     "brute",
	"oracle-brute-stealth":             "brute",
	"oracle-sid-brute":                 "brute",
	"ovs-agent-version":                "brute",
	"pcanywhere-brute":                 "brute",
	"pgsql-brute":                      "brute",
	"pop3-brute":                       "brute",
	"redis-brute":                      "brute",
	"rexec-brute":                      "brute",
	"rlogin-brute":                     "brute",
	"rpcap-brute":                      "brute",
	"rsync-brute":                      "brute",
	"rtsp-url-brute":                   "brute",
	"sip-brute":                        "brute",
	"smb-brute":                        "brute",
	"smb-psexec":                       "brute",
	"smtp-brute":                       "brute",
	"snmp-brute":                       "brute",
	"socks-brute":                      "brute",
	"ssh-brute":                        "brute",
	"svn-brute":                        "brute",
	"telnet-brute":                     "brute",
	"vnc-brute":                        "brute",
	"vmauthd-brute":                    "brute",
	"xmpp-brute":                       "brute",
	"mikrotik-routeros-username-brute": "brute",

	"broadcast-avahi-dos": "dos",
	"dns-fuzz":            "dos",
	"http-form-fuzzer":    "dos",
	"ipv6-ra-flood":       "dos",
	"smb-flood":           "dos",
	"smb-vuln-regsvc-dos": "dos",

	"broadcast-listener":             "info-gathering",
	"targets-asn":                    "info-gathering",
	"targets-ipv6-multicast-echo":    "info-gathering",
	"targets-ipv6-multicast-invalid": "info-gathering",
	"targets-ipv6-multicast-mld":     "info-gathering",
	"targets-ipv6-multicast-slaac":   "info-gathering",
	"targets-ipv6-wordlist":          "info-gathering",
	"targets-sniffer":                "info-gathering",
	"targets-traceroute":             "info-gathering",
	"targets-xml":                    "info-gathering",
	"traceroute-geolocation":         "info-gathering",

	"ssh-hostkey": "syntax-error",
}

Functions

func GetBlacklistStats

func GetBlacklistStats() map[string]int

GetBlacklistStats returns statistics about the blacklist

func IsBlacklisted

func IsBlacklisted(scriptName string) (bool, string)

IsBlacklisted checks if a script should be excluded

func SaveManifest

func SaveManifest(manifest *Manifest, path string) error

SaveManifest saves the manifest to the specified path

Types

type DefaultGitOps

type DefaultGitOps struct{}

DefaultGitOps implements GitOperations using real Git commands

func (*DefaultGitOps) Clone

func (g *DefaultGitOps) Clone(repoURL, targetPath string) error

func (*DefaultGitOps) Fetch

func (g *DefaultGitOps) Fetch(repoPath string) error

func (*DefaultGitOps) Reset

func (g *DefaultGitOps) Reset(repoPath string) error

type GitOperations

type GitOperations interface {
	Clone(repoURL, targetPath string) error
	Fetch(repoPath string) error
	Reset(repoPath string) error
}

GitOperations defines the interface for Git operations

type Manifest

type Manifest struct {
	Name        string            `json:"name"`
	Version     string            `json:"version"`
	Description string            `json:"description"`
	Scripts     map[string]Script `json:"scripts"`
}

Manifest represents the NSE scripts manifest

func LoadManifest

func LoadManifest(path string) (*Manifest, error)

LoadManifest loads the manifest from the specified path

type Metadata

type Metadata struct {
	Author      string   `json:"author"`
	Tags        []string `json:"tags"`
	Description string   `json:"description"`
}

Metadata represents additional information about a script

type RepoManager

type RepoManager struct {
	BasePath string
	RepoURL  string
	// contains filtered or unexported fields
}

RepoManager handles NSE script repository operations

func NewRepoManager

func NewRepoManager(basePath string, repoURL string) *RepoManager

NewRepoManager creates a new RepoManager instance

func (*RepoManager) EnsureRepo

func (r *RepoManager) EnsureRepo() error

EnsureRepo ensures the repository exists and is up to date

func (*RepoManager) GetManifest

func (rm *RepoManager) GetManifest() (*Manifest, error)

GetManifest returns the current manifest from the repository

func (*RepoManager) SetGitOps

func (rm *RepoManager) SetGitOps(gitOps GitOperations)

SetGitOps sets the GitOperations implementation (useful for testing)

type Repository

type Repository struct {
	Name string `json:"name"`
	URL  string `json:"url"`
}

Repository represents a single NSE script repository

type RepositoryList

type RepositoryList struct {
	Repositories []Repository `json:"repositories"`
}

RepositoryList represents the manifest file structure

func LoadRepositoryList

func LoadRepositoryList(path string) (*RepositoryList, error)

LoadRepositoryList loads the built-in repository list from manifest.json

type Script

type Script struct {
	Name     string `json:"name"`
	Path     string `json:"path"`
	Protocol string `json:"protocol"`
}

Script represents a single NSE script

type ScriptContent

type ScriptContent struct {
	Content   string   `json:"content"`   // The actual script content
	Metadata  Metadata `json:"metadata"`  // Script metadata
	UpdatedAt int64    `json:"updatedAt"` // Unix timestamp of last update
}

ScriptContent represents a script's content and metadata in the KV store

type ScriptSelector

type ScriptSelector struct {
	// contains filtered or unexported fields
}

ScriptSelector handles the selection of NSE scripts based on protocols

func NewScriptSelector

func NewScriptSelector(manifest *Manifest) *ScriptSelector

NewScriptSelector creates a new ScriptSelector instance

func (*ScriptSelector) BuildNmapScriptFlag

func (s *ScriptSelector) BuildNmapScriptFlag(protocols ...string) (string, error)

BuildNmapScriptFlag constructs the --script flag value for Nmap command It returns both the flag and any error that occurred during construction

func (*ScriptSelector) GetScriptsByProtocol

func (s *ScriptSelector) GetScriptsByProtocol() map[string][]Script

GetScriptsByProtocol returns a map of protocols to their associated scripts

func (*ScriptSelector) SelectScripts

func (s *ScriptSelector) SelectScripts(protocols ...string) []string

SelectScripts returns a list of script paths that match the given protocols If no protocols are provided, returns scripts marked with "*" protocol

type SyncManager

type SyncManager struct {
	// contains filtered or unexported fields
}

SyncManager handles synchronization between local NSE scripts and ValKey store

func NewSyncManager

func NewSyncManager(repoManager *RepoManager, kvStore store.KVStore) *SyncManager

NewSyncManager creates a new SyncManager instance

func (*SyncManager) Sync

func (sm *SyncManager) Sync(ctx context.Context) error

Sync publishes one coherent catalog across all configured repositories. It never replaces UI-owned or unclassified legacy entries, and honors deletions.

func (*SyncManager) SyncScriptContent

func (sm *SyncManager) SyncScriptContent(id string, script Script) error

SyncScriptContent synchronizes a single script's content

func (*SyncManager) UpdateScriptFromUI

func (sm *SyncManager) UpdateScriptFromUI(ctx context.Context, scriptID string, content *ScriptContent) error

UpdateScriptFromUI updates a script's content and metadata from the UI. The incoming scriptID may be the canonical id ("foo") or the legacy extension form ("foo.nse"); both resolve to the same Valkey key.

func (*SyncManager) UpdateValKeyManifest

func (sm *SyncManager) UpdateValKeyManifest(ctx context.Context, manifest *Manifest) error

UpdateValKeyManifest updates the manifest in ValKey store

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL