Back to writeups

International Hack10 CTF 2026

Malware Or Not

International HACK@10 CTF 2026 hack10, forensics, reverse engineering writeup covering Malware Or Not with analysis, solution steps, and final recovery notes.

Date
Platform
CTF
Category
CTF
Difficulty
Medium
#ctf#hack10#forensics#reverse-engineering#malware-analysis

CTF: International HACK@10 CTF 2026 Category: Forensics / Malware Analysis Points: 448 Flag Format: hack10{url} Author: Wh1teB3ar

Challenge Overview

The challenge provides a document file named malware.doc. The goal is to analyze the document in a controlled environment and identify the suspicious URL acting as an Indicator of Compromise.

The final flag must be submitted as:

hack10{url}

Initial Analysis

The document appears simple when opened. The visible content is only:

Testing
Im hacker

However, malicious Office documents often hide behavior inside their internal XML structure instead of visible text.

Modern Word documents are usually OOXML files, which are ZIP archives containing XML files. Even if the extension is .doc, the file may still be ZIP-based.

Initial commands:

file malware.doc
strings malware.doc | grep -Ei "http|https|Target|External|oleObject"
unzip malware.doc -d extracted_doc

After extraction, the important location is:

word/_rels/document.xml.rels

This file stores document relationships, including external objects, links, and embedded references.

Vulnerability / Weakness Identification

The suspicious behavior comes from an external relationship inside the Word document.

The document contains an external OLE object reference:

Target="https://happy.divide.cloud/nowyouknow.html"
TargetMode="External"

This is suspicious because the document can reference a remote resource when opened. In malware analysis, such URLs are treated as IoCs because they may be used for tracking, beaconing, payload delivery, or command-and-control staging.

Exploitation Strategy

The simplest reliable method is static analysis.

Plan:

  1. Treat the document as a ZIP archive.

  2. Extract all internal files.

  3. Search XML relationship files for URLs.

  4. Identify relationships using TargetMode="External".

  5. Extract the suspicious URL.

  6. Wrap the URL using the required flag format.

No dynamic execution is needed.

Proof of Concept

Manual extraction:

mkdir extracted_doc
unzip malware.doc -d extracted_doc
cat extracted_doc/word/_rels/document.xml.rels

Search for URLs:

grep -RniE "https?://" extracted_doc

Expected suspicious result:

https://happy.divide.cloud/nowyouknow.html

Full Python Solver

#!/usr/bin/env python3
import zipfile
import re
import sys
from pathlib import Path
import xml.etree.ElementTree as ET


def extract_urls_from_docx_relationships(file_path):
    """
    Extract suspicious external URLs from OOXML relationship files.
    Works for .docx files and .doc files that are actually ZIP-based OOXML.
    """
    path = Path(file_path)

    if not path.exists():
        print(f"[!] File not found: {file_path}")
        sys.exit(1)

    if not zipfile.is_zipfile(path):
        print("[!] This file is not a ZIP-based OOXML document.")
        print("[*] Falling back to raw string URL extraction...")

        data = path.read_bytes()
        urls = re.findall(rb"https?://[^\s\"'<>()]+", data)

        return sorted(set(url.decode(errors="ignore") for url in urls))

    found_urls = set()

    with zipfile.ZipFile(path, "r") as z:
        print("[*] OOXML ZIP document detected.")
        print("[*] Searching relationship files...")

        for name in z.namelist():
            if name.endswith(".rels"):
                content = z.read(name)

                # Raw regex extraction as backup
                urls = re.findall(rb"https?://[^\s\"'<>()]+", content)
                for url in urls:
                    found_urls.add(url.decode(errors="ignore"))

                # XML parsing for TargetMode="External"
                try:
                    root = ET.fromstring(content)
                    for rel in root:
                        target = rel.attrib.get("Target", "")
                        mode = rel.attrib.get("TargetMode", "")
                        rel_type = rel.attrib.get("Type", "")

                        if mode.lower() == "external" and target.startswith(("http://", "https://")):
                            print(f"[+] External relationship found in: {name}")
                            print(f"    Type   : {rel_type}")
                            print(f"    Target : {target}")
                            found_urls.add(target)

                except ET.ParseError:
                    pass

    return sorted(found_urls)


def main():
    if len(sys.argv) != 2:
        print(f"Usage: python3 {sys.argv[0]} <document>")
        sys.exit(1)

    file_path = sys.argv[1]
    urls = extract_urls_from_docx_relationships(file_path)

    if not urls:
        print("[!] No URLs found.")
        sys.exit(1)

    print("\n[*] URLs found:")
    for url in urls:
        print(f"    {url}")

    # For this challenge, the suspicious IoC is the external URL.
    ioc = urls[0]
    print("\n[+] Flag:")
    print(f"hack10{{{ioc}}}")


if __name__ == "__main__":
    main()

Walkthrough

Save the script:

nano solve.py

Run it:

python3 solve.py malware.doc

Expected output:

[*] OOXML ZIP document detected.
[*] Searching relationship files...
[+] External relationship found in: word/_rels/document.xml.rels
    Target : https://happy.divide.cloud/nowyouknow.html

[+] Flag:
hack10{https://happy.divide.cloud/nowyouknow.html}

Troubleshooting:

sudo apt install unzip python3

If unzip fails, use:

strings malware.doc | grep -Ei "https?://"

Flag

hack10{https://happy.divide.cloud/nowyouknow.html}

Conclusion

The root cause of the challenge is a hidden external relationship inside an OOXML Word document. The visible document content is only a decoy. The real IoC is stored inside word/_rels/document.xml.rels.

Key lesson: never trust only the visible content of an Office document. Always inspect internal OOXML relationship files for external URLs, embedded objects, and suspicious remote references.

Authorized security practice only. These notes are for lab, CTF, and explicitly permitted environments.