diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index e6d822e..a35fafd 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -87,6 +87,7 @@ "./offsec/pentest-metasploit", "./offsec/recon-nmap", "./offsec/network-netcat", + "./offsec/ot-security-assessment", "./offsec/analysis-tshark", "./offsec/webapp-sqlmap", "./offsec/webapp-nikto", diff --git a/README.md b/README.md index 9fac6fd..9d89011 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ SecOpsAgentKit provides specialized Claude Code skills for security operations, - **[pentest-metasploit](skills/offsec/pentest-metasploit/SKILL.md)** - Penetration testing framework using [Metasploit](https://docs.metasploit.com/) for exploit development and vulnerability validation - **[recon-nmap](skills/offsec/recon-nmap/SKILL.md)** - Network reconnaissance and security auditing using [Nmap](https://nmap.org/book/) for port scanning and service detection - **[network-netcat](skills/offsec/network-netcat/SKILL.md)** - Network utility using [Netcat](https://nmap.org/ncat/guide/index.html) for reading/writing data across TCP/UDP connections and port scanning +- **[ot-security-assessment](skills/offsec/ot-security-assessment/SKILL.md)** - Operational Technology security assessment using [Nmap](https://nmap.org/book/) and [Metasploit](https://www.rapid7.com/db/modules/) for OT/ICS device discovery and vulnerability assessment - **[analysis-tshark](skills/offsec/analysis-tshark/SKILL.md)** - Network protocol analyzer and packet capture tool using [tshark](https://www.wireshark.org/docs/man-pages/tshark.html) for traffic analysis - **[webapp-sqlmap](skills/offsec/webapp-sqlmap/SKILL.md)** - Automated SQL injection detection and exploitation using [SQLMap](https://sqlmap.org/) for web application security testing - **[webapp-nikto](skills/offsec/webapp-nikto/SKILL.md)** - Web server vulnerability scanner using [Nikto](https://cirt.net/Nikto2) for identifying security issues and misconfigurations diff --git a/skills/offsec/ot-security-assessment/SKILL.md b/skills/offsec/ot-security-assessment/SKILL.md new file mode 100644 index 0000000..3becadd --- /dev/null +++ b/skills/offsec/ot-security-assessment/SKILL.md @@ -0,0 +1,505 @@ +--- +name: ot-security-assessment +description: > + Operational Technology (OT) security assessment using a two-stage methodology: (1) Identification/Discovery + of OT devices and protocols, and (2) Vulnerability Assessment using online sources and Metasploit. Use when: + (1) Conducting authorized OT/ICS security assessments, (2) Identifying and enumerating OT protocols + (Modbus, S7, IEC 104, DNP3, BACnet, EtherNet/IP), (3) Discovering industrial control devices and PLCs, + (4) Assessing OT protocol vulnerabilities and security weaknesses, (5) Performing compliance scanning + aligned with IEC 62443 standards, (6) Validating network segmentation and access controls in OT environments. +version: 0.1.0 +maintainer: https://github.com/i8void/ +category: offsec +tags: [ot, ics, scada, modbus, siemens, industrial-security, vulnerability-assessment, reconnaissance] +frameworks: [MITRE-ATT&CK, IEC-62443, PTES] +dependencies: + packages: [nmap, metasploit-framework, python3] + tools: [modbus-cli, plcscan, python-snap7, pymodbus] +references: + - https://nmap.org/book/ + - https://docs.rapid7.com/metasploit/msf-overview/ + - https://www.cisa.gov/news-events/cybersecurity-advisories + - https://attack.mitre.org/techniques/T1046/ + - https://www.isa.org/standards-and-publications/isa-standards/isa-iec-62443-series-of-standards +--- + +# OT Security Assessment + +## Overview + +This skill provides a structured methodology for conducting Operational Technology (OT) and Industrial Control System (ICS) security assessments. The approach follows a two-stage methodology: (1) **Identification/Discovery** of OT devices, protocols, and services, and (2) **Vulnerability Assessment** using online vulnerability databases and Metasploit Framework for deeper analysis. + +**IMPORTANT**: OT security assessments may impact critical industrial processes and must only be conducted with proper authorization. Always ensure written permission before assessing OT systems. Never test production systems without explicit authorization. + +**OT Network Security Considerations**: +- Well-secured OT systems will not allow internet-connected devices (like this system) to be plugged into the network for assessment +- Most production OT assessments will be conducted offline on air-gapped networks +- This skill is suitable for: + - Less secure or open OT/SCADA systems + - Lab environments and test networks + - Authorized assessment scenarios where network isolation is managed separately +- Always coordinate with operations team to ensure proper network isolation and security controls + +## Quick Start + +Basic OT device discovery and protocol enumeration: + +```bash +# TCP Connect scan for common OT ports (no root required, safer for OT) +nmap -sT -p 502,102,2404,20000,47808,2222 + +# Modbus enumeration (no root required) +nmap -p 502 --script modbus-read-registers,modbus-read-coils + +# Comprehensive OT scan with service detection (no root required) +# Note: dnp3-info script is included in assets/ directory (see DNP3 section for installation) +nmap -sV -p 502,102,2404,20000,47808,2222 --script modbus-read-registers,s7-info,dnp3-info,bacnet-info +``` + +## Placeholder System + +When executing commands, replace these placeholders with actual values: + +- `` - Single IP address (e.g., `192.168.1.100`) +- `` - IP range in CIDR notation (e.g., `192.168.1.0/24`) +- `` - Remote host (Metasploit) - IP address or hostname +- `` - Remote port (Metasploit) - Port number +- `` - Modbus unit ID (typically 1-255) + +## Core Workflow + +### Workflow Checklist (for complex operations) + +Progress: +[ ] 1. Verify authorization and scope for OT assessment +[ ] 2. Perform network discovery and identify live hosts +[ ] 3. Scan for common OT protocol ports +[ ] 4. Enumerate OT protocols and identify devices +[ ] 5. Gather device information and service versions +[ ] 6. Research vulnerabilities using online sources +[ ] 7. Perform vulnerability assessment with Metasploit +[ ] 8. Document findings and generate assessment report +[ ] 9. Validate results and identify false positives + +Work through each step systematically. Check off completed items. + +### 1. Authorization Verification + +**CRITICAL**: Before any OT assessment activities: +- Confirm written authorization from system owner and operations team +- Review scope document for in-scope IP ranges and OT systems +- Verify scanning windows and rate-limiting requirements (OT systems are sensitive) +- Document emergency contact for accidental disruption +- Confirm blacklisted hosts (production PLCs, safety systems, critical infrastructure) +- Coordinate with operations team for safe testing windows + +### 2. Network Discovery + +Identify live hosts in target OT network: + +```bash +# Ping sweep (ICMP echo) +nmap -sn /24 + +# ARP scan (local network only, faster and more reliable) +nmap -sn -PR /24 + +# TCP SYN ping (when ICMP blocked, use OT ports) +nmap -sn -PS502,102,2404 /24 + +# Disable ping, assume all hosts alive (common in OT networks) +nmap -Pn /24 + +# Output live hosts to file +nmap -sn /24 -oG - | awk '/Up$/{print $2}' > live_hosts.txt +``` + +**OT Network Discovery Techniques**: +- **ICMP Echo (-PE)**: Standard ping, often blocked in OT networks +- **TCP SYN (-PS)**: Half-open connection to OT protocol ports (502, 102, etc.) +- **UDP (-PU)**: Sends UDP packets to OT UDP ports (47808 for BACnet) +- **ARP (-PR)**: Layer 2 discovery, only works on local network segment + +### 3. OT Protocol Port Scanning + +Scan discovered hosts for common OT protocol ports: + +```bash +# TCP Connect scan for common OT protocol ports (no root required) +nmap -sT -p 502,102,2404,20000,47808,2222,161,623 -iL live_hosts.txt + +# Comprehensive scan with service detection (no root required) +nmap -sV -p 502,102,2404,20000,47808,2222 -iL live_hosts.txt -oA ot_scan + +# UDP scan for OT protocols (BACnet, SNMP) - requires root +sudo nmap -sU -p 47808,161,623 -iL live_hosts.txt -oA ot_udp_scan +``` + +**Common OT Protocol Ports**: +- **502**: Modbus TCP +- **102**: S7/Siemens +- **2404**: IEC 104 +- **20000**: DNP3 +- **47808**: BACnet/IP (UDP) +- **2222**: EtherNet/IP +- **161**: SNMP (UDP) +- **623**: IPMI (UDP) + +**Timing and Performance for OT Networks**: + +OT networks are sensitive to high traffic volumes. Use conservative timing: + +```bash +# Polite (2) - Recommended for OT networks +nmap -T2 --max-rate 10 -p 502,102,2404 + +# Scan with delays to avoid disruption +nmap --scan-delay 2s -p 502,102,2404 +``` + +### 4. OT Protocol Enumeration + +Enumerate and identify OT protocols and devices: + +#### Modbus TCP (Port 502) + +```bash +# Basic Modbus enumeration +nmap -p 502 --script modbus-read-registers,modbus-read-coils + +# Comprehensive Modbus enumeration +nmap -p 502 --script modbus-read-registers,modbus-read-coils -oA modbus_enum + +# Read holding registers (unit ID 1, start 0, count 10) +modbus read 502 1 0 10 +``` + +#### S7/Siemens (Port 102) + +```bash +# S7 information gathering +nmap -p 102 --script s7-info -oA s7_info + +# Python SNAP7 enumeration +python3 -c "import snap7; client = snap7.client.Client(); client.connect('', 0, 1); print(client.get_cpu_info()); client.disconnect()" +``` + +#### Other OT Protocols + +```bash +# IEC 104 (Port 2404) +nmap -p 2404 -sV -oA iec104_scan + +# DNP3 (Port 20000) +nmap -p 20000 --script dnp3-info -oA dnp3_info +``` + +**Note**: The `dnp3-info` NSE script is not included in standard Nmap installations. The script is included in this skill's `assets/` directory. Copy and install it: + +```bash +# Copy dnp3-info.nse script from skill assets to Nmap scripts directory +cp skills/offsec/ot-security-assessment/assets/dnp3-info.nse /usr/local/share/nmap/scripts/dnp3-info.nse + +# Update Nmap script database +nmap --script-updatedb + +# Verify script is available +nmap --script-help dnp3-info + +# BACnet/IP (Port 47808/UDP) - requires root for UDP scan +sudo nmap -sU -p 47808 --script bacnet-info -oA bacnet_info + +# EtherNet/IP (Port 2222) +nmap -p 2222 -sV -oA ethernetip_tcp +``` + +### 5. Service and Device Information Gathering + +Identify services and extract version information: + +```bash +# Service version detection for OT protocols +nmap -sV -p 502,102,2404,20000,47808,2222 + +# OT-specific service enumeration (no root required for TCP scans) +nmap -p 502 --script modbus-read-registers,modbus-read-coils +nmap -p 102 --script s7-info +# Note: dnp3-info script is included in assets/ directory (see DNP3 section for installation) +nmap -p 20000 --script dnp3-info +# UDP scan requires root +sudo nmap -sU -p 47808 --script bacnet-info +``` + +### 6. Online Vulnerability Research + +Research identified devices and services for known vulnerabilities: + +```bash +# Query NVD for ICS/SCADA vulnerabilities +curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=industrial+control+system" \ + -H "apiKey: " -o nvd_ics_$(date +%Y%m%d).json + +# Fetch latest ICS-CERT advisories +curl -s "https://www.cisa.gov/news-events/cybersecurity-advisories" \ + -o ics-cert_$(date +%Y%m%d).html + +# Search CVE database +curl -s "https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=SCADA" \ + -o cve_scada_$(date +%Y%m%d).html +``` + +### 7. Metasploit Vulnerability Assessment + +Use Metasploit Framework for deeper OT protocol analysis: + +```bash +# Start Metasploit Framework console +msfconsole -q + +# Search for OT/ICS modules +msf6 > search modbus +msf6 > search scada +msf6 > search siemens +``` + +#### Using Modbus Metasploit Modules + +```bash +msf6 > use auxiliary/scanner/scada/modbus_findunitid +msf6 auxiliary(scanner/scada/modbus_findunitid) > set RHOSTS +msf6 auxiliary(scanner/scada/modbus_findunitid) > set RPORT 502 +msf6 auxiliary(scanner/scada/modbus_findunitid) > run + +# Read registers +msf6 > use auxiliary/scanner/scada/modbus_read +msf6 auxiliary(scanner/scada/modbus_read) > set RHOSTS +msf6 auxiliary(scanner/scada/modbus_read) > set RPORT 502 +msf6 auxiliary(scanner/scada/modbus_read) > set UNIT_ID 1 +msf6 auxiliary(scanner/scada/modbus_read) > set REGISTER_START 0 +msf6 auxiliary(scanner/scada/modbus_read) > set REGISTER_COUNT 10 +msf6 auxiliary(scanner/scada/modbus_read) > run +``` + +#### Using S7/Siemens Metasploit Modules + +```bash +msf6 > use auxiliary/gather/s7_comm_read +msf6 auxiliary(gather/s7_comm_read) > set RHOSTS +msf6 auxiliary(gather/s7_comm_read) > set RPORT 102 +msf6 auxiliary(gather/s7_comm_read) > run +``` + +#### Using Other OT Protocol Modules + +```bash +# DNP3 +msf6 > use auxiliary/scanner/scada/dnp3_info +msf6 auxiliary(scanner/scada/dnp3_info) > set RHOSTS +msf6 auxiliary(scanner/scada/dnp3_info) > set RPORT 20000 +msf6 auxiliary(scanner/scada/dnp3_info) > run + +# BACnet +msf6 > use auxiliary/scanner/scada/bacnet_info +msf6 auxiliary(scanner/scada/bacnet_info) > set RHOSTS +msf6 auxiliary(scanner/scada/bacnet_info) > set RPORT 47808 +msf6 auxiliary(scanner/scada/bacnet_info) > run +``` + +### 8. Documentation and Reporting + +Organize findings and generate assessment reports: + +```bash +# Organized output with timestamps +nmap -p 502 --script modbus-read-registers,modbus-read-coils -oA modbus_enum_$(date +%Y%m%d_%H%M%S) + +# Create summary report +cat > assessment_summary_$(date +%Y%m%d).md << EOF +# OT Security Assessment Summary + +## Target Information +- IP Address: +- Assessment Date: $(date) + +## Stage 1: Identification Results +[Insert discovery findings] + +## Stage 2: Vulnerability Assessment Results +[Insert vulnerability findings] + +## Recommendations +[Insert recommendations] +EOF +``` + +### 9. Validation and False Positive Analysis + +- Manually verify findings with specific tools +- Check service version against CVE databases +- Cross-reference with authenticated vulnerability scanners +- Validate protocol-specific vulnerabilities +- Review Metasploit module outputs for accuracy + +## Security Considerations + +- **Authorization and Access Control**: OT security assessments require explicit written authorization from system owners and operations teams. Never test production systems without proper authorization. Coordinate with operations team for safe testing windows and rate-limiting requirements. +- **Sensitive Data Handling**: OT assessment findings may contain sensitive information about industrial control systems, network topology, and device configurations. Store assessment data securely and follow data classification requirements. Do not expose OT network details in public repositories or unsecured locations. +- **Access Control**: Commands requiring root/sudo privileges: + - TCP SYN scans (`nmap -sS`): Requires root for raw sockets + - UDP scans (`nmap -sU`): Requires root for raw sockets + - Packet capture (`tcpdump`, `tshark`): Requires root or `CAP_NET_RAW` capability + + Commands NOT requiring root: + - TCP Connect scans (`nmap -sT`): Safe, no root needed + - Service version detection (`nmap -sV`): No root needed + - Most Python tools (pymodbus, snap7): Run as regular user + - Metasploit console: Runs as regular user + +- **Claude CLI Safety Considerations**: + - Review all commands before execution, especially those with `sudo` + - Prefer `-sT` (TCP Connect) over `-sS` (SYN scan) when possible + - Configure Linux capabilities instead of full sudo when available: + ```bash + sudo setcap cap_net_raw,cap_net_admin+eip $(which nmap) + # Then run without sudo: nmap -sS + ``` + - Log all privileged command executions for audit purposes + - Use principle of least privilege - only elevate when necessary + +- **Audit Logging**: Document all assessment activities including: + - Authorization documents and scope + - Scanning windows and rate limits + - All privileged command executions + - Discovered devices and protocols + - Vulnerability findings and remediation status + +- **Compliance**: OT assessments should align with: + - IEC 62443 standards for industrial automation and control systems security + - MITRE ATT&CK for ICS framework + - PTES (Penetration Testing Execution Standard) methodology + - Organization-specific OT security policies + +## Bundled Resources + +### Assets (`assets/`) +- `dnp3-info.nse` - Nmap NSE script for DNP3 protocol enumeration. Copy to `/usr/local/share/nmap/scripts/` and run `nmap --script-updatedb` to use. + +**Future enhancements could include**: +- Scripts for automated OT protocol enumeration +- Reference documentation for detailed OT protocol specifications +- Configuration templates for OT assessment reporting + +## Common Patterns + +### Pattern 1: OT Network Discovery + +```bash +# Phase 1: Identify live hosts +nmap -sn -PE -PS502,102 -PA2404 /24 -oG - | awk '/Up$/{print $2}' > ot_hosts.txt + +# Phase 2: Scan common OT protocol ports (TCP Connect scan, no root required) +nmap -Pn -sT -sV -p 502,102,2404,20000,47808,2222 -iL ot_hosts.txt -oA ot_scan + +# Phase 3: Protocol-specific enumeration +nmap -p 502 --script modbus-read-registers,modbus-read-coils -iL ot_hosts.txt -oA modbus_enum +nmap -p 102 --script s7-info -iL ot_hosts.txt -oA s7_enum +``` + +### Pattern 2: Modbus Assessment + +```bash +# Phase 1: Discover Modbus devices +nmap -p 502 --script modbus-read-registers,modbus-read-coils /24 -oA modbus_discovery + +# Phase 2: Enumerate Modbus data +nmap -p 502 --script modbus-read-registers,modbus-read-coils -oA modbus_enum + +# Phase 3: Vulnerability assessment with Metasploit +msfconsole -q +msf6 > use auxiliary/scanner/scada/modbus_findunitid +msf6 auxiliary(scanner/scada/modbus_findunitid) > set RHOSTS +msf6 auxiliary(scanner/scada/modbus_findunitid) > run +``` + +### Pattern 3: Multi-Protocol OT Assessment + +```bash +# Phase 1: Comprehensive OT port scan (TCP Connect, no root required) +nmap -sT -sV -p 502,102,2404,20000,47808,2222,161,623 /24 -oA ot_comprehensive + +# Phase 2: Protocol-specific enumeration +nmap -p 502 --script modbus-* -oA modbus_full +nmap -p 102 --script s7-* -oA s7_full + +# Phase 3: Vulnerability research +# Query NVD, ICS-CERT, manufacturer databases for identified versions + +# Phase 4: Metasploit assessment +msfconsole -q +msf6 > search scada +# Use appropriate modules based on discovered protocols +``` + +## Integration Points + +- **Metasploit**: Import Nmap results with `db_import ` for correlation and deeper analysis +- **SIEM Integration**: Parse Nmap XML output for security monitoring and alerting on discovered OT devices +- **Asset Management**: Update CMDB with discovered OT devices, protocols, and service versions +- **Reporting**: Generate structured reports from Nmap XML output and combine with Metasploit results for comprehensive assessment documentation +- **CI/CD**: Not typically applicable for OT assessments due to air-gapped network requirements + +## Troubleshooting + +### Issue: Nmap scan fails with "Operation not permitted" + +**Solution**: This occurs when attempting SYN scans (`-sS`) or UDP scans (`-sU`) without root privileges. Use TCP Connect scans (`-sT`) instead, which do not require root: +```bash +# Instead of: sudo nmap -sS +# Use: nmap -sT +``` + +### Issue: dnp3-info script not found + +**Solution**: The `dnp3-info` NSE script is not included in standard Nmap installations. The script is included in this skill's `assets/` directory. Copy and install it: +```bash +# Copy dnp3-info.nse script from skill assets to Nmap scripts directory +cp skills/offsec/ot-security-assessment/assets/dnp3-info.nse /usr/local/share/nmap/scripts/dnp3-info.nse +# Or if using from repository root: +# cp assets/dnp3-info.nse /usr/local/share/nmap/scripts/dnp3-info.nse +nmap --script-updatedb +``` + +### Issue: OT devices not responding to scans + +**Solution**: OT networks often have strict firewall rules and may block ICMP. Try: +- Disable ping: `nmap -Pn ` +- Use TCP Connect scans with conservative timing: `nmap -sT -T2 --max-rate 10 ` +- Scan during authorized maintenance windows +- Coordinate with operations team for network access + +### Issue: Metasploit module not found + +**Solution**: Ensure Metasploit Framework is updated and search for available modules: +```bash +msfconsole -q +msf6 > search scada +msf6 > search modbus +msf6 > search siemens +``` + +### Issue: High false positive rate in vulnerability assessment + +**Solution**: +- Manually verify findings with protocol-specific tools +- Cross-reference service versions with CVE databases +- Validate protocol-specific vulnerabilities with authenticated scanners +- Review Metasploit module outputs for accuracy + +## References + +- [Nmap Documentation](https://nmap.org/book/) - Comprehensive Nmap scanning guide +- [Metasploit Framework Modules](https://github.com/rapid7/metasploit-framework) - Metasploit module documentation +- [CISA ICS-CERT Advisories](https://www.cisa.gov/news-events/cybersecurity-advisories) - Industrial control system security advisories +- [MITRE ATT&CK for ICS](https://attack.mitre.org/techniques/T1046/) - Network service scanning techniques +- [IEC 62443 Standards](https://en.wikipedia.org/wiki/IEC_62443) - Industrial automation and control systems security standards + diff --git a/skills/offsec/ot-security-assessment/assets/dnp3-info.nse b/skills/offsec/ot-security-assessment/assets/dnp3-info.nse new file mode 100644 index 0000000..b0772a0 --- /dev/null +++ b/skills/offsec/ot-security-assessment/assets/dnp3-info.nse @@ -0,0 +1,207 @@ +local bin = require "bin" +local nmap = require "nmap" +local shortport = require "shortport" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" + +description = [[ + +This nmap NSE will send a command to query through the first 100 addresses of +DNP3 to see if a valid response is given. If a valid response is given it will +then parse the results based on function ID and other data. + +]] + +--- +-- @usage +-- nmap --script dnp3-info -p 20000 + +author = "Stephen J. Hilt" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"discovery", "intrusive"} + + +-- +-- Function to define the portrule as per nmap standards +portrule = shortport.port_or_service(20000, "dnp", "tcp") + +-- Datalink Function Codes PRM=0 +local function_id = { +[0] = "ACK", +[1] = "NACK", +[11] = "Link Status", +[15] = "User Data" +} +-- Data Link Function Codes PRM=1 +local alt_function_id = { +[0] = "RESET Link", +[1] = "Reset User Process", +[2] = "TEST link", +[3] = "User Data", +[4] = "User Data", +[9] = "Request Link Status" +} +-- lookup function codes based off the PRM (byte 2) +function funct_lookup(id) + local funct_id + -- if the string is 4 bytes then was 0x0 + if (string.len(id) < 5) then + -- look up function id in the table, if doesn't exist then its unknown + funct_id = function_id[tonumber(id,2)] or "Unknown Function ID" + id = tonumber(id,2) + -- else byte was 0x?? + else + local first_value = string.byte(id, 2) % 0x10 + local second_value = tonumber(string.byte(id,5) % 0x10 .. string.byte(id,6) % 0x10 .. string.byte(id,7) %0x10 .. + string.byte(id,8) % 0x10,2) + if( first_value == 0) then + -- look up function id in the table, if doesn't exist then its unknown + funct_id = function_id[second_value] or "Unknown Function ID" + else + -- look up function id in the table, if doesn't exist then its unknown + funct_id = alt_function_id[second_value] or "Unknown Function ID" + end + -- overwrite id to output what the value for if it was 0x?? + id = second_value + end + return string.format("%s (%d)", funct_id, id) +end +--- +-- Function to set the nmap output for the host, if a valid DNP3 packet +-- is received then the output will show that the port as DNP3 instead of +-- dnp +-- +-- @param host Host that was passed in via nmap +-- @param port port that DNP3 is running on (Default TCP/20000) +function set_nmap(host, port) + + --set port Open + port.state = "open" + -- set version name to DNP3 + port.version.name = "DNP3" + nmap.set_port_version(host, port) + nmap.set_port_state(host, port, "open") + +end + + +--- +-- Action Function that is used to run the NSE. This function will send the initial query to the +-- host and port that were passed in via nmap. The initial response is parsed to determine if host +-- is a DNP3 device. If it is then more actions are taken to gather extra information. +-- +-- @param host Host that was scanned via nmap +-- @param port port that was scanned via nmap +action = function(host, port) + + + -- create new socket + local sock = nmap.new_socket() + -- set timeout low in case we don't get a response + sock:set_timeout(1000) + -- create output table + local output = stdnse.output_table() + -- query to pull the fist 100 address + local first100 = bin.pack("H", "056405C900000000364C056405C901000000DE8E056405C" .. + "9020000009F84056405C9030000007746056405C9040000" .. + "001D90056405C905000000F552056405C906000000B4580" .. + "56405C9070000005C9A056405C90800000019B9056405C9" .. + "09000000F17B056405C90A000000B071056405C90B00000" .. + "058B3056405C90C0000003265056405C90D000000DAA705" .. + "6405C90E0000009BAD056405C90F000000736F056405C91" .. + "000000011EB056405C911000000F929056405C912000000" .. + "B823056405C91300000050E1056405C9140000003A37056" .. + "405C915000000D2F5056405C91600000093FF056405C917" .. + "0000007B3D056405C9180000003E1E056405C919000000D" .. + "6DC056405C91A00000097D6056405C91B0000007F140564" .. + "05C91C00000015C2056405C91D000000FD00056405C91E00" .. + "0000BC0A056405C91F00000054C8056405C920000000014" .. + "F056405C921000000E98D056405C922000000A887056405" .. + "C9230000004045056405C9240000002A93056405C925000" .. + "000C251056405C926000000835B056405C9270000006B99" .. + "056405C9280000002EBA056405C929000000C678056405C" .. + "92A0000008772056405C92B0000006FB0056405C92C0000" .. + "000566056405C92D000000EDA4056405C92E000000ACAE0" .. + "56405C92F000000446C056405C93000000026E8056405C9" .. + "31000000CE2A056405C9320000008F20056405C93300000" .. + "067E2056405C9340000000D34056405C935000000E5F605" .. + "6405C936000000A4FC056405C9370000004C3E056405C93" .. + "8000000091D056405C939000000E1DF056405C93A000000" .. + "A0D5056405C93B0000004817056405C93C00000022C1056" .. + "05C93D000000CA03056405C93E0000008B09056405C93F0" .. + "0000063CB056405C940000000584A056405C941000000B0" .. + "88056405C942000000F182056405C943000000194005640" .. + "5C9440000007396056405C9450000009B54056405C94600" .. + "0000DA5E056405C947000000329C056405C94800000077B" .. + "F056405C9490000009F7D056405C94A000000DE77056405" .. + "C94B00000036B5056405C94C0000005C63056405C94D000" .. + "000B4A1056405C94E000000F5AB056405C94F0000001D69" .. + "056405C9500000007FED056405C951000000972F056405C" .. + "952000000D625056405C9530000003EE7056405C9540000" .. + "005431056405C955000000BCF3056405C956000000FDF90" .. + "56405C957000000153B056405C9580000005018056405C9" .. + "59000000B8DA056405C95A000000F9D0056405C95B00000" .. + "01112056405C95C0000007BC4056405C95D000000930605" .. + "6405C95E000000D20C056405C95F0000003ACE056405C96" .. + "00000006F49056405C961000000878B056405C962000000" .. + "C681056405C9630000002E43056405C9640000004495") + -- Connect to the remote host + local constatus, conerr = sock:connect(host, port) + if not constatus then + stdnse.debug1( + 'Error establishing a TCP connection for %s - %s', host, conerr + ) + return nil + end + -- send query for the first 100 addresses + local sendstatus, senderr = sock:send(first100) + if not sendstatus then + stdnse.debug1( + 'Error sending dnp3 request to %s:%d - %s', + host.ip, port.number, senderr + ) + return nil + end + -- receive the response for parseing + local rcvstatus, response = sock:receive() + if(rcvstatus == false) then + stdnse.debug1( "Receive error: %s", response) + return nil + end + -- if the response was timeout, then we will return that we had a timeout + --(for now add more addresses later) + if (response == "TIMEOUT" or response == "EOF") then + sock:close() + return "TIMEOUT: No response from query" + end + -- unpack first two bytes + local pos, byte1, byte2 = bin.unpack("CC", response, 1) + -- check to see if it is 0x0564 + if( byte1 == 0x05 and byte2 == 0x64) then + -- close socket + sock:close() + -- set nmap to reflect open DNP3 + set_nmap(host,port) + -- unpack bit string for PRM checking as well as function codes + local pos, ctrl = bin.unpack("B", response, 4) + -- destination address + local pos, dstadd = bin.unpack("S", response, 5) + -- source address + local pos, srceadd = bin.unpack("S", response, pos) + -- set up output table with values + output["Source Address"] = srceadd + output["Destination Address"] = dstadd + output["Control"] = funct_lookup(ctrl) + -- return output + return output + -- if non 0x0564 response, then this is not a valid packet. + else + sock:close() + return "ERROR: Non Valid DNP3 Packet Response\n\t" .. stdnse.tohex(response) + end + +end + + +