Home page logo
/

nmap-dev logo Nmap Development mailing list archives

Re: Another SCADA/ICS NMAP NSE script - Rockwell MicroLogix Series 1400 enumeration script
From: Verde Denim <tdldev () gmail com>
Date: Wed, 2 Feb 2011 15:13:12 -0500

On Mon, Dec 6, 2010 at 10:28 PM, Bob Radvanovsky <rsradvan () unixworks net>wrote:

This is one of several enumeration scripts that I have written for the
SCADA/industrial control systems community.  This checks/validates the SNMP
traffic for the Allen-Bradley/Rockwell MicroLogix Series 1400 PLC
controller.

The same script is shown below; if you wish to download the script, the
script may be accessed here:
http://www.infracritical.com/enum-scripts/micrologix1400.nse

===============================================

description = "Confirms/verifies that target device is Rockwell
MicroLogix."
author      = "Bob Radvanovsky <rsradvan at infracritical dot com>"
license     = "Refer to: http://nmap.org/book/man-legal.html for license."
categories  = {"default", "discovery", "safe"}
dependencies= {"snmp-brute"}

--
--  Filename:      micrologix1400.nse
--
--  Purpose:       Checks for the following elements confirming said
device:
--
--  1.  PHASE I - SNMP verification.
--      a.  STEP 1:  Performs verification through 'snmpwalk'.
--      b.  STEP 2:  Acquires specific details from SNMP 'sysDescr.0'.
--
--  2.  PHASE II - Documentation.
--
--
 ==========================================================================
--
--  Version(s):    4.0, 5.0
--
--  Usage:         nmap --script=./micrologix1400.nse <IP>
--                 (continued) --script-args='dox=1' -PN -sU -p161 -v
--
--  Author(s):     Bob Radvanovsky - Infracritical
--                 <rsradvan at infracritical dot com>
--
--  Initwritten:   September 2010
--
--  DATE----  INIT
DESCRIPTION------------------------------------------------
--  10.05.09  rsr  Inital development - VERSION 001.
--  10.05.09  rsr  Included URL links for related reference documentation.
--
--  NOTE: Script is a derived work from Thomas Buchanan's
"snmp-sysdescr.nse"
--        NSE script, and has been modified to work specifically on/for the
--        Allen-Bradley/Rockwell Automation MicroLogix Series 1400 devices.
--
--  NOTE: We try and verify, running tests on as many versions of this
device
--        as possible.  If you encounter an "UNKNOWN", this may mean that
you
--        have scanned a device version/variant that was not tested.
--
--        Since we are providing this script free-of-charge to everyone,
--        would help us - and the community - if you would report the
variance
--        to us.  Submit your findings to "report () infracritical com".
 Thanks!
--

require("nmap")
require("nsedebug")
require("datafiles")
require("stdnse")
require("shortport")
require("snmp")
require("http")
require("url")
require("strbuf")

portrule = shortport.portnumber({80,161}, "udp", {"open", "open|filtered"})

action = function(host, port)

 -- create the socket used for our connection
 local socket = nmap.new_socket()

 -- set a reasonable timeout value
 socket:set_timeout(5000)

 -- do some exception handling / cleanup
 local catch = function()
   socket:close()
 end

 -- connect to the potential SNMP system
 local try = nmap.new_try(catch)
 try(socket:connect(host.ip, port.number, "udp"))

 -- If you want to perform a test verifiication/validation of another OID,
 -- here are some values (as shown below):
 -- get value: 1.3.6.1.2.1.1.1 (SNMPv2-MIB::sysDescr.0)
 -- get value: 1.3.6.1.2.1.1.2 (SNMPv2-MIB::sysObjectID.0)
 -- get value: 1.3.6.1.2.1.1.3 (SNMPv2-MIB::sysUpTime.0)
 -- get value: 1.3.6.1.2.1.1.4 (SNMPv2-MIB::sysContact.0)
 -- get value: 1.3.6.1.2.1.1.5 (SNMPv2-MIB::sysName.0)
 -- get value: 1.3.6.1.2.1.1.6 (SNMPv2-MIB::sysLocation.0)
 -- get value: 1.3.6.1.2.1.1.7 (SNMPv2-MIB::sysServices.0)
 local payload; local options = {}; options.reqId = 28428 -- unnecessary?
 payload = snmp.encode(snmp.buildPacket(snmp.buildGetRequest(options,
"1.3.6.1.2.1.1.1.0")))
 try(socket:send(payload))
 local status, response

 -- read in any response we might get
 status, response = socket:receive_bytes(1)
 if (not status) or (response == "TIMEOUT") then return; end

 -- since we got something back, the port is definitely open
 nmap.set_port_state(host, port, "open")

 local confirm = tostring(snmp.fetchFirst(response))
 -- print(confirm)
 result = "CONFIRM DEVICE AS ALLEN-BRADLEY/ROCKWELL MICROLOGIX"

 local split = stdnse.strsplit(" ",confirm)
 local split2 = stdnse.strsplit("-",split[1])

 if (string.match(split2[1], "Allen") and string.match(split2[2],
"Bradley")) or string.match(confirm, "Rockwell") then
   if string.match(confirm, "MicroLogix1400") then
     if nmap.verbosity() > 1 then
       result = result .. "\n** PHASE 1: SNMP verification"
       result = result .. "\n....Step 1: MicroLogix device info :
CONFIRMED"
     else
       result = result .. "\n** IF YOU REQUIRE MORE INFO, USE THE \"-v\"
OPTION"
     end
   end
   local split = stdnse.strsplit(" ",confirm)
   if string.match(split2[1], "Allen") then
     name = string.sub(split[1],1,15)
   end
   if string.match(confirm, "Rockwell") then
     name1 = string.sub(split[1],1,15)
     name2 = string.sub(split[2],1,15)
     name = name1 .. " " .. name2
   end
   modelnum = string.sub(split[2],1,14)
   version = string.sub(split[3],3,6)
   fullversion = string.sub(split[3],1,6)
   modeltype = string.sub(split[4],1,10) .. " " ..
string.sub(split[4],11,14)
   series = string.sub(split[6],1,1)
   revision = string.sub(split[8],1,4)
   if nmap.verbosity() > 1 then
     result = result .. "\n............Version S/W            : " ..
fullversion
   else
     result = result .. "\n............MicroLogix device info : CONFIRMED"
     result = result .. "\n............Version S/W            : " ..
version
   end
   if nmap.verbosity() > 1 then
     result = result .. "\n....Step 2: SNMP device detailed information"
     result = result .. "\n............Manufacturer name      : " .. name
     result = result .. "\n............Model number           : " ..
modelnum
     result = result .. "\n............Type/model type        : " ..
modeltype
     result = result .. "\n............Series type            : " .. series
     result = result .. "\n............Revision number        : " ..
revision
     result = result .. "\n** PHASE 2: Documentation"
     result = result .. "\n....Step 1: Documentation exist?   : YES"
     result = result .. "\n"
     result = result .. "\n............
ninja.infracritical.com/dox/1766-in001_-en-p.pdf"
     result = result .. "\n............
ninja.infracritical.com/dox/1766-um002_-en-p.pdf"
   end
 else
   if nmap.verbosity() > 1 then result = "Fingerprint not found."; end
 end
 if nmap.verbosity() > 1 then result = result .. "\n"; end
 return result
end

===============================================

Same output was conducted on four (4) Internet-connected PLC devices "in
the wild", and will look similar to something shown below. NOTE:
"xxx.xxx.xxx.xxx" represents a sanitized IP address of the device taken from
"in the wild" (thank you SHODAN).

[root () server nmap]# nmap --script=./micrologix1400.nse xxx.xxx.xxx.xxx -PN
-sU -p161 -vv

Starting Nmap 5.35DC1 ( http://nmap.org ) at 2010-12-06 21:08 CST
NSE: Loaded 1 scripts for scanning.
Initiating Parallel DNS resolution of 1 host. at 21:08
Completed Parallel DNS resolution of 1 host. at 21:08, 0.15s elapsed
Initiating UDP Scan at 21:08
Scanning xxx.domain.com (xxx.xxx.xxx.xxx) [1 port]
Discovered open port 161/udp on xxx.xxx.xxx.xxx
Completed UDP Scan at 21:08, 2.01s elapsed (1 total ports)
NSE: Script scanning xxx.xxx.xxx.xxx.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 21:08
Completed NSE at 21:08, 0.14s elapsed
Nmap scan report for xxx.domain.com (xxx.xxx.xxx.xxx)
Host is up (1.8s latency).
Scanned at 2010-12-06 21:08:34 CST for 2s
PORT    STATE SERVICE
161/udp open  snmp
| micrologix1400: CONFIRM DEVICE AS ALLEN-BRADLEY/ROCKWELL MICROLOGIX
| ** PHASE 1: SNMP verification
| ....Step 1: MicroLogix device info : CONFIRMED
| ............Version S/W            : A/5.00
| ....Step 2: SNMP device detailed information
| ............Manufacturer name      : Allen-Bradley
| ............Model number           : 1766-L32AWAA
| ............Type/model type        : MicroLogix 1400
| ............Series type            : A
| ............Revision number        : 5.0
| ** PHASE 2: Documentation
| ....Step 1: Documentation exist?   : YES
| ............ninja.infracritical.com/dox/1766-in001_-en-p.pdf
|_............ninja.infracritical.com/dox/1766-um002_-en-p.pdf

Read data files from: /usr/local/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 2.58 seconds
          Raw packets sent: 2 (176B) | Rcvd: 2 (160B)
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Fyodor
Are there some linkages that would be helpful in writing nse scripts that
you can recommend? I'm involved in a couple of projects at work related to
what Bob is doing and would gladly offer assistance to him, but need to get
up to speed on mechanics...

Regards
Jack
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


  By Date           By Thread  

Current thread:
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]