From 6f56b53c3590657de74c7bee4082fa0c2f3f044d Mon Sep 17 00:00:00 2001 From: Jonathan Rose Date: Mon, 23 Apr 2012 14:21:30 +0000 Subject: [PATCH] AST-2012-004: 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. (closes issue ASTERISK-17465) Reported By: David Woolley Patches: 162_ami_readfunc_security_r2.diff uploaded by jrose (license 6182) 18_ami_readfunc_security_r2.diff uploaded by jrose (license 6182) 10_ami_readfunc_security_r2.diff uploaded by jrose (license 6182) git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@363117 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/manager.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/main/manager.c b/main/manager.c index c691f30f4d..9e106fcec3 100644 --- a/main/manager.c +++ b/main/manager.c @@ -415,6 +415,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) { @@ -1918,6 +1931,12 @@ static int action_getvar(struct mansession *s, const struct message *m) 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) { @@ -1985,6 +2004,11 @@ static int action_status(struct mansession *s, const struct message *m) 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 { @@ -2567,6 +2591,24 @@ static int action_originate(struct mansession *s, const struct message *m) } } } else 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) + && ( + strcasestr(app, "system") || /* System(rm -rf /) + TrySystem(rm -rf /) */ + strcasestr(app, "exec") || /* Exec(System(rm -rf /)) + TryExec(System(rm -rf /)) */ + strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) + EAGI(/bin/rm,-rf /) */ + (strstr(appdata, "SHELL") && (bad_appdata = 1)) || /* NoOp(${SHELL(rm -rf /)}) */ + (strstr(appdata, "EVAL") && (bad_appdata = 1)) /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ + )) { + 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; + } res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); } else { if (exten && context && pi)