ProProfs is riddled with bugs

Hacking user-base of 1,214,000+ including Sony, Dell, Cisco, DHL, Yale, University of Phoenix

Piyush Raj ~ Rex
4 min readJul 9, 2020

Original timeline: August 2018 — September 2020

I remember last year (2018) getting all frustrated by those idiotic subjects which don’t made any sense to what I was interested in and thus, I loved making final year projects, completing company recruitment challenges and solving quizzes of seniors. If interested, you can visit my personal blog where I publish those mushy blogs, one of them is “Relating Every Subject To Computer Science In My Freshmen Year”. I named my blog, Tinkernel — Tinkering the kernel. Dope, right?

Let’s continue, shall we?

Anyways, soon, I got to know our university uses a website named Proprofs for taking quizzes, and boy, it looked nasty.

One fine day, I was about to give a quiz, for one of my seniors, I was waiting for the portal to open up as quizzes were password protected and professors used to send the intended password to students through messages and then the process was easy, fill in the password, voila —

quiz time baby

While I was waiting, I got an urge to see the source, just so, you know. Wait, why the right click is not responding? Maybe I broke the key?

Ah, wait, that old context menu trick? Okay just let me handle that —

javascript:void(document.oncontextmenu=null);

Okay, so, where were we, oh yeah, let’s see…

<div class=””>
<strong>Password</strong><br>
<input class=”user_pass” name=”quiz_pwd” autocomplete=”off” id=”quiz_pwd” value=”” type=”password” style=” “>
<input name=”quiz_correcr_pwd” type=”hidden” id=”quiz_correcr_pwd” value=”5d41402abc4b2a76b9719d911017c592">&nbsp;
<input name=”password_validate” type=”hidden” id=”password_validate” value=”Password you entered is incorrect”>&nbsp;
</div>

The related JavaScript block having quote unquote “check” implemented —

if(quiz_required_pwd==1)
{var quiz_pwd=document.getElementById(“pquiz_pwd”).value;var quizpwd=md5(quiz_pwd);var quiz_correcr_pwd=document.getElementById(“pquiz_correcr_pwd”).value;if(quiz_pwd==’’)
{alert(“Password you entered is incorrect. “);document.quizpwdForm.pquiz_pwd.focus();return false;}

Good lord!, client-side password validation!!??

The rule when writing a server application is simply never trust what comes from client. Checks done client side are great as they allow a nice user experience with nice popups and immediate display. But as anything can happen, from a disabled JavaScript browser to a user using a scripting language to simulate a browser, all checks must be done (again) server side.

I mean..., it is what it is, I can just take the MD5 hash, pass it to John the Ripper —

https://www.youtube.com/watch?v=ItFi_08B4wc

Easy.

And that was it, everyone was happy getting the password way before the time, because some profs. didn’t set both start-time & password limits, they just set the time-duration & end-time and gave passwords to initiate the quizzes.

Fast forward to this year, now, my friends wanted to cheat so, I just thought why not surf the target again for fun’s* sake.

Revisiting targets enormously help in the introspection of oneself’s what I call “knowledge timeline”

Obviously, cheating is bad, and I don’t like cheating. *coughs* Okay, okay, I don’t like cheating in subjects I genuinely love. But, why not check the strength of a system?

Revisiting the target

To have a better view, I was able to create a trial quiz creation account, setup a quiz and started to analyse how everything works under-the-hood.

There was lots and lots of scary things going on, like, i stumbled upon a custom API which can be used to automate logging in and to carry out various Learning Management System (LMS) actions. The API key was also hashed with MD5 which when decrypted popped a 6-digit string and well, …

I didn’t tried to exploit it as it wasn’t being used in our university, so, it went to the famous “out-of-scope” category.

Say My Name And Get Pwned!

The persistent (or stored) XSS vulnerability is the most devastating variant of a cross-site scripting flaws. And I found just that.

The most funny thing is, the vulnerable vector was the “Enter Name” input, hence the title. Now, I can’t really lay out comprehensive details and honestly, no input sanitization/validation was happening so, it was basically a high severity low hanging fruit, anyways, I sure can share a lovely proof-of-concept which deleted whole quiz’s marks data as soon as the victim viewed the submitted quiz having the payload given below —

pwn = () => {
document.querySelector(‘.checkbox_css’).click()
document.querySelector(‘.delete_confirm’).click()
document.querySelector(‘.proceed-btns’).click()
}
pwn();

I think, waiting for almost one year before doing public disclosure is a good rule of thumb. Yeah. I should stop finding vulnerabilities in companies who don’t even have a responsible disclosure section.

Hey, remember about my personal blog that I told above?
Still interested to peep? — Here you go — Tinkernel.

--

--

Piyush Raj ~ Rex

Google Code-In C. Winner. GsOCer ‘19. Independent Security Researcher. Have hacked Medium, Mozilla, Opera & many more. Personal Website: https://0x48piraj.com