Upon accessing the challenge, we’re greeted by a straightforward page featuring an image of a vending machine and a text input field.
My first instinct was to examine the page source, where I discovered a JavaScript file named script.js.
// script.js
async function handleSubmit(event) {
event.preventDefault(); // Prevent the default form submission
const input = document.getElementById('product-input').value;
const output = document.getElementById('output');
const item = document.getElementById('item');
// Simple product check and image mapping
const products = {
chips: "assets/chips.png",
soda: "assets/soda.png",
candy: "assets/candy.png",
juice: "assets/juice.png"
};
setTimeout(async () => {
// Wait for PHP response
const response = await sendProduct(input);
output.innerHTML = response; // Show PHP response
item.style.transform = "translateY(0)"; // Reset position for next drop
setTimeout(() => item.style.display = "none", 1000); // Hide item after a second
}, 2000); // Time it takes to drop the item
if (products[input.toLowerCase()]) {
output.innerHTML = `Dropping ${input}... 🥳`;
// Show item and animate drop
item.style.display = "block"; // Show the item
item.innerHTML = `<img src="${products[input.toLowerCase()]}" alt="${input}">`; // Set image source
// Move item up to simulate dropping down
item.style.transform = "translateY(-60px)"; // Move up to simulate dropping down
}
// Clear input field
document.getElementById('product-input').value = '';
}
// Function to send product to PHP and return response
async function sendProduct(product) {
const response = await fetch('drop-item.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `product=${encodeURIComponent(product)}` // Send product name
});
if (response.ok) {
const responseData = await response.text(); // Get the response text
return responseData; // Return response to be displayed
} else {
return "Error communicating with the server."; // Handle errors
}
}
The function sendProduct particularly stood out, as it sends a request to drop-item.php with the user input as a parameter. After testing various inputs, I noticed it only accepted specific products (chips, soda, candy, juice) and filtered out most special characters and spaces. However,
Finding a Way In
When I attempted certain shell commands, such as ls, the application returned a message indicating it was “not allowed.”
I tried different commands that list directory contents. When I tested the dir command, it unexpectedly worked, revealing the directory contents. Among the files listed was one called entrypoint.sh
Upon inspecting entrypoint.sh, I noticed it reads the flag from an environment variable named FLAG and stores it in a file located at /home/apache/flag with permissions set to allow reading.
To retrieve the value, I used printenv to list all environment variables. Sure enough, this revealed the hidden flag at the end.