In this paper, Bernhard Mueller talks about how we could get OTP from RSA and DigiPass by reverse engineering the products.
1. MOBILE ONE-TIME PASSWORD TOKEN OVERVIEW
It is clear that in the case of OATH-TOTP, the shared key K needs to be kept secret: An adversary knowing K would be able to calculate the correct OTP at any point in time.
In order to generate one-time passwords, the user must first initialize a local token instance by registering with an authentication service. During the registration process the shared secret is agreed upon, and additional
information such as device binding data may be exchanged. This process is also known as provisioning.
Because the shared secret usually isn’t very large, some solutions also allow the user to enter it manually (e.g. in the form of a registration code).
A popular and convenient method of installing the secret are QR codes. These codes allow a user to provision a token instance by pointing the smartphone camera at the screen. The seed data may be encoded directly in the QR code, or the QR code may trigger a more elaborate process. As an example, Google Authenticator QR codes encode an otpauth:// URL with the secret appended.
Let’s imagine a hypothetical malicious entity – Francis - scheming to impersonate an innocent victim’s (Peter’s) account. To gain access to the 2FA-protected service, Francis needs to generate the correct OTP at the time of the login attempt. In the ideal case (or worst, if you’re on Peter’s side), he’d want to obtain a fully functional copy, or clone, of Peter’s OTP generator, so that he can generate valid OTPs at arbitrary times. Simpler methods, such as instrumenting the token generator directly on Peter’s device, may also be effective.
Just like other mobile apps, mobile tokens on Android and iOS are subject to containerization, so (unless the developers made some terrible choices) the users’ data and secret keys are protected by the default OS protection mechanisms. Once root access is obtained, only the proprietary defenses added by the vendor stand in Francis’ way. In fact, the whole point of having those defenses in the first place is to prevent cloning of the token instance in this scenario.
RETRIEVAL FROM PERMANENT STORAGE
As a prerequisite however, Francis needs to know what comprises the secret (what algorithm is used, and what are the expected secret inputs), where it is stored, and how it is protected.
Francis (or one of his minions) must first reverse engineer the storage and encryption mechanisms used by that particular app. Once this is done, he can devise an attack tool to copy the data for the mobile token.
RETRIEVAL FROM MEMORY
In simple cases, simply dumping the Java heap may suffice. For example, our proof-of-concept tool for RSA SecurID uses code injection to instantiate the app’s own encryption classes which are then used to load, decrypt and dump the encrypted secret.
CODE LIFTING AND INSTRUMENTATION
For most practical purposes, such as replicating the OTP sequence, Francis doesn’t necessarily need to know all the details about how the OTP is computed. Instead of painstakingly reverse engineering the code, he can simply copy and re-use whole implementation instead. This kind of attack is known as code lifting and is commonly used for breaking DRM and white-box cryptographic implementations.
To counter this kind of attack, mobile token vendors implement measures to bind the OTP computation to the user’s mobile device. Preferably, the OTP generator should execute correctly only in the specific, legitimate mobile environment. For example, certain cryptographic keys (or part of those
keys) are generated using data collected from the device. Techniques that tie the functionality of an app to a specific environment are known as device binding.
3. THE ANDROID REVERSER'S TOOLBOX
DE-COMPILERS, DISASSEMBLERS AND DEBUGGERS
TRACING JAVA CODE
This is particularly useful when dealing with a large obfuscated codebase, as it allows us to observe all method calls in the order they are executed.
- METHOD TRACING WITH JDB
- DDMS: THE SURPRISING POWER TOOL
Both JDB and DDMS depend on the Java Debug Wire Protocol (JDWP), so on stock Android the target app needs to be marked as a debug build for the tools to work. We can however bypass this requirement with a modification to the default.prop file.
- INSTRUMENTING ART
- PROGUARD WOES
TRACING NATIVE CODE
- CPU TRACING USING THE EMULATOR
- DYNAMIC BINARY INSTRUMENTATION
TRACING SYSTEM CALLS
- CLASSIC LINUX ROOTKIT STYLE
DYNAMIC ANALYSIS FRAMEWORKS
RUNTIME INSTRUMENTATION WITH FRIDA
AUTOMATING SYSTEM CALL HOOKING WITH ZORK
Yet to be public
4. Case Study
Please refer to paper.