-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Port MASTG-TEST-0050: Testing Runtime Integrity Checks (android) #3692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…chniques and examples
| 1. **Memory checksums**: Comparing memory contents or checksums against known good values. | ||
| 2. **Signature-based detection**: Searching memory for signatures of unwanted modifications. | ||
| 3. **Java Runtime tampering detection**: Detecting modifications to the Android Runtime (ART) made by hooking frameworks. | ||
| 4. **Injected class detection**: Identifying classes injected by frameworks like Xposed. | ||
| 5. **GOT hook detection**: Verifying Global Offset Table entries point to legitimate libraries. | ||
| 6. **Inline hook detection**: Inspecting function prologues/epilogues for trampolines or suspicious jump instructions. | ||
|
|
||
| Techniques 1 and 2 are foundational approaches that underpin the more specific detection methods (3-6). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to give a good structure here. I would definitely need a 2nd or 3rd expert to proof-read this as I am not extremely familiar with all techniques, especially native ones.
|
|
||
| On Android, common signatures to detect include: | ||
|
|
||
| - **Inline hook trampolines**: A trampoline is a small piece of code that redirects execution from one location to another. Hooking frameworks insert trampolines at function entry points to intercept calls—when the original function is called, the trampoline jumps to the hook handler instead. On ARM64, a common trampoline pattern loads a 64-bit target address into a scratch register and branches to it: `LDR X16, .+8; BR X16` followed by the 8-byte absolute address. Scratch registers (X16 and X17 on ARM64) are temporary registers that the calling convention allows to be overwritten without saving, making them ideal for trampolines. Based on the [ARM A64 instruction set encoding](https://developer.arm.com/documentation/ddi0602/latest/), this sequence encodes to bytes `50 00 00 58 00 02 1F D6`. Scanning for such patterns at function entry points can reveal hooks. The [O-MVLL anti-hooking pass](https://obfuscator.re/omvll/passes/anti-hook/) exploits the fact that Frida's Interceptor requires X16/X17 as scratch registers by injecting prologues that use these registers, preventing Frida from hooking. Note that ARM32/Thumb code uses different trampoline patterns (e.g., `LDR PC, [PC, #-4]`) and should be checked separately if the app includes 32-bit libraries. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can unshamelessly say that this bullet is AI-assisted, especially the bytes. However it looked interesting to bring for discussion here.
Let's not rush merging this before validating.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love the honest AI disclosure!
| --- | ||
| platform: android | ||
| title: App Terminating on Frida Hook Detection Before Cipher.doFinal Execution | ||
| id: MASTG-DEMO-0088 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update before merge + filename
| --- | ||
| platform: android | ||
| title: Extracting Sensitive Data from Cipher.doFinal via Frida Hooking | ||
| id: MASTG-DEMO-0087 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update before merge + filename
| --- | ||
| platform: android | ||
| title: Testing Runtime Hook Detection | ||
| id: MASTG-TEST-03te |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Allocate before merge + filename
| - R | ||
| profiles: [R] | ||
| status: deprecated | ||
| covered_by: [MASTG-TEST-03te] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update before merge
| --- | ||
|
|
||
| Controls in this category verify the integrity of the app's memory space to defend the app against memory patches applied during runtime. Such patches include unwanted changes to binary code, bytecode, function pointer tables, and important data structures, as well as rogue code loaded into process memory. Integrity can be verified by: | ||
| Controls in this category verify the integrity of the app's memory to defend against runtime memory patches. Such patches include unwanted changes to binary code, bytecode, function pointer tables, and important data structures, as well as rogue code loaded into process memory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know "controls" was already there but I don't think this refers (anymore?) to MASVS controls. Should we say methods/techniques or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind much the term "controls" but we can also say "techniques" as you suggest. A technique that verifies a security goal such as integrity can be considered a control.
From ISC2's glossary:
control The use of access rules or countermeasures to limit a subject’s access to an object. See also security control, safeguards, and countermeasures.
Security control The mechanism used to address security vulnerabilities to reduce or man- age risk. See also control, safeguards, and countermeasures.
| title: App Terminating on Frida Hook Detection Before Cipher.doFinal Execution | ||
| id: MASTG-DEMO-0088 | ||
| code: [kotlin] | ||
| test: MASTG-TEST-03te |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update before merge
| title: Extracting Sensitive Data from Cipher.doFinal via Frida Hooking | ||
| id: MASTG-DEMO-0087 | ||
| code: [kotlin] | ||
| test: MASTG-TEST-03te |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update before merge
| title: Bypassing Frida Detection in /proc/self/maps to Extract Sensitive Data | ||
| id: MASTG-DEMO-0089 | ||
| code: [kotlin] | ||
| test: MASTG-TEST-03te |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update before merge
| --- | ||
| platform: android | ||
| title: Bypassing Frida Detection in /proc/self/maps to Extract Sensitive Data | ||
| id: MASTG-DEMO-0089 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update before merge + filename
| --- | ||
| title: Hardening Against Runtime Hooking | ||
| alias: hardening-against-runtime-hooking | ||
| id: MASTG-BEST-0029 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Allocate before merge + filname
|
|
||
| Defending against runtime hooking requires a layered approach that combines several types of security controls: | ||
|
|
||
| - **Preventive controls**: Implement root detection (@MASTG-KNOW-0027) and device/app attestation (https://github.com/OWASP/mastg/issues/3505) as the first line of defense, since most hooking frameworks (e.g., Frida server, Xposed) require rooted devices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Create new BEST practice: device, app attestation with hardware backed keys #3505 should be removed before merge. Demonstrated the connection of the topics
| - **Memory scanning**: Scan `/proc/self/maps` and process memory for known artifacts (e.g., "LIBFRIDA", frida-agent libraries, Xposed bridge classes). | ||
| - **Integrity checksums**: Compute checksums of critical code sections at build/load time and verify them periodically at runtime to detect patches and inline hooks. | ||
| - **GOT/PLT verification**: Verify that Global Offset Table entries point to addresses within their expected libraries. | ||
| - **Function prologue inspection**: Compare the first bytes of security-critical functions against their expected values to detect trampoline patterns (e.g., `LDR X16, .+8; BR X16` on ARM64). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also consider: #3692 (comment)
demos/android/MASVS-RESILIENCE/MASTG-DEMO-0089/MASTG-DEMO-0089.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm considering:
- having the bypass as a new demo vs
- add the bypass to 0088 after the evaluation
Do you think is it worth to keep them separate? The test fails in any case ... the bypass is just "informative"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Demos 87, 88, and 89 demonstrate the "cat and mouse" issue of RASP.
- 87 is a failed test (failed defence/successful attack) against a hook (simple attack)
- 88 is a successful test (successful defense/failed attack) against the attack of 87
- 89 is a failed test (failed defence/successful attack) against the defenses of 88 by using a more "complex" attack.
- In theory, we could make a new Demo- 90 which has defenses against the attack of 89.
This would most likely go on and on, and the attacker would always win.
Maybe we can explain this relationship in all 3 demos' description.
I preferred the separation and to also keep 88, as for a given attack, the defense passes. It also has a stand-alone merit as demonstration on how to detect /proc/self/maps).
This structure might recur in any runtime protection-related demos.
Now, merging 88 and 89 would require a fail/pass grouping within the same demo. Do we have something similar, or would it be the first? If so, maybe not as part of this PR, since it's a structural question and we should consider other DEMOs with a similar pass/failure relationship.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this. We should give it a try and see how it works with the rest of RESILIENCE. Thanks Dio!
Co-authored-by: Carlos Holguera <[email protected]>
|
@Diolor please move temporarily to "fake IDs" to avoid the conflicts we're seeing here with other demos, best practices, etc. Thanks 🙏 |
This PR closes #3017
Description
AI Tool Disclosure
If AI tools were used to generate or substantially modify code or text, complete the following.