Wednesday, June 29, 2011

Challenges in developing unicode exploits

In a precious post, i wrote about exploiting a stack buffer overflow for the vulnerable version of minishare (version 1.4.1). This was basically my interpretation and understanding of lupin's write up of the same exploit in tutorial form over here. If you need more elaboration on the exploit writing process, i suggest that you look at his tutorial on exploiting minishare (there are other tutorials as well). There is also a good tutorial at corelan.be on writing exploits. It was the tutorials over at corelan that got me into unicode exploits. This is a very length tutorial on unicode exploits that made me really understand the challenges in writing such an exploit.

Unicode exploits are basically the same as traditional stack buffer overflow exploits but it comes with a bigger challenge. The idea between both exploit types are the same; Overwrite EIP (or seh) with a useful address that would execute a command that jumps us back to our buffer that contains our code. Although their goals are the same, how you would go about achieving these goals differ.

The differnce that you would notice from the traditional ascii exploit and a unicode one is that every byte is appended with a null or 0x00 byte. For example, the string "DOG" in uppercase will be "44 4F 47" in ascii bytes. The unicode representation of the same string will be " 44 00 4F 00 47 00". So if when you overwrite a buffer with a crap load of AAAAAAAAA's, in a unicode exploit, each A in the buffer will be appened with a null. Therefore your buffer will look like this in bytes: "41 00 41 00 41 00 41 00 41 00 ...".

Usually with unicode exploits, you are quite limited in what memory addresses you can overwrite EIP or SEH with and you also have a limed instruction set in which you can use. You must accept that every byte in your supplied buffer will contain a trailing null byte and work your way from there. This also means that your buffer must contain code thats unicode compatible. For example, putting a short jump where the next seh address resides, i.e jmp 0x6, is common in seh exploits to jump over seh address towards your shellcode. This jmp 0x6 in bytes is " eb 06". If when send this in our buffer, the nulls will be appeneded to each byte before the code is run, i.e "eb 00 06 00" . If you look at the instructions that these bytes represents, its not what you would've intended it to be. This is a major point that must be kept in mind when dealing with unicode exploits.

You must be wondering how do we overcome the limitations discussed earlier. You basically use unicode compatible instructions to accomplish the same thing. These instructions include single byte instructions like push, pop, inc, dec and ret just to name a few. When using single byte instructions, each instruction must be seperated by some nop-equivalent code in the form of "00 nn 00" where nn will be an opcode that will give the effect of a nop instruction. There are not too many opcodes that we can use here. Some of them are 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x62 and 0x6D. These opcodes when used in the format "00 nn 00" will produce assembly instrunctions like "add byte ptr [ebp], ch". Replacing nn with one of the opcode bytes would produce something similar. For this to work however, the relevant register (ebp in our example) must contain an address which is writeable or else an exception will occur. Each opcode byte will normally result in giving you a different register at your disposal. Because the code that this produces probly would not affect our buffer (or shellcode), it can be used as filler or nop-like code in between single byte instructions and other relevant code pieces. If you need further elaboration of the uses on this, please read the unicode exploit over at corelan.be. They did a great job explaining this, but most importantly, they also walk you through developing an exploit using the above mentioned techniques.

