Monday, November 2, 2009

You will be redirected to the new blog

Please wait, you're being redirected to the new blog...

Sunday, July 19, 2009

No more updates here

Please check http://chirashi.zensay.com/ for continued updates to this blog. I have moved sites. Thanks.

Sunday, May 31, 2009

Sending messages to the Apache Error.log file when using Django

I spent a considerable amount of time reading documentation that told me how to send errors to the Apache log filewhen you use mod_wsgi. I read documentation on how to integrate mod_wsgi with Apache and Django. All of this was fine, but when I was trying to get it to work with my Django 1.0.2 installation and Apache2 running mod_wsgi, I was constantly greeted by lots of errors. The documents online didn't help at all.

Finally, after looking into the django.core.handlers.wsgi module, I figured out how to send errors to the wsgi.errors setting and subsequently send errors to your Apache2 Error.log file.

I started off with my views.py as follows:

from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
from myapp.models import F

def index(request):
c = {}
return render_to_response('myapp/index.html',c)

def detail(request, name):
n = F.objects.get(name=name)
c = {'name': n.fof}
return render_to_response('myapp/detail.html',c)

If I needed to write to the Error.log file, I would have to change the code thusly:

from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
from myapp.models import F

def index(request):
c = {}
print >> request.environ['wsgi.errors'],"Teh Errorist!"
return render_to_response('myapp/index.html',c)

def detail(request, name):
n = F.objects.get(name=name)
c = {'name': n.fof}
return render_to_response('myapp/detail.html',c)

The change is in line 7

I felt really stupid, because the solution was so straightforward. I felt even more stupid that I couldn't find any documentation out there. Either way, I'm pleased that my app works, and in case someone else out there is searching for how to achieve this, then the above is how to do it.

Friday, May 8, 2009

Re-login plugin for Burp Suite

One of the first things I do when I begin a web application security assessment is figure out how the login sequence works. Then as I begin to annoy the application, I figure out what makes the application say, "Enough!" and kick me out by invalidating my session. With this, I can automate the process and save a huge amount of time logging into the application manually when my session is made invalid.

I'm a big fan of
Burp Suite. Burp Suite is a set of tools that I believe every web application pen-tester should find indispensable. Developed by Dafydd Stuttard a.k.a. Port Swigger, it is available in both Free and Professional (read paid) versions. Its a great set of tools and I use it's extensibility to achieve the automated login process. Dafydd has also co-authored the book The Web Application Hacker's Handbook. No, I don't personally know Dafydd, and no, he's not paying me to say these things (although I would never dare to send back a free copy of the Pro version he would send me ;) ), but I use the tools and I think they're quite awesome.

I recently pen-tested a banking application that was being launched by a large bank and dusted off my re-login plugin. Given that the bank used the F5 Big IP appliance with the application security module and the fact that it employed a ticketing system, I had to make extensive changes to my once humble re-login plugin. So I did. In the spirit of giving back, I thought someone else might find the plugin useful or can even build off my one (if you do, please do share the improved version) so I'll post my research and final plugin here.

Because of the pain in the ass Big IP, I had to craft my re-login plugin as follows:

  1. Record the error page of the Big IP and find a unique string to identify the page
  2. Record the POST request for the login page
  3. Write the plugin to detect if this string is in the response
  4. If it is, then make an HTTP GET request to the start page.
  5. Grab the cookies from the GET request
  6. Replace the cookies from the POST request with the ones from the GET request
  7. Make the HTTP POST request
  8. Grab the response and send it back to the browser.

Now when I send that incredibly long string in the "Amount" field or send a whole load of XSS in the "Description" field, I am no longer greeted by the Big IP error page. Instead, my plugin takes over, seamlessly logs me back in and brings me to the landing page.

Here is the source code:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import burp.IBurpExtender;
import burp.IBurpExtenderCallbacks;


public class BurpExtender implements IBurpExtender {

public burp.IBurpExtenderCallbacks callBacks;

public void applicationClosing() {
}

public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
callBacks = callbacks;
}

public void setCommandLineArgs(String[] cla) {
}

