Friday, May 25, 2012

Cross-compilation of a static Nmap with OpenSSL for Android


I am Gorjan Petrovski and this summer I’ll be your Android Network Scanner developer as part of the Google Summer of Code 2012 program :) . In short, my main goal is to build a good frontend for an advanced network scanner for Android which will use Nmap as a backend, but its architecture will be designed so that we can use other scanners too. My proposal describes the goals of my project in more detail. 

Before I head on to code an Android frontend for Nmap, first I needed to cross-compile Nmap for Android, and this blog post documents my experiences. I decided to cross-compile Nmap as a static executable as the most reliable option. Another purpose of this text is to help people which want to build a static Nmap executable with OpenSSL for themselves; If you just need the binaries, please head on to the excellent manual which this post is based on where you can download them:

So, if there’s already a cross-compiled version of Nmap and a manual, why this blog post, you might ask. The simple reason are some problems I encountered as a beginner with Android NDK while trying to cross-compile OpenSSL libs as static and link it to Nmap. Namely, I found some OpenSSL repos on github which compiled the libs as shared, modified them, but afterwards I could not link them to Nmap because of missing static dependencies (libz and libdl). This is why I decided on building OpenSSL and the other libs from the Android source code. 

Building the static libs (libdl, libcrypto, libssl) for Android

It might seem that building the source code of Android for getting these libs is an unnecessary, long and arduous process, but I would highly recommend it to any beginner working with Android NDK, as it will clear up quite a lot of things. 

I don’t plan to guide you through the Android build process because it is well documented and there are people who will help you who are far more experienced than me. I’m only going to give you a few tips which I found helpful:

I highly recommend that you build the whole Android source code to make sure everything is in order with your build environment. After you set up your build environment you can continue with building the modules:

I'm going to suppose that the directory where you've downloaded the Android source code is called ANDROID.

The modules by default are configured to be built as shared libraries, so what I've done is change the in their adequate directories so they'll be build as static libraries. Below are the links for the diffs of the libraries:

After you've patched the respectable libraries/directories with the diffs, you can build the modules by cd'ing to ANDROID and running:

$ make clean; make libdl libssl libcrypto

Tip: Don't forget to run $ . build/ to set the environment variables you're gonna need.

If you followed the instructions carefully the modules should be built. You can find the libraries in ANDROID/out/target/product/generic/obj/STATIC_LIBRARIES/ in their respectable libXXX_intermediate directories (ex. for libcrypto the library is libcrypto_intermediates/libcrypto.a). 

Building Nmap

If you compiled the libraries you are now ready to build Nmap. For this you'll need to download and install the Android NDK and Android SDK. I've found that it's most helpful if you expose the directories of the binaries to the PATH environment variable. For example, if you have Android NDK version r8 and it's extracted to your home dir, add this line to your .bashrc script:
export PATH=$PATH:~/android-ndk-r8:~/android-sdks/tools:~/android-sdks/platform-tools

Get Nmap from my github repo (it is version 5.61TEST4 with an additional directory - android):
$ git clone nmap
Copy the ANDROID/external/openssl/include dir to the nmap/android/openssl dir:
$ mkdir -p nmap/android/openssl
$ cp -a ANDROID/external/openssl/include nmap/android/openssl/

and copy the compiled static libraries to the nmap/android dir:
$ cp ANDROID/out/target/product/generic/obj/STATIC_LIBRARIES/lib*_intermediates/lib*.a nmap/android

Edit the NDK variable in the nmap/android/Makefile script to point to the location of your Android NDK and make sure that /tmp is writable for your user because the standalone toolchain will be copied there. After that you're ready to compile Nmap:
$ cd nmap/android; make

...and you should have your nmap static binary ready and compiled in your nmap folder.

Preparing and deploying Nmap to your device

You should still be in your nmap/android dir, and just plug your Android device in and run:

$ adb shell mkdir /data/local/nmap
$ adb push nmap /data/local/nmap

... and you can run nmap from adb or a terminal emulator on your phone by running:
# /data/local/nmap/bin/nmap

Happy Hacking!

If you're interested in Nmap for Android keep yourself updated with this blog, as I’ll publish builds of new versions and I'll probably automate this process even more as I continue to build newer versions of Nmap. It's going to be a fun summer.