onesixtyone icon indicating copy to clipboard operation
onesixtyone copied to clipboard

multiple ports

Open executionByFork opened this issue 1 year ago • 2 comments

SNMP uses ports 161 and 162 as standard. This tool only attempts to scan port 161 by default. There is a -p option but this only takes one port. The code strtol(optarg, NULL, 10) == 0 will take the first number it finds in the string and set as the port, then drop everything else as soon as a bad character is encountered.

As such, -p161,162 will run, but only scan port 161. This is confusing and unexpected behavior given that the command runs without warning or error. The current code only ever errors out if -p begins with a non-numeric character.

Suggestion: Implement functionality for multiple ports to be scanned from one program invocation. Allow the tool to take 161,162 and know to scan both ports 161 and 162. Additionally, scan both 161 and 162 by default

executionByFork avatar Aug 30 '24 18:08 executionByFork

I may be wrong about needing to scan p162. This port seems to be used for different types of calls. Having the option to specify multiple ports with -pmight still be nice though

executionByFork avatar Aug 30 '24 18:08 executionByFork

Analysis of Issue #33: Multiple Port Support

I've analyzed this feature request and confirmed the current limitation. Here's a comprehensive analysis and implementation plan for adding multiple port support to onesixtyone.

Current Behavior Analysis

The current port parsing has a silent failure issue:

// Current code at line 295-300:
if (strtol(optarg, NULL, 10) == 0) {
    printf("Malformed port: %s\n", optarg);
    exit(1);
} else {
    o.port = strtol(optarg, NULL, 10);
}

What happens with -p161,162:

  • strtol("161,162", NULL, 10) returns 161 and ignores ,162
  • No error or warning is shown
  • Users think they're scanning both ports, but only port 161 is scanned

SNMP Port Context

Clarification on SNMP port usage:

  • Port 161: SNMP agent (standard SNMP requests/responses)
  • Port 162: SNMP trap receiver (notifications/alarms)

While port 162 is primarily for traps (not typical scanning), there are valid use cases for multi-port scanning:

  1. Non-standard SNMP configurations
  2. Security testing across multiple services
  3. Devices running SNMP on alternate ports

Implementation Plan

Phase 1: Basic Multiple Port Support

Data Structure Changes:

// Replace single port with array
struct {
    int debug;
    int log;
    int ports[MAX_PORTS];      // New: array of ports
    int port_count;             // New: number of ports to scan
    int print_ip;
    int quiet;
    long wait;
    FILE* log_fd;
} o;

#define MAX_PORTS 16  // Reasonable limit

Port Parsing Enhancement:

case 'p':
    o.port_count = parse_ports(optarg, o.ports, MAX_PORTS);
    if (o.port_count <= 0) {
        printf("Invalid port specification: %s\n", optarg);
        printf("Valid formats: 161 or 161,162,8161\n");
        exit(1);
    }
    break;

New Parsing Function:

int parse_ports(char *portstr, int *ports, int max_ports) {
    char *str = strdup(portstr);
    char *token;
    int count = 0;
    
    token = strtok(str, ",");
    while (token != NULL && count < max_ports) {
        char *endptr;
        long port = strtol(token, &endptr, 10);
        
        // Validate port
        if (*endptr != '\0' || port <= 0 || port > 65535) {
            free(str);
            return -1;  // Invalid port
        }
        
        ports[count++] = (int)port;
        token = strtok(NULL, ",");
    }
    
    free(str);
    return count;
}

Main Loop Modification:

// Wrap existing loop in port iteration
for (int p = 0; p < o.port_count; p++) {
    remote_addr.sin_port = htons(o.ports[p]);
    
    if (!o.quiet && o.port_count > 1) {
        printf("Scanning port %d...\n", o.ports[p]);
    }
    
    for (c = 0; c < community_count; c++) {
        // Existing community/host loops
        for (i = 0; i < host_count; i++) {
            // Existing scanning code
        }
    }
}

Phase 2: Enhanced Features (Optional)

  1. Port Range Support (-p161-163):

    • Parse ranges and expand them
    • Useful for scanning sequential ports
  2. Mixed Format (-p161,8161-8163,9161):

    • Combine individual ports and ranges
    • Maximum flexibility
  3. Service Detection:

    • Different timeouts for trap ports
    • Port-specific community strings

Backward Compatibility

  • Default behavior remains unchanged (port 161)
  • Single port syntax (-p161) works exactly as before
  • New syntax only activated with commas or ranges

Output Format Changes

For multiple ports, enhance output to show port number:

192.168.1.1:161 [public] Linux router 5.4.0
192.168.1.1:8161 [private] Custom SNMP Agent v2.0

Testing Recommendations

  1. Single port (regression): -p161
  2. Multiple ports: -p161,162,8161
  3. Invalid formats: -p161,abc, -p161,0, -p161,70000
  4. Edge cases: -p161,161 (duplicate), -p (missing arg)

Security Considerations

  • Limit maximum ports to prevent resource exhaustion
  • Validate all port numbers (1-65535)
  • Consider rate limiting for multiple port scans

Estimated Effort

  • Basic implementation: ~100 lines of code changes
  • Full implementation with ranges: ~200 lines
  • Testing: Moderate complexity
  • Documentation updates: README, man page, usage()

This enhancement would make onesixtyone more versatile for real-world scenarios where SNMP services run on non-standard ports, while maintaining backward compatibility and the tool's simplicity.

dguido avatar Aug 30 '25 17:08 dguido