[asterisk-users] Executing shell commands via AMI

Tzafrir Cohen tzafrir.cohen at xorcom.com
Thu Mar 17 06:28:27 CDT 2011


On Wed, Mar 16, 2011 at 01:33:24PM -0500, Tilghman Lesher wrote:
> On Wednesday 16 March 2011 13:14:40 Vinícius Fontes wrote:
> > action: command
> > command: ! /bin/ls -l /
> 
> For security reasons, you cannot do this.  This is intentional, not a bug.
> Consider the command 'rm -rf /' for the reason why.

I would not call this "security reasons". '!' does not run a shell
command by the Asterisk host. It allows the remoet Asterisk guest to
escape to a shell.

You might as well have run 'system("rm -rf /")' on the local client
connecting to the manager interface.

        if (s[0] == '!') {
                if (s[1])
                        ast_safe_system(s+1);
                else
                        ast_safe_system(getenv("SHELL") ?
getenv("SHELL") : "/bin/sh");
        } else
                ast_cli_command(STDOUT_FILENO, s);

I'm root. Asterisk runs as user asterisk. '!' runs commands as user
root.

sweetmorn:~# id -a
uid=0(root) gid=0(root) groups=0(root)
sweetmorn:~# ps u `cat /var/run/asterisk/asterisk.pid `
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
asterisk 24280  0.6  0.6 122312 12620 ?        Ssl  13:25   0:00 /usr/sbin/aster

sweetmorn:~# asterisk -r
[snip]
sweetmorn*CLI> !id -a
uid=0(root) gid=0(root) groups=0(root)




Asterisk does have an extra check for manager commands that may
potentially allow a remote user to inject a system command:

  /* 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") ||       /* NoOp(${SHELL(rm -rf /)})  */
                  strstr(appdata, "EVAL")           /* 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.");

So indeed 'write=command' was not enough here. write='command,system' is
more like it. If you know what you're doing (or have a system to play
with, or whatever).


Also note that if you run Asterisk as a non-root user, system() will not
make the code magically run as root. Did I mention you should avoid
running Asterisk as root?

-- 
               Tzafrir Cohen
icq#16849755              jabber:tzafrir.cohen at xorcom.com
+972-50-7952406           mailto:tzafrir.cohen at xorcom.com
http://www.xorcom.com  iax:guest at local.xorcom.com/tzafrir



More information about the asterisk-users mailing list