Headline
CVE-2020-6137: TALOS-2020-1080 || Cisco Talos Intelligence Group
SQL injection vulnerability exists in the password reset functionality of OS4Ed openSIS 7.3. The password_stf_email parameter in the password reset page /opensis/ResetUserInfo.php is vulnerable to SQL injection. An attacker can send an HTTP request to trigger this vulnerability.
Summary
Multiple SQL injection vulnerabilities exist in the password reset functionality of OS4Ed openSIS 7.3. A specially crafted HTTP request can lead to SQL injection. An attacker can send an HTTP request to trigger this vulnerability.
Tested Versions
OS4Ed openSIS 7.3
Product URLs
https://opensis.com/
CVSSv3 Score
9.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE
CWE-89 - Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
Details
openSIS is a student information system and school management system. It is available in commercial and open-source versions. It allows schools to create schedules and track attendance, grades and transcripts.
Multiple SQL injections exist in the password reset functionality of openSIS 7.3. A successful attack could allow an attacker to access information such as usernames and password hashes as well as other data stored in the database.
CVE-2020-6137 - password_stf_email parameter
The password_stf_email parameter in the password reset page /opensis/ResetUserInfo.php is vulnerable to SQL injection.
Below is an example post that will trigger the vulnerability:
POST /opensis/ResetUserInfo.php HTTP/1.1
Host: [IP]
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 167
Origin: http://[IP]
DNT: 1
Connection: close
Referer: http://[IP]/opensis/ForgotPass.php
Upgrade-Insecure-Requests: 1
pass_user_type=pass_parent&pass_type_form=password&password_stn_id=&uname=za&month_password_dob=&day_password_dob=&year_password_dob=&pass_email=&password_stf_email=aa[SQL INJECTION]
The vulnerable code for this parameter is also at line 313:
301 if ($_REQUEST['pass_user_type'] == 'pass_parent') {
302 if ($_REQUEST['uname'] == '') {
303 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Username.</b></font>';
304 echo'<script>window.location.href="ForgotPass.php"</script>';
305 }
306 if ($_REQUEST['password_stf_email'] == '') {
307 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Email Address.</b></font>';
308 echo'<script>window.location.href="ForgotPass.php"</script>';
309 }
310
311 if ($_REQUEST['password_stf_email'] != '' && $_REQUEST['uname'] != '') {
312
313 $par_info = DBGet(DBQuery('SELECT p.* FROM people p,login_authentication la WHERE la.USER_ID=p.STAFF_ID AND la.USERNAME=\'' . $_REQUEST['uname'] . '\' AND p.EMAIL=\'' . $_REQUEST['password_stf_em ail'] . '\' AND la.PROFILE_ID = 4'));
314
315 if ($par_info[1]['STAFF_ID'] == '') {
316 $_SESSION['err_msg'] = '<font color="red" ><b>Incorrect login credential.</b></font>';
317 echo'<script>window.location.href="ForgotPass.php"</script>';
318 } else {
319 $flag = 'par_pass';
320 }
321 }
322 }
CVE-2020-6138 - uname parameter
The uname parameter in the password reset page /opensis/ResetUserInfo.php is vulnerable to SQL injection. Below is an example post that will trigger the vulnerability:
POST /opensis/ResetUserInfo.php HTTP/1.1
Host: [IP]
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 167
Origin: http://[IP]
DNT: 1
Connection: close
Referer: http://[IP]/opensis/ForgotPass.php
Upgrade-Insecure-Requests: 1
pass_user_type=pass_parent&pass_type_form=password&password_stn_id=&uname=za[SQL INJECTION]&month_password_dob=&day_password_dob=&year_password_dob=&pass_email=&password_stf_email=aa
The vulnerable code for opensis/ResetUserInfophp is at line 313 is due to a lack of input sanitation leading:
301 if ($_REQUEST['pass_user_type'] == 'pass_parent') {
302 if ($_REQUEST['uname'] == '') {
303 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Username.</b></font>';
304 echo'<script>window.location.href="ForgotPass.php"</script>';
305 }
306 if ($_REQUEST['password_stf_email'] == '') {
307 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Email Address.</b></font>';
308 echo'<script>window.location.href="ForgotPass.php"</script>';
309 }
310
311 if ($_REQUEST['password_stf_email'] != '' && $_REQUEST['uname'] != '') {
312
313 $par_info = DBGet(DBQuery('SELECT p.* FROM people p,login_authentication la WHERE la.USER_ID=p.STAFF_ID AND la.USERNAME=\'' . $_REQUEST['uname'] . '\' AND p.EMAIL=\'' . $_REQUEST['password_stf_em ail'] . '\' AND la.PROFILE_ID = 4'));
314
315 if ($par_info[1]['STAFF_ID'] == '') {
316 $_SESSION['err_msg'] = '<font color="red" ><b>Incorrect login credential.</b></font>';
317 echo'<script>window.location.href="ForgotPass.php"</script>';
318 } else {
319 $flag = 'par_pass';
320 }
321 }
322 }
CVE-2020-6139 - username_stf_email parameter
The username_stf_email parameter in the password reset page /opensis/ResetUserInfo.php is vulnerable to SQL injection.
Below is an example post that will trigger the vulnerability:
POST /opensis/ResetUserInfo.php HTTP/1.1
Host: [IP]
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 162
Origin: http://[IP]
DNT: 1
Connection: close
Referer: http://[IP]/opensis/ForgotPass.php
Upgrade-Insecure-Requests: 1
user_type_form=username&uname_user_type=uname_staff&username_stn_id=1&pass=12&month_username_dob=1&day_username_dob=1&year_username_dob=1994&username_stf_email=1[SQL INJECTION
The vulnerable code in this case is at line 340:
324 if ($_REQUEST['user_type_form'] == 'username') {
325 if ($_REQUEST['uname_user_type'] == 'uname_student') {
326 if ($_REQUEST['username_stn_id'] == '') {
327 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Student Id.</b></font>';
328 echo'<script>window.location.href="ForgotPass.php"</script>';
329 }
330 if ($_REQUEST['pass'] == '') {
331 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Password.</b></font>';
332 echo'<script>window.location.href="ForgotPass.php"</script>';
333 }
334 if ($_REQUEST['month_username_dob'] == '' || $_REQUEST['day_username_dob'] == '' || $_REQUEST['year_username_dob'] == '') {
335 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Birthday Properly.</b></font>';
336 echo'<script>window.location.href="ForgotPass.php"</script>';
337 }
338
339 if ($_REQUEST['username_stn_id'] != '' && $_REQUEST['pass'] != '' && $_REQUEST['month_username_dob'] != '' && $_REQUEST['day_username_dob'] != '' && $_REQUEST['year_username_dob'] != '') {
340 $stu_dob = $_REQUEST['year_username_dob'] . '-' . $_REQUEST['month_username_dob'] . '-' . $_REQUEST['day_username_dob'];
341 $stu_info = DBGet(DBQuery('SELECT s.* FROM students s,login_authentication la WHERE la.USER_ID=s.STUDENT_ID AND la.PASSWORD=\'' . md5($_REQUEST['pass']) . '\' AND s.BIRTHDATE=\'' . date('Y-m-d', strtotime($stu_dob)) . '\' AND s.STUDENT_ID=' . $_REQUEST['username_stn_id'] . ''));
342
343 if ($stu_info[1]['STUDENT_ID'] == '') {
344 $_SESSION['err_msg'] = '<font color="red" ><b>Incorrect login credential.</b></font>';
345 echo'<script>window.location.href="ForgotPass.php"</script>';
346 } else {
347 $get_uname = DBGet(DBQuery('SELECT USERNAME FROM login_authentication WHERE USER_ID=' . $_REQUEST['username_stn_id'] . ' AND PROFILE_ID=3'));
348 $_SESSION['fill_username'] = $get_uname[1]['USERNAME'];
349 echo'<script>window.location.href="index.php"</script>';
350 }
351 }
352 }
CVE-2020-6140 - username_stn_id parameter
The password_stf_email parameter in the password reset page /opensis/ResetUserInfo.php is vulnerable to SQL injection.
Below is an example post that will trigger the vulnerability:
POST /opensis/ResetUserInfo.php HTTP/1.1
Host: [IP]
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 143
Origin: http://[IP]
DNT: 1
Connection: close
Referer: http://[IP]/opensis/ForgotPass.php
Upgrade-Insecure-Requests: 1
user_type_form=username&uname_user_type=uname_student&username_stn_id=1[SQL INJECTION]&pass=12&month_username_dob=1&day_username_dob=1&year_username_dob=1994
The vulnerable code for this issue is at line 365:
353 if ($_REQUEST['uname_user_type'] == 'uname_staff') {
354
355 if ($_REQUEST['pass'] == '') {
356 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Password.</b></font>';
357 echo'<script>window.location.href="ForgotPass.php"</script>';
358 }
359 if ($_REQUEST['username_stf_email'] == '') {
360 $_SESSION['err_msg'] = '<font color="red"><b>Please Enter Email Address.</b></font>';
361 echo'<script>window.location.href="ForgotPass.php"</script>';
362 }
363
364 if ($_REQUEST['username_stf_email'] != '' && $_REQUEST['pass'] != '') {
365 $stf_info = DBGet(DBQuery('SELECT s.* FROM staff s,login_authentication la WHERE la.USER_ID=s.STAFF_ID AND la.PASSWORD=\'' . md5($_REQUEST['pass']) . '\' AND s.EMAIL=\'' . $_REQUEST['username_stf_email'] . '\''));
366
367 if ($stf_info[1]['STAFF_ID'] == '') {
368 $_SESSION['err_msg'] = '<font color="red" ><b>Incorrect login credential.</b></font>';
369 echo'<script>window.location.href="ForgotPass.php"</script>';
370 } else {
371 $get_uname = DBGet(DBQuery('SELECT USERNAME FROM login_authentication WHERE USER_ID=' . $stf_info[1]['STAFF_ID'] . ' AND PROFILE_ID=' . $stf_info[1]['PROFILE_ID']));
372 $_SESSION['fill_username'] = $get_uname[1]['USERNAME'];
373 echo'<script>window.location.href="index.php"</script>';
374 }
375 }
376 }
Timeline
2020-06-02 - Vendor Disclosure
2020-08-13 - Vendor provided patch to Talos for testing
2020-08-17 - Talos confirmed patch resolved issue
2020-08-31 - Public Release
Discovered by Yuri Kramarz of Cisco Talos.