entry.picoevents.ch – SOLV-DB exploit (#mvid1)

Document Title:
===============
entry.picoevents.ch – SOLV-DB exploit


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


CVSSv2 Overall Score:
===============
5.7


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


Product & Service Introduction:
==============
picoEvents provides an online registration and live result service to simplify the timekeeping in orienteering combined with SPORTident.
http://picoevents.ch/


Abstract:
==============
Simon Monai found a vulnerability in the source code of the registration formular. Using the exploit it is possible to gain the runner’s SOLV-ID* and his mail address apart of other information.

* The SOLV-ID is an unique identifier used for the runner’s database of the Swiss orienteering federation (SOLV).


Report Timeline:
==============
2016-08-31: Vendor information
2016-09-30: Vendor reminder
2016-09-30: Vendor response, asking for further information
2016-10-17: Further information submitted, vendor response
2016-10-31: Patch release
2016-10-31: Patch approved by mosi security research
2016-11-04: Public Disclosure


Discovery Status:
=============
Patched - Public Disclosure


Affected Products:
=============
picoEvents entry form


Exploitation Technique:
=============
Remote


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


Technical Details & Description:
=============
Some privacy violating information is included
Request Method(s):
[+] GET

Vulnerable Module(s):
[+] http://picoevents.ch/entry/

Vulnerable File(s):
[+] anmeldung2.php

Vulnerable Parameter(s):
[+] solvnr
[+] mail


Proof of Concept (PoC):
=============
After choosing the event on the main page (http://entry.picotiming.ch/) a first register page is shown after a request with the url http://picoevents.ch/entry/regist/anmeldung.php?recordID=171 (recordID vary depending event).
Following form is loaded:

<form id="form1" method="get" action="anmeldung2.php">
<input type="text" name="lastname" value="" size="25" autocomplete="off">
<input type="text" name="firstname" value="" size="25" autocomplete="off">
<input type="submit" name="sendsolv" id="sendsolv" value="weiter"></td>
</form>

With entering the runner’s personal last (Muster) and first name (Hans) following url will be generated:
http://picoevents.ch/entry/regist/anmeldung2.php?lastname=Muster&firstname=Hans&sendsolv=weiter&recordID=171

Be aware that this get request could be generated by a bot using some runner information collected for example from official rankings.

The request generated above generates following response (only essential code reported):
<form action="/entry/regist/anmeldung2.php?lastname=Muster&amp;firstname=Hans&amp;sendsolv=weiter&amp;recordID=171" method="post" id="form3">
Name*: <input type="text" name="Name" value="Muster" size="25" autocomplete="off">
Vorname*: <input type="text" name="Vorname" value="Hans" size="25" autocomplete="off">
Geschlecht*:<input type="text" name="sex" value="M" size="4">

<!-- DopingStatut und IOF-ID immer hidden übergeben -->

<input type="hidden" name="DopSt" value="1">
<input type="hidden" name="IOFID" value="0">
<!-- <input type="hidden" name="mobile" value="0761234567" /> -->

Jahrgang*: <input type="text" name="Jahrgang" value="1970" size="25"></td>
Kategorie*:
<select name="Kategorie" id="Kat">
<option value="D20">D20</option>
<option value="DE">DE</option>
<option selected="selected" value="N/A">bitte wählen...</option>
<option value="H20">H20</option>
<option value="HE">HE</option>
</select>
Wohnort* (ohne PLZ):
<input type="text" name="Wohnort" value="Zürich" size="25" autocomplete="off">
Club: <input type="text" name="Club" value="OLG Noname" size="25">
SI-Card-Nummer:
<input type="text" name="sicard" value="1230321" size="25" autocomplete="off">
SOLV-Nummer*:
<input name="solvnr" type="hidden" class="grossbuchstaben" value="AB1MUH" size="8" maxlength="6" autocomplete="off">
<p>wird nicht angezeigt, aber übergeben<p>
Mailadresse*:
<input type="hidden" name="mail" value="Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!" size="32">
<p>nicht angezeigt, aber übergeben</p>
Bemerkungen:<input name="bemerkungen" type="text" id="comment" value="" size="32">
MutationsPasswort* (Gebdatum TTMMJJ):
<input name="passwort" type="text" value="" size="8" maxlength="6" autocomplete="off">

<!-- recordID -->
<input type="button" onclick="window.location.href= ' anmeldung.php?recordID=170 '" value="zurück zum leeren Formular"></td>

<input type="submit" value="anmelden">
<input type="hidden" name="MM_insert" value="form3">
</form>

Even though the mail address and the solv-id are not displayed on the site, a user analyzing the source code can extract all those informations.

Possible Solution:
============
It is strongly recommended to use sessions on the server side and to do not send the SOLV-id nor the mail address across the internet.
As less performant solution (but easier to implement) it is recommended to run the SQL query twice. The first time you get the necessary information to let the customer fill out the form, and the second request to handle the SOLV-id and mail address without storing it on the client side.
Additionally it is highly recommended to use ssl encryption by loading the page to prevent sniffing of the user’s data and gain speed with the new standard http/2.


Security Risk:
============
Medium with high exploitability (CVSSv2 5.8)


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


Public Disclosure:
============
2016-11-30 - https://jongliertricks.ch/mosi-security-research/34


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