Jump to content
Nytro

assembly, c-sharp, anti-sandbox, anti-antivirus, anti-debug

Recommended Posts

Posted (edited)

assembly, c-sharp, anti-sandbox, anti-antivirus, anti-debug, and malware research

Hello fellow readers!

You all are probably wondering what the hell I’ve been up to this past month. Lot’s of stuff. This post is all over the place with code and slides and malware and general wackiness. Rather than spreading it out over several blog posts, I decided to just get it all over with so I can focus on cooler things in the future.

I saw an interesting webinar on sandbox detection techniques employed by malware by Cyphort. They haven’t released their slides like they said they would, so here are the ones I took. These are cool and all, but I felt like I could contribute.

I read an awesome paper on bypassing antiviruses by employing a number of code based tricks. The idea behind them was that AV’s will skip binaries based on certain behaviors. One thing missing though – an AV will skip the “dropper” heuristic if the file ends in ‘.msi’. All the code I saw was in C/C++. I figured why not try and convert it to assembly? Next thing to do is make a patcher that can inject these into pre-compiled binaries. A future project perhaps? Anyways, I only did 2 before I lost interest. Read the article here.

;AV bypass 1

xor eax, eax

db Caption "Joe"

db Text "Giron"

mov edx, 5F5E100h

joe:

inc eax

dec edx

jnz joe

cmp eax, 5F5E100h

jnz short urafag

push 0 ; MB_OK

push offset Caption

push offset Text

push 0 ; hWnd

call MessageBoxA

urafag:

xor eax, eax

retn

;AV bypass 1.5

; same as above, just using the loop instruction instead of branching conditionals

xor eax, eax

db Caption "Joe"

db Text "Giron"

mov ecx, 5F5E100h

joe: ; essentially do nothing

mov eax,10

mov ebx,20

xchg eax,ebx

loop joe

; now start code

xor eax,eax

xor ebx,ebx

push 0 ; MB_OK

push offset Caption

push offset Text

push 0 ; hWnd

call MessageBoxA

retn

;AV bypass 2

push ebx

push edi

push 5F5E100h ; bytes to alloc

push 40h ; zero init

call GlobalAlloc

mov ebx, eax

test ebx, ebx

jz short cleanup

mov edi, ebx

mov eax, 0FFFFFFF1h

mov ecx, 5F5E100h

rep stosb

push 0 ; MB_OK

push offset Caption ; "Joe"

push offset Text ; "Giron"

push 0 ; hWnd

call MessageBoxA

push ebx ; memory handler

call GlobalFree

cleanup:

xor eax, eax

pop edi

pop ebx

retn

Feels good to put my crappy assembly skills to good use. Especially now that I figured out how to use inline assembly within C#. Sort of. The way it works is by utilizing delegates and cramming code inside an executable code page. Observe this piece of genius:

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

namespace InLineAsm

{

static class Program

{

[unmanagedFunctionPointer(CallingConvention.StdCall )]

delegate void JoesAntiDebuggery();

[DllImport("kernel32.dll", SetLastError = true)]

static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, IntPtr flAllocationType, IntPtr flProtect);

static byte[] opcodez = {

0x55, 0x89, 0xE5, 0x31, 0xC0, 0xBA, 0x00, 0xE1, 0xF5, 0x05, 0x40, 0x4A, 0x75, 0xFC, 0x3D, 0x00,

0xE1, 0xF5, 0x05, 0x75, 0x14, 0x6A, 0x00, 0x68, 0x12 ,0x70, 0x40, 0x00, 0x68, 0x0C, 0x70, 0x40,

0x00, 0x6A, 0x00, 0xFF, 0x15, 0xD0, 0x80, 0x40, 0x00, 0x31, 0xC0, 0x68, 0x00, 0x70, 0x40, 0x00,

0xE8, 0x3B, 0x00, 0x00, 0x00, 0x59, 0x31, 0xC0, 0x89, 0xEC, 0x5D, 0xC3

}

// opcodes taken from disassembled program.

/*

__asm

{

xor eax, eax

mov edx, 5F5E100h

joe:

inc eax

dec edx

jnz joe

cmp eax, 5F5E100h

jnz short urafag

}

MessageBox(0,Text, Caption,0);

__asm

{

urafag:

xor eax, eax

}

*/

static IntPtr codeBuffer = VirtualAlloc(IntPtr.Zero, new UIntPtr((uint)opcodez.Length), (IntPtr)(0x1000 | 0x2000), (IntPtr)0x40);

// EXECUTE_READWRITE, MEM_COMMIT | MEM_RESERVE

Marshal.Copy(opcodez, 0,codeBuffer, opcodez.Length);

JoesAntiDebuggery JoeDbg = (JoesAntiDebuggery)

Marshal.GetDelegateForFunctionPointer(codeBuffer, typeof(JoesAntiDebuggery));

static void Main(string[] args)

{

Console.Write("lol");

JoeDbg();

}

}

}

