编写IE CSS漏洞、DNP3协议、TFTP协议、modbus功能码异常、wincc flexible缓冲区溢出的suricata规则-测试(9004104-9004134)

1.测试规则(9004104-9004108)

1.主机B开启9100端口
nc -l -p 9100

2.主机A发送请求
printf '@PJL FSDIRLIST NAME="0:\\" \r\n' | nc 10.10.10.2 9100
printf '@PJL FSUPLOAD NAME="0:\\config\\net.cfg" \r\n' | nc 10.10.10.2 9100
printf '@PJL FSDOWNLOAD NAME="0:\\tmp\\a.bin" \r\n' | nc 10.10.10.2 9100
printf '@PJL FSDELETE NAME="0:\\tmp\\a.bin" \r\n' | nc 10.10.10.2 9100

3.主机B分析测试流量
tshark -r pjl.pcap -o tcp.desegment_tcp_streams:TRUE -q -z follow,tcp,ascii,0

 2.测试规则(9004109-9004110)

1.主机B开启监听20000
nc -l -p 20000 > /tmp/recv_20000.bin

2.主机A发送请求
python - << 'PY'
import socket
dst=("10.10.10.2",20000)
p=bytearray()
p += b"\x05\x64"         # DNP3 start
p += b"\x20"             # payload[2] = 0x20 (通过 byte_test)
p += b"\x00" * 20        # padding(让结构更像真实帧,但不必严格)
p += b"\x01\x46"         # 关键字段1
p += b"\x00" * 50
p += b"\x13"             # 关键字段2(在 01 46256 内)
p += b"\x00" * 40        # 确保 dsize > 80
s=socket.socket()
s.connect(dst)
s.sendall(bytes(p))
s.close()
print("sent",len(p),"bytes")
PY

3.测试规则(9004111-9004113)

1.主机A发送请求
python - << 'PY'
import socket
dst=("10.10.10.2",69)
pkt=b"\x00\x01" + b"NVRAM/D20.zlb" + b"\x00" + b"octet" + b"\x00"
socket.socket(socket.AF_INET,socket.SOCK_DGRAM).sendto(pkt,dst)
print("sent RRQ",pkt)
PY

python - << 'PY'
import socket
dst=("10.10.10.2",69)
pkt=b"\x00\x02" + b"NVRAM/test.cfg" + b"\x00" + b"octet" + b"\x00"
socket.socket(socket.AF_INET,socket.SOCK_DGRAM).sendto(pkt,dst)
print("sent WRQ",pkt)
PY

python - << 'PY'
import socket, time
dst=("10.10.10.2",69)
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
for i in range(15):
    fn=f"file{i}.bin".encode()
    pkt=b"\x00\x01" + fn + b"\x00" + b"octet" + b"\x00"
    s.sendto(pkt,dst)
time.sleep(1)
print("sent 15 RRQ")
PY

 4.测试规则(9004114-9004115、9004127)

1.主机B开启502端口监听
nc -lk -p 502 >/dev/null

2.主机A发送请求,测试9004115、9004127
python - << 'PY'
import socket, struct
def send(payload):
    s=socket.socket()
    s.connect(("10.10.10.2",502))
    s.sendall(payload)
    s.close()
def mbap(func, extra=b""):
    tid=0x1234
    pid=0x0000
    length=1+1+len(extra)
    unit=0x01
    return struct.pack(">HHHB", tid, pid, length, unit) + bytes([func]) + extra
send(mbap(0x5A, b"\x11" + b"\x30" + b"\x00"))
send(mbap(0x10, b"\x00\x00\x00\x01\x02\x12\x34"))
print("sent")
PY

5.测试规则(9004116-9004120)

1.主机B开启502监听
nc -lk -p 502 >/dev/null

