这个周末,我一直在鼓捣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写了一个小脚本。如果你的网卡性能不错的话,你可以利用masscanZmap等工具来扫描互联网,寻找在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分发系统的更多相关文章

  1. 使用 expect 命令执行自动分发系统

    一.命令 except 实例详解 1. 介绍 expect 使用场景 expect可以让我们实现自动登录远程机器,并且可以实现自动远程执行命令.当然若是使用不带密码的密钥验证同样可以实现自动登录和自动 ...

  2. 基于BT协议的文件分发系统

    基于BT协议的文件分发系统构成:    1.一个Web服务器:保存着种子文件    2.一个种子文件:保存共享文件的一些信息(文件名,文件大小    ,Tracker服务器地址,torrent为后缀) ...

  3. 任务分发系统gearman

    1 Gearman是什么 Gearman Job Server@http://gearman.org/. Gearman 是一个任务分发系统,它提供了一个分发框架,能够分发某类任务到更适合处理这类任务 ...

  4. Django之路由分发系统

    web的基本工作流程 首先,我们先来思考一下我们平常在上网浏览网页时候的场景,大致就是打开一个web浏览器,输入某一个网站的地址,然后转到该网址,在浏览器中得到该网址的页面.从这个场景中我们可以抽象出 ...

  5. 关于LT分发系统的设计构想

    git地址 https://github.com/cxyxd/LtDistribution 背景 对tomcat做集群,在多机多tomcat的情况下,如果要更新代码,只能手动的将代码复制,粘贴,然后下 ...

  6. 深度解读阿里巴巴云原生镜像分发系统 Dragonfly

    Dragonfly 是一个由阿里巴巴开源的云原生镜像分发系统,主要解决以 Kubernetes 为核心的分布式应用编排系统的镜像分发难题.随着企业数字化大潮的席卷,行业应用纷纷朝微服务架构演进,并通过 ...

  7. expect脚本同步文件 expect脚本指定host和要同步的文件 构建文件分发系统 批量远程执行命令

    自动同步文件 #!/usr/bin/expect set " spawn rsync -av root@.txt /tmp/ expect { "yes/no" { se ...

  8. centos shell编程4【分发系统】 服务器标准化 mkpasswd 生成密码的工具 expect讲解 expect传递参数 expect自动同步文件 expect指定host和要同步的文件 expect文件分发系统 expect自动发送密钥脚本 Linux脚本执行方式 第三十八节课

    centos shell编程4[分发系统] 服务器标准化  mkpasswd 生成密码的工具  expect讲解   expect传递参数   expect自动同步文件  expect指定host和要 ...

  9. 第四部分shell编程5项目二分发系统

    第一部分:expect讲解expect可以让我们实现自动登录远程机器,并且可以实现自动远程执行命令.当然若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令.但当不能使用密钥验证的时候,我 ...

随机推荐

  1. 关于RabbitMQ Queue Argument的简介

    1.Message TTL message在队列queue中可以存活多长时间,以毫秒为单位:发布的消息在queue时间超过了你设定的时间就会被删除掉. channel.queueDeclare(&qu ...

  2. BZOJ4025 二分图(线段树分治+并查集)

    之前学了一下线段树分治,这还是第一次写.思想其实挺好理解,即离线后把一个操作影响到的时间段拆成线段树上的区间,并标记永久化.之后一块处理,对于某个节点表示的时间段,影响到他的就是该节点一直到线段树根的 ...

  3. MT【217】韦达定理应用

    若2018次方程$x^{2018}-4036x^{2017}+a_{2016}x^{2016}+\cdots+a_1x+a_0=0$ 有2018个正实数, 则对于所有可能的方程$\sum\limits ...

  4. Windows Server 脚本记录Apache、Mysql 每分钟并发数

    打开windows server 计划任务管理器.定时执行如下的Bat脚本即可. 在D盘新建一个monitor文件夹,创建ApacheMysql.bat文件.内容如下: 在monitor文件夹中新建m ...

  5. SharePoint “File not found” 错误

    Troubleshooting the SharePoint "File not found" Error Have you ever come across a "Fi ...

  6. binary search模板总结

    二分查找算法是最常用的一种高效算法,所以本文将常见的情形做一个总结,得到一个二分查找的模板,方便应对各种二分查找中的问题. 当前有一个有序的数列: 1, 5, 9 [每个数字都是唯一的] 1, 2, ...

  7. luogu2634 聪聪可可 (树形dp)

    要求出两点间距离==0(mod3) 的数量,然后除以(n*n) 设f[i][j]为i的子树到i的距离==j(mod3)的数量,然后做树形dp即可 因为要最简,所以要求一下gcd,然后除下去 #incl ...

  8. CF1114B Yet Another Array Partitioning Task(贪心,构造题)

    我至今不敢相信我被这么一道简单的题卡了这么久……看来还是太弱了…… 题目链接:CF原网 题目大意:定义一个序列的“美丽度”为这个序列前 $m$ 大的数的和.现在有一个长度为 $n$ 的序列,你需要把它 ...

  9. Linux下的定时器类实现(select定时+线程)

    更好的计时器类实现:LINUX RTC机制实现计时器类(原创) 很多时候需要在LINUX下用到定时器,但像setitimer()和alarm()这样的定时器有时会和sleep()函数发生冲突,这样就给 ...

  10. Android原生(Native)C开发之四:SDL移植笔记

    http://www.apkbus.com/forum.php?mod=viewthread&tid=1989 SDL(Simple DirectMedia Layer)是一套开放源码的跨平台 ...