2010/11/12

Using iptables on Android to redirect HTTP connections to a running Charles proxy instance

During development it is often desirable to inspect the HTTP requests from your applications. As reported in Android Issue 1273 there is no easy way to set a HTTP proxy when using WIFI. In this article I describe how to use Charles as a Webproxy at least for unencrypted connections.

Unfortunately, you have to root your telephone, as otherwise you are not allowed to call iptables. Rooting is easy to do, visit unrevoked and follow the instructions. If you want to install a custom rom with Froyo just follow the instructions on Wildpuzzle (or any other) ROM for HTC Wildfire.

Then install Charles, see my article on Using BaseX and Charles. Start it up and configure Charles to be a transparent HTTP proxy in Proxy/Proxy Settings....

I assume you installed the Android SDK (for Mac OS X use Homebrew, see my article on starting an Android emulator via LaunchAgent for specifics).

On your device allow USB Debugging (Settings/Applications/Development/USB Debugging). Now connect your rooted device via USB. Enter adb shell, you should be greeted with a sh-3.2 prompt. In this example 192.168.51.9 is the address of the computer running Charles, 8888 is the port.

sh-3.2# iptables -t nat -A OUTPUT -p tcp -o eth0 --dport 80 -j DNAT --to 192.168.51.9:8888
FIX ME! implement getprotobyname() bionic/libc/bionic/stubs.c:378

You may ignore the error.

sh-3.2# iptables -t nat -L -nvx
Chain PREROUTING (policy ACCEPT 19 packets, 4832 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 1068 packets, 65421 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 1050 packets, 63721 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
       8      472 DNAT       tcp  --  *      eth0    0.0.0.0/0            0.0.0.0/0           tcp dpt:80 to:192.168.51.9:8888 

Hint: On Mac OS X you have to allow incoming connections to your computer e.g. by going to System Settings/Security and disabling the firewall. Now you should see all your unencrypted HTTP connections going through Charles.

To disable using Charles as a proxy enter:

sh-3.2# iptables -t nat -F OUTPUT

This will reset the routing again and all HTTP connections will go directly to the hosts again.

Unfortunately this approach will not work for encrypted connections right now, I am still investigating this.

2 comments:

  1. Hi

    Interesting post. I'm getting an error when executing iptables -t nat -L -nvx:

    getsockopt for multiport failed strangely: No such file or directory
    getsockopt for multiport failed strangely: No such file or directory
    iptables: No chain/target/match by that name

    Which one could be the reason?

    ReplyDelete
  2. Hello Narseo, sorry I did not see this on my system. Did you search for this? It seems the method I used is only feasible for a hacked Wildfire depending on the kernel version as well.

    ReplyDelete