How we hacked Blackboard and changed our grades

Author

A technical walk-through of how we hacked Blackboard and changed our grades.

What is Blackboard?

Blackboard is a web application that teachers and students use to deliver and evaluate assignments, manage courses and exchange files.

According to their website they currently serve over 16,000 schools and universities across 90 countries reaching 100 million users.

What did you do?

Eirik Fosse, Sondre Hjetland and Michael McMillan discovered three vulnerabilities that enabled us to hijack our teacher's account and change our grades.

Does it still work?

No. The vulnerabilities were immediately reported to Blackboard and the NTNU Security Operations Center on the 9th of February 2018. They were confirmed patched 61 days later.

Below is a timeline of the most important events.

  • 02/09: Initial report on filter evasion using XML and session hijacking
  • 02/09: NTNU SOC acknowledges the report and implements a temporary fix
  • 02/12: Attended conference call with Blackboad and NTNU to explain exploit
  • 02/13: Reproduced exploit in NTNU's test environment
  • 02/20: Second report on null byte evasion through WebDAV
  • 02/27: Attended conference call with Blackboard and NTNU to explain exploit
  • 04/12: NTNU SOC confirms that the vulnerabilities were patched

Blackboard stopped responding to our e-mails 02/28.

How did it work?

A student (attacker) submits an assignment to his professor (victim). The professor clicks the link and evaluates the assignment. The student has now gained access to the professor's account – unbeknownst to the professor – and has full access to whatever the professor is authorized to do on Blackboard; change grades, download files not intended for students, e-mail other users and so on.

So what made this possible? Let's walk through it.

1. Same-origin policy for user uploaded files

Like most learning platforms, Blackboard allows its users to upload files. This feature is primarily used by students to upload assignments and by professors to upload slides. But unlike the other platforms, Blackboard serves the uploaded files on the same origin as the application itself.

Needless to say, this is disastrous from a security perspective and in violation of one of the fundamental tenets of software security: Never trust user input. Consequently, this means that a user uploaded file on Blackboard is indistinguishable from Blackboard's application. An unsuspecting user who views an uploaded file on Blackboard automatically grants it access to perform actions on his behalf.

2. The cross-site scripting filter that could be fooled

It turns out that Blackboard had anticipated that user uploaded files could abuse the same-origin policy by including malicious code. Their solution? Filter out anything that looks malicious. If your alarm bell didn't go off at the previous section, it's hopefully making a lot of noise now.

After a lot of trial and error we found two ways of fooling the cross-site scripting filter.

Smuggling malicious code with a
\x00
null byte

Blackboard let's users upload files using the WebDAV protocol – a true 20th century Frankenstein brought to life by Microsoft. With some technical acrobatics we discovered that the cross-site scripting filter tripped up when we uploaded a file with a null byte through WebDAV.

For some inexplainable reason a different set of filters were applied when uploading files that contained a leading null byte.

However, the null byte was no silver bullet – it only opened the door to a cleverly crafted exploit as certain characters re-activated the original filters. The malicious code in the uploaded file could therefore only consist of a small subset of harmless-looking characters.

To our surprise we discovered that with only 6 characters ([, ], (, ), !, +) one can craft perverse, yet valid JavaScript. Coincidentally, these characters did not trigger the filter after fooling it with the null byte. This meant that an attacker could simply encode his malicious code and smuggle it right past the filter, as demonstrated below.

$ hexdump -C null-byte.html
00000000  00 3c 69 6d 67 20 73 72  63 3d 2e 20 6f 6e 65 72  .<img src=. oner
00000010  72 6f 72 3d 5b 5d 5b 28  21 5b 5d 2b 5b 5d 29 5b  ror=[][(![]+[])[
00000020  2b 5b 5d 5d 2b 28 5b 21  5b 5d 5d 2b 5b 5d 5b 5b  +[]]+([![]]+[][[
00000030  5d 5d 29 5b 2b 21 2b 5b  5d 2b 5b 2b 5b 5d 5d 5d  ]])[+!+[]+[+[]]]
[...]

When omitting the null byte the filter correctly disarms the onerror attribute by replacing it with xx.

$ hexdump -C without-null-byte.html
00000000  3c 69 6d 67 20 73 72 63  3d 2e 20 78 78 3d 5b 5d  <img src=. xx=[]
00000010  5b 28 21 5b 5d 2b 5b 5d  29 5b 2b 5b 5d 5d 2b 28  [(![]+[])[+[]]+(
00000020  5b 21 5b 5d 5d 2b 5b 5d  5b 5b 5d 5d 29 5b 2b 21  [![]]+[][[]])[+!
00000030  2b 5b 5d 2b 5b 2b 5b 5d  5d 5d 2b 28 21 5b 5d 2b  +[]+[+[]]]+(![]+

Upload an XML or SVG file

A more trivial way of bypassing the cross-site script filter was to upload an XML or SVG file that referenced the HTML namespace. This blindspot allowed us to drop straight into a script element and run whatever JavaScript we pleased.

$ cat malicious.xml
<html>
  <head></head>
  <body>
    <ouch:script xmlns:ouch="http://www.w3.org/1999/xhtml">
      alert('😞');
    </ouch:script>
  </body>
</html>

Just as effective, but not nearly as cool as the null byte.

3. The httpOnly session that wasn't

Blackboard had taken the preventive measure of adding an httpOnly flag to the session identifier. This flag blocks JavaScript running on the same origin from retrieving session identifiers via. the document.cookie object.

Unfortunately, Blackboard rendered this protection useless by also including the session identifier in their WYSIWYG editor. This meant that an attacker only had to scrape the session identifier by sending an XMLHttpRequest (XHR) on behalf of the authenticated user – which we showed how to do in the previous sections – and forward it to himself.

The following snippet was embedded in the source code of the "Send message" feature.

new tinyMceWrapper.Editor('messagetext', {
  [...]
  tempWirisWebLocation: "https://ntnu.blackboard.com/sessions/78CFDDD4C957[...]",
  [...]
}

Hire us!

The BustByte team

Hire us to perform a thorough penetration test of your software. We produce a detailed report and provide patches. Shoot us an e-mail at [email protected].

If you have any questions regarding this post, please drop us a line in the comments below.