Buffer Overflow & Ασφάλεια

...το μέρος για να ξεκινήσετε!

Συντονιστής: adem1

Κανόνες Δ. Συζήτησης
Παρακαλώ να επιλέξετε, με προσοχή, την άδεια που θέλετε να έχουν οι οδηγοί που συγγράφετε.
Πληροφορίες για τις άδειες μπορείτε να βρείτε εδώ.
Άμα επιθυμείτε κάποια άλλη άδεια επικοινωνήστε με κάποιο Διαχειριστή είτε Συντονιστή.

Σημαντικό είναι να χρησιμοποιήσετε την υπηρεσία http://imagebin.ubuntu-gr.org για τις εικόνες.

Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό Star_Light » 17 Απρ 2011, 23:03

Σε αυτόν τον οδηγό θα προσπαθήσω να προσεγγίσω θεωρητικά το θεματάκι(και οχι με πολυ κουραστική πολυλογία) με το Buffer Overflow και να δούμε και 2-3 πρακτικά απλά τίπς για το πώς μπορούμε να είμαστε ενήμεροι ως προς την ασφάλεια για αυτο το θέμα ως προς τις διάφορες εφαρμογές που παίζουν.

Καταρχήν με τον όρο Buffer Overflow εννοούμε μια μη επιθυμητή κατάσταση κατα την οποία μια διεργασία / ένα πρόγραμμα προσπαθεί να αποθηκεύσει δεδομένα πέραν των ορίων ενός buffer , ένας buffer είναι μια περιοχή προσωρινής αποθήκευσης ελεγχόμενη απο το λειτουργικό σύστημα και δεν σχετίζεται με την φυσική μνήμη του συστήματος μας.

Η πρόσβαση για παράδειγμα σε έναν δίσκο ή σε μια άλλη συσκευή εισόδου/εξόδου ειναι γενικά πολυ πιο αργή απο μια άμεση πρόσβαση στην μνήμη. Μπορούν να γίνουν διάφορες λειτουργίες εισόδου - εξόδου σε ένα buffer που αντιπροσωπεύει το αρχείο εισόδου/εξόδου αντι για το ίδιο το αρχείο.

Το πρόβλημα λοιπον το οποίο έγκειται στην υπερχείλιση μνήμης προκαλεί σε μια διεργασία να λειτουργήσει κάπως περίεργα και να κάνει πράγματα τα οποία δεν ηταν εξαρχής προγραμματισμένη να κάνει. ΜΠορούμε να πούμε οτι ξεγελλίεται ενα πρόγραμμα και εκτελεί διαφορετικό κώδικα.

Φυσικά το τελευταίο μπορεί να γίνει απο την στιγμή που αλλάξει η ροή εκτέλεσης του προγράμματος και την εκτέλεση μετα κακόβουλου κώδικα. :!: :!: :!:

Ο πιο συνηθισμένος τρόπος για να επιτευχθεί το παραπάνω είναι με το να επικαλύψεις ενα τμήμα της στοίβας του προγράμματος που τρέχει. Η στοίβα του προγράμματος μεταξύ άλλων περιέχει και την διευθυνσή επιστροφής δηλαδή την ΘΕΣΗ μνήμης στην οποία το πρόγραμμα θα μεταφέρει τον έλεγχο όταν η συνάρτηση τερματίσει. :idea: :idea: :idea: :idea:

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

Με λίγα λόγια λοιπον και πολυ απλά μια επίθεση υπερχείλισης μνήμης συμβαίνει οταν μια εφαρμογή δεν ελέγχει αν το μέγεθος της εισόδου (μια τιμή απο τον χρήστη) είναι μικρότερη ή ιση απο το μέγεθος της μνήμης που έχει δεσμευτεί για αυτήν τη μεταβλητή η οποια και θα αποθηκεύσει την τιμή που δίνει ο χρήστης.

Πάμε να δούμε τώρα ένα παράδειγμα Υπερχείλισης μνήμης σε πραγματική εφαρμογή :!: :!: :!:

