0% found this document useful (0 votes)
52 views95 pages

Android App Protections 1710880812

Uploaded by

doa ibu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views95 pages

Android App Protections 1710880812

Uploaded by

doa ibu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 95

Hide `n seek with Android

App Protections
&
Beat `em
By Aan @petruknisme
HELLO! I’m…
Aan Wahyu a.k.a petruknisme

● Lead Security Consultant @ Horangi


● Infosec Enthusiast & Part-time coder
● Passionate with OSINT, RE, and Red Team
Background

Along with the rapid development of mobile application technology meeting


various needs and providing convenience to their users. In this case, significant
developments are also needed in the security aspect that guarantees
privacy and security, especially user data.

Therefore, a penetration testing or application audit process is needed to


ensure that an application is suitable for use by the public. If this is not done
properly, there is a high possibility of data leakage resulting in losses on the
user side and on the company.
Background

To prevent modification, manipulation or hacking, it is not uncommon for


developers to apply protection to applications. This aims to minimize losses
that could occur.

As someone who works as a penetration tester, For applications can be tested


properly, it is often necessary to bypass the implemented protection so that
the required tools or processes can run according to the predetermined
penetration testing workflow.
Table of contents

01 02
Root Detection SSL Pinning

03 04
Anti Emulation Frida Detection
01
Root Detection
Root Detection

To prevent modifications or manipulations that impact the application, root


detection is implemented. Basically, the application will check files that are
indicated to be part of the rooted device and when it finds this indication, the
application will prevent access or perform an exit/crash so that the application
cannot run on a rooted device.
Root Detection Methods

Checking the BUILD Checking SU binary Checking dangerous


tag for test-keys and installed root props
package

Checking common Checking permission Many more


root cloaking apps for system directory
Sample Root Detection
Sample Root Detection
Reverse
Engineering
Apk Process
Several processes are required in
reverse engineering an APK. Start
by unpacking the APK using an
archive extractor such as
WinRAR, WinZip, etc. After that,
the dex file will be disassembled
and decompiled into java source
which is still a java class file.
01.1
Manual Modification
Bypassing root detection using manual modification of smali
Extracting Apk
To bypass root detection using the smali patch method, the first step that must be done
is to extract the content in the apk using apktool
Searching the right function
Then we can search for the word isRooted with the help of a code editor. In this example
case, the isRooted function is in the Rootbeer.smali file

As you can see, isRooted function


are calling other function for
checking:

1. Su Binary
2. RW Paths
3. Root via Native Checks
4. Magisk Specific checks
5. etc
Bypassing checkForSuBinary
In the checkForSuBinary() function, change move-result v0 to const/4 v0, 0x0 with the
aim of making the value of the variable v0 false instead of to taking a dynamic value
from the result of the checkForBinary() function

.method public checkForSuBinary()Z


.locals 1
const-string v0, "su"

.line 160
invoke-virtual {p0, v0}, Lcom/scottyab/rootbeer/RootBeer;->checkForBinary(Ljava/lang/String;)Z

const/4 v0, 0x0 <-- Edited

return v0
Bypassing checkSuExist
In the checkSuExist() function, change value of v0 to 0x0 after if-eqz v2
Bypassing checkForRWPaths
In the checkForRWPaths() function, add return v1 at the end of the function so that the
function always returns false because the v1 variable is already false.
Bypassing checkForRootNative
In the checkForRootNative() function, change the v1 value at the end of the function to
0x0 so that the returned value is false.

.method public checkForRootNative()Z


---------------------SNIPPET-------------

if-lez v0, :cond_2


const/4 v1, 0x0 <-- Edited
:catch_0
:cond_2
return v1
.end method
Bypassing checkForMagiskBinary
In the checkForMagiskBinary() function, change move-result v0 to const/4 v0, 0x0
with the aim of making the value of the variable v0 false instead of taking a dynamic
value from the result of the checkForBinary() function
Rebuild, sign and install
Result
We are successfully bypassing
root detection with manual
modification of smali files
01.2
Frida Instrumentation
Bypassing root detection using frida instrumentation
Frida Instrumentation
As we know, we need to bypass these protection to be able to run the
app in rooted device:

● SU Binary
● RW Paths
● Root via Native Checks
● Magisk Specific Checks

I assume that we already know how to write frida script. For the first
step, we will try to hook one of the function to make sure that our
script is working
Frida Instrumentation
Final frida Script
For the rest of functions, we just need to copy and modify with the function name that
we will hook.

But, for keeping it simple(KISS) and


follow DRY principle, I’ve modified
the script to be more simple, short,
and easy to understand.
Result
01.3
Objection
Bypassing root detection using objection
What?
objection is a runtime mobile exploration toolkit, powered by Frida, built to help you
assess the security posture of your mobile applications, without needing a jailbreak.

