← Back to Writeups
CUSTOMEasyMisc

Watermarks (Вотермарки)

XESXOR9/2/20264 min read
#misc#custom#easy#pdf-embedded-image-extraction#document-structure-analysis#hidden-content-discovery-via-p#linux

Watermarks (Вотермарки)

Platform: hackerlab.pro | Category: Misc | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2025-12-23 | Status: Solved Techniques: PDF embedded image extraction, Document structure analysis, Hidden content discovery via pdfimages

Summary

File: watermarks.zip contains Вотермарки.pdf

Watermarks (Вотермарки) — hackerlab.pro

Description

"Недавно у нас в компании была дискуссия на тему полезности вотермарок. Думаем: добавить их в методички наших курсов для отслеживания тех, кто занимается "сливами" или нет. Интересен вопрос надёжности. Сможешь нам помочь?"

(Recently we had a discussion in our company about the usefulness of watermarks. We're thinking: should we add them to our course materials to track those who leak them or not. The question of reliability is interesting. Can you help us?) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

File: watermarks.zip contains Вотермарки.pdf

Analysis

1. Unpacking and Initial Analysis

bash
$ unzip watermarks.zip
Archive:  watermarks.zip
  inflating: Вотермарки.pdf

$ file Вотермарки.pdf
Вотермарки.pdf: PDF document, version 1.4

$ exiftool Вотермарки.pdf
File Type                       : PDF
PDF Version                     : 1.4
Page Count                      : 3

A 3-page PDF document.

2. Text Content Analysis

bash
$ pdftotext Вотермарки.pdf -

The document contains information about watermarks:

  • What watermarks are
  • Why they are needed
  • How they work ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

The text does not contain the flag directly.

3. Extracting Embedded Images

bash
$ pdfimages -list Вотермарки.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     173    35  rgb    3   8  image  no         8  0    96    96 1535B  8.5%
   1     1 image     370   416  rgb    3   8  image  no        10  0    96    96 67.4K  15%
   2     2 image     370   416  rgb    3   8  image  no        12  0    96    96 67.4K  15%
   3     3 image     370   416  rgb    3   8  image  no        14  0    96    96 67.4K  15%
   3     4 image     370   416  rgb    3   8  image  no        16  0    96    96 67.4K  15%

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Found 5 images:

  • img-000: 173x35 pixels — suspiciously small!
  • img-001 to img-004: 370x416 pixels — standard illustrations

4. Extracting Images

bash
$ pdfimages -all Вотермарки.pdf img_
$ ls -la img_*
-rw-r--r--  1 user  staff   1535 Dec 23 12:00 img_-000.png
-rw-r--r--  1 user  staff  69017 Dec 23 12:00 img_-001.png
-rw-r--r--  1 user  staff  69017 Dec 23 12:00 img_-002.png
-rw-r--r--  1 user  staff  69017 Dec 23 12:00 img_-003.png
-rw-r--r--  1 user  staff  69017 Dec 23 12:00 img_-004.png

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

5. Viewing the Small Image

Opening img_-000.png — this small 173x35 pixel image contains the flag text!

Solution

bash
#!/bin/bash
# Watermarks - PDF Image Extraction
# Extracting hidden images from PDF

# Unpack the archive
unzip -o watermarks.zip

# Extract all images from PDF
pdfimages -all "Вотермарки.pdf" extracted_

# View list of extracted files
ls -la extracted_*

# The flag is in the smallest image
# Open extracted_-000.png to view the flag

Alternative Method (Python)

python
#!/usr/bin/env python3
"""
Watermarks - PDF Image Extraction
Uses PyMuPDF (fitz) to extract images
"""
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

import fitz  # PyMuPDF

doc = fitz.open("Вотермарки.pdf")

for page_num in range(len(doc)):
    page = doc[page_num]
    images = page.get_images()
    
    for img_index, img in enumerate(images):
        xref = img[0]
        base_image = doc.extract_image(xref)
        image_bytes = base_image["image"]
        image_ext = base_image["ext"]
        
        filename = f"page{page_num+1}_img{img_index}.{image_ext}"
        with open(filename, "wb") as f:
            f.write(image_bytes)
        print(f"Extracted: {filename} ({len(image_bytes)} bytes)")

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Reference: PDF Analysis Tools

ToolCommandDescription
pdfimagespdfimages -list file.pdfList all images in PDF
pdfimagespdfimages -all file.pdf prefixExtract all images
pdftotextpdftotext file.pdf -Extract text from PDF
exiftoolexiftool file.pdfPDF metadata
pdfinfopdfinfo file.pdfPDF structure information
qpdfqpdf --show-object=N file.pdfView PDF objects

Conclusion

This task demonstrates that watermarks in PDF documents are easily extracted using standard tools like pdfimages. This makes them unreliable for tracking document leaks. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

The flag name REDACTED (nice minus watermark) hints that watermarks can be easily removed or extracted — they do not provide reliable protection.

Additional PDF Protection Methods

For real document leak protection, consider:

  • Unique invisible marks in text (variable-width spaces, Unicode characters)
  • Steganography in document images
  • DRM systems with server-side verification
  • Content personalization (unique wording for each recipient) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