Package: asterisk / 1:1.6.2.9-2+squeeze12

AST-2012-004 Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
From: Jonathan Rose <jrose@digium.com>
Date: Mon, 23 Apr 2012 14:21:30 +0000
Subject: AST-2012-004: further AMI permission fixes
Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=363117
Bug: https://issues.asterisk.org/jira/browse/ASTERISK-17465

Similar fixes to AST-2011-006. Fixes extra cases.

Fix an error that allows AMI users to run shell commands sans authorization:

As detailed in the advisory, AMI users without write authorization for SYSTEM class AMI
actions were able to run system commands by going through other AMI commands which did
not require that authorization. Specifically, GetVar and Status allowed users to do this
by setting their variable/s options to the SHELL or EVAL functions.
Also, within 1.8, 10, and trunk there was a similar flaw with the Originate action that
allowed users with originate permission to run MixMonitor and supply a shell command
in the Data argument. That flaw is fixed in those versions of this patch.

See Also: http://downloads.asterisk.org/pub/security/AST-2012-004.html

(closes issue ASTERISK-17465)
Reported By: David Woolley

Patch was slightly adapted, as original patch was incorrectly backported
to 1.6.2 .

---
 main/manager.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

--- a/main/manager.c
+++ b/main/manager.c
@@ -401,6 +401,19 @@ static struct permalias {
 	{ 0, "none" },
 };
 
+/*! \brief Checks to see if a string which can be used to evaluate functions should be rejected */
+static int check_user_can_execute_function(const char *evaluating, int writepermlist)
+{
+	if (!(writepermlist & EVENT_FLAG_SYSTEM)
+		&& (
+			strstr(evaluating, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
+			strstr(evaluating, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
+		)) {
+		return 0;
+	}
+	return 1;
+}
+
 /*! \brief Convert authority code to a list of options */
 static char *authority_to_str(int authority, struct ast_str **res)
 {
@@ -1902,6 +1915,12 @@ static int action_getvar(struct mansessi
 		return 0;
 	}
 
+	/* We don't want users with insufficient permissions using certain functions. */
+	if (!(check_user_can_execute_function(varname, s->session->writeperm))) {
+		astman_send_error(s, m, "GetVar Access Forbidden: Variable");
+		return 0;
+	}
+
 	if (!ast_strlen_zero(name)) {
 		c = ast_get_channel_by_name_locked(name);
 		if (!c) {
@@ -1969,6 +1988,11 @@ static int action_status(struct mansessi
 	else
 		idText[0] = '\0';
 
+	if (!(check_user_can_execute_function(variables, s->session->writeperm))) {
+		astman_send_error(s, m, "Status Access Forbidden: Variables");
+		return 0;
+	}
+
 	if (all)
 		c = ast_channel_walk_locked(NULL);
 	else {
@@ -2498,6 +2522,7 @@ static int action_originate(struct manse
 		ast_parse_allow_disallow(NULL, &format, codecs, 1);
 	}
 	if (!ast_strlen_zero(app)) {
+		int bad_appdata = 0;
 		/* To run the System application (or anything else that goes to
 		 * shell), you must have the additional System privilege */
 		if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
@@ -2508,10 +2533,12 @@ static int action_originate(struct manse
 				                                     TryExec(System(rm -rf /)) */
 				strcasestr(app, "agi") ||         /* AGI(/bin/rm,-rf /)
 				                                     EAGI(/bin/rm,-rf /)       */
-				strstr(appdata, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
-				strstr(appdata, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
+				(strstr(appdata, "SHELL") && (bad_appdata = 1)) ||       /* NoOp(${SHELL(rm -rf /)})  */
+				(strstr(appdata, "EVAL") && (bad_appdata = 1))           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
 				)) {
-			astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
+			char error_buf[64];
+			snprintf(error_buf, sizeof(error_buf), "Originate Access Forbidden: %s", bad_appdata ? "Data" : "Application");
+			astman_send_error(s, m, error_buf);
 			return 0;
 		}
 	}