public byte[] processProxyMessage(
int messageReference,
boolean messageIsRequest,
String remoteHost,
int remotePort,
boolean serviceIsHttps,
String httpMethod,
String url,
String resourceType,
String statusCode,
String responseContentType,
byte[] message,
int[] action)
{

byte[] firstRequest;
byte[] nextRequest;
String initialCookies = "";

if(!messageIsRequest){
try{
if(isBigIPError(message)){
callBacks.issueAlert("Attempting to re-login...");
firstRequest = new String("[Enter GET Request Here, one string seperate with '\r\n']").getBytes();
nextRequest = new String("[Enter POST Request Here, one string seperate with '\r\n'").getBytes();
byte[] firstResp = callBacks.makeHttpRequest(remoteHost, remotePort, serviceIsHttps, firstRequest);
initialCookies = grabCookies(firstResp);
byte[] interimReq = buildRequest(initialCookies,nextRequest);
message = callBacks.makeHttpRequest(remoteHost, remotePort, serviceIsHttps, interimReq);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return message;
}

private String grabCookies(byte[] getRequest){
String getReq = new String(getRequest);
String regEx = "Set-Cookie:\\s(.*?);";
Pattern pattern = Pattern.compile(regEx, Pattern.DOTALL | Pattern.MULTILINE);
Matcher matcher = pattern.matcher(getReq);
StringBuilder cookies = new StringBuilder();
cookies.append("Cookie: ");
while(matcher.find()){
cookies.append(matcher.group(1)+"; ");
}
cookies.append("\r\n");
return cookies.toString();
}

private byte[] buildRequest(String cookies, byte[] postRequest){
String[] carvedPost = {};
String postReq = new String(postRequest);
carvedPost = postReq.split("\r\n\r\n");
postReq = carvedPost[0]+"\r\nContent-Length: "+carvedPost[1].length()+"\r\n\r\n"+carvedPost[1];
StringBuffer finalReq = new StringBuffer();
String regEx = "Cookie:\\s(.*?)\r\n";
Pattern pattern = Pattern.compile(regEx, Pattern.DOTALL | Pattern.MULTILINE);
Matcher matcher = pattern.matcher(postReq);
while(matcher.find()){
matcher.group();
matcher.appendReplacement(finalReq,cookies.toString());
}
matcher.appendTail(finalReq);
return finalReq.toString().getBytes();
}

private boolean isBigIPError(byte[] msg){
String message = new String(msg);
boolean result =false;
try{
String regEx = "[Enter your RegEx for the Error Page here]";
Pattern pattern = Pattern.compile(regEx,Pattern.DOTALL|Pattern.MULTILINE);
Matcher matcher = pattern.matcher(message);
if(matcher.matches()){
callBacks.issueAlert("Received error from F5 Big-IP!");
result = true;
}

} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

To get this to work in Burp, I will provide you with instructions directly from PortSwigger:

Before you proceed, make sure to change the GET, POST and RegEx to match your own scenario. Just place them into the areas surrounded by square brackets. Remove the square brackets after that.

---------------------------------SNIP-------------------------------------------

If you want to play with this example yourself, you can download the source code. The steps to compile and run the plugin are as follows:

  1. If you don't already have it, download and install the Java Development Kit (JDK) from Sun.

  2. Create a directory to work in, and cd into it from the command line.

  3. Copy the plugin source file (BurpExtender.java) into your working directory.

  4. Create a subdirectory called "burp", and copy theIBurpExtenderCallbacks.java file into this directory. You will need this file in the correct relative path, because the plugin code makes use of the IBurpExtenderCallbacks interface.

  5. In your working directory, compile the BurpExtender.java source file into a .class file using javac, the Java compiler. The exact command will depend on the location of your JDK - for example, on Windows, you might type: "\Program Files\Java\jdk1.6.0_04\bin\javac.exe" BurpExtender.java

  6. Confirm that the file BurpExtender.class has appeared in your working directory.

  7. Build a Java archive (JAR) file containing your .class file. Depending again on your JDK location, you might type:"\Program Files\Java\jdk1.6.0_04\bin\jar.exe" -cf burpextender.jar BurpExtender.class

  8. Confirm that the file burpextender.jar has appeared in your working directory.

  9. Copy your normal Burp JAR file into your working directory.

  10. Using the actual name of your Burp JAR file, start Burp using the command: java -Xmx512m -classpath burpextender.jar;burp.jar burp.StartBurp

If everything works, Burp should launch with a number of entries in the alerts tab, confirming which IBurpExtender methods were successfully loaded from your plugin (in this case, processProxyMessage and registerExtenderCallbacks):

---------------------------------SNIP-------------------------------------------

If you need any clarifications on this or some help, just post some comments and I'll do my best to answer them.

That should be it for now. Go forth and Haxx0r!

--
Chopstick