Summer 2026 SOLUTION LINK click here
Spring2026 SOLUTION LINK click here
FAL2025 SOLUTION LINK click here
SPRING2025 SOLUTION VIEW HERE
FALL2024 SOLUTION VIEW HERE
Setup
To get setup for the flags, follow the steps carefully below, and be sure you are running each in a separate terminal window as noted.
The VM username and password is log4j and Donald-Knuth You will need switch users to login to log4j user via:
Credentials can be found in Canvas on the Log4Shell Assignment page
In the home directory of log4j user, start the container with the start script:
./StartContainer.sh
Open a new terminal window and go to “Desktop/log4shell/logs”:
cd Desktop/log4shell/logs
Run the following command to view the logs:
tail -f cs6035.log
OR to view System.out.println messages:
tail -f console.log
You should now see the tail of the log file from the application running.
**If the logs stop populating, then just stop and restart the tail. This is happening because the data logged gets too large so the log “rolls over” to another file.**
- Run the LDAP Server:
Open a new terminal window and run the following command to set the current directory to “Desktop/log4shell/target”:
You can get the ip address of the vm by running the block below in a terminal (Not necessary, just for informational purposes)
ip addr show
This outputs the vm’s IP
127.0.0.1
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.
You should see the following output:
- Run the Malicious Server:
Open a new terminal and make sure the active directory is the directory that contains your malicious .class file. For simplicity, we have created “Desktop/log4shell/{flag_no}” for you to work in. Do not leave this directory. Run the server in “Desktop/log4shell/{flag_no}” by the following command: python3 -m http.server 4242
It is very important that this matches the port specified in the LDAP 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 You should see the following output:
- Read data that is flowing on the network (This step is required for Flag 2 but is optional for the rest):
To print debug statements from your Java code, tail the
~/Desktop/log4shell/logs/console.log file and add System.out.println statements to your Exploit.java.
Intro Flag
Now that we are set up, let’s do a quick rundown of Log4j, how it works at a high level, and test that we are able to successfully call and exploit the application.
As you should know from the background and resource’s section, Log4j is an application logging library that outputs user defined program information. An example log statement would look like the following:
static Logger log = LogManager.getLogger(RestServlet.class.getName()); log.debug(“ApplicationId: {}”, applicationId);
The log statement above as you can see, defines the class, log level of the message and the actual message. Notice that we are injecting user input into the log message. This is where our vulnerability is.
To be more specific, here is what the output of the message actually will look like:
Now we can map the code above to the logged message. The date/time is defined in configuration files which are out of the scope of this project. Next is where our code starts to map. We have [Classname.java:LineNumber]. This is helpful to know exactly what part of your code is executing and where.
Next, we see DEBUG. This is what is called the log level. Log levels are used for the amount of output you want your application to log, or even to classify errors different from informative messages. The typical log levels are DEBUG, INFO, WARN, ERROR, FATAL. To further explain, if a log level is set to say ERROR, your application will not log anything on WARN, INFO, or DEBUG level. This application is set to DEBUG.
Finally, we get to the actual logged message. As you can see, we log the constant text as well as the injected variable applicationId, which is our applicationId. This is the most important part you will want to pay attention to. Throughout this project, you will try to find messages that log user defined input and inject your malicious string into it.
Now, let’s have some fun and get familiar with the application. To do so, we will call the application normally and then lookup the java version on the application server.
To start we can run a simple inquiry to the services /isAlive endpoint and see what we get back from the logs and see if we can find anything that is exploitable.
GATECH_ID IS A REQUIRED HEADER
Open a new terminal and run:
curl ‘http://localhost:8080/rest/products/isAlive’ -H ‘GATECH_ID:123456789’ -H ‘Accept:application/json’
You should see your logs log some messages in the log tailing terminal window. Let’s inspect it.
Go back to the terminal window you are tailing the logs in. When the server intercepts a request, it logs “Request intercepted” to alert the user where the request starts. As we can see, there is not much going on in terms of useful information, but we can see the service did log a message that could be exploitable.
Voila! In the highlighted message, we see that it is logging the Method Type: GET, the URL: /rest/products/isAlive, and some headers that are null. This is a good indicator that we can exploit this service by sending lookups through a header.
Let’s call one more endpoint to see how headers work and what the application does when we request user data.
In your curl terminal, run the following command:
curl ‘http://localhost:8080/rest/products/productlist’ -H ‘GATECH_ID:123456789’ -H ‘Accept:application/json’
Your output should be similar to:
**Note: You can zoom in by using ctrl + scroll
Take some time to inspect the logged messages and try to understand what the program is doing and the flow of it.
Lets try to get the java version on the server now.
The checked headers for this application are content-type, accept, and XNetworkUserId, although not all are always checked/exploitable.
Construct a malicious payload using one of the logged headers that will return the java version of the host of the web application. You should see something like the screenshot below if successful:
**Note: You might need to scroll up to see this output.
Do you see the same output? LIGHTWEIGHT BABY! Muahaha! If not, try to research the log4shell exploit more and learn how to exploit the lookup.
Our hunch was correct and we have successfully exploited the vulnerability. You can play around with this if you like and see what other lookups you can perform. It is possible to lookup system settings, environment variables and much more just with this.
Be sure to save your work outside of the VM in case the VM crashes or some other unforeseen issue arises. This will ensure you are not losing your work.
Flag 1: Environment Echo (10 pts)
Make sure you have gone through the Setup and Intro sections.
If you haven’t already, run the start script in the home directory of log4j user, start the container with the start script:
./StartContainer.sh
The endpoint for this exploit can be called and inspected via:
curl ‘http://localhost:8080/rest/products/isAlive’ -H ‘GATECH_ID:123456789’ -H ‘Accept:application/json’
| ADMIN_PASSWORD |
Now that you have seen how to check environment variables, run a lookup for which stores your flag for this exercise. If successful, you should see the below output:
Add this flag (Congratulations! Your flag1 is: ____) to your project_log4shell.json file.
NOTE: You do not need to use Java code, ldap, python server, etc to get this flag.
Flag 2: Get a Shell (15 pts)
Make sure you have gone through the Setup and Intro sections.
If you haven’t already, run the start script in the home directory of log4j user, start the container with the start script:
./StartContainer.sh
The endpoint for this exploit can be called and inspected via:
curl ‘http://localhost:8080/rest/products/isAlive’ -H ‘GATECH_ID:123456789’ -H ‘Accept:application/json’
Now that we have proven this service is vulnerable and that we can exploit it in at least one place, let’s try to do more damage and do something more malicious. If you have not already, you NEED to read through the suggested readings and learn how/why it is possible to send jndi lookups.
Open the “Exploit.java” file and construct a malicious payload to execute such that when the jndi/ldap lookup happens, it gives you root access on the vulnerable application server.
You should have a total of 4 terminal windows open which are the 3 from the SETUP section and one terminal window to run your curl command.
Once you are ready to run the exploit, ensure that the java version you are running the command is “java version 1.8.0_20” by running:
To compile your .java file into a class file, move the the directory the .java file is stored in and run:
javac Exploit.java
NOTE: THIS PROJECT IS WRITTEN USING THE VULNERABLE VERSION OF 1.8.0_20.
NOT ALL VERSIONS OF JAVA ALLOW LOOKUPS AND YOU COULD SPIN YOUR WHEELS FOR AWHILE NOT KNOWING WHY YOUR EXPLOIT IS NOT RUNNING IF YOU DO NOT FOLLOW THIS DIRECTION.
We have added the ability to log from your Exploit.java file so that you can log useful debugging information while you are developing your exploit. To log messages from your Java class, tail the ~Desktop/log4shell/logs/console.log file and add System.out.println statements to your Exploit.java.
| Desktop/log4shell/Flagx |
Make sure you are running this command from
This should create Exploit.class. Run your “python3 -m http.server 4242” command in this directory.
Hint: Pay close attention to the ports you are using in this exercise.
If successful, you should see similar console output as the screenshot below:
With success, you should see this in the console output of the nc command. Now type “whoami” and you should see “root”.
Did you get the screenshot above? Congratulations!
If not, keep trying and ensure all of your hosts/ports match. Analyze the screenshots and make sure yours matches. If you are not getting the ldap/python server output, you likely did not set up your hosts/ports correctly OR your Exploit.java file isn’t correct.
You now have root access to the vulnerable application’s server. YIKES! This is a great example why this exploit is so dangerous. You can perform any task on this server now. For now, go back 2 directories using “cd ..” and then run “java -jar Flag2.jar” to get your
flag and add it to the json under “Flag2”.
FLAG 3: Config.Properties Surprise (25 pts)
Make sure you have gone through the Setup and Intro sections.
If you haven’t already, run the start script in the home directory of log4j user, start the container with the start script:
./StartContainer.sh
For this flag we will use the /products/ resource. There are 4 total endpoints for this resource. Only the following 2 are relevant for this flag.
Call the following endpoint to fetch all the records. Save one of the ids. GET All – Fetch all product records:
curl ‘http://localhost:8080/rest/products/productlist’ -H ‘GATECH_ID:123456789’
Call the following endpoint to GET by ID and inspect the logged output.
GET By ID – Fetch a single product record by ID: curl ‘http://localhost:8080/rest/products/product/<id>’ -H ‘GATECH_ID:123456789’
You have caught wind that there is a properties file that this application uses to inject configurable data during runtime.
For this exploit, you will use the log4j exploit to overwrite the “config.properties” file saved in the root directory of the application. This properties file contains a property that will set the customer service email for all of the products.
See if you can find anything that gives you a hint about how to exploit it/what you need to do, to update the property.
This application links the properties’ customer service email address to all products in its response. You have a good friend who has been bothering you so you want to spam his email inbox with customer complaints about these products. First, you need to make sure that this is even possible.
For this flag, you will need to overwrite the properties file so that when the application builds the product response, it sets the email address to your gatechId. *i.e. 123456789, not [email protected] or [email protected]
If successful, you should get your flag in the email field of the response:
Hint: Someone might have tried to roll their own patch and tried to deny requests containing malicious string patterns.
*** **IF THIS FLAG COMES OUT BLANK, Restart container by running the stopContainer and startContainer scripts in the home directory of the log4j user. *****
FLAG 4: Command and Concat (25 pts)
Make sure you have gone through the Setup and Intro sections.
If you haven’t already, run the start script in the home directory of log4j user, start the container with the start script:
./StartContainer.sh
For this flag, we will exploit an endpoint that adds a new user:
curl -X PUT ‘http://localhost:8080/rest/users/user’ -H ‘GATECH_ID:903449128’ -H ‘Content-
Type:application/json’ –data-raw
‘{“id”:8,”userId”:”2134″,”userName”:”RSANCHEZ1″,”userRole”:”R&D”,”adminYN”:”Y”}’
Take some time to inspect this output and see what you need to exploit. Yes the exception is expected, and maybe there is even a clue above it 😉
For this flag, you will construct a malicious file (Exploit.java) and compile it, so that when deserialized it will create a simple “.txt” file on the server to get the flag. Using the log4shell exploit, create a file named “Ronnie.txt” on the server and add ONE line that says “LightWeightBaby!” (You do not need the quote). If you do not follow this exactly, you will not get this flag.
Upon success, you will see the output below. (You might have to scroll for this)
Hint: The name of this flag is a huge hint as to what you need to do. Pay close attention to the logged messages and their format. *** **IF THIS FLAG COMES OUT BLANK, Restart container by running the stopContainer and startContainer scripts in the home directory of the log4j user. *****
FLAG 5: PubSub Override (25 pts)
Make sure you have gone through the Setup and Intro sections.
If you haven’t already, run the start script in the home directory of log4j user, start the container with the start script:
./StartContainer.sh
For this flag, we will exploit a previous endpoint that publishes updates to a topic on the server:
curl -X PUT ‘http://localhost:8080/rest/users/user’ -H ‘GATECH_ID:903449128’ -H ‘Content-
Type:application/json’ –data-raw
‘{“id”:8,”userId”:”2134″,”userName”:”RSANCHEZ1″,”userRole”:”R&D”,”adminYN”:”Y”}’
You remember that properties file? Good! We are going to play with it yet again.
For this exploit, you will use the log4j exploit to overwrite the “config.properties” file saved in the root directory of the application. This properties file contains a topic that the application will publish a message to when updateUser call is made (the application is also subscribed to this topic as you can see in the logs).
You will need to trick the application into publishing a message to a different topic with your GATECH_ID as the account number in order to generate a valid flag.
Upon success, you should see your output similar to that below:
Hint: Look through the cs6035.log to find clues about what this other topic could be. Your flag could be invalid if you have not sent your GATECH_ID appropriately in the published message. *** **IF THIS FLAG COMES OUT BLANK, Restart container by running the stopContainer and startContainer scripts in the home directory of the log4j user. *****
File submission instructions:
This project needs to be submitted via Gradescope. Navigate to the course in Canvas, click ‘Gradescope’, click ‘Project Log4Shell’ and submit there.
This is an autograded project. You will have unlimited submissions with instant feedback. Your Gradescope grade will be your final grade. Be aware that your most recent submission is activated by default and will be used for your grade unless you activate another submission before the deadline.
The contents of the submission file should be the following. There is
| ~/Desktop/log4shell/project_log4shell.json |
a file in your vm with a template set up, or you
| project_log4shell.json |
can copy-paste this to your newly created file elsewhere and replace the placeholders with the flags you retrieve from each relevant task.
Note: You can use Featherpad or Vim to create and edit this file. Do not use LibreOffice or any Word Document editor. It must be in proper JSON format with no special characters in order to pass the autograder and these Word Document editors are likely to introduce special characters.