● Supports both iOS and Android.


● Inspect and interact with container file systems.
● Bypass SSL pinning.
● Dump keychains.
● Perform memory related tasks, such as dumping & patching.
● Explore and manipulate objects on the heap.
● And much, much more…

Installation

Installation is simply a matter of pip3 install objection. This will give you the objection command.
You can update an existing objection installation with pip3 install --upgrade objection.
What?

https://github.com/sensepost/objection/wiki/Screenshots
No need script, only command line
No need script, only command line

Partially success
bypassing rootbeer
checker with objection
command “android root
disable”
Hook & patch the right function
android hooking list class_methods com.example.app.class

Before patching the


functions, we need to
know the class first
Set return value
android hooking set return_value com.app.example.class.method

After we know the right


class_methods, we can
set the return value
01.4
Magisk Zygisk
Bypassing root detection using Magisk Zygisk
Magisk
In simple terms, Magisk is a tool to help users gain root access by patching the ROM.
For further information regarding installation and configuration, please refer to
https://github.com/topjohnwu/Magisk

The easiest method is to rely on Zygisk Denylist in the Magisk application. To be able
to enjoy Zygisk, Magisk version that must be installed is v24.1+.
Setup
Setup
Result
02
SSL Pinning
SSL Pinning

SSL pinning is a technique that helps to


prevent MiTM attacks by hardcoding the
SSL/TLS certificate’s public key into the app
or device. This means that when the app
or device communicates with the server, it
will compare the server’s SSL/TLS
certificate’s public key with the one that is
hardcoded into the app or device.

https://www.indusface.com/learning/what-is-ssl-pinning-a-quick-walk-through/
02.1
Manual Modification
Bypassing SSL Pinning using manual modification of smali
Manual
In this discussion, I will start by explaining how we can bypass the SSL Pinning process by
manually modifying smalis. The target that will be used in this case study is an android
application that use Cordova Framework.

When connecting to the server, the application refused the connection because the
certificate on the device did not match, because I was intercept the traffic using Burp
Suite. With the help of “adb logcat | logcat-color”, I can find out the error message given
by the application when it refuses a connection to the server.
Manual
As you can see, android
certificate pinning is
failing and complaining
about mismatch
certificate hash. Our peer
certificate chain is for
PortSwigger(BurpSuite),
but the Pinned Certificate
for a domain(masked) is
defined in the android
resource file.
Best Approach

Decompile apk and


search for the right
string.

In this case, the file containing the word is in resource/assets/www/pinning/ . After


knowing which file is appropriate, the next step is to modify the string sha256/dGxxxxx to
sha256/fKxxxxx referring to the previous error message.
Recompile
Result
02.2
Objection
Bypassing SSL Pinning using Objection
Approach
As in the discussion for bypassing root detection, we can also do the same thing with
the help of objection. There are two methods that can be done, using the built-in
objection feature or manual patching of the return_value from class_method.

For the study case, we will use

https://github.com/httptoolkit/android-s
sl-pinning-demo/releases/download/v1.
3.1/pinning-demo.apk
Approach

Error when intercepted with burpsuite


Objection
Debugging
Debugging
02.3
Frida
Bypassing SSL Pinning using Frida
Frida
For bypassing SSL Pinning with Frida, we can use frida codeshare or create our own
script.
Frida-codeshare
Bypassing previous ssl pinning protection that failed when using objection, we can use
frida codeshare from https://codeshare.frida.re/@akabe1/frida-multiple-unpinning/
Frida scripting
For manual approach, we can search the right function, hook, replace the return value
same as in the bypassing root detection
02.4
Bypassing Flutter
Bypassing Flutter SSL Pinning
Flutter

One of the reasons it is difficult to bypass SSL Pinning in Flutter is because Flutter
compiles the code into native machine code. This makes common techniques such
as method hooking or code injection in SSL Pinning bypass unable to be carried out,
even the experiments that we have carried out previously.

Flutter ignores proxy settings on the device so that applications cannot be


intercepted. If in the previous case the application would error when passing through
the proxy without the SSL pinning bypass process, this does not apply to Flutter
because the application will only make a direct connection to the server without
passing through the proxy even though it has been set on the device.
02.4.1
reFlutter
Bypassing Flutter SSL Pinning using reFlutter
reFlutter

This framework helps with Flutter apps reverse engineering using the patched version
of the Flutter library which is already compiled and ready for app repacking. This
library has snapshot deserialization process modified to allow you perform dynamic
analysis in a convenient way.
Key features:
● socket.cc is patched for traffic monitoring and interception;
● dart.cc is modified to print classes, functions and some fields;
● display absolute code offset for functions
● contains minor changes for successfull compilation;
● if you would like to implement your own patches, there is manual Flutter code
change is supported using specially crafted Dockerfile
reFlutter
reFlutter
reFlutter
02.4.1
Frida Pattern
Matching
Bypassing Flutter SSL Pinning Ghidra & Frida pattern matching
Concepts