2.主机A发送请求,测试9004116-9004120
'''
python umas_modbus.py --dst 10.10.10.2 --subfunc 0x31   # 9004116
python umas_modbus.py --dst 10.10.10.2 --subfunc 0x32   # 9004117
python umas_modbus.py --dst 10.10.10.2 --subfunc 0x33   # 9004118
python umas_modbus.py --dst 10.10.10.2 --subfunc 0x34   # 9004119
python umas_modbus.py --dst 10.10.10.2 --subfunc 0x35   # 9004120
'''
import socket
import struct
import time
import argparse
from socket import IPPROTO_TCP, TCP_NODELAY

def mbap(tid: int, func: int, extra: bytes, unit: int = 1) -> bytes:
    # MBAP: TID(2) PID(2=0) LEN(2) UNIT(1) + FUNC(1) + EXTRA
    pid = 0
    length = 1 + 1 + len(extra)  # unit + func + extra
    return struct.pack(">HHHB", tid, pid, length, unit) + bytes([func]) + extra

def send_umas_subfunc(dst_ip: str, subfunc: int, port: int = 502, sleep_s: float = 0.2):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)  # 尽量避免粘包
    s.connect((dst_ip, port))
    session_key = 0x11
    # 第1包:CTX 包(仅确保 flowbits 先被 set)
    # func=0x5A,offset9 填 0x00(无所谓)
    pkt_ctx = mbap(0x1111, 0x5A, bytes([session_key, 0x00, 0x00]))
    s.sendall(pkt_ctx)
    time.sleep(sleep_s)
    # 第2包:目标子功能包(offset9 = subfunc)
    pkt = mbap(0x1112, 0x5A, bytes([session_key, subfunc, 0x00]))
    s.sendall(pkt)
    time.sleep(sleep_s)
    s.close()

if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("--dst", required=True,
                    help="PLC/Server IP, e.g. 10.10.10.2")
    ap.add_argument("--subfunc", required=True,
                    help="UMAS subfunc hex, e.g. 0x31")
    ap.add_argument("--sleep", type=float, default=0.2)
    args = ap.parse_args()
    sub = int(args.subfunc, 16)
    send_umas_subfunc(args.dst, sub, sleep_s=args.sleep)
    print(f"sent UMAS subfunc {hex(sub)} to {args.dst}:502")

6.测试规则(9004121-9004123)

1.主机B监听502
nc -lk -p 502 >/dev/null

2.主机A发送请求
'''
python umas_modbus_20_21_29.py --dst 10.10.10.2 --subfunc 0x20   # 9004121
python umas_modbus_20_21_29.py --dst 10.10.10.2 --subfunc 0x21   # 9004122
python umas_modbus_20_21_29.py --dst 10.10.10.2 --subfunc 0x29   # 9004123
'''
import socket
import struct
import time
import argparse
from socket import IPPROTO_TCP, TCP_NODELAY

def mbap(tid: int, func: int, extra: bytes, unit: int = 1) -> bytes:
    pid = 0
    length = 1 + 1 + len(extra)   # unit + func + extra
    return struct.pack(">HHHB", tid, pid, length, unit) + bytes([func]) + extra

def send_subfunc(dst_ip: str, subfunc: int, port: int = 502, sleep_s: float = 0.3):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)  # 降低粘包概率
    s.connect((dst_ip, port))
    session_key = 0x11

    # 1) 先发送 CTX 包:确保 9004114 命中并 set flowbit
    pkt_ctx = mbap(0x2001, 0x5A, bytes([session_key, 0x00, 0x00]))
    s.sendall(pkt_ctx)
    time.sleep(sleep_s)

    # 2) 发送目标 UMAS 子功能包:offset9 = subfunc
    # 额外补一些字节,让长度更像真实请求(不影响 offset 命中)
    extra = bytes([session_key, subfunc]) + b"\x00\x01\x00\x02\x00\x03"
    pkt = mbap(0x2002, 0x5A, extra)
    s.sendall(pkt)
    time.sleep(sleep_s)
    s.close()

