Port Forwarding an Android Local Port
There don’t seem to be many reasons to want to forward a local Android port (listening for connections from localhost only) to a port that can be accessed externally (via LAN, etc.). There are some applications around that allow to forward an Android local port to another one but they offer a lot of overhead, are confusing and some even require root access.
Compiling netcat
for Android was the way I decided to go, it’s only known to be the “swiss-army knife” of networking. The Android source code contains a limited version of nc
which can be compiled by the simple make nc
(after having setup the build environment of course). This version of netcat
does not offer port forwarding functionality.
Grabbing the latest GNU netcat
source and compiling it against the NDK-provided toolchain was the next logical step. Compiling netcat
for my Android device (it’s an unrooted Google Nexus One) was quite straight-forward. Compiling requires the NDK. Inside the $NDK/build/tools
directory there’s a neat utility called make-standalone-toolchain.sh
, invoke this with ./make-standalone-toolchain.sh --platform=android-9 --install-dir=/tmp/android-toolchain --ndk-dir=../../
. This will install a standalone toolchain that can be used to compile C and C++ code for the Android ARM platform.
Head over to the netcat
source and setup the cross-compilation environment variables by issuing export PATH=/tmp/android-toolchain/bin:$PATH
and export CC=arm-linux-androideabi-gcc
. Then ./configure --host=arm && make
was enough, although I suspect some features may not work or segfault since I did not indicate the specific toolchain library paths. Compiling other software from source may require specifying the correct headers (look at ./configure --help
).
The netcat
binary ends up in the src
directory. Issuing a file src/netcat
on it should yield something like: netcat: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped (see how it uses shared library functions arm-linux-androideabi-readelf src/netcat -Ds
, the correct way is to use the Android system headers for these provided by the toolchain and not the headers provided by default).
Native binaries for Android cannot be executed from any other context other than from /data/local/
without rooting the device. So adb push src/netcat /data/local/
should transfer an executable binary. Try it out adb shell /data/local/./netcat -l -p 9990
and nc [device IP] 9990 -v
. Everything should work fine with both “cats” able to communicate.
Forwarding a local Android port requires one to adb shell /data/local/./netcat -L localhost:9990 -p 9998
. This exposes the restricted 9990 port (one which refuses connections from anything but localhost) via port 9998 which is unfiltered by netcat
.
Meow!
Thanks a lot soulseekah. This post was of great help. Learnt how to create binary for arm device using the source through cross compiler. 🙂
Glad the article has been of help 🙂
Hey,
I’m trying this on an emulator but when I run
adb shell /data/local/./netcat -l -p 9990
I get permission denied. The emulator is running android 4.0.
I got an error also with a physical device running 4.0.4, with this I wasn’t able to copy anything to /data/local.
Any ideas?
For the emulator make sure you `chmod +x` the binary after copying, it should have executable permissions. Not sure what getting it to work on your device would entail; find a directory you can copy to that supports execution (the `df` command might help you find mounted executable areas if it exists).
Thanks man,
chmod 777 seems to have worked. The command below seems to have set the emulator listening.
adb shell /data/local/./netcat -l -p 9990
Just need to figure out getting the emulator connected to my wifi now.
I’ve been focusing on trying to get this working on my device. Its a HTC Desire X.
I can’t find any writeable and executable directories on it though. I’ve tried all the root level directories.
Do you have any idea how I could get the netcat file onto the device and executable?
No idea really, there should be an executable area on the filesystem, it certainly won’t be at root level; try `/data/local/tmp/` or other directories under `/data/`.
Thanks soulseekah.
I got it working on an older device. When I nc from one machine to the phone I can see the text I entered being sent across.
I was wondering though, should I not be able to issue commands like “ls” etc from the client to the phone?
No; at least not with that command. You could try piping the shell with the `-e` flag, but the version that you compiled may not support it. Refer to the netcat sources for more information; it’s certainly possible but not without a bit of tinkering and thinking if the specific build of netcat doesn’t support command piping (`-e`).
I’ll look into it.
Thanks again for your help.
Hey,
Sorry to bother you again but just wondering if you have any idea on the problem im having.
After compiling netcat using your instructions it seems it only works with inbound connections, not outbound.
I can set the phone listening for connections but if I try to connect from the phone to a listening server the connection does not work.
Any ideas on that?
This is my command on the phone.
adb shell /data/local/tmp/netcat -n 192.168.0.21 31337 -vv
Total received bytes: 0
Total sent bytes: 0
I’ve tried it on two different devices, one with 4.0.4 and another with 2.2.
Thanks
It seems that the connection is being established; does the receiving server detect a connection?
You should test another server perhaps, many things may be wrong with your current setup, hard to say.
The server doesnt detect a connection. Tried it on 3 different servers now and the same result.
I think i’ll just have to leave it.
Thanks for all your help.
Update: I compiled busybox for android instead of netcat and the version of netcat in busybox worked on my device.
Thanks for the help. 🙂
Yay! I’m really glad you figured it out in the end. Kudos!
Executed the command ‘ nc.exe -lvp 6789 from my windows 10 PC and it started ‘listening on [any] 6789’ … and then I executed ‘nc -e ‘ in terminal emulator app from my Nexus 4 and keeps showing this msg ‘nc: not found’ … help me pls
Did you compile netcat for Android and actually run it? That error message says that nc (netcat) was not found on the system. Read the instructions above carefully and don’t miss a single step. To run cd to /data/local/ first then run nc or netcat however you called the binary that you compiled and uploaded there.
Thanks for this
On my Android 6 device I had to build a position independent executable:
./configure –host=arm CFLAGS=’-fPIE’ LDFLAGS=’-fPIE -pie’
and I had to push to /data/local/tmp:
adb push src/netcat /data/local/tmp