下载源码:
git clone https://github.com/EIPStackGroup/OpENer
编译
首先进入目录
/big/opener/OpENer/bin/posix
执行脚本:
lkmao@ubuntu:/big/opener/OpENer/bin/posix$ ./setup_posix.sh
执行make
lkmao@ubuntu:/big/opener/OpENer/bin/posix$ make
Scanning dependencies of target Utils
[ 2%] Building C object src/utils/CMakeFiles/Utils.dir/random.c.o
[ 4%] Building C object src/utils/CMakeFiles/Utils.dir/xorshiftrandom.c.o
/big/opener/OpENer/source/src/utils/xorshiftrandom.c: In function ‘CalculateNextSeed’:
/big/opener/OpENer/source/src/utils/xorshiftrandom.c:22:21: warning: conversion to ‘uint32_t {aka unsigned int}’ from ‘time_t {aka long int}’ may alter its value [-Wconversion]
SetXorShiftSeed(time(NULL));
/*略*/
[100%] Linking C executable OpENer
[100%] Built target OpENer
开始执行
首先将虚拟机IP地址修改为和PLC相同网段。然后执行OpENer
sudo ./src/ports/POSIX/OpENer ens33
现在可以搜索到了
开一个新的终端,切换目录,
lkmao@ubuntu:/big/opener/OpENer$ pwd
/big/opener/OpENer
创建文件,
lkmao@ubuntu:/big/opener/OpENer$ echo "hello lkmao" > testcase.txt
lkmao@ubuntu:/big/opener/OpENer$ lkmao@
然后执行脚本
lkmao@ubuntu:/big/opener/OpENer$ python fuzz/scripts/send_testcase.py 192.168.250.11 testcase.txt
结果如下所示:
lkmao@ubuntu:/big/opener/OpENer$ python fuzz/scripts/send_testcase.py 192.168.250.11 testcase.txt
[-] Connecting to 192.168.250.11:44818
[-] Init ENIP session
[-] Got ENIP Session Handle: 1
[-] Reading testcase from: 'testcase.txt'
[-] Patching sender context and session handle
[-] Sending testcase of 12 bytes
lkmao@ubuntu:/big/opener/OpENer$
分析脚本send_testcase.py
没必要分析这个脚本
import sys
import socket
import struct
if len(sys.argv) != 3:
print("python {} IP TESTCASE_PATH".format(sys.argv[0]))
sys.exit(1)
HOST_IP = sys.argv[1]
HOST_PORT = 44818
TESTCASE_PATH = sys.argv[2]
ENIP_SESSION_CONTEXT = b"\x92\x83J\x0b=\x9e\x0cW"
ENIP_INIT_SESSION_PACKET = b"e\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" + ENIP_SESSION_CONTEXT + b"\x00\x00\x00\x00\x01\x00\x00\x00"
print("[-] Connecting to {}:{}".format(HOST_IP, HOST_PORT))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST_IP, HOST_PORT))
print("[-] Init ENIP session")
s.sendall(ENIP_INIT_SESSION_PACKET)
enip_session = s.recv(1024)
session_handle = enip_session[4:8]
print("[-] Got ENIP Session Handle: {}".format(struct.unpack("<I", session_handle)[0]))
print("[-] Reading testcase from: '{}'".format(TESTCASE_PATH))
with open(TESTCASE_PATH, "rb") as f:
testcase_data = f.read()
print("[-] Patching sender context and session handle")
testcase = testcase_data[:4] # command, len
testcase += session_handle # session handle
testcase += testcase_data[8:12] # status
testcase += ENIP_SESSION_CONTEXT # session context
testcase += testcase_data[20:] # options and payload
print("[-] Sending testcase of {} bytes".format(len(testcase)))
s.send(testcase)
s.close()