# Referrrrer

## Background

Defeated the security of the website which implements authentication based on
the [Referer](https://developer.mozilla.org/en-
US/docs/Web/HTTP/Headers/Referer) header.  
  
URL : **[http://static-01.heroctf.fr:7000](http://static-01.heroctf.fr:7000)**  
Format : **Hero{flag}**  
Author : **xanhacks**

![](https://raw.githubusercontent.com/siunam321/CTF-
Writeups/main/HeroCTF-v5/images/Pasted%20image%2020230513135735.png)

## Enumeration

**Home page:**

![](https://raw.githubusercontent.com/siunam321/CTF-
Writeups/main/HeroCTF-v5/images/Pasted%20image%2020230513135622.png)

Seems empty??

**In this challenge, we can download a
[file](https://github.com/siunam321/CTF-
Writeups/blob/main/HeroCTF-v5/Web/Referrrrer/Referrrrer.zip):**  
```shell  
┌[siunam♥earth]-(~/ctf/HeroCTF-v5/Web/Referrrrer)-[2023.05.13|13:58:02(HKT)]  
└> file Referrrrer.zip  
Referrrrer.zip: Zip archive data, at least v1.0 to extract, compression
method=store  
┌[siunam♥earth]-(~/ctf/HeroCTF-v5/Web/Referrrrer)-[2023.05.13|13:58:03(HKT)]  
└> unzip Referrrrer.zip  
Archive: Referrrrer.zip  
creating: app/  
inflating: app/package.json  
inflating: app/index.js  
inflating: app/package-lock.json  
inflating: app/Dockerfile  
inflating: docker-compose.yml  
creating: nginx/  
inflating: nginx/nginx.conf  
```

**In `app/index.js`, we see this:**  
```js  
const express = require("express")  
const app = express()

app.get("/", (req, res) => {  
res.send("Hello World!");  
})

app.get("/admin", (req, res) => {  
if (req.header("referer") === "YOU_SHOUD_NOT_PASS!") {  
return res.send(process.env.FLAG);  
}

res.send("Wrong header!");  
})

app.listen(3000, () => {  
console.log("App listening on port 3000");  
})  
```

When we send a GET request to `/admin`, **if the request header `Referer` is
strictly equal to `YOU_SHOUD_NOT_PASS!`, it'll response us with the flag.**

With that said, we have to some how pass the header check...

**In `nginx/nginx.conf`, we can see there's a rule for location `/admin`:**  
```conf  
[...]  
server {  
listen 80;  
server_name example.com;

location / {  
proxy_pass http://express_app;  
proxy_set_header Host $host;  
proxy_set_header X-Real-IP $remote_addr;  
}

location /admin {  
if ($http_referer !~* "^https://admin\\.internal\\.com") {  
return 403;  
}

proxy_pass http://express_app;  
proxy_set_header Host $host;  
proxy_set_header X-Real-IP $remote_addr;  
}  
}  
[...]  
```

**If the `Referer` header is equal to `https://admin.internal.com`**, it'll
let us pass go to `/admin`.

So... We need to provide `Referer` header with 2 value:
`https://admin.internal.com` **AND** `YOU_SHOUD_NOT_PASS!`?

**However, I tried to include 2 `Referer` header in the `/admin` request:**

![](https://raw.githubusercontent.com/siunam321/CTF-
Writeups/main/HeroCTF-v5/images/Pasted%20image%2020230513145627.png)

But it doesn't work, because it only checks the first `Referer` header and
ignoring the second one.

## Exploitation

**After some research, I found this
[StackOverflow](https://stackoverflow.com/questions/7237262/how-do-i-find-the-
a-referring-sites-url-in-node) post:**

![](https://raw.githubusercontent.com/siunam321/CTF-
Writeups/main/HeroCTF-v5/images/Pasted%20image%2020230513185416.png)

Oh! They are the same thing in Express 4.x?

**Let's try that!**

![](https://raw.githubusercontent.com/siunam321/CTF-
Writeups/main/HeroCTF-v5/images/Pasted%20image%2020230513185444.png)

Nice! We got the flag!

\- **Flag: `Hero{ba7b97ae00a760b44cc8c761e6d4535b}`**

## Conclusion

What we've learned:

1\. Exploiting Referer-based Access Control In Node.js Express

Original writeup (https://siunam321.github.io/ctf/HeroCTF-v5/Web/Referrrrer/).