if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("--dst", required=True, help="Server IP (10.10.10.2)")
    ap.add_argument("--subfunc", required=True,
                    help="UMAS subfunc hex: 0x20 / 0x21 / 0x29")
    ap.add_argument("--sleep", type=float, default=0.3)
    args = ap.parse_args()
    sub = int(args.subfunc, 16)
    send_subfunc(args.dst, sub, sleep_s=args.sleep)
    print(f"sent UMAS subfunc {hex(sub)}")

7.测试规则(9004124-9004126)

1.主机B开启502服务
nc -lk -p 502 >/dev/null

2.主机A发送请求
import socket
import struct
import time
from socket import IPPROTO_TCP, TCP_NODELAY

DST = ("10.10.10.2", 502)

def mbap(tid: int, unit: int, func: int, pdu: bytes) -> bytes:
    # MBAP: TID(2) PID(2=0) LEN(2) UNIT(1) + FUNC(1) + PDU
    pid = 0x0000
    length = 1 + 1 + len(pdu)  # unit + func + pdu
    return struct.pack(">HHHB", tid, pid, length, unit) + bytes([func]) + pdu

def send_one(payload: bytes):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)  # 减少粘包
    s.connect(DST)
    s.sendall(payload)
    time.sleep(0.2)
    s.close()

# 0x05 Write Single Coil: addr(2) + value(2) (0xFF00=ON, 0x0000=OFF)
p05 = mbap(0x1234, 0x01, 0x05, struct.pack(">HH", 0x0001, 0xFF00))

# 0x0F Write Multiple Coils: start(2) qty(2) bytecount(1) values(n)
# 写 8 个线圈 -> bytecount=1 -> values=0xFF (8 bits set)
p0f = mbap(0x1235, 0x01, 0x0F, struct.pack(
    ">HHB", 0x0001, 0x0008, 0x01) + b"\xFF")

# 0x06 Write Single Register: addr(2) + value(2)
p06 = mbap(0x1236, 0x01, 0x06, struct.pack(">HH", 0x0001, 0x1234))

send_one(p05)  # 触发 9004124
time.sleep(1)
send_one(p0f)  # 触发 9004125
time.sleep(1)
send_one(p06)  # 触发 9004126

print("sent 0x05 / 0x0F / 0x06 requests")

 8.测试规则(9004128-9004134)

1.主机B开启2308监听
nc -lk -p 2308 >/dev/null

2.主机A发送请求至2308端口
import socket
import struct
import time
DST = ("10.10.10.2", 2308)
def send(pkt):
    s = socket.socket()
    s.connect(DST)
    s.sendall(pkt)
    time.sleep(0.2)
    s.close()

# 选择一种 rel+23 类型:00 01 03
# 构造:type(3) + padding(23-3) + len(4,little) + filler
def pkt_rel23(msg3=b"\x00\x01\x03", L=0x1200):
    pad = b"\x00"*(23-3)
    return msg3 + pad + struct.pack("<I", L) + b"A"*50

# 选择一种 rel+3 类型:00 04 02
# 构造:type(3) + len(4,little) + filler
def pkt_rel3(msg3=b"\x00\x04\x02", L=0x1200):
    return msg3 + struct.pack("<I", L) + b"B"*50

# 先触发 CTX(任意家族类型即可)
send(b"\x00\x01\x02" + b"\x00"*20)

# 再触发 rel+23 组(9004129/30/31,看 L 大小)
send(pkt_rel23(L=0x0500))  # >0x410 触发 9004129
send(pkt_rel23(L=0x2000))  # >0x1000 触发 9004130
send(pkt_rel23(L=0x5000))  # >0x4000 触发 9004131

# 再触发 rel+3 组(9004132/33)
send(pkt_rel3(L=0x0500))   # >0x410 触发 9004132
send(pkt_rel3(L=0x2000))   # >0x1000 触发 9004133

print("sent")

 

posted @ 2026-01-29 10:55  岐岐卡卡西  阅读(0)  评论(0)    收藏  举报