Reverse Engineering RET Homepage RET Members Reverse Engineering Projects Reverse Engineering Papers Reversing Challenges Reverser Tools RET Re-Search Engine Reverse Engineering Forum Reverse Engineering Links

Go Back   Reverse Engineering Team Board > Reverse Engineering Board > .NET Reverse Engineering
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Display Modes
  #1  
Old 12-08-2009, 11:20 AM
remko remko is offline
Member
 
Join Date: Dec 2009
Posts: 8
Default advise on .net executable

I have some experience in win32/native RCE but .net is completely new to me. I have a target .net executable that is obfuscated with Smart Assembly. I have tried DeSmart (1.0.0.9) and it appears to de-obfuscate (the result is readable in reflector.net). However the executable crashes on startup.

The target seems to be produced in vb.net.

Any advice or tips on how to proceed is welcome, I could provide the target exe if needed (by PM please).
Reply With Quote
  #2  
Old 12-08-2009, 03:47 PM
bball0002 bball0002 is offline
Senior Member
 
Join Date: Mar 2009
Posts: 72
Default

Can you give us a link to the target?
Reply With Quote
  #3  
Old 12-08-2009, 03:54 PM
remko remko is offline
Member
 
Join Date: Dec 2009
Posts: 8
Default

I put the file on rapidshare and SendSpace (pwd in pm), thanks!

Last edited by remko : 12-08-2009 at 04:44 PM. Reason: Added SendSpace link
Reply With Quote
  #4  
Old 12-08-2009, 04:26 PM
bball0002 bball0002 is offline
Senior Member
 
Join Date: Mar 2009
Posts: 72
Default

The file won't run because you only sent me the dlls and not the installer, but if you open the app in cff explorer, go to the methods section under Tables. Go to method 9290, and that is the entrypoint method. I'm not sure if there's some kind of login form or something, because again I can't load the program, but if there is you could probably patch this method to load the mainform instead.

This is the method:

Code:
L_00000000:   call 0x06000005
L_00000005:   call 0x0A000E34
L_0000000A:   call 0x0A0011AB
L_0000000F:   leave.s 0x00000012
L_00000011:   endfinally
L_00000012:   call 0x06002468
L_00000017:   ldarg.0
L_00000018:   callvirt 0x0A000E2F
L_0000001D:   ret
If there's some sort of registration form or a login form, you can probably just patch it to load the mainform, as I said above. You can try patching it in Reflector with the ReflexIL plugin, and if that doesn't work (it should), then open the app in a hex editor and go to 0x108FB0 (method start), and edit the method that way.

Last edited by bball0002 : 12-08-2009 at 04:50 PM.
Reply With Quote
  #5  
Old 12-09-2009, 05:24 AM
remko remko is offline
Member
 
Join Date: Dec 2009
Posts: 8
Default

I think the problem lies here:
Code:
unit  Namespace_01;
interface
type
strict private Class_01 = class sealed
    // Methods
    function Class_01.Method_00(num1: Integer): string;
    var
        buffer: Byte[];
    begin
        lock (typeof(Class_01))
        beginif (Class_01.Field_00 = nil) then
            begin
                executingAssembly := Assembly.GetExecutingAssembly;
                Class_01.Field_00 := executingAssembly.GetManifestResourceStream(executingAssembly.ManifestModule.ModuleVersionId.ToString('B'));
                publicKeyToken := executingAssembly.GetName.GetPublicKeyToken;
                if (publicKeyToken <> nil) then
                begin
                    index := 0;
                    repeat
                        Class_01.Field_01 := (Class_01.Field_01 xor ((publicKeyToken[index] shl 8) + publicKeyToken[(index + 1)]));
                        inc(index, 2)
                    until (index >= (publicKeyToken.Length - 1))
                end;
                num2 := (((MethodBase.GetCurrentMethod.MetadataToken and $ffffff) - 1) mod $ffff);
                Class_01.Field_01 := (Class_01.Field_01 xor num2)
            end;
            Class_01.Field_00.Position := (num1 - Class_01.Field_01);
            num3 := Class_01.Field_00.ReadByte;
            count := 0;
            if ((num3 and $80) = 0) then
                count := num3;
            if ((num3 and $40) = 0) then
                count := (((num3 and $3f) shl 8) + Class_01.Field_00.ReadByte)
            else
                count := (((((num3 and $1f) shl $18) + (Class_01.Field_00.ReadByte shl $10)) + (Class_01.Field_00.ReadByte shl 8)) + Class_01.Field_00.ReadByte);
            buffer := New(array[count] of Byte);
            Class_01.Field_00.Read(buffer, 0, count)
        end;
        if (buffer.Length = 0) then
            begin
                Result := string.Empty;
                exit
            end;
        bytes := Convert.FromBase64String(Encoding.UTF8.GetString(buffer, 0, buffer.Length));
        begin
            Result := string.Intern(Encoding.UTF8.GetString(bytes, 0, bytes.Length));
            exit
        end
    end;


    // Fields
    strict private class var Field_00: Stream;
    strict private class var Field_01: Integer = 0;

