Skip to content

Add Ignition gateway fingerprint scanner (auxiliary/scanner/scada/ignition_statusping) - #21603

Merged
bwatters-r7 merged 10 commits into
rapid7:masterfrom
ethan-thomason:ignition-scada-modules
Aug 25, 2026
Merged

Add Ignition gateway fingerprint scanner (auxiliary/scanner/scada/ignition_statusping)#21603
bwatters-r7 merged 10 commits into
rapid7:masterfrom
ethan-thomason:ignition-scada-modules

Conversation

@ethan-thomason

Copy link
Copy Markdown
Contributor

Resubmission of #21273 with all Copilot review feedback addressed:

  • Add frozen_string_literal magic comment
  • Track found state to avoid spurious 'no endpoint' message
  • Remove references to modules not yet in codebase
  • Replace regex JSON parsing with JSON.parse + ParserError rescue
  • Use Rex::Socket.to_authority for IPv6-safe output
  • report_host now uses actual OS value; Ignition data in report_note
  • SSL-aware service name (https vs http)
  • Parse runtimeVersion from JSON StatusPing response
  • Replace public IP in docs with RFC 5737 test address (192.0.2.32)

Tested against Ignition 7.9.21, 8.1.15, 8.1.17, and 8.3.4 on Linux.

…ition_statusping)

Fingerprints Inductive Automation Ignition gateways across all major
versions by probing version-specific unauthenticated info endpoints.

Tested against:
  - Ignition 7.9.21 (/main/system/gwinfo, key=value)
  - Ignition 8.1.15 (/system/StatusPing, JSON)
  - Ignition 8.1.17 (/system/StatusPing, JSON)
  - Ignition 8.3.4  (/system/gwinfo, key=value)

Reference: https://ethomason.com/posts/fingerprinting-ignition-gateways/
- Add frozen_string_literal magic comment
- Track found state to avoid spurious 'no endpoint' message
- Remove references to modules not yet in codebase
- Replace regex JSON parsing with JSON.parse + ParserError rescue
- Use Rex::Socket.to_authority for IPv6-safe output
- report_host now uses actual OS value; Ignition data in report_note
- SSL-aware service name (https vs http)
- Parse runtimeVersion from JSON StatusPing response
- Replace public IP in docs with RFC 5737 test address (192.0.2.32)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Metasploit auxiliary scanner module to fingerprint Inductive Automation Ignition gateways by probing unauthenticated version/info endpoints across major Ignition versions, with accompanying user documentation.

Changes:

  • Introduces auxiliary/scanner/scada/ignition_statusping to probe /system/gwinfo, /system/StatusPing, and /main/system/gwinfo and report discovered gateway details.
  • Adds module documentation with verification steps and example scan scenarios.

Impact Analysis: isolated change; no meaningful downstream impact identified from diff.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
modules/auxiliary/scanner/scada/ignition_statusping.rb New auxiliary scanner that probes Ignition info endpoints, parses responses, and reports results to the MSF database.
documentation/modules/auxiliary/scanner/scada/ignition_statusping.md New module documentation describing affected versions/endpoints, usage, and example output.

Comment thread modules/auxiliary/scanner/scada/ignition_statusping.rb
Comment thread modules/auxiliary/scanner/scada/ignition_statusping.rb Outdated
Comment thread modules/auxiliary/scanner/scada/ignition_statusping.rb Outdated
- Replace JSON.parse with framework res.get_json_document helper (AGENTS.md:51)
- Pass response object to parse_statusping instead of body string
- Replace non-ASCII em dashes in description with ASCII hyphens (AGENTS.md:47)
@ethan-thomason

ethan-thomason commented Jun 25, 2026 via email

Copy link
Copy Markdown
Contributor Author

@bwatters-r7 bwatters-r7 self-assigned this Aug 24, 2026
@bwatters-r7

Copy link
Copy Markdown
Contributor

Test Results

  • Target: 10.5.135.119:18088
  • Image: inductiveautomation/ignition:8.1.17
  • Container: msf-pr21603-ignition-8117
  • Status: Running and healthy

Module Output

  [+] 10.5.135.119:18088 - Ignition 8.1.17 | State: RUNNING | OS: Linux | Java: 11.0.15 | GAN role: Independent
  [*] Scanned 1 of 1 hosts (100% complete)
  [*] Auxiliary module execution completed

Result

Pass: The module correctly identified the Ignition version, state, operating system, Java version, and GAN role.

Comment thread documentation/modules/auxiliary/scanner/scada/ignition_statusping.md Outdated
…ing.md

Co-authored-by: Brendan <bwatters@rapid7.com>

@bwatters-r7 bwatters-r7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We updated rubocop rules, and it looks like this got caught. Scanners already print out the ip and port when you call print, so adding them again creates duplicates.

Comment thread modules/auxiliary/scanner/scada/ignition_statusping.rb Outdated
Comment thread modules/auxiliary/scanner/scada/ignition_statusping.rb Outdated
ethan-thomason and others added 2 commits August 25, 2026 11:30
Co-authored-by: Brendan <bwatters@rapid7.com>
Co-authored-by: Brendan <bwatters@rapid7.com>
@ethan-thomason

Copy link
Copy Markdown
Contributor Author

We updated rubocop rules, and it looks like this got caught. Scanners already print out the ip and port when you call print, so adding them again creates duplicates.

Applied both, thanks. Good to know the scanner mixin handles the prefix. I'd assumed HttpClient-based scanners needed it manually. Checked opcua_enum on #21612 and it's already clean.

@bwatters-r7

Copy link
Copy Markdown
Contributor

Test Environment

  • Target: 10.5.135.119:18088
  • Container: msf-pr21603-ignition-8117
  • Image: inductiveautomation/ignition:8.1.17
  • Commit: 8e4001d
  • Container status: running healthy

Session Output

  $ ./msfconsole -q
  [*] Using configured payload windows/x64/meterpreter/reverse_tcp

  msf6 > use auxiliary/scanner/scada/ignition_statusping
  msf6 auxiliary(scanner/scada/ignition_statusping) > set RHOSTS 10.5.135.119
  RHOSTS => 10.5.135.119
  msf6 auxiliary(scanner/scada/ignition_statusping) > set RPORT 18088
  RPORT => 18088
  msf6 auxiliary(scanner/scada/ignition_statusping) > set VERBOSE true
  VERBOSE => true
  msf6 auxiliary(scanner/scada/ignition_statusping) > run

  [+] Ignition 8.1.17 | State: RUNNING | OS: Linux | Java: 11.0.15 | GAN role: Independent
  [*] Scanned 1 of 1 hosts (100% complete)
  [*] Auxiliary module execution completed

Result

The module successfully detected and reported the Ignition version, state, operating system, Java runtime, and GAN role.

@bwatters-r7 bwatters-r7 moved this from Todo to What about Second Review? in Metasploit Kanban Aug 25, 2026
}
)
)
register_options([Opt::RPORT(8088)])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment/ the HttpClient mixin will register RPORT: #21612 (comment)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done - applied the same DefaultOptions pattern here, removed the register_options call. Confirmed RPORT still defaults to 8088.

@github-project-automation github-project-automation Bot moved this from What about Second Review? to In Progress in Metasploit Kanban Aug 25, 2026
@bwatters-r7

Copy link
Copy Markdown
Contributor

For what it is worth, Github's CI testing is not having a great day. The failing tests are not because of this code, but because of dependency and test setup failures.
I'm going to try and get these to pass one more time today, but the github testing gods may fail me.
I do not think you need to do anything with these PRs, but I need to keep kicking off the tests again until it gets the setup and passes CI tests. If I can't get them to pass pretty soon, I'll just back ff and try again in the morning.

@bwatters-r7
bwatters-r7 merged commit f51cfe4 into rapid7:master Aug 25, 2026
50 of 60 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Metasploit Kanban Aug 25, 2026
@bwatters-r7

Copy link
Copy Markdown
Contributor

Release Notes

Adds an auxiliary scanner module that fingerprints Inductive Automation Ignition
gateways across all major version families by probing unauthenticated info endpoints.

@bwatters-r7 bwatters-r7 added the rn-modules release notes for new or majorly enhanced modules label Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rn-modules release notes for new or majorly enhanced modules

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants