gonmap

repository·master·Indexed 43 days ago

https://github.com/lcvvvv/gonmap

A Go implementation of Nmap-style service and version detection. It provides a framework for probing ports, matching responses against fingerprints, and identifying services and versions using a probe-based engine. Features include deep identification via OpenDeepIdentify, custom logger support, and utilities for managing port ranges and protocol normalization.

Tokens
2.9K
Snippets
19
Records
20
Agent score
56%

What's inside gonmap

  1. How Nmap service scanning works

    master

    The Nmap struct implements a probe-based service detection engine.

    The Scanning Lifecycle

    1. Probe Selection: For a given port, the engine selects a list of probes. It prioritizes probes mapped specifically to that port, then adds general probes (allProbeMap), and finally adds SSL-specific probes (sslProbeMap).
    2. Execution: It executes the first probe. If the port is not Closed or Matched, it proceeds to subsequent probes.
    3. Fingerprinting: When a probe returns data, the engine uses getFinger to match the response against known service patterns. It converts binary responses to UTF-8 strings to facilitate regex matching.
    4. Fallback Mechanism: If a probe fails to match a service, it can follow a fallback chain to try related probes (e.g., falling back from a specific protocol to a more generic one).
    5. SSL/HTTPS Refinement: If a service is identified as ssl, the engine automatically triggers getResponseBySSLSecondProbes to ensure the service isn't actually standard http running over TLS (identifying it as https).
  2. Guess the protocol for a given port

    master

    Use GuessProtocol(port int) to determine the likely protocol running on a specific port. If the port is unknown, it defaults to http.

    protocol := gonmap.GuessProtocol(80)
    // returns "http"
  3. Create a new Nmap instance with New()

    master

    To get a fresh instance of the Nmap engine based on the current global configuration, call New(). This returns a pointer to an Nmap struct that is a copy of the initialized global state.

    n := gonmap.New()
  4. Configure the custom Logger for gonmap

    master

    The gonmap package uses a Logger interface to manage library logging. By default, it logs to os.Stderr with a [gonmap] prefix. You can provide your own implementation of the Logger interface to redirect logs to your application's logging system using SetLogger.

    type Logger interface {
    	Printf(format string, v ...interface{})
    	Println(v ...interface{})
    }
    
    // To use your own logger:
    // SetLogger(myCustomLogger)
  5. Normalize protocol names with FixProtocol

    master

    The FixProtocol(oldProtocol string) function is used to clean up and normalize protocol strings for final output. It performs several transformations:

    • Converts ssl/http to https.
    • Converts http-proxy to http.
    • Maps specific service names like ms-wbt-server to rdp, microsoft-ds to smb, and ms-sql-s to mssql.
    • Handles ssl/ prefixes by converting them to -ssl suffixes (e.g., ssl/ssh becomes ssh-ssl).
    • Replaces underscores _ with hyphens -.
    • Prepends S to protocols that start with a digit.
    cleanName := gonmap.FixProtocol("ssl/http")
    // returns "https"
    
    cleanName := gonmap.FixProtocol("ms-wbt-server")
    // returns "rdp"
  6. Perform network scans with Nmap.Scan

    master

    The Scan method performs a service version detection scan on a specific IP and port. It uses a sequence of probes (requests) to identify the service running on the port. The process involves:

    1. Selecting probes based on the port (using portProbeMap).
    2. Attempting the first probe.
    3. If the first probe doesn't result in a Matched or Closed status, it iterates through remaining probes.
    4. If an SSL service is detected, it performs secondary SSL/HTTPS probes to refine the identification.

    Returns a Status (e.g., Matched, Closed, Open, NotMatched) and a *Response containing the raw data and FingerPrint.

    status, response := nmapInstance.Scan("127.0.0.1", 80)
  7. Enable deep identification with OpenDeepIdentify

    master

    Calling OpenDeepIdentify enables deep service version detection (similar to the -sV flag in Nmap). It configures the scanner to use the full allProbeMap (the sorted list of all available probes) instead of just port-specific probes.

    nmapInstance.OpenDeepIdentify()
  8. Set the probe filter level

    master

    You can control the initialization and filtering of Nmap probes using SetFilter(filter int). This re-initializes the internal Nmap engine with the specified filter level. This is useful if you need to adjust the depth or scope of the fingerprinting logic during runtime.

    // Set the filter level
    gonmap.SetFilter(9)
  9. Add custom match expressions with AddMatch

    master

    The AddMatch method allows you to extend an existing probe's matching capabilities by adding a new regular expression expression. This is used to refine how a specific probeName identifies a service.

    nmapInstance.AddMatch("HTTP", "Server: Apache/.*")
  10. Use Status constants to interpret scan results

    master

    The Status type represents the outcome of a scan. It is an integer type that can be converted to a human-readable string using the .String() method. Use the following constants to check the state of a service or port:

    // Example of checking a status
    if status == gonmap.Open {
        fmt.Println("Port is open")
    }
    
    // Example of getting the string representation
    fmt.Println(status.String()) // Outputs: "Open", "Closed", etc.
  11. Perform network scans with Nmap.ScanTimeout

    master

    The ScanTimeout method is a wrapper around Scan that enforces a hard deadline using a context.WithTimeout. This is useful for preventing scans from hanging indefinitely on unresponsive hosts.

    If the timeout is reached before the scan completes, it returns Closed and nil.

    status, response := nmapInstance.ScanTimeout("127.0.0.1", 443, 5 * time.Second)