Όλοι γνωρίζουμε την εφαρμογή MTA sendmail. Όλοι ή εστω οι περισσότεροι συζητούσαν για το ότι το sendmail δεν ειναι τόσο ασφαλές πχ απο το Postfix , αρκετά ζητήματα ασφάλειας υπήρχαν στο πρώτο . Ένα απο αυτά σχετίζεται με την Υπερχείλιση μνήμης για την οποία κάνουμε λόγο στον συγκεκριμένο οδηγό. ΠΙο συγκεκριμένα ο sendmail daemon χρησιμοποιεί μια σταθερού μεγέθους συμβολοσειρά buffer.
Ταυτόχρονα επιτρέπει στους πελάτες του δικτύου να παραθέτουν συμβολοσειρές που υπερχειλίζουν το buffer .

Ας δούμε και το πιο κάτω τμήμα κώδικα σε γλώσσα C.

Κώδικας: Επιλογή όλων


#include <stdio.h>
int main ( )
{
char username[32]; /*Wstoso to UNix epitrepei mexri 8 xaraktirwn onomata*/
printf("Please enter your username: ");
gets(username);      /* Diavazei eisodo xrhsth */
return 0;
}


Όταν γράφουμε κώδικα καλό είναι να λαμβάνουμε υπόψιν τι μπορεί να κάνει ένας κακόβουλος. ( Οι επισημάνσεις και οι προειδοποιήσεις που μας δινει o geany editor δεν είναι τυχαίες)
Αν εδω δοθεί σκόπιμα ενα πολύ μεγάλο όνομα χρήστη θα αποθηκευτεί στην στοίβα και θα επικαλύψει κομμάτια επιτρέποντας την επίθεση κάποιου κακόβουλου.

:idea: :idea: :idea: :idea:

Όταν διαβάζουμε συμβολοσειρές μπορούμε να παίζουμε με την δυναμική δέσμευση μνήμης την οποία μας παρέχει η C σαν μια χαμηλού επιπέδου λειτουργία (διαχείριση μνήμης επι της ουσίας) αλλα μπορει να αποδειχθεί σωτήρια. Σε γενικές γραμμές υπερχείλιση μπορεί να συμβεί σε οποιουδήποτε πίνακα στατικής μορφής - στατικού δηλαδη μεγέθους

Όταν προγραμματίζουμε δεν θα πρέπει να μας ενδιαφέρει μονο η αποτελεσματικότητα ενος προγράμματος αλλα και η ασφάλεια του. Στην C υπάρχουν συναρτήσεις που όταν χρησιμοποιούνται θέλουν ιδιαίτερη προσοχή.

Κώδικας: Επιλογή όλων
strcpy() , gets() , scanf()


Όταν πάμε να αντιγράψουμε κάτι με την με την strcpy θα υπάρξει αδυναμία - κενό αν δεν κάνουμε κάποιον έλεγχο στο μέγεθος. Αν ένας επιτιθέμενος διαπιστώσει τέτοιου είδους αδυναμία μπορεί να εισάγει μια μεγάλου μήκους συμβολοσειρά για παράδειγμα που στο τέλος της να περιέχει εκτελέσιμο κώδικα .

Συμπερασματικά η λύση γυρω απο τέτοιου είδους επιθέσεις ειναι η ενημέρωση.
Οι εκδόσεις 5.2 , 5.3 , 5.3.5 & 5.2.17 της PHP αντιμετωπίζουν ενα πρόβλημα σχετικα με την υπερχείλιση μνήμης.
Απο το τερματικό μπορούμε να δώσουμε την εξής εντολή

Κώδικας: Επιλογή όλων
kostas@kostas-SSL:~$ php -v
PHP 5.3.3-1ubuntu9.3 with Suhosin-Patch (cli) (built: Jan 12 2011 16:07:38)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
kostas@kostas-SSL:~$


για να δούμε ποια έκδοση της εφαρμογής χρησιμοποιούμε. Μπορούμε να το κάνουμε αυτο γενικά και για κάθε εφαρμογή απο το τερματικό
Κώδικας: Επιλογή όλων
<application> -v


Μια παρόμοια εντολή με την πιο πάνω ειναι επίσης και η

Κώδικας: Επιλογή όλων
kostas@kostas-SSL:/etc$ dpkg -l apache2
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Όνομα     Έκδοση   Περιγραφή
+++-==============-==============-============================================
ii  apache2        2.2.16-1ubuntu Apache HTTP Server metapackage
kostas@kostas-SSL:/etc$


Μπορούμε να επισκεφτούμε και την σελίδα

Κώδικας: Επιλογή όλων
http://packages.qa.debian.org/pkg-name


ή την

Κώδικας: Επιλογή όλων
http://bugs.debian.org/pkg-name



Οπότε μπορούμε μετά να μπαίνουμε στην αντίστοιχη σελίδα αναφοράς
Κώδικας: Επιλογή όλων
http://www.php.net/


και να βλέπουμε αν η συγκεκριμένη εφαρμογή αντιμετωπίζει θέματα σχετικά με την υπερχείλιση μνήμης. Η έκδοση 5.3.3 της δικιάς μου PHP αναφέρεται σε αριθμό δευτερεύουσας έκδοσης η ομάδα της PHP χρησιμοποιεί αριθμούς δευτερεύουσας έκδοσης (παρόμοια φιλοσοφία θα παίζει και σε πληθώρα εφαρμογών) για να χαρακτηρίσει τις ενημερώσεις της κύριας έκδοσης του λογισμικού που περιέχουν σχετιζόμενες με την ασφάλεια βελτιώσεις ή διορθώσεις σφαλμάτων.

Ένας επίσης πολύ καλύτερος τρόπος απο τον παραπάνω (ως προς την εκτενέστατη έξοδο του σχετικά με τις πληροφορίες για την php μας είναι χρησιμοποιώντας την συνάρτηση)

Κώδικας: Επιλογή όλων
<?php phpinfo()
?>


Η έξοδος του παραπάνω script άν το δώσουμε απο το localhost του apache δείχνει μια μεγάλη ποσότητα πληροφοριών σχετικά με την τρέχουσα κατάσταση της PHP . Πληροφορίες σχετικά με την μεταγλώττιση , επεκτάσεις , την έκδοση (που με την προηγούμενη εντολή php -v βλέπαμε μονο αυτο το στοιχείο ) το περιβάλλον της PHP και άλλα πολλά.

ΣΤην συνέχεια μπορούμε να διαβάσουμε και την τεκμηρίωση της PHP για την ασφάλεια.

http://www.php.net/manual/en/security.php

:!: :!: :!: :!: Ευχαριστώ τον Αποστόλη για την παραπάνω επισήμανση μιας και ο ίδιος μου το τόνισε την αξία της phpinfo()

Υπάρχουν και άλλοι πιο γρήγοροι - αξιοπιστοι και ευκολοι τρόποι για να μπορέσει κάποιος να μάθει απο τι είδους ευπάθεια μπορει να πάσχουν οι εφαρμογές που τρέχει το συστημά του συμπεριλαμβανομένης και της υπερχείλισης μνήμης :

Εγκατάσταση του network mapper (nmap)

Κώδικας: Επιλογή όλων
sudo apt-get install nmap


και απο το κέλυφος η εντολή

Κώδικας: Επιλογή όλων
nmap -sV 127.0.0.1

το flag -sV που δέχεται σαν παράμετρος το nmap ουσιαστικά δεν κάνει τιποτε αλλο
απο ενα scan σε όλες τις ανοικτές πόρτες για να επιστρέψει τις εκδόσεις των εφαρμογών που τρέχουν σε αυτες.

Αν υποθέσουμε πως στο σύστημα τρέχει εφαρμογή εξυπηρετητή ProFTPD 1.3.2rc3 τότε υπάρχει ευπάθεια υπερχείλισης μνήμης οπως μπορει κανεις να διαβάσει και εδω

Κώδικας: Επιλογή όλων
http://www.saintcorporation.com/cgi-bin/demo_tut.pl?tutorial_name=ProFTPD_vulnerabilities.html&fact_color=&tag=


ΌΠως επισημάνθηκε και πιο πάνω η καλύτερη λύση είναι η συνεχής ενημέρωση. Ωστόσο υπάρχει ενα χρονικό διάστημα στο οποίο ένα κενό ασφάλειας έχει βρεθεί μεν αλλα πρεπει και να δημοσιοποιηθεί , σε τέτοιες περιπτώσεις κάποιος οφείλει να ακολουθεί ένα απο τα βασικά τιπ ασφάλειας περα απο το Buffer Overflow και να απενεργοποιεί υπηρεσίες που δεν του χρειάζονται ετσι οι πιθανότητες κάποιας παραβίασης φυσικα μειώνονται



Τέλος αξίζει να επισημανθεί οτι το θέμα με την συγκεκριμένη ευπάθεια ειναι ιδιαίτερα σημαντικό για την ασφάλεια ενός συστήματος καθώς αρκετά προγράμματα τα οποία θα τρέχουν ως root οπότε καταλαβαίνουμε όλοι τι θα συμβεί αν κάποιος αποκτήσει τον έλεγχο πάνω τους.