It’s a thing of beauty – Assembly, C code, op codes / hex, delegates, and C#.

Moving on to what else I’ve been up to – pulling apart malwarez. This one piece gave me trouble for a few days. Namely because of the weird anti-debugging counter measure I encountered. I’m unsure if its even anti-debug as the conditions always seem to equate to false. I mean it’s easy to get around when you see it, but you can’t get around it automatically – you have to patch it. I even took a video of the weird behavior.

Took me some time, but I figured it out.

The following is the sequence called not 5 instructions after the entry point

anti-debuggery.png

sub_4017CF proc near

push ebp

mov edi, edx

add edi, ebx

not ebx

mov ebp, esp

add edi, ebx

add esp, 0FFFFFF94h

mov edx, ebx

inc ebx

mov ecx, esp

dec ebx

mov edi, eax

add ecx, 48h

mov ebx, ecx

dec edi

cmp eax, ecx

jz short labelforyou

neg edx

leave

not edx

mov eax, edi

neg eax

leave

add edx, edi

not edx

retn

labelforyou:

leave

retn

The first thing you may notice about this procedure is the weird stack frame setup. Most of the time, the intro stack frame will be “push ebp” followed directly by “mov ebp, esp”. This one is different in that it plays with the registers a little before the “mov ebp, esp” assembly codes. You may also notice the 2 “leave” instructions at the end of the procedure as opposed to the 1 for the “labelforyou” conditional. The 2 “leave” instructions are why the program jumps to ExitThread. When you leave a stack frame twice and ‘ret’, any windows program jumps to ntdll.RtlExitUserThread. An interesting intrinsic way of quietly exiting without warning.

But what about the code that leads up to the ‘JZ’ branch and the 2 leaves? The comparison is EAX to ECX. Every time I run, EAX always ends up as 1 and ECX as some stack address. I’m postulating that the malware I grabbed was extracted from a dropper. That makes sense given the stack value / pointer points to nothing useful.

If you’re curious what the malware does, it attempts to download and run a ‘doc’ file from a russian host. Inside the ‘doc’ file is HTML code with a meta redirect to a host my DNS server can’t seem to find:

what-it-do.png

You can download the malware here. Pass in ‘infected’.

The other piece of malware I went through lacked a DOS sub. Most exe’s have this little DOS application inside that reads “this program cannot be run in DOS mode” and is placed at the start of an exe just in case someone attempts to run an exe on an old DOS system. Its a forward compatibility thing Microsoft does. Compare a normal exe to the binary:

w1-300x91.png

So how the hell do you remove the DOS sub and still maintain functionality? According to TinyPE, you do it in assembly via zeroing out the MZ header with the exception of the ‘e_magic’ field ‘MZ’ at the start and the ‘e_lfanew’ field value at the bottom. The ‘e_lfanew’ field is just a 4 byte offset to where the PE header is located.

mzhdr:

dw "MZ" ; e_magic

dw 0 ; e_cblp UNUSED

dw 0 ; e_cp UNUSED

dw 0 ; e_crlc UNUSED

dw 0 ; e_cparhdr UNUSED

dw 0 ; e_minalloc UNUSED

dw 0 ; e_maxalloc UNUSED

dw 0 ; e_ss UNUSED

dw 0 ; e_sp UNUSED

dw 0 ; e_csum UNUSED

dw 0 ; e_ip UNUSED

dw 0 ; e_cs UNUSED

dw 0 ; e_lsarlc UNUSED

dw 0 ; e_ovno UNUSED

times 4 dw 0 ; e_res UNUSED

dw 0 ; e_oemid UNUSED

dw 0 ; e_oeminfo UNUSED

times 10 dw 0 ; e_res2 UNUSED

dd pesig ; e_lfanew

But what about doing it to a pre-compiled binary? I just used CFF explorer and HXD. Jot down the ‘e_lfanew’ field offset and zero out the entries between the PE header, the MZ field, and the ‘e_lfanew’ field:

remove_dos_sub.png

The malware does code running modification and is surprisingly sophisticated, but this blog post is long enough. I’m done for now.

The next post will be much more interesting, however its unfinished and needs more research. Except it soon.

BiNUecP.jpg

This entry was posted on Saturday, November 22nd, 2014 at 1:51 pm and is filed under code, Joe you evil bastard, reversing. You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.

Sursa: assembly, c-sharp, anti-sandbox, anti-antivirus, anti-debug, and malware research « Joe's Security Blog

Edited by Nytro

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...