Referring to the article


https://blog.nviso.eu/2022/08/18/intercept-flutter-traffic-on-ios-and-android-http-h
ttps-dio-pinning/, to bypass SSL pinning on Flutter , we can use the pattern matching
method after knowing the pattern of the SSL pinning checking offset address. In
simple terms, the steps taken are:
● Find references to the string “x509.cc” and compare them to x509.cc to find
session_verify_cert_chain
● Find references to the method you identified in order to identify ssl_verify_peer_cert
Concepts

https://blog.nviso.eu/2019/08/13/intercepting-traffic-from-android-flutter-applications/
Concepts
Concepts

Alternatively, we can use Frida’s pattern matching engine to search for functions that
look very similar to the function from the demo app. The first bytes of a function are
typically very stable, as long as the number of local variables and function arguments
don’t change. Still, different compilers may generate different assembly code (e.g.
usage of different registers or optimisations) so we do need to have some wildcards
in our pattern.

https://blog.nviso.eu/2022/08/18/intercept-flutter-traffic-on-ios-and-android-http-https-dio-pinning/
reFlutter
03
Emulator Detection
Emulator Detection
Emulators are usually used to make it easier for reverse engineers, hackers or pentesters
to run applications without needing to have the original device. Because usually,
emulators can be easily created and deleted when there are errors or different needs,
whereas the original device cannot. It is not uncommon for malware developers to use
this check to ensure that their application is able to obtain or control the victim's original
data or device. For this case study, we will use https://github.com/reveny/Android-Emulator-Detection/

The app detect emulator with this checks:


● checkHardware();
● checkMounts();
● checkModules();
● checkCPU();
● checkFiles();
● checkCPUArchitecture();
Emulator Detection
Concepts

Different from the previous discussion, this time our target is using the Java Native
Interface. So, we can't do hooking like we did before. This is because all checking
processes occur in libraries that have been compiled into objects. In this example, all
the checks are in the libemulatordetector.so file.

The first thing we have to do is find out what JNI functions are available, you can use
Frida's help or use nm demangle.
Bypass

To bypass, the first thing to do is tracing with frida-trace. In this case, I will specifically
look for the dlopen function because this function is usually used to load shared
libraries. It can be seen that what is used is android_dlopen_ext to load the shared
library file libemulatordetector.so. So with this info, we can create code to hook Frida.
When we run Frida with this code, we can see that libemulatordetector.so is
loaded from the android_dlopen_ext function
03
Frida Detection
Concepts

In some cases, developers create protection so that the application checks the
existence of Frida on the device. This is to prevent pentesters/hackers from being able
to run Binary Instruments using Frida as in the previous discussion.

There are several mechanisms used to detect the presence of frida, including:
● Detection of named pipes used by Frida
● Detect frida specific thread names
● Detect the port used by Frida
● Etc

For this discussion, I used a customized application to detect frida existence


Concepts

In some cases, developers create protection so that the application checks the
existence of Frida on the device. This is to prevent pentesters/hackers from being able
to run Binary Instruments using Frida as in the previous discussion.

There are several mechanisms used to detect the presence of frida, including:
● Detection of named pipes used by Frida
● Detect frida specific thread names
● Detect the port used by Frida
● Etc

For this discussion, I used a customized application to detect frida existence


Sample app
Frida-server detection

The mechanism used by


the application to detect
frida-server is to check
whether there are files in
/data/local/tmp/frida-se
rver.
Frida-server detection
/proc detection

The mechanism used is


to check /proc/self/maps
to detect the presence of
frida-agent
/proc detection
Default frida port detection

Another mechanism is to
check the default Frida
port, if the default port
can be accessed then
that indicates Frida is
running
Default frida port detection

To bypass this protection,


we can change the
default port used when
running frida-server with
the following command
Default frida port detection
Frida Thread Detection
The application detects the Frida thread by checking /proc/self/task/<PID>/status and
comparing its contents with FRIDA_THREAD_GUM_JS_LOOP and
FRIDA_THREAD_GMAIN.
Frida Thread Detection
To bypass this protection, we can easily manipulate the strstr function every time we
find the specified words
Thanks!
Do you have any questions?
me@petruknisme
t.me/@petruknisme
linkedin.com/in/aancw

CREDITS: This presentation template was created by Slidesgo, and


includes icons by Flaticon, and infographics & images by Freepik

Please keep this slide for attribution

You might also like