1

I am interested in demoing printf vulnerabilities via an NDK app. To be clear, I am aware that to log in the console we can use __android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "Print : %d %s",someVal, someStr);. I have tried it and I know it works. But I explicitly want to demo the vulnerabilities of printf(), specifically to use the %n specifier to write to a pointed location.

Is there a way to make printf() work to this effect or is it possible to achieve this via __android_log_print()? I attempted it with the android/log.h header but it didn't work.

I can get the app to crash by running something along the lines of printf(%s%s%s%s%s%s%s%s%s%s). But again, I can't manipulate pointers.

For general knowledge purposes, why is it that printf() doesn't work in the first place and how does __android_log_print() prevent these exploits?

sam_c
  • 810
  • 7
  • 25

2 Answers2

5

You do realize that Android is open source.

Starting with looking for __android_log_print() and finding it: https://android.googlesource.com/platform/system/core/+/refs/heads/master/liblog/logger_write.cpp

int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
  va_list ap;
  char buf[LOG_BUF_SIZE];
  va_start(ap, fmt);
  vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
  va_end(ap);
  return __android_log_write(prio, tag, buf);
}

I eventually ended up looking at: https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/stdio/vfprintf.cpp

lines 453-454:

  case 'n':
    __fortify_fatal("%%n not allowed on Android");

Also referenced in the code is additional safety through FORTIFY which is described in the following blog post:

https://android-developers.googleblog.com/2017/04/fortify-in-android.html

Morrison Chang
  • 11,691
  • 3
  • 41
  • 77
  • What!? It's open source?? – sam_c Mar 28 '19 at 05:58
  • Can't tell if we both are being sarcastic. Regardless when you are trying to get into the deeper weeds of Android, you can read the source to see how it handles things. – Morrison Chang Mar 28 '19 at 06:18
  • Yeah I've been reading through some of the source trying to track stuff like this down. Guess I just didn't hit the right stuff. This explains to me why the ```__android_log_print()``` functions the way it does. So thank you for that. You'll have to forgive me but I'm still confused why ```printf()``` doesn't function at all. – sam_c Mar 28 '19 at 06:26
  • 1
    `printf()` sends to console. In the context of Android there is no console. See: [How to get “printf” messages written in NDK application?](https://stackoverflow.com/q/10274920/295004) If you are trying to walk through the code [this post on printflike modifier](https://stackoverflow.com/questions/5825270/printflike-modifier) may help. – Morrison Chang Mar 28 '19 at 06:47
0

Android specifically does not support %n format specifiers because they're vulnerable.

https://android.googlesource.com/platform/bionic/+/400b073ee38ecc2a38234261b221e3a7afc0498e/tests/stdio_test.cpp#328

Dan Albert
  • 10,079
  • 2
  • 36
  • 79