Working on bug bounties as a novice hacker can accelerate your learning path in cybersecurity. Luckily, the hacker community collects top HackerOne reports for our studying pleasure. For example, check out this list: Top disclosed reports from HackerOne. Using that list, we can pick any of the reports and expect to find a gem to help us learning hacking. Just since it sounds fun, I decided to go with this one: Account takeover via leaked session cookie.
In this article, we’re going to breakdown this report into understandable terms and recreate it ourselves using a homemade app. Let’s start by looking at what the report says. I recommend you open the report and read it yourself, before beginning with the summary below.
Summary of the report
To put it as concisely as possible, a hacker tricked a Security Analyst from HackerOne into sharing their session cookie. If you know what that means, feel free to skip to the next section. If not, we’ll briefly explain it here.
Imagine you’re developing a web app (like HackerOne itself!) that lets users login. How do users stay logged in when they visit the site in the future? Their browser could store their username and password and send it with every request. But this comes with a price – now, if any request is ever stolen or intercepted, the hacker owns that account.
Instead, wouldn’t it be better if the user could stay logged in without sending their credentials with every request? That’s where session cookies come into play. When you login, you are given a special token representing your session. As long as you send this with each request, the server knows you are logged in. If an attacker steals it, they can access your session, but they don’t know the actual password for your account. This is why on many social media apps, you need to supply your password for certain critical actions (like deleting your account) even though you’re already logged in!
In the case of the report from HackerOne, a Security Analyst was coaxed into revealing their session cookie. In so doing, they allowed the hacker to access their account. Luckily, this hacker was of the white hat variety, and reported this immediately to HackerOne, who promptly invalidated the tainted cookie.
But that’s enough theory, let’s make our own app that uses session cookies so we can really understand what’s going on here!
Creating a proof-of-concept web app
To best emphasize the relevant parts of the code, I’m going to create the simplest possible app to show how this works. The server code below only does two things:
- Let a user log in with their username and password
- Let users who have logged in access content with their session cookie
We can start by creating a simple PoC using Node.js and Express that looks like this:
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const app = express();
const users = {
'user1': 'password1',
'user2': 'password2'
};
const messages = {
'user1': ['Hello, user1!', 'Welcome back!'],
'user2': ['Hi, user2!', 'You have new messages.']
};
app.use(bodyParser.urlencoded({ extended: true }));
app.use(session({
secret: 'secret key',
resave: false,
saveUninitialized: true,
cookie: { secure: false } // Set to true if using HTTPS
}));
app.get('/login', (req, res) => {
res.send(`
<form action="/login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<button type="submit">Login</button>
</form>
`);
});
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (users[username] && users[username] === password) {
req.session.user = username;
res.send(`Welcome, ${username}!`);
} else {
res.status(401).send('Invalid username or password.');
}
});
app.get('/messages', (req, res) => {
if (req.session.user && messages[req.session.user]) {
res.json(messages[req.session.user]);
} else {
res.status(401).send('You must be logged in to view messages.');
}
});
app.listen(3000, () => {
console.log(`Server running at http://localhost:3000`);
});
Even if JavaScript isn’t your cup of tea, the snippet above should be simple enough if you have any background in web coding. Or even if not, you might be able to follow along!
To install this, save it as server.js and then run the following commands:
npm init
npm install express
npm install express-session
Now you can run the app by running the command:
node server.js
Okay, now let’s try opening the login endpoint in our browser to see if anything appears. We can do this by browsing to http://localhost:3000, as indicated in the server code.
It works – by entering the password hard coded into the server code, we can access the /messages endpoint using our session cookie that the server gave us.
Okay, great! The app “works”, though barely. Now we can hack it using the same trick from the HackerOne report.
Learning hacking by exploiting our PoC
At its core, the hack described in the report is a social engineering attack. So we can imagine we’re a bug bounty hunter, trying to trick someone with an account (ideally, an account with juicy admin privileges!), what do we do?
We could convince the admin that there’s a bug in the app, and we want to show them how it works. First, they need to go to the /messages endpoint. Once there, they should open up their browser’s debugging interface and click on the Storage tab. Here is where they’ll “see the bug”, according to our trick. They just need to click on the connect.sid cookie.
So they do, and they ask us what to do next? “Hmm”, we reply, “it’s hard to explain – can you send me a screenshot of what you see there?”
We get this:
That’s all we need to begin executing our attack. It’s quite simple: we can copy that cookie to access this user’s session – we will be logged in as them. Watch as we access their messages from the command line using this cookie:
$ curl 'http://localhost:3000/messages' -H 'Cookie: connect.sid=s%3A12oJhOBODGP4Zv1aPWpu_2Ljf2ANjC8C.0cEahCm69qhxPKFcfCw4rw01bJlrwsanCeHwEguoclk'
["Hello, user1!","Welcome back!"]
Marvelous, we get the result we would want! We have accessed the endpoint by using the session cookie we stole from the hapless admin. In the command line snippet above, we did it using the curl command for the sake of keeping things simple. However, we could just as easily do the same thing in the browser, by manually adding the cookie using your browser’s dev tools.
Learning hacking – more about bug bounties!
We’ve actually written quite a bit about bug bounties in the past. Check out the following learning materials to explore other things you can do with bug bounties:
Additionally, PortSwigger Academy hosts excellent guides on web vulns, which are by far the most common source of bug bounty payoffs on mainstream platforms like HackerOne and Bugcrowd. What if “mainstream” isn’t your thing? No need to fret, you can earn in crypto on platforms such as HackenProof and Immunefi.
The point you should take home is that bug bounty hunting has grown bigger than ever. Far from being a saturated market, there’s opportunity for hackers at every level, even those who have just begun learning hacking. So get started while the bugs are plenty – it won’t be like this forever!
Leave a Reply