Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Deface σε managed κώδικα...

Îåêßíçóå áðü ôï ìÝëïò Thiseas. Τελευταία δημοσίευση από το μέλος KelMan στις 18-02-2008, 12:13. Υπάρχουν 6 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  05-06-2007, 16:32 32633

    Deface σε managed κώδικα...

    To deface είναι μια "διαδικασία" κατά την οποία "χαλάμε" ή αλλάζουμε προς το συμφέρον μας κάποιο αντικείμενο, όπως μια
    εικόνα, ένα πρόγραμμα ακόμα κι ένα web site. Η διαδικασία του deface δεν δηλώνει (σχέδον ποτέ) ικανότητα και μαγκιά!
    Συνήθως πραγματοποιείται από πιτσιρικάδες που έχουν βρεί 2,3 έτοιμα προγράμματα και εφαρμόζουν τις "ικανότητες" τους σε
    αθώους στόχους. Οι λόγοι που κάποιος κάνει ένα deface σε ένα πραγματικό περιβάλλον και όχι για εκπαιδευτικούς σκοπούς
    είναι πολλοί... βασικά όμως είναι η επίδειξη που συνεπάγεται μετριότητα και βλακεία!

    Αυτό που θέλω να πω με αυτό το post, συνδέοντάς το με κάποιο τρόπο με ένα προηγούμενο μου... που ίσως θεωρήθηκε
    αναχρονιστικό, είναι πως η λογική assembler και stack processing είναι αναπόσπαστο κομμάτι όχι μόνο των εφαρμογών του
    1980, 1990 αλλά και του 2000+.
    Κοινώς ... "τα ίδια παλιά καλά κρασιά σε νέα μπουκάλια".

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

    Επιτρέψτε μου να το εξηγήσω με ένα πάρα πολύ απλό παράδειγμα: Το παράδειγμα μου θα ακολουθεί επίτηδες τον παραδοσιακό
    τρόπο προγραμματισμού (από command line) πιο πολύ για να δείξω οτι υποστηρίζεται ακόμα (μετά από 10+ χρόνια windows
    domination).

    Πολοί είναι αυτοί που υποστηρίζουν οτι τα καλύτερα "κόλπα" γίνονται από command line... και δεν μιλώ μόνο για τους
    linuxάδες (που ίσχύει 100%) αλλά κ για τους win32...!


    Έστω οτι γράφουμε ένα πρόγραμμα το ίδιο χαζό με αυτό που είχαμε γράψει όταν κάναμε το παράδειγμα στο post για το "Πως
    λειτουργεί ένα πρόγραμμα....
    "

    Αυτή τη φορά θα γράψουμε σε C# και managed κώδικα:

    // Test3.cs
    public class test3
    {
       public static void Main()
       {
          function1 (10, 20, 30);
       }

       public static void function1 (int a, int b, int c)
       {
          string s;

          s = "Hello World!";
          System.Console.WriteLine(s);
       }
    }

    Κάνουμε compile από command line:
    c:\>csc test3.cs
    Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.42
    for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
    Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

    c:\>_


    Έχει δημιουργηθεί το test3.exe. Αυτό το 'exe' δεν ακολουθεί την δομή των "κλασικών" PE executables αλλά έχει πληροφορίες
    για τα περιεχόμενα του σε επίπεδο κλάσεων, μεταβλητών, members κλπ...

    Θα μπορούσαμε να φτιάξουμε έυκολα ένα πρόγραμμα που να τις διαβάζει αυτές τις πληροφορίες, αλλά δεν χρειάζεται γιατι το
    έχει κάνει η Microsoft για εμάς.
    Είναι το ildasm.exe (intermidiate language disassembler <- μάλλον )

    Καλώντας λοιπόν :
    c:\>ildasm test3.exe /all=test.il

    θα δημιουργήσει το αρχείο test.il με τον κώδικα σε CIL (common intermidiate language). Αυτός ο κώδικας μοιάζει πάρα πολύ με την
    assembly και αποτελείται από assembly-like intructions. Ο assembler αυτός δεν διαφέρει από τον assembler της "μηχανής"
    (π.x. τον περίφημο macro-assembler) και μαλιστα είναι stack oriented όπως θα δούμε παρακάτω.


    Πέρα από σημαντικά και ενδιαφέροντα στοιχεία για το πρόγραμμα μας που αναφέρονται μέσα στο test.il, για τις παραπάνω
    member functions θα δούμε:


    .class public auto ansi beforefieldinit test3
           extends [mscorlib]System.Object
    {
      .method public hidebysig static void  Main() cil managed
      {
        .entrypoint
        // Code size       11 (0xb)
        .maxstack  8
        IL_0000:  nop        --> Mην κάνεις τίποτε (no operation).
        IL_0001:  ldc.i4.10  --> LDC (load numeric constant) φόρτωσε από την μνήμη στο stack την τιμή 10
        IL_0002:  ldc.i4.20  --> LDC (load numeric constant) φόρτωσε από την μνήμη στο stack την τιμή 20
        IL_0003:  ldc.i4.30  --> LDC (load numeric constant) φόρτωσε από την μνήμη στο stack την τιμή 30
        IL_0004:  call       void test3::function1(int32,
                                                   int32,
                                                   int32)    --> Kάλεσε την function1 με παραμέτρους 3 intergers 32bits 
                                                             --> από το stack.
        IL_0009:  nop         --> μην κάνεις τίποτε (no operation).
        IL_000a:  ret         --> επέστρεψε στο λειτουργικό.
      } // end of method test3::Main
       
    Ομοίως για την function1 έχουμε:

      .method public hidebysig static void  function1(int32 a,
                                                      int32 b,
                                                      int32 c) cil managed
      {
        // Code size       15 (0xf)
        .maxstack  1
        .locals init ([0] string s)             --> Kαθορισμός της σχετικής address 0->μεταβλητής για την αποθήκευση της s.
        IL_0000:  nop 
        IL_0001:  ldstr      "Hello World!"     --> Φορτώνεται η σταθερά στο stack.
        IL_0006:  stloc.0                       --> Καταχωρείται στην μνήμη στη θέση 0 η μεταβλητή που
                                                --> τα περιεχόμενά της είναι ήδη στο stack (από την προηγ. εντολή).
        IL_0007:  ldloc.0                       --> Καταχωρείται από την μνήμη (θέση 0) στο stack.
        IL_0008:  call       void [mscorlib]System.Console::WriteLine(string) --> Εμφάνισε στην οθόνη οτι έχεις στο stack
        IL_000d:  nop
        IL_000e:  ret                           --> Eπέστρεψε απο όπου εκεί που κλήθηκες.
      } // end of method test3::function1

       
    Άν τρέξω το πρόγραμμα μου θα δω το εξής:
    c:\>test3
    Hello World!
       
    Τρομερό πρόγραμμα ε?
    Χμ...

    Έστω τώρα οτι εγώ έκανα deploy αυτό το πρόγραμμα και έβαζα κάπου μόνο το test3.exe.
    Κάποιος μπορούσε να παράξει τον intermidiate κωδικα του, δίνοντας όπως είπαμε:
    c:> ildasm test3.exe /out=test3.il

    Μετά θα μπορούσε να μπεί μέσα στον intermidiate κώδικα και να τον αλλάξει αλλάζοντας π.χ. τα λεκτικά ή καλύτερα βάζοντας
    δικά του.
    Στην συγκεκριμένη περίπτωση θα αλλάξει την function 'funtion1' ως εξής


      .method public hidebysig static void  function1(int32 a,
                                                      int32 b,
                                                      int32 c) cil managed
      {
        // Code size       15 (0xf)
        .maxstack  1
        .locals init ([0] string s)            --> καθορισμός της σχετικής address 0->μεταβλητής για την αποθήκευση της s
        IL_0000:  nop 
        IL_0001:  ldstr      "Hello World!"    --> Φορτώνεται η σταθερά στο stack.
        IL_0006:  stloc.0                      --> Καταχωρείται στην μνήμη στη θέση 0 η μεταβλητή που
                    --> τα περιεχόμενά της είναι ήδη στο stack (από την προηγ. εντολή)
        IL_0007:  ldloc.0                       --> Καταχωρείται από την μνήμη (θέση 0) στο stack.
        IL_0008:  call       void [mscorlib]System.Console::WriteLine(string) --> Εμφάνισε στην οθόνη οτι έχεις στο stack

        IL_000100:  ldstr      "Defaced by Thiseas!" --> Φορτώνεται η σταθερά στο stack.
        IL_000600:  stloc.0                          --> Καταχωρείται στην μνήμη στη θέση 0 η μεταβλητή που
                                                     --> τα περιεχόμενά της είναι ήδη στο stack (από την προηγ. εντολή)
        IL_000700:  ldloc.0                          --> Καταχωρείται από την μνήμη (θέση 0) στο stack.
        IL_000800:  call       void [mscorlib]System.Console::WriteLine(string) --> Εμφάνισε στην οθόνη οτι έχεις στο stack.

        IL_000d:  nop
        IL_000e:  ret         --> επέστρεψε απο όπου εκεί που κλήθηκες.
      } // end of method test3::function1


    Μπορώ τώρα όμως να παράξω το test3.exe από τον παραπάνω αλλαγμένο intermidiate κώδικα?
    Φυσικά.
    Καλώντας τον assembler:

    c:\>ilasm test3.il

    Microsoft (R) .NET Framework IL Assembler.  Version 2.0.50727.42
    Copyright (c) Microsoft Corporation.  All rights reserved.
    Assembling 'test3.il'  to EXE --> 'test3.exe'
    Source file is ANSI

    Assembled method test3::Main
    Assembled method test3::function1
    Assembled method test3::.ctor
    Creating PE file

    Emitting classes:
    Class 1:        test3

    Emitting fields and methods:
    Global
    Class 1 Methods: 3;
    Resolving local member refs: 1 -> 1 defs, 0 refs, 0 unresolved

    Emitting events and properties:
    Global
    Class 1
    Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
    Writing PE file
    Operation completed successfully

     

    Άν τρέξω το πρόγραμμα μου θα δω το εξής:
    c:\>test3
    Hello World!
    Defaced by Thiseas
    !

    Η διαδικασία ήταν πάρα πολύ απλή. Μάλιστα είναι πολύ πιο απλή από το όταν είχαμε traditional ΕΧΕs... που μπορούσανε
    βέβαια και αυτά να "πειραχτούν" υπο τις κατάλληλες προυποθέσεις ή με έναν απλό hex-editor. Για μεγάλες αλλάγες όμως
    συνήθως ήταν πιο δύσκολο.

    Συμπέρασμα:
    Παλαιότερα το πάρεις όλες τις πληροφορίες, την ονοματολογία, τα μεγέθοι, τις κλάσεις κλπ κλπ από ένα EXE ήτανε απλά αδύνατον.
    Τώρα είναι δυνατόν.
    Το θεωρείται καλύτερο ή χειρότερο?
    Ασφαλέστερο ή όχι?
    Να μπορεί ο καθένας να δει σχεδόν τον κώδικά σας...επεμβαίνοντας κατά βούληση?

     


    Nothing to declare...
  •  05-06-2007, 17:24 32635 σε απάντηση της 32633

    Απ: Deface σε managed κώδικα...

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

    Ως προς τη …«δημόσια θέα» του κώδικα, η λύση είναι το obfuscation. Ακόμα και με την community έκδοση του obfuscator που έρχεται μαζί με το Visual Studio μπορεί να γίνει σωστή δουλειά. Από εκεί και πέρα, αν θέλουμε κάτι ακόμα πιο δυνατό, αγοράζουμε το κάποιο εργαλείο με ακόμα περισσότερες δυνατότητες (στο θέμα του obfuscation). Πάντως γενικότερα το θέμα του δημόσιου κώδικα δε με απασχολεί. Θεωρώ ότι το σύγχρονο business model είναι περισσότερο θέμα υπηρεσιών και λιγότερο προϊόντων. Σκέφτομαι ότι, σε καμία εφαρμογή που έχω γράψει δεν έχω κάνει κάτι πραγματικά πρωτοποριακό που να αξίζει να κλειδωθεί. Το μεγαλύτερο ποσοστό της κάθε μου εφαρμογής είναι implementation πάνω σε κοινή γνώση που μπορεί να βρει κανείς ακόμα και στο MSDN. Περισσότερο ανησυχώ μην αποκαλυφθεί ότι χρησιμοποιώ GOTO Big Smile

    Τώρα, ως προς το deface, εδώ η λύση είναι τα «strong names». Πέρα από το θέμα του versioning, τα strong-named assemblies δεν επιτρέπουν την αλλαγή του κώδικα σε binary επίπεδο. O μηχανισμός είναι πολύ απλός και δεν χρειάζεται να πληρώσουμε λεφτά σε VeriSign, κλπ. Αρχικά παράγουμε ένα public/private key ζευγάρι με το sn tool. Κατά το build κάνουμε sign το assembly μας με το private key. Κατά τη διαδικασία του signing δημιουργείται ένα hash value από ολόκληρο το assembly που αποτελεί τη ψηφιακή υπογραφή του assembly. Κατόπιν, αυτό το hash value κρυπτογραφείται με to private key. Τώρα, κατά τη στιγμή που το CLR φορτώνει το assembly, το κάνει hash και με το public key κάνει  decrypt το hash value που είχε το assembly όταν έγινε signed. Μόνο αν ταιριάζουν αυτά τα δύο εκτελείται το assembly.


    Vir prudens non contra ventum mingit
  •  05-06-2007, 23:03 32641 σε απάντηση της 32635

    Απ: Deface σε managed κώδικα...

    Σ' ευχαριστώ Μάνο για την απάντηση σου.

    Πρέπει να συμφωνήσω μαζί σου και να πω οτι πράγματι το obfuscation είναι ένας καλός αν και όχι 100% (όπως είπες κι εσύ) ασφαλής τρόπος για να κρύψουμε των κώδικα μας από αδιάκριτα μάτια.

    Τώρα, για τα strong names... χρειάζομαι λίγο διάβασμα ακόμα για να αποφανθώ με κάποιο δικό μου παράδειγμα... πρέπει όμως να σου αναφέρω όμως οτι υπάρχουν σοβαρές αντιρήσεις από κάποιους... Stick out tongue


    Nothing to declare...
  •  05-06-2007, 23:42 32643 σε απάντηση της 32641

    Απ: Deface σε managed κώδικα...

    Εκεί όπου σταματάνε οι obfuscators, ξεκινούν οι protectors. Το μειονέκτημα είναι η δυσκαμψία που προσθέτουν στο τελικό σύνολο.

    Πάντως, σε αυτά που αναφέρει ο Μάνος, συμπληρώνω ότι η νοοτροπία των χρηστών διαφέρει αρκετά από αυτήν που νομίζουμε. Πειρατές θα υπάρχουν πάντα, καθώς ό,τι κλειδώνει, ξεκλειδώνει. Το λάθος είναι να θεωρούμε μία πειρατική κόπια ως μία χαμένη κόπια. Ωστόσο οι legitimate χρήστες που θα πληρώσουν κάτι που τους χρησίμεψε σε μια λογική τιμή κατά τη γνώμη μου αποτελούν πλειοψηφία. Οι σχεδόν παρανοϊκές απόπειρες κλειδώματος (πχ με dongles) συνήθως οδηγούν στην απομάκρυνση όχι μόνο των πειρατών, αλλά και των legitimate χρηστών! Παραδείγματα υπάρχουν πολλά, στα παιχνίδια (starforce), στη δημιουργία μουσικής (iLok dongles) κοκ τα οποία αποδεικνύουν το παραπάνω.

    Μην αφήνετε τα media να σας "ταΐζουν"!
  •  06-06-2007, 01:28 32644 σε απάντηση της 32643

    Απ: Deface σε managed κώδικα...

    Ναι, γενικά η φιλοσοφία που θα πρέπει να διέπει την προστασία των εφαρμογών θα πρέπει να είναι "λογικά αντίμετρα για λογικούς κινδύνους". Όπως τα αυτοκίνητα. Αν έχεις ένα μικρό αυτοκίνητο των 10.000€ θα βάλεις ανάλογο απλό συναγερμό που δεν έχει καμία σχέση με τον συναγερμό που θα έβαζες σε ένα αυτοκίνητο των 200.000€. Αν βγάλω μία εφαρμογή shareware, θα βολευτώ με τον comunity edition obfuscator που σε συνδυασμό με ένα strong named assenbly θα δυσκολέψει αρκετά αυτούς που θα ασχοληθούν με την εφαρμογή μου. Αν θέλω κάτι παραπάνω, μπορώ και να προσθέσω σύστημα προστασίας με activation over internet. Είναι σχετικά απλό, αλλά έχει κι αυτό τα μειονεκτήματά του, βλ. διαχειριστικό κόστος από πλευράς μου και ανάγκη να έχει internet connection o πελάτης. Τα πάντα έχουν μειονεκτήματα και πλεονεκτήματα. Το θέμα είναι να τα ξέρεις και να παίρνεις τη σωστότερη απάντηση κάτω από δεδομένες συνθήκες.

    Τώρα, ως προς τα strong named assemblies. O μηχανισμός των strong names δεν είναι τόσο πολύ για security όσο για versioning. Προστατεύει ως έναν βαθμό αλλά για να γίνει ισχυρός μηχανισμός θα πρέπει το assenbly να σχετιστεί με ένα certificate γιατί διαφορετικά έχουμε "μισό" μηχανισμό προστασίας. Το certificate είναι που δίνει trusted assemblies τα οποία μέσω .ΝΕΤ framework security policies (τα οποία παίζουν σε επίπεδο enterprise, machine ή user) μπορούν να οριοθετήσουν τα δικαιώματα που έχει το assembly.

    Τέλος, ως προς το ότι αποτελεί πρόβλημα να χάσεις το private key, ε τώρα τι να πω... Σαφώς, υπάρχουν κάποιες δυνάμεις στις οποίες υποκύπτουν ακόμα και τα ισχυρότερα συστήματα ασφάλειας. Τέτοιες είναι οι δυνάμεις της χαζομάρας και της βλακείας (πάνω στις οποίες στηρίζεται το social engineering) καθώς και η δύναμη "έχω χάσει το μυαλό μου και δεν θυμάμαι που παράτησα το flash disk με το private key" Big Smile


    Vir prudens non contra ventum mingit
  •  18-02-2008, 12:01 40281 σε απάντηση της 32633

    Απ: Deface σε managed κώδικα...

    μια μικρή επισήμανση μόνο όσον αφορά τα strong names.

    δυστυχώς δεν προσφέρουν απολύτως τίποτε. υπάρχουν εργαλεία με τα οποία απλά τα αφαιρείς, καθώς και τα references τους στα υπόλοιπα assemblies.

    ένα τέτοιο εργαλείο είναι και αυτό.

  •  18-02-2008, 12:13 40283 σε απάντηση της 40281

    Απ: Deface σε managed κώδικα...

    Όπως ανέφερα,

    KelMan:

    O μηχανισμός των strong names δεν είναι τόσο πολύ για security όσο για versioning. Προστατεύει ως έναν βαθμό αλλά για να γίνει ισχυρός μηχανισμός θα πρέπει το assenbly να σχετιστεί με ένα certificate γιατί διαφορετικά έχουμε "μισό" μηχανισμό προστασίας. Το certificate είναι που δίνει trusted assemblies τα οποία μέσω .ΝΕΤ framework security policies (τα οποία παίζουν σε επίπεδο enterprise, machine ή user) μπορούν να οριοθετήσουν τα δικαιώματα που έχει το assembly.

    Που σημαίνει, αν έστω χρησιμοποιήσεις το εργαλείο που αναφέρεις, δεν θα έχεις πλέον trusted assemblies οπότε δεν θα μπορούν να τρέξουν λόγω policies.


    Vir prudens non contra ventum mingit
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems