Porting your favourite cmdline tool to Android
-
Upload
vlatko-kosturjak -
Category
Technology
-
view
694 -
download
0
Transcript of Porting your favourite cmdline tool to Android
PORTING TO ANDROID
PORTING YOUR FAVOURITE CMDLINE TOOL
TO ANDROID
Vlatko Kosturjak (@k0st), Droidcon Zagreb, 30th of April
AGENDAIntroductionNative codeToolchainsThings I wish I knew in advanceCalling native executablesIssues and implicationsSummaryQuestions and answers
45 minutes
ABOUT ME
Security Consultant in DivertoLinux and FLOSS enthusiastOpen source developer
Have code in OpenVAS, Nmap, Metasploit, ...
Android "developer" since 2010started counting from first Market appmostly focused on NDK and ADK
https://github.com/kost
ABOUT ME IN PICTURES
ABOUT ME IN PICTURES
INTRODUCE ELEPHANTTalk will cover
producing standalone binaries
executing standalone binaries
Talk is mostly about Nmap experience
Most Nmap frontends on playstore are using this port
in source or binary form
Talk will NOT cover
producing libraries or JNI
integrating with Android Studio
https://github.com/kost/nmap-android
https://github.com/kost/NetworkMapper
NATIVE CODE
NOT your Java code :)
It's mostly about
C/C++
Assembler
Not portable across platforms
For each platform, you need different binary
x86
arm
mips
WHY BOTHER WITH NATIVE CODE?performancelegacy codecode reuseyou just need that tool
WHAT'S THE PROCESS?compiling
compiling on same machinecross-compiling
compiling on (host) machine for other (target) machine
TOOLCHAINSAndroid NDK
Commercial
Open Source
Custom
CUSTOM TOOLCHAINYour own version of compilerYour own version of build scriptsCustom
COMMERCIAL
EmbarcaderoGood old Borland...
XamarinNative apps in C#
...
OPEN SOURCE / FREE
Crystax
drop-in replacement for Google's NDK
WCHAR, locales, full C+11 standard library...
Buildroot
Standard embedded cross compilation toolchain
ARM, x86, MIPS
Scratchbox
ARM, x86, MIPS (experimental)
Anyone remembers Maemo? :)
...
ANDROID NDK
Android official toolchain
Available for free from developer.android.com
Bionic
No full ANSI C support
locale
different threads
Patch as you grow
standalone binary support/bugs
stdout symbol bug
WCHAR support
standard library support
WHAT'S THE FUZZ?
Download NDKDownload tool you want to port
./configure --host=arm-linux-androideabimakemake install
It works - go home!
IN CASE IT IS HELLO WORLD.../* Hello World program */
#include <stdio.h>
void main()
{
printf("Hello World");
}
It works pretty well indeed.
IN REAL WORLD
Code isn't perfectNot portableEndianessPath SeparatorsDependenciesExtensions3rd party libraries
TWO WAYS TO INVOKE COMPILER
Calling with sysrootexport CC="$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc"
export CFLAGS="--sysroot=$SYSROOT"
$CC $CFLAGS -o hello hello.c
Producing directory for target
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-3 --install-dir=/
/opt/ndk3/bin/arm-linux-androideabi-gcc -o hello hello.c
NDK PLATFORMS
NDK platform Platforms 32/64 bit
3 ARM 32
9 ARM/MIPS/Intel 32
21 ARM/MIPS/Intel 64
PROCESS OF CROSS COMPILING
Compile and fix as you go :)sorry, no single recipe
Standard problemsstdout bugold autoconf/automake support filesarm-linux-androideabi missing
In shortnothing that google/stackoverflow can't help :)
STATIC VS DYNAMIC LINKINGDynamic
small sizerun-time dependency
Staticlarge sizeno dependencies
LIFE IS PERFECTStatic binaries working like a charm
“until resolv.conf disappeared :) ”
DNS PROBLEMS
int main(int argc,char *argv[]) {
int i;
struct hostent *hp;
for ( i=1; i<argc; ++i ) {
hp = gethostbyname(argv[i]);
if ( !hp ) {
fprintf(stderr, "%s: host '%s'\n", hstrerror(h_errno),
argv[i]);
continue;
}
printf("Host:\t%s\n" ,argv[i]);
printf("\tResolves to:\t%s\n", hp->h_name);
}
}
Original at gist
DNS AND RESOLV.CONF
#ifdef ANDROID_CHANGES /* READ FROM SYSTEM PROPERTIES */ dns_last_change_counter = _get_dns_change_count(); [..]#else /* !ANDROID_CHANGES - IGNORE resolv.conf in Android */#define MATCH(line, name) \ [..]
Original at https://code.google.com/p/android-source-
browsing
DYNAMIC VS STATIC
Type Size Dependency DNS OOTB
Dynamic smaller yes yes
Static bigger no no
Mixed medium yes (basic) yes
HERE COMES LOLIPOPerror: only position independent executables (PIE) are supported.
Position Independent Executable (PIE)PIE support appeared in API level 16Finally they implemented it :)
Too bad binaries does not work
WHAT'S PIE?
Position Independent Executable (PIE)
Security protection
better Address Space Layout Randomization (ASLR)
Exploitation mitigation technique
Harder return-to-libc exploitation
Requirements
PIE required for dynamic executables
PIE not required for static executables
PIE EXAMPLE#include <stdio.h>
int global;
int checkadr (int *bla){ int local; printf("bla adr = %p\n", &bla); printf("global adr = %p\n", &global); printf("local adr = %p\n", &global);}
int main (void) { int c; printf("c adr = %p\n", &c); printf("checkadr adr = %p\n", &checkadr);
PIE SUPPORT
Android version Supported Required
1,2,3 no no
4 yes no
5 yes yes
PIE WORKAROUND
Way to run PIE executables on non supported systemsif system suppports PIE
just run executableif system does not suppport PIE
use run_pie.crun_pie your_proggy args
CFLAGS +=-fvisibility=default -fPIELDFLAGS += -rdynamic -pie
https://gist.github.com/kost/5fd4628f45a4995bec28
CALLING NATIVE EXECUTABLESp = Runtime.getRuntime().exec(command);p.waitFor();BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));String line;while ((line = reader.readLine()) != null) { output.append(line).append("\n");}
BETTER WAY - USING
PROCESSBUILDER
ProcessBuilder processBuilder = new ProcessBuilder(shellToRun);
processBuilder.redirectErrorStream(true);
scanProcess = processBuilder.start();
outputStream = new DataOutputStream(scanProcess.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(scanProcess.getInputStream()));
while (((pstdout = inputStream.readLine()) != null)) {
output.append(pstdout).append("\n");
}
RUNNING BINARIES AS ROOT
Not needed to set any new android permission
Historic references to SUPERUSER permissions
Not much different than executing as normal user
Have to Runtime.getRuntime().exec("su")
Write commands to stdin of process
Loop the output
ROOT IMPLICATIONS
Killing run away root processes
Hard as it can be due to blocking nature
UI does not have root access
Killing spawned root processes
parse ps output
spawn su shell
kill process
SECURITY IMPLICATIONS
Native binary problemsMemory corruption attacks (Buffer overflows, ...)Format string problems......
PermissionsCommand injections
SECURITY IMPLICATIONS -
PERMISSIONS
Setting insecure permissions to executables/libraries
Very common when something does not work
Dangerous and heroic
Other apps can write to your bin or library
Exploitation
Find insecure .so library, inject your code
Find insecure binary, replace it with your version!
echo "#!/bin/sh" > /data/data/com.heroic.app/bin/mybinaryecho "echo '0wned!'" >> /data/data/com.heroic.app/bin/mybinary
SECURITY IMPLICATIONS -
UNTRUSTED INPUT
Passing untrusted/unvalidated input to shellRunning native executables can lead to commandinjections
Extremely dangerous if running as userExtremely heroic and dangerous if running as root
Pay special attention to exported activitiesother apps can call that intentwhich means they can execute commands as yourapp!!
UNTRUSTED INPUT EXAMPLEBundle b = getIntent().getExtras();
configFilePath = b.getString("path");
[..]
ShellExecuter exe = new ShellExecuter();
return exe.Executer("cat " + configFilePath);
<activity
android:name=".MyHeroicActivity"
....
android:exported="true" />
UNTRUSTED INPUT EXPLOITATION
public void onBtnClick(View view) { Intent intent = new Intent(); intent.setClassName("com.heroic.app", "com.heroic.app.MyHeroicActivity" intent.putExtra("path", "/system/etc/hosts; echo 'Owned' > /data/data/com.heroic.app/bin/binary" startActivity(intent);}
ON THE END..You get bad comments :)
Don't use ratings for bug reports ;)
Please submit VERBOSE bug reports to author directly
FORTUNATELY
Fortunately, there are good comments ;)
Thanks on these
SUMMARYPorting is quite possible
Not as easy as marketing says
You can't configure; make; make install in most cases
Expect you'll have to patch if project is bigger
Not that hard
If you know requirements upfront
Have listened to this lecture carefully
Be aware of security implications!
THANKS ON LISTENING
?ANY QUESTIONS?