使用PLC作为payload/shellcode分发系统
这个周末,我一直在鼓捣Modbus,并利用汇编语言开发了一个stager,它可以从PLC的保持寄存器中下载payload。由于有大量的PLC都暴露在互联网上,我情不自禁地想到,是否可以利用它们提供的处理能力和内存来存储某些payload,以便以后(从stager)下载它们。
所以,我们不妨考虑下面的场景:
1. 攻击者从互联网上寻找一个具有足够的空间来存储payload的PLC。实际上,带有几十KB内存的Modbus设备是很容易找到的。
2. 攻击者将payload上传到PLC的内存。
3. 攻击者用dropper感染一个主机,然后利用stager与Modbus进行“交流”,从PLC中下载并执行该stage。
采用PLC保持寄存器存储Payload的优点
由于使用了第三方PLC,所以具有很好的匿名性,跟踪的难度非常大。无需将payload上传到服务器。
由于payload存放在PLC的内存中,所以加大了取证分析的难度。此外,一旦payload被取出,其内容可以被容易地覆盖(甚至stager自身就能做到这一点)。
此外,我认为Modbus Stager在某些ICS环境中也是非常有用的,因为这些环境下Modbus之外的协议会引起人们的警觉,并且WinHTTP / WinInet stager也不是最适用的。所以,在这种情况下,你只需要一个Modbus处理程序或者只是使用一个仿真器,在stager连接它时,由其提供stage即可。此外我们还发现,许多网络上都有可以远程管理的Modbus设备,所以它们也是这种stager的用武之地。
重要说明:请不要对任何第三方PLC执行这些操作。PLC寄存器上的任何写操作都可能毁坏原来的过程控制策略。
活跃在互联网上采用Modbus协议的PLC数量
为了弄清楚暴露在互联网中、使用Modbus协议的PLC的数量,我使用Censys API写了一个小脚本。如果你的网卡性能不错的话,你可以利用masscan或Zmap等工具来扫描互联网,寻找在502端口上运行Modbus协议的设备。
从以下输出可以看出,至少有5500个PLC可供利用。
在这些IP中,许多只是些蜜罐,这很容易看出来;例如,Conpot以及托管在云服务中的其他服务。就本文来说,即使蜜罐也无所谓,只要它们的内存足够大就行了。
如何将Payload上传至PLC保持寄存器
好了,为了将payload上传到PLC中,我编写了一个名为plcInjectPayload.py的python脚本。根据加载的控制策略的不同,对PLC可用内存大小的要求也有所变化,因此该脚本首先检查它们是否有足够的内存空间来存放相应的payload。为了检测内存的大小,可以发送操作ID为03(读取保持寄存器)的Modbus请求,尝试从某个地址读取特定记录(每个记录长度为16比特)。如果收到一个0x83异常,那么说明这个PLC对于我们来说是无法使用的。
要上传payload,请使用-upload选项,具体如下所示。该选项允许使用参数-addr规定起始地址,也就是说,从这个保持寄存器编号(如果未指定,则为地址0)开始加载payload。
如果payload的字节数为奇数,就需要用“0x90”来进行填充,以避免在读取时出现一些问题。在前面的示例中,大小为1536字节; 为了检查加载操作是否成功,我们可以利用选项-download从地址0处下载同样数量的字节。
很明显,该脚本不仅可以上传payload,实际上还可以上传任何类型的文件。所以,我们觉得这是一个泄露和共享信息的有趣方法。设想一下,有谁会怀疑某个公共PLC的保存寄存器会存有.docx或.zip文件呢?
需要格外注意的是,存放payload的记录可能会被PLC所改变。由于我们不清楚PLC I / O及其过程控制策略,所以需要寻找一个通常不会被修改到的内存范围。为此,我们可以将payload加载到某个范围,然后在一段时间内,payload经多次检查未发现任何变化的话,这就是我们要找的内存区域。为了达到这个目的,我们可以借助于plcInjectPayload.py以及另外几个bash指令即可。
在受控主机中读取PLC中存储的Payload
payload上传到PLC之后,还必须从受害者的计算机中读取它。为此,我建立了一个基于Modbus协议的stager;它的大小还不到500字节(我会设法让它变得更小)。其中,它的reverse_tcp和block_api代码取自Metasploit(https://github.com/rapid7/metasploit-framework/tree/master/external/source/shellcode/windows/x86/src/block)。下图展示的是block_recv_modbus.asm的asm代码,它的一部分职责是通过Modbus协议获取payload。因此,这段代码需要通过Modbus协议与PLC通信,以下相应的payload。这里的代码会利用前4个字节来了解该stage大小,并通过VirtualAlloc分配必要的内存。然后,通过不断发送“read holding”请求(功能代码03)来获取payload。根据协议规定,对于每个读请求,PLC最多可以返回250个字节(125个保持寄存器),因此,stager可以以它为单位,逐步下载payload。
实例解析
下面我们来看一个实际的例子。最近,我在www.exploit-db.com网站上发现一个用于Windows系统的键盘记录shellcode,大小只有600字节;虽然它的尺寸很小,但是对于一个只有几个MODBUS请求(记住,每个请求的最大字节数为250字节)的POC来说已经足够了。shellcode在执行后,会把按键敲击动作写入到用户的%TEMP%目录下的“log.bin”文件中。
因此,我们首先把该payload放到一个二进制文件中,并在它的前面放上其长度,这里是以小端字节表示的长度(4字节)。
现在,让我们从地址0开始将其上传到PLC:
这个stager一旦运行,就会通过3个请求下载该payload:250 + 250 + 102 = 602字节。下图详细描述了Modbus通信过程。
下图展示了Wireshark对上述通信过程的跟踪情况。进程监视器窗口表明,该stage在成功运行(检查log.bin文件就能看到保存的击键)
我已经通过Modbus仿真器和实际PLC对这个代码进行了验证,结果一切正常,但是如前所述,我认为该shellcode还可以进一步优化。为了进行第一个测试,我在python(plcModbusHandler.py)中创建了一个Modbus处理程序,用来把该payload发送给stager。
我正在设法把这个处理程序移植到Metasploit。更多详情,请观看下面的视频。
参考链接:http://bobao.360.cn/learning/detail/3311.html
原文链接:http://www.shelliscoming.com/2016/12/modbus-stager-using-plcs-as.html
使用PLC作为payload/shellcode分发系统的更多相关文章
- 使用 expect 命令执行自动分发系统
一.命令 except 实例详解 1. 介绍 expect 使用场景 expect可以让我们实现自动登录远程机器,并且可以实现自动远程执行命令.当然若是使用不带密码的密钥验证同样可以实现自动登录和自动 ...
- 基于BT协议的文件分发系统
基于BT协议的文件分发系统构成: 1.一个Web服务器:保存着种子文件 2.一个种子文件:保存共享文件的一些信息(文件名,文件大小 ,Tracker服务器地址,torrent为后缀) ...
- 任务分发系统gearman
1 Gearman是什么 Gearman Job Server@http://gearman.org/. Gearman 是一个任务分发系统,它提供了一个分发框架,能够分发某类任务到更适合处理这类任务 ...
- Django之路由分发系统
web的基本工作流程 首先,我们先来思考一下我们平常在上网浏览网页时候的场景,大致就是打开一个web浏览器,输入某一个网站的地址,然后转到该网址,在浏览器中得到该网址的页面.从这个场景中我们可以抽象出 ...
- 关于LT分发系统的设计构想
git地址 https://github.com/cxyxd/LtDistribution 背景 对tomcat做集群,在多机多tomcat的情况下,如果要更新代码,只能手动的将代码复制,粘贴,然后下 ...
- 深度解读阿里巴巴云原生镜像分发系统 Dragonfly
Dragonfly 是一个由阿里巴巴开源的云原生镜像分发系统,主要解决以 Kubernetes 为核心的分布式应用编排系统的镜像分发难题.随着企业数字化大潮的席卷,行业应用纷纷朝微服务架构演进,并通过 ...
- expect脚本同步文件 expect脚本指定host和要同步的文件 构建文件分发系统 批量远程执行命令
自动同步文件 #!/usr/bin/expect set " spawn rsync -av root@.txt /tmp/ expect { "yes/no" { se ...
- centos shell编程4【分发系统】 服务器标准化 mkpasswd 生成密码的工具 expect讲解 expect传递参数 expect自动同步文件 expect指定host和要同步的文件 expect文件分发系统 expect自动发送密钥脚本 Linux脚本执行方式 第三十八节课
centos shell编程4[分发系统] 服务器标准化 mkpasswd 生成密码的工具 expect讲解 expect传递参数 expect自动同步文件 expect指定host和要 ...
- 第四部分shell编程5项目二分发系统
第一部分:expect讲解expect可以让我们实现自动登录远程机器,并且可以实现自动远程执行命令.当然若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令.但当不能使用密钥验证的时候,我 ...
随机推荐
- rhel6+apache2.4+mysql5.7+php5.6部署LAMP架构
rhel6+apache2.4+mysql5.7+php5.6部署LAMP架构 2017年10月01日 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~准备阶段~~~~~~~~~~~~~ ...
- Python中print/format字符串格式化实例
Python 字符串格式化使用 "字符 %格式1 %格式2 字符"%(变量1,变量2),%格式表示接受变量的类型.简单的使用例子如下 # 例:字符串格式化Name = '17jo' ...
- python之Counter类:计算序列中出现次数最多的元素
Counter类:计算序列中出现次数最多的元素 from collections import Counter c = Counter('abcdefaddffccef') print('完整的Cou ...
- BZOJ3075[USACO 2013 Mar Gold 3.Necklace]——AC自动机+DP
题目描述 给你一个长度为n的字符串A,再给你一个长度为m的字符串B,求至少在A中删去多少个字符才能使得B不是A的子串.注:该题只读入A和B,不读入长度,先读入A,再读入B.数据保证A和B中只含小写字母 ...
- LOJ117 有源汇有上下界最小流(上下界网络流)
跑出可行流后从原来的汇点向原来的源点跑最大流,原图最小流=inf-maxflow.显然超源超汇的相关边对其也没有影响.原图最小流=可行流-原图新增流量,因为t向s流量增加相当于s向t流量减少.但为什么 ...
- MT【23】用算术几何不等式证明数列极限存在
评:如果不需要精确到3,上界的求法可以利用$$(1+\frac{1}{n})^n*\frac{1}{2}*\frac{1}{2}<(\frac{n+\frac{1}{n}*n+\frac{1}{ ...
- Android自动化测试探索
Android自动化测试探索 前言 通常来说,我们开发完成产品之后,都是由测试组或者是我们自己点一点,基本上没有问题了就开始上线.但是,随着时间的堆叠,一款产品的功能也越来越多.这时,我们为了保证产品 ...
- [luogu4264][USACO18FEB]Teleportation
题解 先吐槽一波题目:便便传送门,出题人还真的有一点厉害的滑稽. 废话不多说. 首先问题的本质就是求如果当这个传送门的端点位于\(y\)的时候,最小的求出总代价,我们设为函数\(f(y)\). 因为这 ...
- Mysql的命令总结
Mysql常用命令 启动 net start mysql 关闭 net stop mysql 连接mysql mysql -uroot -ppssword mysql -uroot -P3307 -p ...
- 做一个懒COCOS2D-X程序猿(一)停止手打所有cpp文件到android.mk
前言:”懒”在这里当然不是贬义词,而是追求高效,拒绝重复劳动的代名词!做一个懒COCOS2D-X程序猿的系列文章将教会大家在工作中如何偷懒,文章篇幅大多较短,有的甚至只是几行代码,争取把懒发挥到极致! ...