Low-level RASP: Protecting Applications Implemented in High-level Programming Languages
This talk introduces a low-level Runtime Application Self-Protection (RASP) architecture designed to protect applications written in high-level languages like Java, Node.js, PHP, Python, and Ruby. By operating at the native layer rather than the application runtime layer, the proposed solution achieves language-independent security monitoring and interception. The speaker demonstrates how this approach bypasses common RASP evasion techniques, such as stack trace manipulation and reflection-based hooks, while maintaining high performance. The presentation includes a live demonstration of the tool intercepting malicious system calls in multiple language environments.
Why Your RASP Implementation Is Likely Bypassed by Default
TLDR: Most Runtime Application Self-Protection (RASP) tools rely on hooks within the application runtime, making them vulnerable to evasion via native code execution or stack manipulation. This research demonstrates that by moving security monitoring to the native layer using eBPF and custom ptrace-based injection, you can achieve language-agnostic interception that remains invisible to standard application-level bypasses. Security teams should stop treating the application runtime as a trusted boundary and start monitoring at the syscall interface.
Runtime Application Self-Protection has long been sold as the silver bullet for web application security. The pitch is simple: while a Web Application Firewall (WAF) sits at the perimeter and guesses at intent, RASP sits inside the application, watching the actual execution flow. If a piece of code tries to execute a system command or open a file it shouldn't, RASP kills the process. It sounds perfect until you realize that most RASP implementations are just fancy monkey-patching. They live inside the same memory space and runtime environment as the application they are supposed to protect.
If you are a pentester, you already know the game. If you can control the execution flow of the application, you can control the RASP. By using techniques like reflection, native method calls, or simply manipulating the stack, you can often blind these tools or force them to ignore your payload. The fundamental flaw is that RASP is playing by the rules of the language it is protecting.
The Native Layer Advantage
The research presented at Black Hat 2023 shifts the battlefield. Instead of hooking methods inside the Java Virtual Machine (JVM) or the V8 engine, this approach operates at the native layer. By intercepting execution at the syscall interface, the security logic becomes entirely independent of the high-level language. Whether the application is written in Java, Node.js, PHP, Python, or Ruby, the underlying system calls for spawning a process or opening a socket remain the same.
This architecture uses a combination of eBPF for monitoring and ptrace-based injection to place hooks at the native library level. Because the interception happens before the application can even process the request, the attacker cannot use language-specific tricks to bypass the monitor. If the application tries to call execve to launch a shell, the native hook catches it regardless of whether the call originated from a legitimate function or a malicious gadget chain.
Breaking the Hook
Consider the standard Java command execution flow. Most RASP tools set their hook points at java.lang.Runtime.exec. An attacker can easily bypass this by using reflection to call the underlying native methods directly or by using a gadget chain that avoids the hooked method entirely.
The low-level approach described in this research renders these bypasses useless. By hooking the native fork and exec calls within libc.so or the equivalent native libraries, the security monitor sits beneath the application's reach. Even if an attacker successfully manipulates the Java stack to bypass the RASP's Java-level hooks, they still have to interact with the operating system to perform the malicious action. That interaction is where the native-level RASP catches them.
To implement this, the researchers developed a modular system where the "hook" is language-independent, but the "context" is language-aware. They use a lightweight extension to extract the stack trace from the native side, allowing the security engine to understand exactly which part of the application triggered the syscall. This provides the best of both worlds: the visibility of a RASP with the robustness of a kernel-level monitor.
Practical Implications for Pentesters
During a penetration test, you should treat standard RASP implementations as a hurdle, not a wall. If you encounter an application protected by a traditional RASP, look for ways to trigger native code execution. If you can drop a small native library or use a language feature that allows for direct syscalls, you can often bypass the application-level hooks entirely.
However, if you are testing an environment that uses this native-level monitoring, your standard bypasses will fail. You will see your payloads being blocked even when you are using advanced techniques like gadget chains that typically evade application-layer detection. This is a sign that the defense has moved down the stack.
For those interested in the mechanics, the eBPF documentation provides a solid foundation for understanding how these native-level hooks are implemented. Monitoring syscalls like execve, connect, and openat is the most effective way to detect A03:2021-Injection attempts, as these are the final steps in almost any successful RCE or file-read exploit.
Moving Forward
The era of relying on application-runtime hooks for security is coming to an end. As attackers get better at manipulating runtimes, defenders must move their instrumentation to where the rubber meets the road: the kernel and the native library interface.
If you are building security tools, stop trying to fight the language. Start watching the OS. If you are a researcher, start looking at how your favorite RASP tools interact with native libraries. You might find that the "unbreakable" security layer is just a few lines of code away from being completely bypassed by a well-placed native call. The next time you are on an engagement, don't just look at the application code. Look at the syscalls. That is where the truth of the execution flow lies.
Vulnerability Classes
Attack Techniques
OWASP Categories
All Tags
Up Next From This Conference

Chained to Hit: Discovering New Vectors to Gain Remote and Root Access in SAP Enterprise Software

Zero-Touch-Pwn: Abusing Zoom's Zero Touch Provisioning for Remote Attacks on Desk Phones

ODDFuzz: Hunting Java Deserialization Gadget Chains via Structure-Aware Directed Greybox Fuzzing
Similar Talks

Kill List: Hacking an Assassination Site on the Dark Web

Unmasking the Snitch Puck: The Creepy IoT Surveillance Tech in the School Bathroom

