Exploit-DB #42187
Description: IBM Informix Dynamic Server - Code Injection / Remote Code Execution
Type: webapps
Platform: linux
Date: 2017-06-16
Author: IMgod

Exploit:
#!/usr/local/bin/python
"""
IBM Informix Dynamic Server doconfig PHP Code Injection Remote Code Execution Vulnerability (0DAY)
Bonus: free XXE bug included!
Download: https://www-01.ibm.com/marketing/iwm/iwm/web/reg/download.do?source=swg-informixfpd&S_PKG=dl&lang=en_US&cp=UTF-8&dlmethod=http
Twitter: https://twitter.com/rgod777
Found by: IMgod aka rgay

About:
~~~~~~

So after Andrea Micalizzi decided to audit this software and found some bugs I decided to audit it too. (see https://blogs.securiteam.com/index.php/archives/3210)
What's that? Where is all your main frame, super 1337 hacks now rgod? Why did you miss these 3 bugs?

- unauthed XXE
- unauthed SQLi
- unauthed RCE

Your ub3r 31337 PHP hacks are soooooooooooo cool, maybe you should commit seppuku again. Or maybe you should have taken one of the 143 jobs you were offered? Cos I'm about to rekt dis cunt.

Vulnerable Code:
~~~~~~~~~~~~~~~~

Of course, rgod misses this bug in openadmin/admin/index.php:

$admin->run();                                                                  // 1. calls run()

$idsadmin->html->render();

        function run()
        {

                if ( isset ( $this->idsadmin->in['helpact'] )
                && $this->idsadmin->in['do'] != "doedithelp"
                && $this->idsadmin->in['do'] != "doaddhelp" )
                {
                        header("Location: {$this->idsadmin->get_config("BASEURL")}/index.php?act=help&helpact={$this->idsadmin->in['helpact']}&helpdo={$this->idsadmin->in['helpdo']}");
                        die();
                }

                if ( isset($this->idsadmin->in['lang']) )
                {
                    // If the user has changed the language, set the new language now.
                    $this->idsadmin->validate_lang_param();
                    $this->idsadmin->phpsession->set_lang($this->idsadmin->in['lang']);
                }

                switch( $this->idsadmin->in['do'] )                                                         // 2. switch our do parameter
                {
                        case "getconnections":
                                if ( ! isset($this->idsadmin->in['group_num']) )
                                {
                                        $grpnum = 1;
                                }
                                else
                                {
                                        $grpnum = $this->idsadmin->in['group_num'];
                                }
                                $this->getconnections($grpnum);
                                break;
                        ...

                        case "doconfig":
                                $this->idsadmin->html->set_pagetitle($this->idsadmin->lang("OATconfig"));
                                $this->doconfig();                                                          // 3. calls doconfig
                                break;

Now, onto the doconfig function:

        function doconfig()
        {
                // None of the config parameters can contain quotes.
                foreach ($this->idsadmin->in as $i => $v)
                {
                        if (strstr($v,"\"") || strstr($v,"'"))
                        {
                                $this->idsadmin->load_lang("global");
                                $this->idsadmin->error($this->idsadmin->lang("invalidParamNoQuotes",array($i)));
                                $this->config();
                                return;
                        }
                }

                $conf_vars = array (
        "LANG"         => $this->idsadmin->lang("LANG")
        ,"CONNDBDIR"    => $this->idsadmin->lang("CONNDBDIR")
        ,"BASEURL"      => $this->idsadmin->lang("BASEURL")
        ,"HOMEDIR"      => $this->idsadmin->lang("HOMEDIR")
        ,"HOMEPAGE"     => $this->idsadmin->lang("HOMEPAGE")
        ,"PINGINTERVAL" => $this->idsadmin->lang("PINGINTERVAL")
        ,"ROWSPERPAGE" => $this->idsadmin->lang("ROWSPERPAGE")
        ,"SECURESQL"    => $this->idsadmin->lang("SECURESQL")
        ,"INFORMIXCONTIME"      => $this->idsadmin->lang("INFORMIXCONTIME")
        ,"INFORMIXCONRETRY"     => $this->idsadmin->lang("INFORMIXCONRETRY")
        );

        # create backup of file
        $src=$this->idsadmin->get_config('HOMEDIR')."/conf/config.php";
        $dest=$this->idsadmin->in['HOMEDIR']."/conf/BAKconfig.php";
        copy($src,$dest);
        # open the file
        if (! is_writable($src))
        {
                $this->config($this->idsadmin->lang("SaveCfgFailure"). " $src");
                return;
        }
        $fd = fopen($src,'w+');                                                                 // 4. get a handle to a php file
        # write out the conf
        fputs($fd,"<?php \n");
        foreach ($conf_vars as $k => $v)
        {
                if ($k == "CONNDBDIR" || $k == "HOMEDIR")
            {
                // Replace backslashes in paths with forward slashes
                $this->idsadmin->in[$k] = str_replace('\\', '/', $this->idsadmin->in[$k]);
            }
                $out = "\$CONF['{$k}']=\"{$this->idsadmin->in[$k]}\";  #{$v}\n";                // 5. dangerous
                fputs($fd,$out);                                                                // 6. PHP Injection
        }
        fputs($fd,"?>\n");
        fclose($fd);

        $this->idsadmin->html->add_to_output($this->idsadmin->template["template_global"]->global_redirect($this->idsadmin->lang("SaveCfgSuccess"),"index.php?act=admin"));

        } #end config

I suspect Andrea missed this bug because of this code:

                // None of the config parameters can contain quotes.
                foreach ($this->idsadmin->in as $i => $v)
                {
                        if (strstr($v,"\"") || strstr($v,"'")