3 min read

10 Anti-debugging Techniques for Mobile Banking and Payment Apps

10 Anti-debugging Techniques for Mobile Banking and Payment Apps

In the mobile environment, while debuggers are legal and legitimate development tools, hackers can also use them to reverse mobile banking and payment applications. This article describes some of the possible mobile app anti-debugging techniques you can deploy to protect your customers.

Using a debugger is a reversing technique that gives insight into an application. Equipped with debugging tools, attackers can inject malicious code into a banking application. Alternatively, they can create a stub application that either replaces the legitimate banking application or modifies parts of its logic. Sometimes changing the value of a boolean variable is enough to compromise security.

Debugging is a very effective way to reverse run-time application behavior. A debugger allows, among other things, an attacker to:

  • Go through the application flow
  • Stop the execution of the application at arbitrary points
  • Watch the state and values of variables
  • Read and modify the memory used by the application

MASC Product sheet Therefore, it's crucial, in the context of Real-Time Application Self-Protection (RASP), to actively prevent debuggers from being attached to mobile banking and payment applications.

Mobile app anti-debugging systems deploy primary and secondary countermeasures to prevent unwanted access:

  1. Primary: choose to prevent a debugger from being attached to a process.
  2. Secondary: reactively terminate the application if a hacker circumvents the primary countermeasure and it detects an active debugger.

A general technique is to try to detect the presence of known debuggers and reversing tools, like the Frida Instrumentation framework, by checking their signature on the mobile operating system’s files, packages, processes, etc. 

Anti-Debugging Techniques for Mobile Banking & Payment Applications (iOS)

iOS runs on an XNU kernel, which is a Unix-like hybrid kernel. This allows the use of several anti-debug techniques that are common to all the operating systems running on Unix-like kernels, including Android. 

PT_DENY_ATTACH 

Using the PT_DENY_ATTACH flag is a well-known technique to implement mobile app anti-debugging in iOS. 

Using ptrace with PT_DENY_ATTACH validates that no other debugger may attach to the protected process. If a debugger tries to attach, the process will then terminate.

Note that ptrace and the PT_DENY_ATTACH flag are not part of the public iOS API, and as such, it may prevent an iOS banking or payment application using it to be published in the Apple store.

Sysctl

In iOS, it's possible to use sysctl to detect a debugger attached to a process. Sysctl is a function from the iOS API that can retrieve information about a process, especially if it’s been debugged.

Anti-Debugging Techniques for Mobile Banking & Payment Applications (Android)

Android has two possible debugging systems

  • A Java-level debugger using JDWP (Java Debug Wire Protocol), which is the debug protocol between a debugger and the Java VM. 
  • A ptrace-based debugger acting on the native Android Linux kernel. 

Obviously, protecting mobile and payment applications from being debugged must take into account both JWDP and ptrace debuggers. 

Anti-JDWP-debugging

For a Java-based Android application, it’s not difficult to allow it to be debugged. It is enough to change its manifest file and a few other similar resources. 

Using the Debuggable Flag 

The android:debuggable attribute indicates if the process allows debugging or not. If that value has been set to true, then a debugger can be attached.

Timer Checks

The value Debug.threadCpuTimeNanos is an indicator of the time the application is using to execute. Since debuggers significantly slow normal execution, this is a way to detect them.

Using JDWP-related Data Structures

The Dalvik VM holds certain registers accessible via the DvmGlobals structure.

That structure gives information about the presence of debuggers. A similar structure can be exploited in the Android RunTime (ART) to give information about debuggers.

Anti-native-debugging

The defenses mentioned before are useless against ptrace-based debuggers. Classical Linux techniques must be used against such native code debuggers.

Monitoring TracerPid

It is possible to monitor the "TracerPid" field located in the status file of the process. The value of "TracerPid" for ‘no process attached’ is 0, so a value different from 0 means that a debugger is attached or that there are attempts in that direction. 

Force Debug of a Dummy Process

It is possible to exploit the fact that only one debugger at a time can attach to a process. By doing so, the debugger can be prevented from attaching to the current process by forcing it to automatically debug a dummy child process. 

Anti-Anti-Debug or How to Prevent Bypassing Debugger Detection

Finally, a sophisticated way of detecting debuggers is to detect anti-anti-debug measures. There is a list of known hooks that can be performed to prevent some of the aforementioned techniques from working. It's possible to detect the presence of these hooks to spot attempts to counter anti-debug.

 

Read White Paper

References and Further Reading