end;
and it called in the code like this:
Code:
    function LandBase.ToString: string;
    begin
        Result := string.Format(Class_01.Method_00($7588), self.Naam)
    end;
It seems to return a string from an encrypted resource and this fails because the public key has changed??
Reply With Quote
  #6  
Old 12-09-2009, 05:45 AM
remko remko is offline
Member
 
Join Date: Dec 2009
Posts: 8
Default

Quote:
Originally Posted by bball0002 View Post
...
If there's some sort of registration form or a login form, you can probably just patch it to load the mainform, as I said above. You can try patching it in Reflector with the ReflexIL plugin, and if that doesn't work (it should), then open the app in a hex editor and go to 0x108FB0 (method start), and edit the method that way.
I tried but any change made to the file will make it crash.
Reply With Quote
  #7  
Old 12-09-2009, 06:57 AM
kao kao is offline
Senior Member
 
Join Date: Sep 2007
Posts: 184
Default

You are right, using public key token to decode parts of code/resources/strings is very popular method these days.. .NET Reactor does the same.
Easiest solution is to modify your function Class_01.Method_00() to use hardcoded decryption key instead of public key token.
Reply With Quote
  #8  
Old 12-09-2009, 07:44 AM
remko remko is offline
Member
 
Join Date: Dec 2009
Posts: 8
Default

Quote:
Originally Posted by kao View Post
Easiest solution is to modify your function Class_01.Method_00() to use hardcoded decryption key instead of public key token.
Sounds like a good idea, what confused me however, I tried to get the Public Key Token (with Powershell) like this:
Code:
[System.Reflection.Assembly]::LoadFile('target.exe').GetName().GetPublicKeyToken()
but the result is null, please advise how to get the public key token.
Reply With Quote
  #9  
Old 12-09-2009, 10:29 AM
remko remko is offline
Member
 
Join Date: Dec 2009
Posts: 8
Default

OK, I read the code again and the Public Key Token can be null (which it is). I also checked GetManifestResourceStream(executingAssembly.Manife stModule.ModuleVersionId.ToString('B')) and the result is
Code:
{2602d3bb-5287-4d6f-9a35-61240bcf8c57}
which is a resource (probably encrypted or encoded strings.

How to get the value of this: MethodBase.GetCurrentMethod.MetadataToken ?
Reply With Quote
  #10  
Old 12-09-2009, 11:17 AM
kao kao is offline
Senior Member
 
Join Date: Sep 2007
Posts: 184
Default

PublicKeyToken should be null only if assembly is not signed by strong name key. Are you sure about that? Check the original file, not the one produced by DeSmart.

GetCurrentMethod.MetadataToken is an identifier of the current method, in your case identifier of Class_01.Method_00().

I would use ILDASM and other Microsoft tools for all those tasks. It takes some time to get used to it's output but it's really powerful. It's possible that other tools (for example, Reflector) show method tokens as well, but I'm not sure about that..

Showing strong name token of an assembly (sn.exe is part of Microsoft.NET SDK):
Code:
C:\>sn -T test.exe

Microsoft (R) .NET Framework Strong Name Utility  Version 2.0.50727.42
Copyright (c) Microsoft Corporation.  All rights reserved.

Public key token is 67d0e8149152d3d2
Example ILDASM output from my test assembly:
Code:
.method /*060049B8*/ privatescope hidebysig static void  '3wW1VNpxI$PST060049B8'() cil managed noinlining
So, the token of method '3wW1VNpxI$PST060049B8' is 0x060049B8.
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump





Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.