1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Introduction to Cracking - (Part III)

Discussion in 'Ethical hacking Tips' started by SaswatPadhi, May 24, 2009.

  1. SaswatPadhi

    SaswatPadhi ~ Б0ЯИ Τ0 С0δЭ ~

    Joined:
    May 5, 2009
    Messages:
    1,343
    Likes Received:
    55
    Trophy Points:
    0
    Occupation:
    STUDENT !
    Location:
    Orissa, INDIA
    Home Page:

    Summary of previous parts



    In Part-I, and Part -II we saw Reflector can very accurately de-compile .NET apps and we also studies some basics of packing and obfuscation.
    We saw that Reflector cannot directly de-obfuscate obfuscated assemblies, so we need external tools to de-obfuscate .NET assemblies. {smartkill} is one such tool that can de-obfuscate assemblies obfuscated by {smartassembly}.
    Reflector can't also unpack/decrypt packed/crypted exes, so we need unpackers and decryptors. PEiD can identify huge array of packed and crypted exes, to make our lives easier.

    Introduction



    I think readers are starting to lose interest as I cover only theoretical aspects of cracking. So, in this part I will actually CRACK an app :wink:
    As I have written only about .NET cracking till now, so I would crack a .NET app. We will cover other languages gradually.

    Here is the link to the target of this article is : http://crackmes.de/users/w02057/crackme5_by_w02057/download

    Background



    The target is a Level-2 crackme, solved my me. This crackme was an easy one, designed by w02057.

    The author(w02057) gives the following information about his crackme:
    (*) Language : .NET
    (*) Platform : Windows

    The rule that the author stated for solving are:
    (*) No Patching : that would make it too easy :p
    (*) No Bruteforcing : that would make it time-consuming and boring

    ACTION :)



    (1) Load the crack me into Reflector: File --> Open --> Select crackme location

    (2) Expand the following: CrackMe5 --> frmMain --> btnValidate_Click

    (3) See that it works with the following:
    ..(*) txtKey : a textbox obviously
    ..(*) txtSerial : another textbox obviously
    ..(*) getserial : a function
    ..(*) check : a function

    (4) Click 'check' to goto the associated code. You will see this:
    Code:
    Private Function check(ByVal str As String) As Boolean
    	    Dim num As Integer = 0
    	    Dim num2 As Integer = 0
    	    Dim startIndex As Integer = 0
    	    Dim flag2 As Boolean = False
    		    Try 
    	        num2 = 1
    	        Do
    	            Dim num4 As Integer = (str.Length - 1)
    	            startIndex = 0
    	            Do While (startIndex <= num4)
    	                If (Conversions.ToDouble(str.Substring(startIndex, 1)) = num2) Then
    	                    If flag2 Then
    	                        Return False
    	                    End If
    	                    flag2 = True
    	                End If
    	                startIndex += 1
    	            Loop
    	            flag2 = False
    	            num2 += 1
    	        Loop While (num2 <= 9)
    	        If Operators.ConditionalCompareObjectEqual(Operators.AddObject(Operators.AddObject(Conversion.Int(str.Substring(0, 1)), Conversion.Int(str.Substring(4, 1))), Conversion.Int(str.Substring(8, 1))), 15, False) Then
    	            num += 1
    	        End If
    	        If Operators.ConditionalCompareObjectEqual(Operators.AddObject(Operators.AddObject(Conversion.Int(str.Substring(2, 1)), Conversion.Int(str.Substring(4, 1))), Conversion.Int(str.Substring(6, 1))), 15, False) Then
    	            num += 1
    	        End If
    	        If Operators.ConditionalCompareObjectEqual(Operators.AddObject(Operators.AddObject(Conversion.Int(str.Substring(0, 1)), Conversion.Int(str.Substring(3, 1))), Conversion.Int(str.Substring(6, 1))), 15, False) Then
    	            num += 1
    	        End If
    	        If Operators.ConditionalCompareObjectEqual(Operators.AddObject(Operators.AddObject(Conversion.Int(str.Substring(1, 1)), Conversion.Int(str.Substring(4, 1))), Conversion.Int(str.Substring(7, 1))), 15, False) Then
            	    num += 1
    	        End If
    	        If Operators.ConditionalCompareObjectEqual(Operators.AddObject(Operators.AddObject(Conversion.Int(str.Substring(2, 1)), Conversion.Int(str.Substring(5, 1))), Conversion.Int(str.Substring(8, 1))), 15, False) Then
    	            num += 1
    	        End If
    	        If Operators.ConditionalCompareObjectEqual(Operators.AddObject(Operators.AddObject(Conversion.Int(str.Substring(0, 1)), Conversion.Int(str.Substring(1, 1))), Conversion.Int(str.Substring(2, 1))), 15, False) Then
    	            num += 1
    	        End If
    	        If Operators.ConditionalCompareObjectEqual(Operators.AddObject(Operators.AddObject(Conversion.Int(str.Substring(3, 1)), Conversion.Int(str.Substring(4, 1))), Conversion.Int(str.Substring(5, 1))), 15, False) Then
    	            num += 1
    	        End If
            	If Operators.ConditionalCompareObjectEqual(Operators.AddObject(Operators.AddObject(Conversion.Int(str.Substring(6, 1)), Conversion.Int(str.Substring(7, 1))), Conversion.Int(str.Substring(8, 1))), 15, False) Then
    	            num += 1
    	        End If
    	    Catch exception1 As Exception
    	        ProjectData.SetProjectError(exception1)
    	        ProjectData.ClearProjectError
    	        Return False
    	    End Try
    	    Return (num = 8)
    	End Function
    (5) Press Back to go back and click 'getserial' to goto associated code. You will observe this:
    Code:
    Private Function getserial(ByVal str As String) As Object
            Dim obj2 As Object
            Try 
                Dim str3 As String = Conversions.ToString(Me.hash(str))
                Dim str2 As String = ""
                Dim startIndex As Integer = 0
                Dim num2 As Integer = (str.Length - 1)
                startIndex = 0
                Do While (startIndex <= num2)
                    str2 = (str2 & str3.Substring(CInt(Math.Round(CDbl((Conversions.ToDouble(str.Substring(startIndex, 1)) - 1)))), 1))
                    startIndex += 1
                Loop
                str = Conversions.ToString(Me.hash(str2))
                str2 = ""
                startIndex = 1
                Do
                    str2 = (str2 & str.Substring((startIndex * 4), 4))
                       If (startIndex <> 5) Then
                        str2 = (str2 & "-")
                    End If
                    startIndex += 1
                Loop While (startIndex <= 5)
                obj2 = Strings.UCase(str2)
            Catch exception1 As Exception
                ProjectData.SetProjectError(exception1)
                obj2 = Nothing
                ProjectData.ClearProjectError
            End Try
            Return obj2
        End Function
    (6) You see another unknown funtion 'hash' used in the first line of 'Try' block. So click 'hash' in Reflector and you go here:
    Code:
    Private Function hash(ByVal str As String) As Object
    	    Dim provider As New MD5CryptoServiceProvider
    	    Dim bytes As Byte() = Encoding.ASCII.GetBytes(str)
    	    bytes = provider.ComputeHash(bytes)
    	    str = ""
    	    Dim num As Byte
    	    For Each num In bytes
    	        str = (str & num.ToString("x2"))
    	    Next
    	    Return str
    	End Function
    NOTE FOR NEWBIES : Don't be afraid of seeing so much code. Your work is simple (as you will see when you read further). At max, you'll have to write about 10 lines :eek: of code.

    (7) So, now we have enough information, about what's going on inside :wink: :
    ..(*) The check function checks if the entered key is valid.
    ..(*) If key is valid, it generates a serial and matches the entered serial with it.
    Simple, isn't it ?

    (8) So, what we do to crack this easily is.. we try to understand what the check function expects as a GOOD key. Lets's analyze :

    OBSERVATION : Observe the Do...Loop While(num2 <= 9) loop inside the 'Try' block.
    CONCLUSION : It ensures that, there are not repeated digits in the key. Thus, note that, the key consists only of DIGITS no alphabets.
    OBSERVATION : Next move to the sequence of 'If' Checks. [ There are 8 'If's ]. If an 'If' is satisfied, num is increased by 1 ( 'cuz num += 1). At the end the function checks if num = 8.
    CONCLUSION : So, ALL 'If's must be satisfied.

    (9) Study the 'If's now. BTW, hover mouse over 'Substring' and 'Conversions' to know about them. See that, the author extracts the i'th character in the string str (which is the key), by using the command 'str.Substring(i-1, 1)'. So, 'str.Substring(1, 1)' would give the 2nd character in the key.
    Note that, the author uses i = 9 at max because he uses 'str.Substring(8, 1)' at maximum.
    So, we got a hint -- the author checks ONLY the first 9 chars of key.

    (10) Now, what does he check ?? Note again that, 'Conversion.Int(c)' returns the digit contained in the character c. As the key consists only of digits, 'Conversion.Int(str.Substring(i-1, 1))' would return the i'th digit in the key.

    (11) So, finally we get to know that the function 'check' does this:
    Code:
    	(*) Checks that first 9 digits in key are unequal.
    	(*) Checks that the key satisfies the following:
    		(1)  0 + 4 + 8 = 15
    		(2)  2 + 4 + 6 = 15
    		(3)  0 + 3 + 6 = 15
    		(4)  1 + 4 + 7 = 15
    		(5)  2 + 5 + 8 = 15
    		(6)  0 + 1 + 2 = 15
    		(7)  3 + 4 + 5 = 15
    		(8)  6 + 7 + 8 = 15
    		[ Here 0 represents 1st digit, 4 represents 5th digit and so on... ;) ]
    (12) So we need a unique permutation of the digits 123456789 as the first 9 digits which satisfies above. Simple observation leads to a better representation of the above conditions [ as a MAGIC SQUARE ]
    Code:
    	0   1   2   <-- 15
    
    	3   4   5   <-- 15
    
    	6   7   8   <-- 15
                       
         /  ^   ^   ^  \
        /	 |   |   |   \
       15	15  15  15   15
    
    Sum of each Row, Column and Diagonal is 15. So, lets fill up the magic square.

    (13) Representation of 15 as sum of 3 distinct natural numbers :
    Code:
    ..(*)   Using 1 :  1 + 6 + 8 [ as 1 can be present in 2 different combinations, it must be, ]
                       1 + 5 + 9 [ at the mid-point of a side of the magic square	       ]
    ..(*)	Using 2 :	2 + 6 + 7	[ as 2 can be present in 3 different combinations, it must be, ]
    	               2 + 5 + 8 [ at a vertex of of the magic square                           ]
    	               2 + 4 + 9
    ..(*)	Using 3 :	3 + 5 + 7	[ as 3 can be present in 2 different combinations, it must be, ]
    	               3 + 4 + 8 [ at the mid-point of a side of the magic square	       ]
    ..(*)	Using 4 :	4 + 2 + 9	[ as 4 can be present in 3 different combinations, it must be, ]
    	               4 + 3 + 8 [ at a vertex of of the magic square                           ]
    	               4 + 5 + 6
    We have enough hints now. So, we now have the magic square of the form:
    2 x x
    x x 1
    4 3 x

    Now we can fill up logically as follows:
    Code:
    (*) 1 and 3 cannot be opposite to each other as they are not together in any combination.
    (*) 4 should not be above or below 1 as they are not together in any combination.
    (*) Mid-Left is obviously 9.
    (*) Bottom-Right is obviously 8.
    Now we have:
    2 x x
    9 x 1
    4 3 8

    Code:
    (*) Center is of course 5
    (*) Top-Right is 6.
    (*) Mid-Top is 7.
    So finally we have the grid as:
    2 7 6
    9 5 1
    4 3 8

    So, the key corresponding to this is 276951438.
    NOTE: All other keys can be formed by simply rotating and transposing.

    (14) Now we know the valid keys. The getserial function can fetch us a valid serial for a key, so we don't need to be bothered about calculating a serial. We can just copy the getserial function (and the hash function, because getserial uses it) to VB.NET and can pass the keys as arguments to get the serials :wink:

    (15) So, we are done ! We have just finished a keygen for w02057's Crackme :happy:
    All the valid keys and serial combination are :
    Code:
    --------------------------------------------------
            KEYS              SERIALS
    --------------------------------------------------
    	276951438  :  7DFF-7430-C0FE-FB5E-5675
    	294753618  :  C528-6819-5244-62B2-9FA4
    	438951276  :  CDB6-32A6-C696-62DA-E1BA
    	492357816  :  3AE9-0717-B6B6-7AFC-D688
    	618753294  :  8DC0-E6A2-D499-0F1E-29D5
    	672159834  :  C520-15B6-6AFA-6B40-DFA1
    	816357492  :  CE71-5143-D977-A8EA-C38E
    	834159672  :  60D7-0189-3A7E-5172-CE21

    I hope you enjoyed making the keygen, as much as I enjoyed it.

    Greets to shabbir and all my friends here at G4EF and thanks to you for reading this long article !

    Take care and good bye :smile:
     
    delossantosrommel16 likes this.
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,283
    Likes Received:
    364
    Trophy Points:
    83
  3. mdjww

    mdjww New Member

    Joined:
    Jun 4, 2009
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    i have checked it’s really great
     
  4. SaswatPadhi

    SaswatPadhi ~ Б0ЯИ Τ0 С0δЭ ~

    Joined:
    May 5, 2009
    Messages:
    1,343
    Likes Received:
    55
    Trophy Points:
    0
    Occupation:
    STUDENT !
    Location:
    Orissa, INDIA
    Home Page:
    Thanx for the feedback ! :)
     
  5. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,283
    Likes Received:
    364
    Trophy Points:
    83
  6. anthzer0

    anthzer0 New Member

    Joined:
    Jul 13, 2009
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    Im new at this. Could you tell me how you plugged in the numbers for the magic cube? The 2, 3 and 4. I understood they equal 15 but not how they were placed where they were. Thanks :)
     
  7. SaswatPadhi

    SaswatPadhi ~ Б0ЯИ Τ0 С0δЭ ~

    Joined:
    May 5, 2009
    Messages:
    1,343
    Likes Received:
    55
    Trophy Points:
    0
    Occupation:
    STUDENT !
    Location:
    Orissa, INDIA
    Home Page:
    You can do that in two ways :

    (1) Use a logical approach as I mentioned in POINT (13) : You calculate "in how many different valid combinations, does a digit occur". From that knowledge, you can easily know its position.

    (2) Brute-force ! Write a program in any language of your choice to brute-force all the valid combinations.

    If you still have doubts, I can post a simple C++ Bruter here. Or I can explain POINT 13.
     
  8. !Newbie!

    !Newbie! New Member

    Joined:
    Apr 13, 2009
    Messages:
    131
    Likes Received:
    4
    Trophy Points:
    0
    Location:
    Around
    Good one...
     
  9. SaswatPadhi

    SaswatPadhi ~ Б0ЯИ Τ0 С0δЭ ~

    Joined:
    May 5, 2009
    Messages:
    1,343
    Likes Received:
    55
    Trophy Points:
    0
    Occupation:
    STUDENT !
    Location:
    Orissa, INDIA
    Home Page:
    Thanx !Newbie!. Glad that you liked it.
     
  10. naimish

    naimish New Member

    Joined:
    Jun 29, 2009
    Messages:
    1,046
    Likes Received:
    18
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    On Earth
    Awesome Man :)
     
  11. alok1995

    alok1995 New Member

    Joined:
    Jul 31, 2014
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    I want to know these things:-
    STEP(8) = OBSERVATION : Observe the Do...Loop While(num2 <= 9) loop inside the 'Try' block.
    CONCLUSION : It ensures that, there are not repeated digits in the key. Thus, note that, the key consists only of DIGITS no alphabets.
    how can i find this that there is only digits no alphabets and even digits are not repeated.
    STEP(14)= i am newbie so i don't know "how to " and "where is to" put getserial function.

    And by the way this is an amazing article on cracking
     

Share This Page