ChatGPT Scripting ICS OT Lab Manual
ChatGPT Scripting ICS OT Lab Manual
Mike Holcomb
GRID, CISSP, ISA 62443
mikeholcomb.com
1 | Page
© 2024 Mike Holcomb
Contents
Using ChatGPT to Write Defensive & Offensive Scripts for ICS/OT............................................. 1
Lab Requirements..................................................................................................................... 3
Exercise 1.1 Installing Python on Windows............................................................................... 3
Exercise 1.2 Creating Your First ChatGPT Python Script..........................................................3
Exercise 1.2 Updating an Existing Script...................................................................................4
Exercise 1.3 Converting Python Scripts to Other Languages....................................................5
Exercise 1.4 Creating a Basic ICS/OT Port Scanner.................................................................5
Exercise 1.5 Troubleshooting Error Code..................................................................................6
Exercise 1.6 Adding Functionality to an Existing Script.............................................................7
2 | Page
© 2024 Mike Holcomb
Lab Requirements
● Windows host
● Virtualization software (e.g., VMware, Oracle VirtualBox, Hyper-V)
● Kali Linux
● A paid for ChatGPT account is preferred
o A free ChatGPT can work but will be limited in some cases
● Lab setup
2. Once downloaded, install Python. For the purpose of this course, accept all defaults.
3. To verify that Python is installed correctly on your system, open a command prompt and
type the following:
python --v
C:\Users\micha>python --version
Python 3.12.2
If you receive a message that starts with “Requirement already satisfied” then you do not
need to take any further action.
3 | Page
© 2024 Mike Holcomb
2. If it appears that PIP is not installed on your system, download the current version of PIP
using the following link: https://bootstrap.pypa.io/pip/pip.pyz.
3. Once downloaded, launch the .pyz file which is a specially crafted ZIP file for Python. At
this point, PIP should install on your system.
2. Copy the following prompt into the ChatGPT window and click the up arrow icon (“Send
Message”) to process.
Prompt:
Write a Python script that will print "Hello, friend..." on the screen.
3. Once the prompt is processed, ChatGPT should display a code window with the script.
Click the ‘Copy code’ button in the upper right corner of the code window to copy the
script to your Windows clipboard.
4. In a folder on your Windows system, such as C:\Scripts, create a text file names hello.py.
Edit the contents, paste in the code from ChatGPT and save the file.
5. Once saved, run your Python script from the Windows command link.
C:\Scripts\hello.py
4 | Page
© 2024 Mike Holcomb
1. Copy the following prompt into the ChatGPT window and click the up arrow icon (“Send
Message”) to process.
Prompt:
Update the previous script to include a blank line before writing to the screen.
2. Note the output of the new script. ChatGPT added the print() command to add a
blank line.
3. Update your hello.py script with the new code and run it. You should see the “easier to
read” output:
In this exercise, we’ll convert the previous Python script to PowerShell which is installed by
default on Windows to leverage Living off the Land techniques.
1. In ChatGPT, submit the following prompt to convert the previous Python script to its
PowerShell equivalent.
NOTE: Some times ChatGPT will provide details on what it is doing for you. If you want
more, or less, details, you can simply let us know by using “Provide more (or less) details on
what you are doing.”
2. Save the new script to hello.p1 and run it. You should see very similar output compared
to the previous Python script, including the extra line we added for readability.
5 | Page
© 2024 Mike Holcomb
Exercise 1.4 Creating a Basic ICS/OT Port Scanner
Text
1. Use the following script to create a basic network scanner in Python to detect the
presence of common ICS/OT ports on a specific host. We will be continuing to add
functionality to the scanner.
2. In ChatGPT, submit the following prompt to create a basic ICS/OT port scanner. The
scanner will check for the presence of open ports on a single IP address. The open
ports checked for will be TCP 80, TCP 443, TCP 102, TCP 502.
Prompt:
Write a Python script to detect the presence of open TCP ports on a single target IP
address. The script will ask the user to provide the IP address. The script should check to
see if the IP address provided is valid or not. If not valid, ask the user again for the IP
address. If valid, scan the IP address to determine if TCP 80, 443, 102 or 502 are open on
the target system.
3. Save the output as scanner.py and run the script. Conduct a port scan against a known
IP address.
When you do, you will receive an error message similar to the one seen here:
6 | Page
© 2024 Mike Holcomb
2. Troubleshooting error code can be a challenging process. Thankfully, ChatGPT does an
exceptional job troubleshooting code errors. Especially ones that it’s created!
3. To troubleshooting the PowerShell scanner script, copy the red error message into
ChatGPT and submit it as a prompt. Once submitted, ChatGPT should find the issue,
explain the problem and how to fix it.
4. It should also provide a fixed script or a fixed script portion. In this example, ChatGPT
only returns the single line that needs to be fixed which it has corrected:
5. If it only returns the portion that needs to be fixed and not the entire script, you can
simply use the following prompt:
Prompt:
Provide the full fixed script.
For the sake of space, the fixed script is not included here.
6. Update your scanner.ps1 file and run it to make sure it runs just as the Python version
does now that it is fixed.
7. As you can see, while the functionality is the same, the output is different with the
PowerShell version.
7 | Page
© 2024 Mike Holcomb
Exercise 1.6 Adding Functionality to an Existing Script
While the port scanner has basic functionality, we could add additional features. For example,
we might want to add the ability to scan an entire subnet.
1. Use the following prompt to update the port scanner Python script to include the ability to
scan a subnet in addition to single IP addresses.
Prompt:
Update the previous script to allow the user to provide a single IP address or
subnet with CIDR notation.
2. Update your scanner.py script with the updated script provided by ChatGPT.
3. Run the script and run a scan against your local subnet.
As you can see, your port scanner isn’t necessarily the fastest, but it does work!
4. Consider what other updates you might make to the script to make it more useful. Some
items to consider include:
● Adding ‘help’ output
● Error handling
Prompt:
Create a Python script that asks the user for a URL. The script will then connect to the URL
and enumerate all IP addresses from the page and then print those IP addresses on the
screen.
8 | Page
© 2024 Mike Holcomb
2. In your browser, visit the IP test page at https://www.mikeholcomb.com/iptest to see a
simple page created to supply several IP addresses for testing.
Depending on how the script runs and parses IP addresses, you might see an order that
is different than what is on the web page.
4. Update the script to display IP addresses in numerical order. You should now see the
following output:
If you need a little help, use the following to have the scraper.py display the IP address
list in numerical order.
9 | Page
© 2024 Mike Holcomb
Prompt:
Update the previous script so that the gathered IP addresses are listed in numerical order.
Of course, there are many different ways to try. If you’re able to tell ChatGPT what you
want, it “should” be able to understand. We’ll see some examples as we go throughout the
exercises of when ChatGPT can and cannot understand necessarily.
1. Let’s update our scraper.py script to add the functionality for performing GeoIP location
lookups for each IP address and displaying it on the screen. For the ability to perform
GeoIP lookups, we will use the free subscription plan for the ipinfo.io service.
3. On the main page, you should see the GeoIP information displayed for your own public
IP address.
5. Once signed in, click on the ‘Token’ option on the left-hand menu. This will take you to
the page that lists your API token for the ipinfo.io service. Leave the page open as we’ll
be referring to it shortly.
6. Back in ChatGPT, let’s tell it to update our previous scraper.py script with the ipinfo.io
API functionality to perform GeoIP lookups and display the information on the screen.
10 | Page
© 2024 Mike Holcomb
Prompt:
Update the previous script to perform a GeoIP location lookup for each IP address using
API functionality with ipinfo.io. Display the GeoIP location along with each IP address.
7. ChatGPT should provide you with an updated script along with instructions on how to
update the script with your ipinfo.io API token. Make the specified adjustments and save
your script.
For example, in my version, I had to find the API_TOKEN value and replace it with my
actual API token listed on the ipinfo.io Token page we looked at earlier.
def get_geoip_location(ip_address):
try:
# Send a GET request to ipinfo.io API with the access token
response =
requests.get(f"https://ipinfo.io/{ip_address}/json?token={API_TOKEN}")
def get_geoip_location(ip_address):
try:
# Send a GET request to ipinfo.io API with the access token
response =
requests.get(f"https://ipinfo.io/{ip_address}/json?token={
b40068db3857}")
8. Run your updated version of the scraper.py script with GeoIP lookup functionality. You
should see something similar to the following.
11 | Page
© 2024 Mike Holcomb
Exercise 1.9 Finding PLCs Exposed to the Internet
While there are several ways to find Internet exposed PLCs, our friends at the NSA gave us a
few methods for doing so in their ELITEWOLF project. While the project provided several Snort
intrusion detection signatures for ICS/OT defenders to identify potentially malicious activity on
their networks, the signatures also provided us with some Google searches to find PLCs.
3. Looking at the last part of each Snort rule, the URL portion specified in the content:
section can be used in Google to find Allen Bradley/Rockwell Automation PLCs exposed
to the Internet.
4. Go to Google and run a search for the first URL portion listed in the ELITEWOLF file as
seen below.
5. While some results will refer to PLC documentation and the ELITEWOLF Github page
itself, most results will refer to actual PLCs exposed to the Internet. For example, my
12 | Page
© 2024 Mike Holcomb
search results start with the two exposed PLCs at 173.181.149.217 and 185.9.25.82 as
seen below.
As expected, based on the ELITEWOLF file we pulled the search string from, these
appear to be AllenBradley/Rockwell Automation PLCs.
6. Click on one of the links for the exposed PLCs. You should see a web page that
displays various statistics related to the PLC’s TCP functionality such as seen below.
7. While each of the URLs can provide interesting pieces of information, I’m always
fascinated when I can see the netstat output of a remote system. Run a Google search
using the partial URL of ‘/rokform/advancedDiags?pageReq=tcpconn’.
13 | Page
© 2024 Mike Holcomb
8. Access the URL. You should see the exposed PLCs netstat information, showing all IP
addresses (external AND internal) that are communicating with the PLC.
● The PLC is being remotely accessed from Shenyang in China, Sao Paulo in
Brazil, Brussels in Germany and (of course) Simpsonville, South Carolina, United
States.
● Internal hosts communicating with the PLC include
192.1168.1.100,192.168.1.122,192.168.1.125, 192.168.1.127,192.168.1.130 and
192.168.1.131.
14 | Page
© 2024 Mike Holcomb
So it appears we are not the only external visitors to the PLC’s web interface. Not only
that, but we have also enumerated more than a few internal hosts on the PLCs ICS/OT
network.
15 | Page
© 2024 Mike Holcomb