HTCinside
Κατά τη δημοσίευση των προϊόντων λογισμικού μας, όλοι χρησιμοποιούμε για να γράφουμε σε EULA 'Δεν επιτρέπεται η αναστροφή μηχανικής, η απο-μεταγλώττιση ή η αποσυναρμολόγηση του Λογισμικού'. Ωστόσο, σε πολλές περιπτώσεις, οι λέξεις δεν είναι η καλύτερη προστασία και πρέπει πραγματικά να εισαγάγετε ορισμένα τεχνικά εργαλεία για να αποτρέψετε την αναστροφή του λογισμικού και να προστατέψετε την τεχνογνωσία σας από την αποκάλυψη.
Υπάρχουν διάφορες τεχνολογικές προσεγγίσεις για την πρόληψη της αντίστροφης μηχανικής λογισμικού: anti-debug, anti-dump και άλλες. Σε αυτήν την ανάρτηση, θα επικεντρωθούμε σε ορισμένες μεθόδους κατά του εντοπισμού σφαλμάτων, καθώς αποτελούν τον πυρήνα της προστασίας κατά της αντίστροφης μηχανικής. Η προσάρτηση ενός προγράμματος εντοπισμού σφαλμάτων στη διαδικασία που ερευνήθηκε για την εκτέλεσή του βήμα-βήμα είναι πολύ σημαντικό στάδιο οποιασδήποτε εργασίας αντιστροφής – οπότε ας ρίξουμε μια ματιά στα εργαλεία που μπορούμε να χρησιμοποιήσουμε για να κάνουμε τη ζωή των αντιστροφέων πιο δύσκολη.
Υπάρχουν μερικά πράγματα που θα ήθελα να αναφέρω στην αρχή. Το πρώτο είναι ότι δεν υπάρχει καθολική ή 100% αλεξίσφαιρη προστασία από την αντίστροφη μηχανική λογισμικού. Υπάρχει πάντα τρόπος να μπει ο αντιστροφέας, η μόνη στρατηγική που έχουμε είναι να κάνουμε τη δουλειά του όσο το δυνατόν πιο σκληρή και απαιτητική.
Στη συνέχεια, υπάρχουν αρκετές τεχνικές κατά της αντίστροφης μηχανικής και ειδικότερα μέθοδοι κατά του εντοπισμού σφαλμάτων, συμπεριλαμβανομένης της προστασίας βάσει χρόνου ή ακόμη και συγκεκριμένων τεχνολογιών ενσωματωμένων σε κώδικα όπως οι νανομίτες. Σε αυτήν την ανάρτηση, θα εξετάσουμε μόνο αρκετές τυπικές προσεγγίσεις ειδικά για συστήματα που βασίζονται σε Windows, τις πιο δημοφιλείς.
Οι προσεγγίσεις που παρουσιάζονται παρακάτω περιγράφονται γενικά.
Περιεχόμενα
Τα συστήματα Windows μας παρέχουν ορισμένα έτοιμα εργαλεία για τη δημιουργία απλής προστασίας κατά του εντοπισμού σφαλμάτων. Μία από τις απλούστερες τεχνικές κατά του εντοπισμού σφαλμάτων βασίζεται στην κλήση της συνάρτησης IsDebuggerPresent. Αυτή η συνάρτηση επιστρέφει TRUE εάν ένας εντοπισμός σφαλμάτων σε λειτουργία χρήστη πραγματοποιεί αυτήν τη στιγμή εντοπισμό σφαλμάτων στη διαδικασία.
Αυτή η συνάρτηση αναφέρεται στο PEB (Process Environment Block, μια δομή κλειστού συστήματος) και συγκεκριμένα στο πεδίο BeingDebugged. Οι αναστροφείς όταν παρακάμπτουν μια τέτοια τεχνική προστασίας χρησιμοποιούν αυτό το γεγονός: π.χ. εφαρμόζοντας την έγχυση DLL, ρύθμισαν την τιμή BeingDebugged σε 0 ακριβώς πριν πραγματοποιηθεί αυτός ο έλεγχος στον προστατευμένο κώδικα.
Δυο λόγια για το πού να γίνει ένας τέτοιος έλεγχος. Η κύρια λειτουργία δεν είναι η καλύτερη επιλογή: οι αντιστροφείς συνήθως την ελέγχουν πρώτα στην αποσυναρμολογημένη λίστα. Είναι καλύτερο να εκτελέσετε έλεγχο κατά του εντοπισμού σφαλμάτων στο TLS Callback, όπως ονομάζεται πριν από το σημείο κλήσης εισόδου της κύριας εκτελέσιμης μονάδας.
Μια άλλη επιλογή λειτουργικού ελέγχου είναι το CheckRemoteDebuggerPresent. Σε αντίθεση με τη συνάρτηση που περιγράφεται παραπάνω, ελέγχει εάν μια άλλη παράλληλη διεργασία διορθώνει αυτήν τη στιγμή μια διεργασία. Βασίζεται στη συνάρτηση NtQueryInformationProcess και συγκεκριμένα στην τιμή ProcessDebugPort.
Ενώ η προηγούμενη ομάδα μεθόδων βασίστηκε στον έλεγχο της παρουσίας του προγράμματος εντοπισμού σφαλμάτων, αυτή θα παρέχει ενεργή προστασία από αυτό.
Ξεκινώντας με τα Windows 2000, η συνάρτηση NtSetInformationThread λαμβάνει τη νέα σημαία που ονομάζεται ThreadHideFromDebugger. Αυτή είναι μια πολύ αποτελεσματική τεχνική κατά του εντοπισμού σφαλμάτων που παρέχεται στο λειτουργικό σύστημα Windows. Ένα νήμα με αυτό το σύνολο σημαιών σταματά για να στέλνει ειδοποιήσεις συμβάντων εντοπισμού σφαλμάτων, συμπεριλαμβανομένων σημείων διακοπής και άλλων, με αποτέλεσμα να κρύβεται από οποιοδήποτε πρόγραμμα εντοπισμού σφαλμάτων. Η ρύθμιση του ThreadHideFromDebugger για το κύριο νήμα θα περιπλέξει σημαντικά τη διαδικασία σύνδεσης του προγράμματος εντοπισμού σφαλμάτων σε ένα νήμα.
Η λογική συνέχεια εισήχθη στα Windows Vista με τη συνάρτηση NtCreateThreadEx. Έχει την παράμετρο CreateFlags, η οποία ρυθμίζει μεταξύ άλλων τη σημαία THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER. Η διαδικασία με αυτό το σύνολο σημαιών θα είναι κρυφή από το πρόγραμμα εντοπισμού σφαλμάτων.
Ο εντοπισμός σφαλμάτων που εκτελείται μπορεί να ανιχνευθεί από τις αλλαγμένες τιμές διαφορετικών σημαιών σε διάφορες δομές συστημάτων και διεργασιών.
Τα Windows NT περιλαμβάνουν μια καθολική μεταβλητή που ονομάζεται NtGlobalFlag με ένα σύνολο σημαιών, που χρησιμοποιείται για την ανίχνευση συστήματος και τον εντοπισμό σφαλμάτων. Η προαναφερθείσα δομή PEB περιλαμβάνει το δικό της πεδίο NtGlobalFlag. Κατά τον εντοπισμό σφαλμάτων, αυτή η τιμή πεδίου αλλάζει με πολλές συγκεκριμένες σημαίες που έχουν οριστεί. Ο έλεγχος αυτών των σημαιών μπορεί να δημιουργήσει έναυσμα για προστασία κατά του εντοπισμού σφαλμάτων.
Ένα εκτελέσιμο αρχείο μπορεί να επαναφέρει τις σημαίες NtGlobalFlag της δομής PEB μέσω μιας συγκεκριμένης δομής που ονομάζεται IMAGE_LOAD_CONFIG_DIRECTORY, η οποία περιέχει συγκεκριμένες παραμέτρους διαμόρφωσης για το πρόγραμμα φόρτωσης συστήματος. Έχει το πεδίο GlobalFlagsClear, το οποίο επαναφέρει τις σημαίες NtGlobalFlag του PEB. Από προεπιλογή, αυτή η δομή δεν προστίθεται σε ένα εκτελέσιμο αρχείο, αλλά μπορεί να προστεθεί αργότερα. Το γεγονός ότι ένα εκτελέσιμο δεν έχει αυτήν τη δομή ή την τιμή GlobalFlagsClear ισούται με 0, ενώ το αντίστοιχο πεδίο που είναι αποθηκευμένο στο δίσκο ή στη μνήμη της διαδικασίας που εκτελείται δεν είναι μηδέν, υποδηλώνει την παρουσία ενός κρυφού εντοπισμού σφαλμάτων. Αυτός ο έλεγχος μπορεί να εφαρμοστεί στον εκτελέσιμο κώδικα.
Μια άλλη ομάδα σημαιών είναι αυτή του σωρού διεργασιών. Υπάρχουν δύο πεδία στην αντίστοιχη δομή _HEAP: Flags και ForceFlags. Και οι δύο αλλάζουν τις τιμές τους όταν η αντίστοιχη διεργασία διορθώνεται και έτσι μπορούν να αποτελέσουν τη βάση του ελέγχου και της προστασίας κατά του εντοπισμού σφαλμάτων.
Ένας ακόμη έλεγχος σημαίας, ο οποίος μπορεί να χρησιμοποιηθεί για τον εντοπισμό του εντοπισμού σφαλμάτων, είναι ο έλεγχος Trap Flag (TF). Είναι στο μητρώο EFLAGS. Όταν το TF ισούται με 1, η CPU δημιουργεί INT 01h (εξαίρεση «Single Step») μετά από κάθε εκτέλεση εντολής που υποστηρίζει τη διαδικασία εντοπισμού σφαλμάτων.
Τα σημεία διακοπής είναι το ουσιαστικό μέρος οποιασδήποτε διαδικασίας εντοπισμού σφαλμάτων και έτσι ανιχνεύοντάς τα, μπορούμε να εντοπίσουμε και να εξουδετερώσουμε ένα πρόγραμμα εντοπισμού σφαλμάτων. Οι τακτικές κατά του εντοπισμού σφαλμάτων που βασίζονται στην ανίχνευση σημείων διακοπής είναι μία από τις πιο ισχυρές και δύσκολο να παρακαμφθούν.
Υπάρχουν δύο τύποι σημείων διακοπής: λογισμικού και υλικού.
Τα σημεία διακοπής του λογισμικού ορίζονται από τον εντοπισμό σφαλμάτων με την εισαγωγή της εντολής int 3h στον κώδικα. Έτσι, οι μέθοδοι ανίχνευσης του εντοπισμού σφαλμάτων βασίζονται στον υπολογισμό και τον έλεγχο του αθροίσματος ελέγχου της αντίστοιχης συνάρτησης.
Δεν υπάρχει καθολική μέθοδος καταπολέμησης αυτής της προστασίας – ένας χάκερ θα πρέπει να βρει το κομμάτι του κώδικα που υπολογίζει το άθροισμα ελέγχου και να αντικαταστήσει τις επιστρεφόμενες τιμές όλων των αντίστοιχων μεταβλητών.
Τα σημεία διακοπής υλικού ορίζονται χρησιμοποιώντας συγκεκριμένους καταχωρητές εντοπισμού σφαλμάτων: DR0-DR7. Χρησιμοποιώντας τα, οι προγραμματιστές μπορούν να διακόψουν την εκτέλεση ενός προγράμματος και να μεταφέρουν τον έλεγχο σε έναν εντοπισμό σφαλμάτων. Η προστασία κατά του εντοπισμού σφαλμάτων μπορεί να βασίζεται στον έλεγχο των τιμών αυτών των καταχωρητών ή να είναι πιο προληπτική και να επαναφέρει αναγκαστικά τις τιμές τους για να σταματήσει τον εντοπισμό σφαλμάτων χρησιμοποιώντας τη συνάρτηση SetThreadContext.
Το Structured Exception Handling ή SEH είναι ένας μηχανισμός που επιτρέπει σε μια εφαρμογή να λαμβάνει ειδοποιήσεις για εξαιρετικές καταστάσεις και να τις χειρίζεται αντί για λειτουργικό σύστημα. Οι δείκτες προς τους χειριστές SEH ονομάζονται πλαίσια SEH και τοποθετούνται στη στοίβα. Όταν δημιουργείται μια εξαίρεση, αντιμετωπίζεται από το πρώτο πλαίσιο SEH στη στοίβα. Εάν δεν ξέρει τι να κάνει με αυτό, μεταβιβάζεται στον επόμενο στη στοίβα και ούτω καθεξής μέχρι τον χειριστή συστήματος.
Όταν γίνεται εντοπισμός σφαλμάτων της εφαρμογής, ένα πρόγραμμα εντοπισμού σφαλμάτων θα πρέπει να παρεμποδίσει τον έλεγχο μετά την παραγωγή 3 ωρών, διαφορετικά ένας χειριστής SHE θα τον πάρει. Αυτό μπορεί να χρησιμοποιηθεί για την οργάνωση προστασίας κατά του εντοπισμού σφαλμάτων: μπορούμε να δημιουργήσουμε τον δικό μας χειριστή SEH και να τον τοποθετήσουμε στην κορυφή της στοίβας και στη συνέχεια να αναγκάσουμε τη γενιά int 3h. Εάν ο χειριστής μας πάρει το στοιχείο ελέγχου, η διαδικασία δεν διορθώνεται - διαφορετικά μπορούμε να επιβάλουμε μέτρα κατά του εντοπισμού σφαλμάτων καθώς εντοπίσαμε ένα πρόγραμμα εντοπισμού σφαλμάτων.
Αυτές είναι μόνο μερικές τεχνικές κατά του εντοπισμού σφαλμάτων από μια μεγάλη ποικιλία από αυτές.
Μια καλή πρακτική είναι ο συνδυασμός διαφορετικών τεχνικών κατά της αναστροφής καθιστώντας πολύ πιο δύσκολη την παράκαμψη της προστασίας. Πρόσθετοι έλεγχοι μπορούν να επιβραδύνουν την εκτέλεση μιας εφαρμογής, γι' αυτό συνήθως εφαρμόζονται οι ισχυρότερες τεχνικές προστασίας στις βασικές μονάδες που περιέχουν κατοχυρωμένες τεχνολογίες και τεχνογνωσία. Τέλος, είναι μια αντιστάθμιση μεταξύ του επιπέδου ασφάλειας του κώδικα και της απόδοσης της εφαρμογής.
Θα ήθελα να αναφέρω ότι η αντίστροφη μηχανική λογισμικού δεν είναι πάντα παράνομη και μερικές φορές μπορεί να εφαρμοστεί κατά τη διάρκεια της ερευνητικής διαδικασίας για εργασίες όπως η βελτίωση συμβατότητας, η ενημέρωση κώδικα, η μη τεκμηριωμένη χρήση διεπαφής συστήματος κ.λπ. Νομικές υπηρεσίες αντίστροφης μηχανικής που παρέχονται από επαγγελματίες ασχολούνται επίσης με την προστασία κατά του εντοπισμού σφαλμάτων, αλλά από την άλλη πλευρά - παρακάμπτοντάς την.