SOLV-DB - Runner ID changeable (#mvid2)

Document Title:
===============
SOLV-DB - Runner ID changeable


mosi Vulnerability ID (mvid):
===============
2


Discovery Status:
=============
No Fix


CVSSv2 Overall Score:
===============
6.1


CVSSv2 Vector:
==============
(AV:N/AC:M/Au:S/C:N/I:C/A:N/E:POC/RL:U/RC:C/CDP:L/TD:H/CR:L/IR:M/AR:H)
https://nvd.nist.gov/cvss.cfm?calculator&version=2&vector=(AV:N/AC:M/Au:S/C:N/I:C/A:N/E:POC/RL:U/RC:C/CDP:L/TD:H/CR:L/IR:M/AR:H)


Product & Service Introduction:
==============
The SOLV-DB is a central runner database used for simplifying the organisation and registration of runners for orienteering competitions in Switzerland and is provided by the Swiss Orienteering federation.
Every runner has it's own runner ID, which is central for the registration on events.


Abstract:
==============
Simon Monai found a vulnerability in the database form, so he could change the runner's ID.


Report Timeline:
==============
2016-11-29 - Vendor information
2016-12-13 - Vendor reminder
2016-12-13 - Vendor acknowledgement
2016-12-13 - Vendor will not fix vulnerability
2016-12-18 - Public Disclosure


Affected Products:
=============
Swiss Orienteering Runner's Database - Online Form


Exploitation Technique:
=============
HTTP Form Manipulation (Remote)


Security Level:
=============
Medium


Technical Details & Description:
=============
Request method (s):
[+] GET (Possible, not used)
[+] POST

Vulnerable Module(s):
[+] http://www.o-l.ch/cqi-bin/solvdb

Vulnerable File(s):
[+] (None)

Vulnerable Parameter(s):
[+] solvnr

Depending Product(s):
[+] http://www.go2ol.ch


Proof of Concept (PoC):
=============
After login with the user credential on http://www.o-l.ch/cgi-bin/solvdb (nothing but a POST form with the SOLVID and other predefined information) following (simplified) form is loaded:

<form name="competitor" method="POST" action="/cgi-bin/solvdb">
<table width="800" border="0" cellspacing="0" cellpadding="1" bgcolor="#eeeeee">
<tbody>
<tr>
<td>SOLV-Nr:</td>
<td>
<input type="text" size="9" name="solvnr" value="AA1BBB" onfocus="setTimeout('document.competitor.solvnr.blur()',1);">
</td>
<td>SI-Card:</td>
<td>
<input type="text" size="8" maxlength="8" name="sinr" value="1234567">
</td>
<td>IOF Athlete ID:</td>
<td>
<input type="text" size="8" maxlength="8" name="iofid" value="0">
&nbsp;&nbsp;
</td>
</tr>
<tr>
<td>Geschl.:</td>
<td>
<select name="sex" size="1">
<option value="-">-</option>
<option selected="selected" value="M">M</option>
<option value="F">F</option>
</select>
</td>
<td>Vorname:</td>
<td>
<input type="text" size="28" name="fname" value="Hans">
</td>
<td>Nachname:</td>
<td>
<input type="text" size="28" name="lname" value="Muster">
</td>
</tr>
<tr>
<td>Geb.jahr:</td>
<td>
<input type="text" size="5" name="yob" value="1990">
</td>
<td>Address1:</td>
<td>
<input type="text" size="28" name="addr1" value="Musterweg 1">
</td>
<td>Address2:</td>
<td>
<input type="text" size="28" name="addr2" value="">
</td>
</tr>
<tr>
<td>Land:</td>
<td>
<select name="rescntry" size="1">
<option value="-">-</option>
<option selected="selected" value="CH">CH</option>
<option value="AT">AT</option>
<option value="DE">DE</option>
<option value="FR">FR</option>
<option value="IT">IT</option>
</select>
</td>
<td>
PLZ/
<a href="javascript:chooseWindow('/cgi-bin/solvdb?&amp;sessid=725gQBBZBOp4I'+'&amp;choose=1&amp;plz=0')">
Ort
</a>
:
</td>
<td>
<input type="text" size="5" name="plz" value="0000" onchange="changePlz(this.form)" onfocus="checkCountry();">
<input type="text" size="22" name="city" value="Musterdorf" onfocus="checkCountry();">
</td>
<td>Kanton:</td>
<td>
<input type="hidden" name="kt" value="ZH">
TG&nbsp;
Region:&nbsp;
<input type="hidden" name="rg" value="ZH">
OS
</td>
</tr>
<tr>
<td>Kategorie:</td>
<td>
<select name="categ" size="1">
<option value="-">-</option>
<option value="DE">DE</option>
<option value="DAL">DAL</option>
<option value="DAM">DAM</option>
<option value="DAK">DAK</option>
<option value="DB">DB</option>
<option value="HE">HE</option>
<option value="HAL">HAL</option>
<option selected="selected" value="HAM">HAM</option>
<option value="HAK">HAK</option>
<option value="HB">HB</option>
<option value="OL">OL</option>
<option value="OM">OM</option>
<option value="OK">OK</option>
</select>
</td>
<td>Club:</td>
<td>
<select name="club" size="1">
<option value="-">-</option>
<option value="clubname1">clubname1</option>
<option value="clubname2">clubname2</option>
<option value="clubname2">clubname3</option>
<option value="clubname2">clubname4</option>
</select>
</td>
<td>Nation:</td>
<td>
<select name="cntsh" size="1">
<option value="-">-</option>
<option selected="selected" value="SUI">SUI</option>
<option value="AUT">AUT</option>
<option value="FRA">FRA</option>
<option value="GER">GER</option>
<option value="ITA">ITA</option>
<option value="LIE">LIE</option>
</select>
</td>
</tr>
<tr>
<td colspan="2">&nbsp;</td>
<td>Dop. Stat:</td>
<td>Ja, 2016-01-22
<input type="hidden" name="dopstat" value="1">
<input type="hidden" name="dopstatdate" value="2016-01-22">
</td>
<td>E-Mail:</td>
<td>
<input type="text" size="28" name="email" value="Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!">
</td>
</tr>
<tr>
<td colspan="2">&nbsp;</td>
<td>ID=11111
<input type="hidden" name="id" value="11111">
</td>
<td>&nbsp;</td>
<td>Mobile-Nummer:</td>
<td><input type="text" size="16" maxlength="16" name="mobile" value="0761234567"></td>
</tr>

<input type="hidden" name="subsc" value="0">
<input type="hidden" name="flags" value="0">
<input type="hidden" name="rem" value="">

<tr bgcolor="#cccccc">
<td colspan="3">
<input type="hidden" name="user" value="1">
<input type="submit" value="&nbsp;Submit&nbsp;">
<input type="reset" value="Reset">
</td>
<td>Creation: 2010-01-01</td>
<td>LastMod:</td>
<td>
2015-01-15 09:33:08 laubeh&nbsp;&nbsp;
<a href="http://map.search.ch/0000-Musterdorf/Musterweg%201">map</a>
</td>
</tr>

<input type="hidden" name="competitor" value="modi">
<input type="hidden" name="letter" value="M">
</tbody>
</table>

<input type="hidden" name="sessid" value="725gQBBZBOp4I">
</form>

Every available user information from the Database is transmitted to the client using input fields. This includes the SOLV-ID (or in German solvnr). The user is prevented to change the value only with a crazy JavaScript function in the onfocus event that moves the cursor out of that field.
Anyways, this does not prevent to change the value in the source code or the generated request. In case that the client has JavaScript disabled, this protection is also useless.

The problem itself comes with the submission of the request. In case that the SOLV-ID had been modified, the server will write the changes to the database table of unapproved updates. If the administrator approves now the update, the changes are permanent in the productive system. The data integrity is affected.

 

Possible Solution:
============
The input field for the ID should generally be disabled instead of using JavaScript (that could be disabled on the client, for example by an add-on like NoScript) to move the cursor outside the field.
Further the server should not accept the user provided ID, but use the one stored in the local session variable.


Security Risk:
============
The security risk is estimated as medium (CVSSv2 6.1).
The fact, that there is a second instance checking the integrity of the data slightly weakens the vulnerability.


Author / Credits:
============
mosi security research - Simon Monai (http://jongliertricks.ch/kontakt)


Public Disclosure:
============
2016-12-18 - https://jongliertricks.ch/mosi-security-research/35

----------------------------
https://jongliertricks.ch/mosi-security-research