Some things to keep in mind.
  1. After you found that you can overwrite eip or seh, you will need to find a usable unicode compatible address, i.e, in the form of 00nn00nn. So in the case of an seh exploit, you gonna need to find an address to a pop pop ret (like in a typical seh exploit) but this address must be in the format of 0x00nn00nn. The pvefindaddr plugging for immunity debugger can automate this process.
  2. Make use of single byte instructions like push, pop, inc, dec, and ret and seperate each with one of the nop-like opcodes i mentioned earlier (0x6D, 0x6E, 0x6F, 0x70, 0x71 etc. This will cause opcode to align itself in a way that is unicode compatible.
  3. Shellcode must be encoded with unicode compatible encoder. You can also use metasploit for this: # msfpayload windows/exec CMD=clac.exe R | msfencode -e x86/alpha_mixed -t raw | msfencode -e x86/unicode_upper -t raw BufferRegister=EAX
  4. Unicode encoders usually need you to have at least one register pointing to the begining of the shellcode. Here is an example of how this can be accomplished. Suppose we wanted to get the address of 0x00401030 into eax then jump to it. We can accomplish this like so:
Opcode: Assembly:

B8 00110011 MOV EAX,11001100
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
2D 00010011 SUB EAX,11000100
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
50 PUSH EAX
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
4C DEC ESP
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
58 POP EAX
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
05 00300040 ADD EAX,40003000
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
50 PUSH EAX
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
44 INC ESP
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
58 POP EAX
006D 00 ADD BYTE PTR SS:[EBP],CH //Filler / Nop-like code
C3 RETN

If we were to see this as a stream of bytes, it would look like "B8 00 11 00 11 00 6D 00 2D 00 01 00 11 00 6D 00 50 00 6D 00 4C 00 6D 00 58 00 6D 00 05 00 30 00 40 00 6D
00 50 00 6D 00 44 00 6D 00 58 00 6D 00 C3"

This is unicode compatible code, often known as venetian code. Remember when you are writing your exploit, you will not be including the null bytes. These would get automatically inserted for you when your exploit overflows the buffer.

Saturday, June 4, 2011

Automate log monitoring and get email notifications with swatch

The swatch program (simple watcher) can monitor all sorts of logs and respond to certain events when they occur. Its concept is quite simple. Swatch will monitor a logfile for us , for example, /var/log/syslog, and when a specific event occurs (these events are configured in the swatch config file) and are logged in the log file, swatch can respond by executing a program, sending an email to a sysadmin or sending messages to the console where swatch is being run.

A simple example of swatch in action. If you are the sole sysadmin of a webserver, you would probly want to be notified if someone attempts to try to log into your server (could be over ssh or other authentication services). Being the sole admin of the webserver, no one else should have any business being on the system. Anyone but the admin attempting to login to the system obviously doesn't belong there and may have bad intentions. In this case, you can set up swatch to monitor the auth.log file for failed logon attempts and succesful logon attempts and then send you an email whenever their is attempts from anyone to log in. Of course this will notify you even when you log on to the machine, therefore this might be more practical if you have an unattended system (maybe you are on vacation or away on business).

I use an email program which is actually a perl script, called sendemail. On a debian based system, you can install it via apt-get install sendemail. Likewise, to install swatch, apt-get install swatch. Once both are installed, a simple configuration for swatch is as follows

watchfor /sshd/
echo bold
bell 3
exec "/usr/bin/sendemail -s smtp.live.com:25 -f youremail@hotmail.com -xu youremail@hotmail.com -xp your_hotmail_pass -u "Log alert" -m "Possible SSHD login attemp" -t youremail@hotmail.com -s smtp.live.com"


Save the above to a text file with an appropriate name such as swatch.conf

Then we can execute swatch like this:
# swatch --config-file=/path/to/swatch.conf --script-dir=/path/to/your_config_dir --examine=/var/log/auth.log

Whenever someone attempts to login to your sshd server, the sshd daemon will log the login attemp in /var/log/auth.log. The swatch program will monitor the auth.log file for the string sshd and whenever it gets a match, it will leave a notification on the console and then send an email to youremail@hotmail.com. The swatch program understands regex expressions so you can perform more advanced matches instead of a simple string like sshd.

Tuesday, May 31, 2011

OpenVPN Cont. - Adding username/password authentication to openvpn

This post basically adds onto the steps outlined in the previous post. By adding username/password authentication, you are essentially providing a two factor authentication mechanism to your openvpn server. The client would need a usable client certificate and key to authenticate itself to the server, as well as provide a valid username and password.

We have already discussed using certifcate authentication in the previous post so i wont be going over that here. To add the user/pass mechanism we would be adding to our already existing configuration files one or two lines.

In the server config file, add the following:
plugin /usr/lib/openvpn/openvpn-atuh-pam.so system-auth

On the server create a group called vpn
# groupadd vpn

Then we can create each user:
# useradd -s /bin/false -g vpn vpntest // this creates the user and puts them in the vpn group
# passwd vpntest // gives the user vpntest a password for authentication

On the client config file, add the following:
auth-user-pass
pull

Thats it. Keep in mind that we were adding to our config files from the previous post, so it is presumed that you already have a working openvpn server that accepts client key/certificate authentication

Resources/Good Reading:
http://www.uno-code.com/?q=node/120

Saturday, May 28, 2011

OpenVPN configs made easy

If you are reading this, i'm assuming that you would already know what a VPN is. If you are not familiar with the term, you can read this Wikipedia entry to get up to speed with the technology.
This guide would not be a full featured guide on how to setup the "complicated" openvpn software. For quite sometime now, i have avoided Openvpn as i've always read about how hard it is to setup up and configure. I've used other VPN technologies such as hamachi and adito. While these solutions are great, i've always felt like i was holding myself back by not giving Openvpn a chance. After following some tutorials, some quite simple and others very complex, i am happy to say that i've finally set up Openvpn server. The best thing that i have taken from this experience is that its not all that hard to set up. There are guides out there that seem very intimidating on the topic and my hope is to try and take this confusion away and give you the quick 101 of openvpn.

---+++Using openvpn with secret key.+++---

I've used Backtrack 5 to setup my server (you can use other linux distros as well)

  1. Install Openvpn. Backrack 5 already comes with it pre-installed. If your distro didn't come with it already install, you can install by issuing # apt-get install openvpn (applicable for debian based systems that use apt for managing packages)
  2. Navigate to openvpns config dir. # cd /etc/openvp
  3. Create a secret key. # openvpn --genkey --secret secret.key
  4. By default no config file is available. Lets create one. # touch openvpn.conf
  5. Using your favorite text editor, open up the config file that you've just created and enter in the following:
proto udp # protocol to use. Either tcp or udp
port 1194 # port num
dev tun # can be either tun or tap. Tun is simpler to sertup
ifconfig 10.0.0.1 10.0.0.2 # The 10.0.0.1 is the desired IP for our server's virtual interface and the other is the peer
secret /etc/openvpn/secret.key # secret key used for authentication
cipher AES-128-CBC # encryption cipher to use
user nobody # drop priveledges to this user
group nobody # same as above
verb 3 # logging level
Thats it for the server set up. Now copy the secret.key file and the openvpn.conf file to another linux client that already has openvpn installed. Note that the server and client config files are almost identical with few minor changes. Copy the files to the location /home/user/.openvpn (this location is not mandatory but lets just be organized).

  1. First change permissions of config and secret key file. # chmod 644 secret.txt ; chmod 644 openvpn.conf
  2. We need to add 1 line to the openvpn.conf file and modify the ifconfig parameter. So the client's openvpn.conf file will look like this
remote 192.168.0.5 # VPN's server's real ip
proto udp

port 1194
dev tun
ifconfig 10.0.0.2 10.0.0.1 # notice the change here
secret /home/user/.openvpn/secret.key
cipher AES-128-CBC
user nobody
group nobody
verb 3
Thats all for the client configurati0n.

Starting the server and client take identical commands and require root privileges. Onceyou are root, you can start the server and client like so: # openvpn --config /etc/openvpn/openvpn.conf

Once the connection is established both the server and client terminal windows should give some details similar to this:

Sat May 28 20:53:16 2011 Initialization Sequence Completed

To test your VPN connection, you can use the ping utility.


---+++Using openvpn with certificates.+++---

Server setup:
  1. Copy scripts for handling certificates to /etc/openvpn directory. # cp -r /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn
  2. Goto scripts dir. # cd /etc/openvpn/easy-rsa/2.0
  3. Modify the "vars" file. The variables that you want to modify are at the bottom of the file. These include KEY_COUNTRY, KEY_PROVINCE etc.
  4. After modifying the vars file, issue this command on the file. # source ./vars
  5. Clean up older keys. # ./clean-all
  6. Create CA key and certificate. # ./build-ca
  7. Create the openvpn server's certifcate and key. # ./build-key-server openvpn_server
  8. Create client keys and certificates. # ./build-key client1
  9. Create dh key. # ./build-dh # this can take a 2-4 mins to create. Move your mouse around an be patient :)
  10. Goto keys directory. # cd keys
  11. Copy the dh1024.pem, ca.crt, openvpn_server.crt and the openvpn_server.key files to /etc/openvpn/ directory
  12. Lets create our server config file:
tls-server # this would be the server in tls mode
proto udp
# protocol to use. Either tcp or udp
port 1194 # port num
dev tun # can be either tun or tap. Tun is simpler to sertup
ifconfig 10.0.0.1 10.0.0.2 # The 10.0.0.1 is the desired IP for our server's virtual interface and the other is the peer

ca /etc/openvpn/ca.crt
cert /etc/openvpn/openvpn_server.crt
key etc/openvpn/openvpn_server.key
dh etc/openvpn/dh1024.pem

cipher AES-128-CBC # encryption cipher to use

user nobody # drop priveledges to this user
group nobody # same as above
verb 3 # logging level
Client setup:

  1. Copy the ca.crt, client1.crt and the client1.key files to the client
  2. Create its config file:

tls-client # this would act as client in tls mode
remote 192.168.0.5 # VPN's server's real ip
proto udp

port 1194
dev tun
ifconfig 10.0.0.2 10.0.0.1 # notice the change here

ca /home/user/.openvpn/ca.crt
cert /home/user/.openvpn/client1.crt
key /home/user/.openvpn/client.key

cipher AES-128-CBC
user nobody
group nobody
verb 3
Again, starting the server and client take the same commands but you must have root privileges. Once you are root, you can start the server and client like so: # openvpn --config /etc/openvpn/openvpn.conf

Once the connection is established both the server and client terminal windows should give some details similar to this:

Sat May 28 20:53:16 2011 Initialization Sequence Completed

To test your VPN connection, you can use the ping utility and ping each node.

Extra:

If you want revoke client keys:
# ./revoke-full client1

This would add client1 to a sort of black list that would not allow them to connect to our VPN anymore. The file that houses this black list is crl.pem. Create a hardlink (ln without the -s option)to this file in the /etc/openvpn/ directory.

You would also need to add this line to the configuration file on the server. This causes the server to check its revocation list whenever clients try to establish a connection to the VPN server.

crl-verify /etc/openvpn/crl.pem


I noticed that when a revoked client tried to connect to the vpn, not only were they denied service, the VPN server was also shutting down. It seems like the when openvpn shuts the connection down, it tries to reinitialize its tun interface, but fails to do so because in our config file, we dropped our priveledges to nobody. This issue is quickly resolved by commenting out or deleting the lines with the parameters user and group on the server config file.

Resources/Good Reading:
http://openmaniak.com/openvpn_tutorial.php
http://www.adamsinfo.com/quick-linux-and-windows-openvpn-howto-and-tutorial-including-vpn-routing/

Monday, May 23, 2011

Vicompress: http proxy server

Vicompress is an http proxy server, with the ability to cache requests in memory. It has a small footprint but because of its ability to cache contents in memory, it can eventually use up tons of memory resources. It has decent log statistics capabilities too and outputs to an html formatted page. Most important to me, setup and configuration is quite simple.

Installation:

1 . Download the installation package from visolve website. In my case, i downloaded the .deb version of the package.

2. To install i used the command: # dpkg -i package-name

Configuration:

For details on all configuration parameters, go here

The default configuration would do just fine, but its useful to learn of its parameters
Here is a snapshot of my vicompress.conf configuration file:

listen 0.0.0.0 8080
outgoingip 0.0.0.0
enable_compression yes
enable_caching yes
cache_memory 200
max_cacheditem_size 10000
cache_expires 2
enable_dns_caching yes
dns_expires 2
user nobody
rotatesize 10
logformat squid
enable_debug no
accesslog /usr/local/vicompress/log/accesslog
errorlog /usr/local/vicompress/log/errorlog
errorpage /usr/local/vicompress/etc/errorpage.html
logstats /usr/local/vicompress/logstats

To start the server: # /usr/local/vicompress/bin/vicompress.sh start

To view the statistics of your proxy server, usually a report gets generated every hour. You can speed this process by issueing this command:

# cd /usr/local/vicompress
# ./bin/update_log_stats /log/accesslog logstats

To view the report issue: # firefox /usr/local/vicompress/logstats/statsindex.html

Resources / Goodreading:
visolve

Saturday, May 14, 2011

Inetd and perl

Just a quick simple trick that you can help you set up servers quick and easy. You don't have to know alot about programming either but it helps to know what Inetd is in linux.

Inetd, on its manpages is known as a internet superserver. All those big words aside, it can basically listen on a given port for you and when a connection comes in, it calls the appropriate application to handle them. It so turns out that you can use Inetd's sockets for network communication instead of programming your own. What that means is that inetd can listen on port 80, and when a connection comes in on that port, we can run a shell script that simply sends back some text or html tags. Inetd's output is piped to the calling program or script's standard input and that program's output is redirected to Inetd's standard input.

Lets quickly demonstrate this with a bash script.

#!/bin/bash
echo "Hello World"

Now save that script to a file called hello.sh and give the file executable permissions.
# chmod 555 hello.sh

Now configure /etc/inetd.conf as follows

http-alt stream tcp4 nowait root /root/hello.sh

Now save the file.

Run the inetd daemon
# /etc/init.d/inetutils-inetd start

now netcat to port 8080 (which is what http-alt) service is and you should revecieve a response:

root@bt~#: nc 127.0.0.1 8080
Hello World
root@bt~#:

All should work well if done right. Now to get a lil bit more fancy, i've put together a perl script that takes an input and returns the MD5 hash of that input (an MD5 hashing service if you will).
#!/usr/bin/perl -w


# A simple inetd socket server.

use strict;

my $old_fh = select(STDOUT);
$| = 1;
select($old_fh);
print "++ MD5 pass generator ++\n\n";
print "Type \'exit\' at anytime to quit\n";
print "Enter string to be hashed: ";

while( my $line = )
{
$line =~ s/\r?\n$//;
#chomp($line);
if ($line =~ /^exit$/)
{
die "shutting down\n";
}
# do your processing here!
$line = `echo -n $line | openssl md5`;
print "$line\n";
print "Enter string to be hashed: ";
}
Save the perl script to a file like md5.pl and chmod 555 your file.
Start the inetd daemon as shown above and use netcat to connect to the service :)

Backtrack 5 is out

Backtrack 5 is out folks. Head on over to the backtrack website to get yourself a copy of this well put together masterpiece. There are 32 and 64 bit versions available now, as well as the classic KDE styled version and a new GNOME version, which put you in an Ubuntu like environment. I've decided to go with the Gnome version, as im use to Ubuntu and it was refreshing to use something other than the classic desktop environment. All versions should have the same tools and capabilities so its all a matter of preference.

What are you waiting for? Get your copy here.