Ελπίζω να τον βρείτε χρήσιμο και περιεκτικό. Αναμένω για διορθώσεις , επισημάνσεις και συμπληρώσεις :thumbup: :thumbup: :thumbup:
Τελευταία επεξεργασία από Star_Light και 03 Σεπ 2011, 15:13, έχει επεξεργασθεί 9 φορά/ες συνολικά
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό Star_Light » 14 Μάιος 2011, 19:08

Up to date ! :D
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό Star_Light » 10 Ιουν 2011, 22:49

update! Η συνάρτηση phpinfo() για περισσότερες πληροφορίες σχετικά με την php στο σύστημα μας . Μιας και καθε σύστημα μπορει να ρυθμίζεται με διαφορετικό τρόπο
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό giannosfor » 26 Ιουν 2011, 22:13

Πολύ ενδιαφέρων.
1 Γνώσεις Linux: Καθόλου ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Ικανοποιητικό
2 Ubuntu 12.04 precise 3.2.0-58-generic 32bit (en_US.UTF-8, Unity ubuntu), Ubuntu 3.2.0-57-generic, Microsoft Windows XP Professional
3 Intel Core2 Duo CPU E4600 2.40GHz ‖ RAM 2012 MiB ‖ ASUS INC. P5Q - � P5Q
4 nVidia G94 [GeForce 9600 GT] [10de:0622] {nvidia}
5 eth0: Qualcomm Atheros AR8121/AR8113/AR8114 Gigabit or Fast Ethernet [1969:1026] (rev b0) ⋮ wlan0: 148f:3070 Ralink Technology, Corp. RT2870/RT3070 Wireless Adapter
Άβαταρ μέλους
giannosfor
punkTUX
punkTUX
 
Δημοσιεύσεις: 297
Εγγραφή: 24 Απρ 2011, 20:24
Τοποθεσία: Ηράκλειο
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό Star_Light » 30 Ιουν 2011, 21:40

giannosfor έγραψε:Πολύ ενδιαφέρων.


Ευχαριστω για τα καλα σου λογια... ωστοσο ο οδηγος αυτος :

Αναφερεται σε μια πολυ αρχικη εισαγωγη του θεματος και προσδοκα να δωσει στους αναγνωστες την σπιθα του να ψαχνουν τις εκδοσεις των εφαρμογων που χρησιμοποιουν , το να εισαι ενημερωμενος και οσο καλυτερα προφυλαγμενος δεν απαιτει παντοτε τρομερες προγραμματιστικες τεχνικες και ικανοτητες. Σχετικα με το θεμα τωρα για να μπορεσει καποιος να πει πως κατανοει την λογικη της υπρεχειλισης απο οσο εχω καταλαβει ως τωρα θα πρεπει καταρχην να έχει :


A. KΑλες γνωσεις σε C

B. Αρχικες γνωσεις assembly (Θεωρια καταχωρητων κτλπ)

Γ. Βασικες γνωσεις στις δομες δεδομενων πχ στοιβες.


αφου εχει τα παραπανω μπορει να προσεγγισει σε βαθος το θεμα του BUffer Overflow.

Αρχικα θα πρεπει να καταλαβεις πως δουλευει ενα προγραμμα δηλαδη.
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό migf1 » 06 Σεπ 2011, 03:49

Το buffer-overflow ως έννοια δεν είναι δύσκολο στην κατανόησή του, το να το βρει και να το κάνει exploit όμως κανείς είναι.

Με απλά λόγια, buffer (ενταμιευτής) είναι ένα συνεχόμενο τμήμα της μνήμης, το οποίο προγραμματιστικά συνήθως δημιουργείται όταν διαχειριζόμαστε στατικούς ή δυναμικούς πίνακες ή όταν κάνουμε χειροκίνητα δυναμική διαχείριση μνήμης μέσω δεικτών.

Αν λοιπόν έχουμε ορίσει έναν πίνακα να καταλαμβάνει π.χ. 10 bytes στη μνήμη...
Κώδικας: Επιλογή όλων
    char string[10] = { 0 };

τότε αν έστω και κατά λάθος αρχίζουμε να γράφουμε δεδομένα μετά το τέλος του...
Κώδικας: Επιλογή όλων
    strcpy(string, "this is a string with a lot more than 10 characters");

