How to Hack Conjuemos – A Client-Side Input Validation Tragedy
Disclaimer: All exploitation writeups published on Endure Secure’s website, should never be used against an application, without the explicit, written, consent of someone who is authorised to approve security testing against that application. Writeups are published for educational purposes only.
Introduction
Conju-gue-what??? For those reading this wondering what on earth I’m talking about, this post is the story of a language learning platform which has a history of input validation issues that are possibly still present to this day. Conjuguemos is a Spanish word which means “let’s conjugate”, which if you’re a native English speaker, and you don’t know what that is, it’s is the process of determining the right form of a verb to use in a sentence. For example, “I do”, “he does”, are two examples of conjugating the verb “to do” in English. It’s important to understand this to understand the background of Conjuguemos.
Languages like Spanish, French, and German, have far more complex conjugations than the English language, and so this platform was initially set up to help students studying one of these languages master the difficult world of conjugations. According to the about us page, Conjuguemos was started in 2000 by a Spanish teacher in the US. Software built in the early 2000s seldom understood, let alone prioritised cybersecurity. This being said many older products have retrospectively secured their code as security has become more of a focus, mainly in the last decade.
At the time this article was written, the education industry lacked regulations around securing IT software and infrastructure. Conjuguemos falls into this industry.
My High School Struggle
I was introduced to this platform in 2011 when I was in High School. I was studying Spanish, and while I genuinely enjoyed learning Spanish as a language in High School, there were times I was so busy with homework and extracurricular activities, that it was hard to find the time to do all my homework.
For context, it was a weekly requirement for my Spanish class to use Conjuguemos to conjugate 200 verbs, and translate 200 sentences. In both cases it was a requirement to get over 80% on both. So if you translated 200 verbs, but only getting 70%, you would have to keep going until you reached an 80% pass rate became pretty exhausting. So in some cases you would end up translating 250 – 300 verbs.
Don’t get me wrong, this is a very effective way to teach vocabulary and conjugations, but it’s time consuming.
If my high school Spanish teacher, were to read this, his eyes would be glued to the screen by now. Note that I never did anything dodgy in high school, and to this day I remember to add upside-down question marks to my Spanish sentences. But that didn’t mean I wasn’t curious about Conjuguemos from a security perspective.
Script Kiddies and Google
As a teenager I learnt how to hack WEP wireless networks, torrent files, download the Tor web browser, and I was programming “Hello World” in C#, so naturally I was an expert at exploiting client-side vulnerabilities in JavaScript right? Well despite client-side vulnerabilities being easy to exploit, unfortunately I was not even that advanced.
Well, that didn’t stop me trying. Like any good script kiddie I started Googling how to hack Conjuguemos. What’s amusing is that the search results are still around.
A Trilogy of Errors
Sometime in late 2011, after being exposed to Conjuguemos, I began my journey. I found a couple of tips on answers.com.
I came across two different methods that were supposed to work.
1. Exploit Code
Reference: https://www.answers.com/computer-science/Are_there_any_hacks_for_conjuguemos
checkAnswer() {attempted = 101; correct = 92; }
I love how simple this is, while it didn’t work for me, you could set client-side variables to determine your score. Without doing a single translation, you could get 100%.
Now apparently in 2012 it became even easier.
2. Exploitation Instructions
Reference: https://www.answers.com/computer-science/How_do_you_hack_conjuguemos
Click Start
Enter any answer
>> Print results
Highlight Score (8/10 80%)
Right Click> Inspect Element
>> Edit Text (right click)
Highlight Time (05:00)
Right> Click Inspect Element
-Edit text (right Click)
Then enjoy your new "score"
Updated and works 1/30/2012
Now if you need help understanding this, in Conjuguemos you would start your translation, and you could stop at any time. The idea being your teacher would assign you a number of them to do, and upon submitting your answers and percentages, it would show the teacher how many you had done. This made it very easy for the teacher, and why one of the variables in the first exploit is called “attempted”. In this second exploit you would begin your translation and submit one, correct or not, a button would appear on your screen called “Print results”. This would take you to a pre-submit screen with your results. At this point you could change the text through Inspect Element, before submitting your score. This exploit was not valid for long, and once again I never benefitted from it.
In 2012 Conjuguemos had clearly entered a battle with script kiddies exploiting client-side code. However, they were fighting pebbles with cardboard. In May 2012 another exploit was released, with was far greater in complexity than the first 2.
3. Exploit Code – The First JavaScript
Reference: https://community.wemod.com/t/conjuguemos-auto-complete-script/2210
if (start == 0)
{
if (activityType == "vocabulary") {
jQuery.ajax('/au.php?x=sa&t='+activityType);
randomizeList("yes");
setvariable();
}
else if (activityType == "verbs") {
jQuery.ajax('/au.php?x=sa&t='+activityType);
howToSelectVerbs('yes');
setvariable();
} else {
jQuery.ajax('/au.php?x=sa&t='+activityType);
}
}
var getCorrect = parseInt(prompt("How many would you like to get correct?", 1));
var getIncorrect = parseInt(prompt("How many would you like to get incorrect?", 1));
var qTime = parseInt(prompt("How much time would you like each question to take? (in seconds)", 33));
var totalSecs = (getCorrect + getIncorrect) * qTime;
tmin = Math.round(totalSecs / 60);
tsec = Math.round(totalSecs % 60);
if(tmin > 59)
{
tmin = 59;
tsec = 58;
}
var yi = 0;
for(yi = 0; yi < getIncorrect; yi++)
{
$('#response').val(solution + yi);
verifyAnswer();
$("#form").submit();
}
for(yi = 0; yi < getCorrect; yi++)
{
$('#response').val(solution);
verifyAnswer();
$("#form").submit();
}
stopClock();
alert("Done! Click 'Print Results', check your results, and if all is good click 'Record/send results'.
Create by Stevie Hetelekides.");
I distinctly remember this script. It prompts thrice and asks how many you’d like to answer, how many you’d like to get right, and how long you took per question. Pretty smart, as no one get 100%, and takes 1 second to guess. But what I remember most about this script, was I did execute it, it changed my score, and then I received a JavaScript pop up saying:
“Stop trying to hack us.”
Conjuguemos – 2012
As a script kiddie, that was enough to scare me away; however, I’m retrospectively disappointed in myself, that my journey ended there.
I no longer have access to the proprietary platform, since I graduated high school, but from time to time I still google “How to hack conjuguemos”. Funnily enough JavaScript exploits still rule, with the most recent exploit being written in 2020.
Exploit 4 – The More Recent JavaScript
Reference: https://gist.github.com/SitanHuang/740ed6925e1826bc52d3becbf24aa7df
(function () {
window._storage = {};
window._storage2 = {};
window.lastQ = null;
window.tick = function (i) {
var $exercise = $('#exercise');
var q = $('#pronoun-input, #verb-input').text().trim();
var v = $('#verb-input').text().trim();
if (q) {
if (_storage[q]&&_storage[q].trim().length) {
$('#answer-input').val(_storage[q]);
$('#check-button').click();
} else {
if (lastQ == q) {
_storage2[v]=_storage2[v].filter(x=>x.length);
x = _storage2[v][Math.round(_storage2[v].length * Math.random())];
$('#answer-input').val(x);
$('#check-button').click();
setTimeout(function () {if ($('.js-bubble.coqui-test-bubble.incorrect').length==0){_storage[q]=x;lastQ=null};tick(i)}, i);
return;
}
$('#answer-input').val(Math.random()+'');
$('#check-button').click();
setTimeout(function(){ _storage[q] = $('.js-bubble.coqui-test-bubble.incorrect span').text().trim();
if (!_storage2[v]) _storage2[v] = [];
_storage2[v].push(_storage[q]);
lastQ=q;
setTimeout(function () {tick(i)}, i);
}, 30);
return;
}
tick(i);
return;
}
/*q = $exercise.find('.ac-section:first-child').text().trim();
if (_storage[q]) {
$('#answer-input').val(_storage[q]);
$('#check-button').click();
} else {
$('#answer-input').val('a'+Math.random());
$('#check-button').click();
_storage[q] = $('.js-bubble.coqui-test-bubble.incorrect span').text().trim();
}*/
}
window.start = function (i) {
tick((i || 1000) + 50);
// i = i || 300;
// var id = setInterval(window.tick, i+50);
// setTimeout(function () {clearInterval(id)}, 4*60*1000);
}
})()
I’m not going to write up an analysis of this code, but using the links you can read comments, and apparently this had been built for a specific student’s needs.
In December 2021, someone had the guts to build a chrome extension which autocompletes Conjuguemos. You can find it here, as of February 2023, it was still available for download.
https://chrome.google.com/webstore/detail/conjuguemos-autocomplete/kegahjgfiaoioefjffcjbjccmeffalbj
How to Hack Conjuguemos in 2023
Based on the kinds of exploits written, there is nothing crazy about them. They are all client-side exploits, which says to me that this is a problem that exists because of the dependency on client-side code. Applications written 15-20 years ago, didn’t have the same guidance as modern applications.
Getting Access
The first thing I needed to do was get access to the platform. Fortunately, you can sign up for a low-tier, “independent teacher” account for $0. So that’s what I did.
The Attack
At this point, I opened BurpSuite, and swapped to the built-in Burp-Suite browser. As a teacher I was able to add student accounts, and create activities. So I created a basic verb conjugation activity called “Nunca Descripcion” (No description). I also created a student user “Billy”. The below screenshot shows me logged into Billy’s account, and I can see the graded activity assigned to me.
By clicking on the activity, I was present with a timer for how long I wanted to do the activity, I set it to 1 minute.
After commencing the activity, I turned BurpSuite’s interceptor on, and could see that there were no requests being made during the activity. I finished the activity, and got a score of 1/4 (25%).
After the time ran out, I was able to save my results, which triggered a request, which BurpSuite was able to intercept. In the raw request I identified the parameters “total_attempts” and “valid_attempts”
The value of “total_attempts” was “4” and the value of “valid_attempts” was 1. This makes sense as I answered 1/4 questions correctly. However another field interested me which is the “attempts” field.
I decoded the URL-encoded string in BurpSuite which decoded to an array of my answers.
If the server validates the answers, then changing “valid_attempts” would be futile. While I could updated the attempts, then that would mean I’d have to know the correct answers, making the whole point of this attack pointless.
Nonetheless, I decided to follow my initial hunch, so I changed the value of “valid_attempts” to 4, and submitted the request, and was able to get 100%. Alas the “valid_attempts” parameter was a red herring.
Closing Thoughts
Conjuguemos is truly a wonderful platform; however, I can’t help but imagine that this issue would be pretty prevalent in the educational space. Education is a fairly neglected industry from an information security perspective. That being said it’s amazing that a 22 year-old learning platform, hasn’t ironed out the most important security feature to prevent students cheating – server-side validation.
For more Endure Secure exploits, take a look at our exploit knowledge-base page.