Mittwoch, 26. Mai 2010

self signed certificates, android and HttpsURLConnection

Hi,

I'm a proud "copy&paste" programmer, and often I program only PoCs and stuff that doesn't went into live production environments. The reason is, that I work as a security engineer (according to this I would call myself a "security practitioner") and the most of the time you have to verify that a vuln exists and is practically exploitable. For this task one do not need extensive programming skills. Most of the stuff you need is already out there and only must be glued together.

This time I tried to glue my first android app together. My task was to send a simple POST request to a web server "secured" with a self signed certificate. Pretty simple, heh?
Of course it is, the problem here is the "self-signed" cert. With command-line tools like curl this is only one parameter you have to set to ignore the exceptions caused by this.. I would expect that one only has to set a parameter for HttpsURLConnection. But not in JAVA - from my perspective it's a real PITA (if your're also a "Copy & Paste Programmer - for a skilled JAVA geek this might be a intuitive way to handle this...)

PLEASE NOTE: This code is bad code! Really bad code! This leaves you open to Man-in-the-middle Attacks. You should NEVER, EVER use this in an productive environment!

Here is the code - ready for copy & paste:



package meinpack.wlanpost;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class WlanPost extends Activity {

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
TextView tv = new TextView(this);
tv.setText("Sending User and PW....\n\n");
String urlParameters =
"username=blubb&pwd=googog";
String response = excutePost("https://www.example.com/blubb.php", urlParameters);
tv.setText(response);
tv.append("\n\n");
setContentView(tv);
}
public static String excutePost(String targetURL, String urlParameters)
{
URL url;
HttpsURLConnection connection = null;

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) {
}
}
}; // Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch (Exception e) {
return ("exception " + e.toString());
}

try {
//Create connection
url = new URL(targetURL);
connection = (HttpsURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");

connection.setRequestProperty("Content-Length", "" +
Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");

connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);

//Send request
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes (urlParameters);
wr.flush ();
wr.close ();

//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();

} catch (Exception e) {
return e.toString();

} finally {

if(connection != null) {
connection.disconnect();
}
}
}
}

glued together from this: http://www.exampledepot.com/egs/javax.net.ssl/trustall.html
and this: http://www.xyzws.com/Javafaq/how-to-use-httpurlconnection-post-data-to-web-server/139

1 Kommentar:

  1. Hi, I tried doing the above... But I'm getting an FileNotFoundException pointing to the web service url!!
    Can you please help me...
    Thank you

    AntwortenLöschen