τότε δημιουργούμε buffer-overflow!

Τα έξτρα αυτά δεδομένα πάνε και αντικαθιστούν μερικώς ή ολικώς δεδομένα που βρίσκονται δίπλα από το buffer μας και προφανώς ανήκουν σε άλλες μεταβλητές του προγράμματος μας, ή σε άλλα τμήματά του, ανάλογα με το αν ο υπερχειλισμένος πίνακας είχε οριστεί στατικά (άρα βρίσκεται στο stack) ή δυναμικά (άρα βρίσκεται στο heap).

Είτε έτσι, είτε αλλιώς, όταν το πρόγραμμα πάει να διαχειριστεί το συγκεκριμένο τμήμα της μνήμης βρίσκει "άλλα αντί άλλων" κι ενίοτε παραπέμπεται σε άλλα τμήματα μνήμης, στα οποία όμως δεν του επιτρέπεται η πρόσβαση. Οπότε το λειτουργικό εγείρει exception και στέλνει το αντίστοιχο σήμα στη διεργασία που το προκάλεσε (σε POSIX περιβάλλοντα το signal του segmentation-fault είναι το SIGSEGV).

Άλλη περίπτωση είναι τα έξτρα δεδομένα να είναι τόσα πολλά, ώστε να φτάνουν απευθείας σε read-only τμήματα της μνήμης, οπότε εκεί έχουμε άμεση δημιουργία του exception και αποστολή του σήματος.

Υπάρχουν αρκετοί τρόποι να εκμεταλλευτεί κανείς τα κενά ασφαλείας που δημιουργεί το buffer-overflow, και ποικίλουν από ενσωμάτωση κακόβουλου κώδικα (ή παραπομπής σε κακόβουλο κώδικα) σε μεταβλητές που βρίσκονται δίπλα στο υπερχειλισμένο buffer, μέχρι παρεμβολή, παραπομπή ή και αντικατάσταση της σελίδας που εμπλέκεται στη δημιουργία του exception σε λειτουργικά που χρησιμοποιούν σελιδοποιημένη εικονική μνήμη (τα περισσότερα).

Επειδή η όλη ιστορία είναι αρκετά πολύπλοκη και προϋποθέτει και εξειδικευμένες γνώσεις, αυτό που μπορούμε να κρατήσουμε είναι πως το να εκμεταλλευτεί κανείς το κενό ασφαλείας δεν είναι τετριμμένη διαδικασία. Δεν υπάρχει γενικός μπούσουλας και διαφέρει όχι μόνο από πλατφόρμα σε πλατφόρμα, όχι μόνο από λειτουργικό σε λειτουργικό, αλλά κι από έκδοση σε έκδοση του ίδιου λειτουργικού.

Προγραμματιστικά, οι πιο επιρρεπείς γλώσσες για δημιουργία buffer-overflow είναι οι C και C++ (που μαζί με τη Java είναι οι 3 πιο δημοφιλείς γλώσσες) επειδή αφήνουν τον προγραμματιστή να έχει πρόσβαση σε οποιοδήποτε τμήμα της μνήμης, χωρίς να παρέχουν εξαναγκαστικά μηχανισμούς ελέγχου για την εγκυρότητα αυτής της πρόσβασης. Υπάρχουν όμως εργαλεία που βοηθάνε στην καταπολέμηση του φαινομένου (η C++ παρέχει αρκετά, αρκεί να ξέρει κάποιος να τα χρησιμοποιήσει, ενώ για τη C είναι εξωτερικά προγράμματα που κάνουν συνεχώς monitoring για τις πιο κοινές περιπτώσεις). Αντίθετα, γλώσσες όπως η Java, η Python και η συντριπτική πλειοψηφία των interpreted γλωσσών παρέχουν boundary checking (να μην ξεπερνιούνται δηλαδή τα όρια των πινάκων) είτε στο run-time, είτε στο compilation.

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

Στα χέρια μη έμπειρων προγραμματιστών και σε ελαστικές γλώσσες (όπως η C και η C++), οι δείκτες είναι μια ακόμα πηγή παραγωγής segmentation faults, που όπως είπαμε δημιουργεί κενά ασφαλείας.

Πιο συγκεκριμένα, exception που εγείρονται όταν πάμε να χρησιμοποιούμε μη-αρχικοποιημένους δείκτες, ή δείκτες που είναι NULL ή δείκτες που έχουν γίνει free. Για αυτό πρέπει να είναι κανείς πολύ προσεχτικός όταν γράφει κώδικα με δείκτες.

