CVE-2019-5074
An exploitable stack buffer overflow vulnerability exists in the iocheckd service “I/O-Check” functionality of WAGO PFC 200. A specially crafted set of packets can cause a stack buffer overflow, resulting in code execution. An attacker can send unauthenticated packets to trigger this vulnerability.
WAGO PFC200 Firmware version 03.01.07(13) WAGO PFC200 Firmware version 03.00.39(12) WAGO PFC100 Firmware version 03.00.39(12)
https://www.wago.com/us/pfc200 https://www.wago.com/us/pfc100
9.8 CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE-805: Buffer Access with Incorrect Length Value
The WAGO PFC200 Controller is one of WAGO’s programmable automation controllers that boasts high cybersecurity standards by including VPN, SSL and firewall software. WAGO controllers are used in many industries including automotive, rail, power engineering, manufacturing, and building management. The WAGO PFC200 Controller communicates via both standard and custom protocols.
The iocheckd service “I/O-Check” implements a custom configuration protocol used by WAGO controllers. The iocheckd service “I/O-Check” functionality of WAGO PFC 200 uses an incorrect buffer length when copying system data into a stack buffer when generating a response to the BC_ProductLabel message. When any value is present for the system value QS-STRING, the stack buffer will be overflowed resulting in a crash. Additionally, an attacker can send an unauthenticated packet using the iocheckd protocol to overwrite the QS-STRING value enabling attacker controlled data to overflow this stack buffer. Since the attacker can control the data that is being copied onto the stack, this vulnerability results in remote code execution.
[Annotated Disassembly / Decompilation output]
Here the buffer is allocated on the stack, size 0x20
.text:0001D600 sub_1D600
.text:0001D600
.text:0001D600 s = -0x38
.text:0001D600
.text:0001D600 PUSH {R4-R7,LR}
.text:0001D604 SUB SP, SP, #0x44
.text:0001D608 MOV R7, R0
.text:0001D60C ADD R0, SP, #0x20 ; stack buffer that will be overflowed
.text:0001D610 MOV R4, R1
.text:0001D614 BL sub_13570 ; overflow occurs in this function - snippet below
Here the system value of QS-STRING is copied to the stack buffer - up to 0x40 bytes overflowing the buffer by 0x20 bytes
.text:00013590 STR R0, [R4] ; stack buffer anotated above, size 0x20
.text:00013594 MOV R0, #0x8A4
.text:00013598 STRB R3, [R4,#4]
.text:0001359C MOVT R0, #2 ; r0 = 0x208a4 pointer to data containing 'QS-STRING'
.text:000135A0 BL sub_14B38 ; calls typelabel_SYSTEM_Get
.text:000135A4 SUBS R5, R0, #0
.text:000135A8 BNE loc_135CC
.text:000135AC LDR R6, [SP,#4]
.text:000135B0 MOV R2, #0x40 ; strncpy length is 0x40 when the buffer is 0x20 on the stack
.text:000135B4 MOV R0, R4 ; dest
.text:000135B8 MOV R1, R6 ; src
.text:000135BC BL strncpy
When the function epilogue is entered, the values for pc and r4-r7 are overwritten with the values from the attacker-controlled QS-STRING value
.text:0001D65C loc_1D65C ; CODE XREF: sub_1D600+BC↓j
.text:0001D65C STRB R6, [R4,#4]
.text:0001D660 ADD R0, SP, #0x20
.text:0001D664 BL strlen
.text:0001D668 ADD R3, SP, #0x20
.text:0001D66C MOV R2, SP
.text:0001D670 MOV R1, #0x220E8
.text:0001D678 STRB R0, [R4,#5]
.text:0001D67C ADD R0, R4, #6
.text:0001D680 BL sprintf
.text:0001D684 MOV R3, #0
.text:0001D688 MOV R0, R5
.text:0001D68C STRB R3, [R4,#2]
.text:0001D690 STRB R3, [R4,#3]
.text:0001D694 ADD SP, SP, #0x44
.text:0001D698 POP {R4-R7,PC}
Program received signal SIGSEGV, Segmentation fault.
0x44444444 in ?? ()
(gdb) i r
r0 0xf 15
r1 0x8 8
r2 0xffffffff 4294967295
r3 0x0 0
r4 0x41414141 1094795585
r5 0x41414141 1094795585
r6 0x41414141 1094795585
r7 0x41414141 1094795585
r8 0x91c08 597000
r9 0xb6f7d4e0 3069695200
r10 0x0 0
r11 0x30005 196613
r12 0x220f0 139504
sp 0xbef83cb8 0xbef83cb8
lr 0x1d684 120452
pc 0x44444444 0x44444444
cpsr 0x10 16
fpscr 0x0 0
(gdb) bt
#0 0x44444444 in ?? ()
#1 0x0001d684 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
This vulnerability could be mitigated by disabling the iocheckd service “I/O-Check” via the Web-based management web application.
2019-07-30 - Vendor disclosure
2019-09-06 - 30+ day follow up
2019-10-02 - 60+ day follow up; vendor acknowledged
2019-10-31 - Vendor passed to CERT@VDE for coordination; Talos extended public disclosure deadline
2019-12-16 - Public Release
Discovered by Kelly Leuschner of Cisco Talos