Μερικές πρακτικές που μειώνουν το πρόβλημα (αλλά δεν το λύνουν από μόνες τους) είναι:

  • να αρχικοποιούμε πάντα τους δείκτες όταν τους ορίζουμε, ιδανικά με απευθείας δέσμευση της μνήμης που θα χρησιμοποιήσουν αν προορίζονται για δυναμική διαχείριση μνήμης, ή σε NULL αν πρόκειται για απλούς δείκτες...
    Κώδικας: Επιλογή όλων
        char *p1 = calloc(10, sizeof(char) );
        char *p2 = NULL;

  • να ελέγχουμε να μην είναι NULL ο δείκτης πριν τον χρησιμοποιήσουμε, ΕΙΔΙΚΑ όταν περνιέται ως όρισμα σε συνάρτηση...
    Κώδικας: Επιλογή όλων
    // ---------------------------------------------------
    char *string_ncopy( char *dst, const char *src, size_t n )
    {
          if ( !dst )
                return NULL;
          if ( !src )
                return dst;

          strncpy( dst, src, n );
          return dst;
    }

  • να ελέγχουμε να μην είναι NULL ο δείκτης πριν τον απελευθερώσουμε, κι αμέσως μετά να τον κάνουμε NULL...
    Κώδικας: Επιλογή όλων
        if ( p1 ) {
            free( p1 );
            p1 = NULL;
        }

        if ( p2 ) {
            free( p2 );
            p2 = NULL;
        }
Μερικά από τα παραπάνω γίνονται αυτόματα σε compilers που υποστηρίζουν την αναθεώρηση C99 της C (π.χ. o έλεγχος πριν την απελευθέρωση, ή ακόμα και η ίδια η απελευθέρωση πριν τον τερματισμό του προγράμματος) αλλά αφενός δεν υπάρχει ακόμα compiler που να υποστηρίζει πλήρως όλα τα έξτρα στάνταρ που θέσπισε η αναθεώρηση C99 κι αφετέρου δεν υποστηρίζουν όλοι οι compilers τα ίδια έξτρα στάνταρ.

Οπότε το καλύτερα να τα κάνουμε μόνοι μας, για να έχουμε το κεφάλι μας ήσυχο :)

@Star_Light: btw, αυτοί είναι οι έλεγχοι για τους οποίους ήθελα να σας μιλήσω στο τόπικ της C ;)
Τελευταία επεξεργασία από migf1 και 06 Σεπ 2011, 03:57, έχει επεξεργασθεί 3 φορά/ες συνολικά
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό Star_Light » 06 Σεπ 2011, 03:52

thanx migf1!!!! Θα τα κοιταξω και αυριο με πιο καθαρο μυαλο γιατι τωρα το εχω απλα ανοιχτο και ακουω τραγουδια λιγο πριν την πεσω :lol: :lol:

γενικα ο οδηγος πως σου φανηκε??? (εκτος και αν κανεις καποιον σχολιασμο μεσα στο παραπανω ποστ και το δω αυριο)

Π.Σ Τελος θεωρεις πως για να μπορεσει να κανει καποιος μια buffer overflow πχ πρεπει να έχει γνωσεις assembly???
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό migf1 » 06 Σεπ 2011, 03:55

Διάβασέ το αύριο και τα λέμε ;)

ΥΓ. Αχρείαστα τεχνικός μου φάνηκε ο οδηγός σε μερικά σημεία του.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό Star_Light » 06 Σεπ 2011, 03:56

migf1 έγραψε:Διάβασέ το αύριο και τα λέμε ;)

ΥΓ. Αχρείαστα τεχνικός μου φάνηκε ο οδηγός σε μερικά σημεία του.


xaxaxaxxaa ok! Ε απλα ηθελα να τον κανω και λιγο "πρακτικο"
αλλα ενταξει δεν ειχα και τρομερο υποβαθρο οταν τον εκανα. (Ενω τωρα εχω) :lol: :lol:
ενιγουει αντε καληνυχτα.
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Buffer Overflow & Ασφάλεια

Δημοσίευσηαπό migf1 » 06 Σεπ 2011, 04:02

Καληνύχτα :)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Επόμενο

Επιστροφή στο Οδηγοί - How to - Tutorials