
Содержание
1. Введение в криминалистический анализ PDF документов
2. Установка и настройка инструментов для анализа PDF
3. Интерфейс и основные возможности инструментов
4. Базовые техники анализа PDF документов
5. Анализ метаданных PDF документов
6. Извлечение скрытой информации из PDF
7. Анализ структуры и объектов PDF
8. Обнаружение модификаций и подделок
9. Анализ JavaScript и встроенных скриптов
10. Работа с зашифрованными PDF документами
11. Продвинутые техники криминалистического анализа
12. Интеграция с другими инструментами криминалистики
13. Автоматизация анализа PDF документов
14. Отчетность и документирование результатов
15. Практические примеры и кейсы
16. Часто задаваемые вопросы (FAQ)
1. Введение в криминалистический анализ PDF документов
Криминалистический анализ PDF документов является важнейшим направлением цифровой криминалистики, которое позволяет экспертам исследовать электронные документы, выявлять скрытую информацию, обнаруживать модификации и подделки, а также извлекать доказательства для судебных разбирательств. PDF (Portable Document Format) является одним из наиболее распространенных форматов документов в современном цифровом мире, и умение профессионально анализировать PDF файлы критически важно для специалистов по цифровой криминалистике, экспертов по информационной безопасности и исследователей киберпреступлений.
Проблема, которую решает криминалистический анализ PDF документов, заключается в сложности обнаружения скрытой информации, модификаций и признаков подделки в электронных документах. Современные PDF документы могут содержать множество скрытых элементов: метаданные с информацией об авторе и истории создания, встроенные объекты и файлы, JavaScript код, зашифрованные данные, водяные знаки, комментарии и аннотации, а также следы редактирования и модификации. Без специализированных инструментов и знаний практически невозможно обнаружить эти элементы и провести полноценное криминалистическое исследование.
Основные преимущества профессионального анализа PDF документов включают возможность обнаружения скрытой информации, которая может быть критически важна для расследований, выявление признаков модификации и подделки документов, извлечение метаданных, содержащих информацию об авторе, дате создания и программном обеспечении, использованном для создания документа, анализ встроенных объектов и файлов, которые могут содержать дополнительные доказательства, обнаружение вредоносного кода и потенциальных угроз безопасности, а также создание детальных отчетов для судебных разбирательств.
Криминалистический анализ PDF документов применяется в различных сценариях: расследование киберпреступлений, где PDF документы могут использоваться для распространения вредоносного ПО или фишинговых атак, судебные разбирательства, где необходимо доказать подлинность или подделку документов, корпоративные расследования, связанные с утечками информации или внутренними нарушениями, анализ инцидентов безопасности, где PDF документы могут быть вектором атаки, исследование авторства документов и обнаружение плагиата, а также восстановление удаленной или скрытой информации из документов.
Современные инструменты для анализа PDF документов предоставляют экспертам мощные возможности для исследования структуры документов, извлечения метаданных, анализа объектов, обнаружения модификаций и создания детальных отчетов. Эти инструменты используют различные техники: парсинг структуры PDF, анализ объектов и потоков, извлечение метаданных через XMP и другие стандарты, декодирование и анализ встроенных данных, обнаружение аномалий и признаков модификации, а также интеграцию с другими инструментами криминалистики для комплексного анализа.
Важно понимать, что криминалистический анализ PDF документов требует глубоких знаний формата PDF, понимания его структуры и особенностей, а также владения специализированными инструментами и техниками. Эксперты должны быть знакомы с различными версиями спецификации PDF, методами шифрования и защиты документов, техниками обфускации и сокрытия информации, а также правовыми аспектами работы с электронными доказательствами.
В следующих разделах мы детально рассмотрим инструменты, техники и методы криминалистического анализа PDF документов, начиная с установки и настройки необходимого программного обеспечения, изучения интерфейсов и основных возможностей, базовых и продвинутых техник анализа, работы с метаданными и скрытой информацией, обнаружения модификаций, автоматизации процессов и создания профессиональных отчетов. Вы получите полное понимание процесса криминалистического анализа PDF документов и сможете применять эти знания в практической работе.
2. Установка и настройка инструментов для анализа PDF
Установка и правильная настройка инструментов для анализа PDF документов является первым критически важным шагом для успешного криминалистического исследования. Современные эксперты используют различные инструменты, каждый из которых имеет свои особенности установки и настройки. В этом разделе мы рассмотрим установку основных инструментов для анализа PDF, их системные требования и процесс первоначальной конфигурации.
PDFtk (PDF Toolkit) является одним из наиболее популярных инструментов командной строки для работы с PDF документами. Он позволяет извлекать метаданные, объединять и разделять PDF файлы, а также выполнять различные операции с документами.
Технический пример 1: Установка PDFtk на различных платформах
Установка на Linux (Debian/Ubuntu):
bash
<h2 id="obnovlenie-spiska-paketov">Обновление списка пакетов</h2>
sudo apt update
<h2 id="ustanovka-pdftk">Установка PDFtk</h2>
sudo apt install pdftk -y
<h2 id="proverka-ustanovki">Проверка установки</h2>
pdftk --version
Установка на Linux (Red Hat/CentOS):
bash
<h2 id="ustanovka-cherez-yum">Установка через yum</h2>
sudo yum install pdftk -y
<h2 id="ili-cherez-dnf-dlya-novyh-versiy">Или через dnf для новых версий</h2>
sudo dnf install pdftk -y
Установка на macOS:
bash
<h2 id="ispolzovanie-homebrew">Использование Homebrew</h2>
brew install pdftk-java
<h2 id="proverka-ustanovki">Проверка установки</h2>
pdftk --version
Установка на Windows:
powershell
<h2 id="skachivanie-ustanovschika-s-ofitsialnogo-sayta">Скачивание установщика с официального сайта</h2>
<h2 id="https-www-pdflabs-com-tools-pdftk-the-pdf-toolkit">https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/</h2>
<h2 id="ili-cherez-chocolatey">Или через Chocolatey</h2>
choco install pdftk
<h2 id="dobavlenie-v-path-pri-neobhodimosti">Добавление в PATH при необходимости</h2>Peepdf является специализированным инструментом для анализа PDF документов с фокусом на безопасность. Он написан на Python и позволяет детально анализировать структуру PDF, обнаруживать вредоносный код и извлекать скрытую информацию.
Технический пример 2: Установка Peepdf
Установка через pip:
bash
<h2 id="ustanovka-peepdf">Установка Peepdf</h2>
pip install peepdf
<h2 id="ili-cherez-pip3">Или через pip3</h2>
pip3 install peepdf
<h2 id="proverka-ustanovki">Проверка установки</h2>
peepdf --help
Установка из исходников:
bash
<h2 id="klonirovanie-repozitoriya">Клонирование репозитория</h2>
git clone https://github.com/jesparza/peepdf.git
cd peepdf
<h2 id="ustanovka-zavisimostey">Установка зависимостей</h2>
pip install -r requirements.txt
<h2 id="ustanovka">Установка</h2>
python setup.py install
Использование Peepdf:
bash
<h2 id="bazovyy-analiz-pdf">Базовый анализ PDF</h2>
peepdf -i document.pdf
<h2 id="interaktivnyy-rezhim">Интерактивный режим</h2>
peepdf document.pdf
<h2 id="eksport-rezultatov">Экспорт результатов</h2>
peepdf -i document.pdf -o results.json
pdf-parser является частью набора инструментов Didier Stevens и одним из наиболее мощных инструментов для анализа структуры PDF документов. Он позволяет извлекать объекты, анализировать потоки и обнаруживать аномалии.
Технический пример 3: Установка pdf-parser
Установка на Linux:
bash
<h2 id="skachivanie-pdf-parser">Скачивание pdf-parser</h2>
wget https://didierstevens.com/files/software/pdf-parser_V0_7_7.py
<h2 id="ustanovka-zavisimostey">Установка зависимостей</h2>
sudo apt install python3 python3-pip -y
<h2 id="ustanovka-neobhodimyh-bibliotek">Установка необходимых библиотек</h2>
pip3 install pycryptodome
<h2 id="sozdanie-simvolicheskoy-ssylki-dlya-udobstva">Создание символической ссылки для удобства</h2>
sudo ln -s $(pwd)/pdf-parser_V0_7_7.py /usr/local/bin/pdf-parser
chmod +x pdf-parser_V0_7_7.py
Использование pdf-parser:
bash
<h2 id="bazovyy-analiz">Базовый анализ</h2>
python3 pdf-parser.py document.pdf
<h2 id="poisk-obektov">Поиск объектов</h2>
python3 pdf-parser.py document.pdf --search string
<h2 id="izvlechenie-obektov">Извлечение объектов</h2>
python3 pdf-parser.py document.pdf --object 5
<h2 id="analiz-potokov">Анализ потоков</h2>
python3 pdf-parser.py document.pdf --stats
QPDF является мощным инструментом для структурного анализа и преобразования PDF документов. Он особенно полезен для работы с поврежденными или нестандартными PDF файлами.
Технический пример 4: Установка QPDF
Установка на Linux:
bash
<h2 id="ustanovka-cherez-paketnyy-menedzher">Установка через пакетный менеджер</h2>
sudo apt install qpdf -y
<h2 id="ili-kompilyatsiya-iz-ishodnikov">Или компиляция из исходников</h2>
wget https://github.com/qpdf/qpdf/releases/download/v11.6.3/qpdf-11.6.3.tar.gz
tar -xzf qpdf-11.6.3.tar.gz
cd qpdf-11.6.3
./configure
make
sudo make install
Использование QPDF:
bash
<h2 id="proverka-struktury-pdf">Проверка структуры PDF</h2>
qpdf --check document.pdf
<h2 id="izvlechenie-metadannyh">Извлечение метаданных</h2>
qpdf --show-encryption document.pdf
<h2 id="preobrazovanie-pdf">Преобразование PDF</h2>
qpdf --linearize document.pdf output.pdf
ExifTool является универсальным инструментом для извлечения метаданных из различных форматов файлов, включая PDF. Он особенно полезен для анализа метаданных XMP и другой информации, встроенной в документы.
Технический пример 5: Установка ExifTool
Установка на Linux:
bash
<h2 id="ustanovka-cherez-paketnyy-menedzher">Установка через пакетный менеджер</h2>
sudo apt install libimage-exiftool-perl -y
<h2 id="proverka-ustanovki">Проверка установки</h2>
exiftool -ver
Установка на macOS:
bash
<h2 id="ispolzovanie-homebrew">Использование Homebrew</h2>
brew install exiftool
Установка на Windows:
powershell
<h2 id="skachivanie-s-ofitsialnogo-sayta">Скачивание с официального сайта</h2>
<h2 id="https-exiftool-org">https://exiftool.org/</h2>
<h2 id="ili-cherez-chocolatey">Или через Chocolatey</h2>
choco install exiftool
Использование ExifTool для PDF:
bash
<h2 id="izvlechenie-vseh-metadannyh">Извлечение всех метаданных</h2>
exiftool document.pdf
<h2 id="eksport-v-xml">Экспорт в XML</h2>
exiftool -X document.pdf > metadata.xml
<h2 id="izvlechenie-konkretnyh-tegov">Извлечение конкретных тегов</h2>
exiftool -Creator -Title -Author document.pdf
PDF Examiner является графическим инструментом для анализа PDF документов, который предоставляет удобный интерфейс для исследования структуры документов и извлечения информации.
Технический пример 6: Установка PDF Examiner
Установка на Windows:
powershell
<h2 id="skachivanie-ustanovschika">Скачивание установщика</h2>
<h2 id="https-www-pdfexaminer-com">https://www.pdfexaminer.com/</h2>
<h2 id="ustanovka-cherez-ustanovschik">Установка через установщик</h2>
<h2 id="sledovanie-instruktsiyam-mastera-ustanovki">Следование инструкциям мастера установки</h2>Установка на Linux (через Wine):
bash
<h2 id="ustanovka-wine">Установка Wine</h2>
sudo apt install wine -y
<h2 id="zapusk-ustanovschika-cherez-wine">Запуск установщика через Wine</h2>
wine PDFExaminer_Setup.exe
Настройка рабочей среды для анализа PDF включает создание структурированных директорий для хранения анализируемых файлов, результатов анализа и отчетов.
Технический пример 7: Настройка рабочей среды
Создание структуры директорий:
bash
#!/bin/bash
<h2 id="sozdanie-osnovnoy-direktorii-dlya-raboty">Создание основной директории для работы</h2>
mkdir -p ~/pdf_analysis
<h2 id="sozdanie-poddirektoriy">Создание поддиректорий</h2>
mkdir -p ~/pdf_analysis/{samples,results,reports,tools,scripts}
<h2 id="sozdanie-direktorii-dlya-bekapov">Создание директории для бэкапов</h2>
mkdir -p ~/pdf_analysis/backups
<h2 id="ustanovka-prav-dostupa">Установка прав доступа</h2>
chmod -R 755 ~/pdf_analysis
echo "Рабочая среда создана в ~/pdf_analysis"
Создание конфигурационного файла:
bash
<h2 id="sozdanie-konfiguratsionnogo-fayla">Создание конфигурационного файла</h2>
cat > ~/pdf_analysis/config.conf << EOF
<h2 id="konfiguratsiya-dlya-analiza-pdf">Конфигурация для анализа PDF</h2>
WORK_DIR=~/pdf_analysis
SAMPLES_DIR=\$WORK_DIR/samples
RESULTS_DIR=\$WORK_DIR/results
REPORTS_DIR=\$WORK_DIR/reports
TOOLS_DIR=\$WORK_DIR/tools
<h2 id="nastroyki-analiza">Настройки анализа</h2>
DEEP_ANALYSIS=true
EXTRACT_OBJECTS=true
ANALYZE_JAVASCRIPT=true
CHECK_MALWARE=true
<h2 id="nastroyki-otchetnosti">Настройки отчетности</h2>
REPORT_FORMAT=html
INCLUDE_SCREENSHOTS=true
EOF
Проверка установки всех инструментов:
bash
#!/bin/bash
echo "Проверка установленных инструментов для анализа PDF..."
TOOLS=("pdftk" "peepdf" "qpdf" "exiftool" "python3")
for tool in "${TOOLS[@]}"; do
if command -v $tool &> /dev/null; then
echo "✓ $tool установлен"
$tool --version 2>/dev/null || echo " Версия: доступен"
else
echo "✗ $tool не установлен"
fi
done
<h2 id="proverka-python-bibliotek">Проверка Python библиотек</h2>
echo ""
echo "Проверка Python библиотек..."
python3 -c "import PyPDF2; print('✓ PyPDF2 установлен')" 2>/dev/null || echo "✗ PyPDF2 не установлен"
python3 -c "import pdfplumber; print('✓ pdfplumber установлен')" 2>/dev/null || echo "✗ pdfplumber не установлен"
3. Интерфейс и основные возможности инструментов
Понимание интерфейсов и основных возможностей инструментов для анализа PDF документов критически важно для эффективной работы эксперта. Различные инструменты предоставляют различные интерфейсы: командная строка, графический интерфейс, веб-интерфейс или программный API. В этом разделе мы детально рассмотрим интерфейсы основных инструментов и их ключевые возможности.
Peepdf предоставляет как командный, так и интерактивный интерфейс для анализа PDF документов. Командный интерфейс позволяет быстро выполнять базовые операции, а интерактивный режим предоставляет больше возможностей для детального исследования.
Технический пример 1: Использование интерфейса Peepdf
Командный режим:
bash
<h2 id="bazovyy-analiz-s-vyvodom-informatsii">Базовый анализ с выводом информации</h2>
peepdf -i document.pdf
<h2 id="analiz-s-eksportom-rezultatov">Анализ с экспортом результатов</h2>
peepdf -i document.pdf -o results.json
<h2 id="poisk-javascript-koda">Поиск JavaScript кода</h2>
peepdf -i document.pdf --search js
<h2 id="izvlechenie-obektov">Извлечение объектов</h2>
peepdf -i document.pdf --extract-objects
Интерактивный режим:
bash
<h2 id="zapusk-interaktivnogo-rezhima">Запуск интерактивного режима</h2>
peepdf document.pdf
<h2 id="v-interaktivnoy-konsoli-dostupny-komandy">В интерактивной консоли доступны команды:</h2>
<h2 id="info-informatsiya-o-dokumente">info - информация о документе</h2>
<h2 id="tree-derevo-obektov">tree - дерево объектов</h2>
<h2 id="object-num-prosmotr-obekta">object <num> - просмотр объекта</h2>
<h2 id="stream-num-prosmotr-potoka">stream <num> - просмотр потока</h2>
<h2 id="search-string-poisk-stroki">search <string> - поиск строки</h2>
<h2 id="js-analyse-analiz-javascript">js_analyse - анализ JavaScript</h2>
<h2 id="exit-vyhod">exit - выход</h2>Пример работы в интерактивном режиме:
python
<h2 id="primer-avtomatizatsii-cherez-python-api-peepdf">Пример автоматизации через Python API Peepdf</h2>
from peepdf.PDFCore import PDFParser
<h2 id="parsing-pdf">Парсинг PDF</h2>
parser = PDFParser()
ret, pdf = parser.parse('document.pdf', forceMode=True, looseMode=True)
if ret == 0:
# Получение информации о документе
info = pdf.getBasicMetadata()
print("Версия PDF:", info['version'])
print("Количество объектов:", len(pdf.body))
# Поиск JavaScript
js_code = pdf.getJSCode()
if js_code:
print("Найден JavaScript код:", len(js_code), "блоков")
pdf-parser предоставляет мощный командный интерфейс с множеством опций для детального анализа структуры PDF документов.
Технический пример 2: Использование pdf-parser
Базовые команды:
bash
<h2 id="polnyy-analiz-struktury">Полный анализ структуры</h2>
python3 pdf-parser.py document.pdf
<h2 id="poisk-konkretnoy-stroki">Поиск конкретной строки</h2>
python3 pdf-parser.py document.pdf --search "JavaScript"
<h2 id="prosmotr-konkretnogo-obekta">Просмотр конкретного объекта</h2>
python3 pdf-parser.py document.pdf --object 5
<h2 id="analiz-potokov">Анализ потоков</h2>
python3 pdf-parser.py document.pdf --filter --raw --object 10
<h2 id="statistika-po-dokumentu">Статистика по документу</h2>
python3 pdf-parser.py document.pdf --stats
<h2 id="poisk-uyazvimostey">Поиск уязвимостей</h2>
python3 pdf-parser.py document.pdf --search "/JS"
Извлечение и декодирование:
bash
<h2 id="izvlechenie-potoka-obekta">Извлечение потока объекта</h2>
python3 pdf-parser.py document.pdf --object 10 --filter --raw > stream_10.raw
<h2 id="dekodirovanie-potoka">Декодирование потока</h2>
python3 pdf-parser.py document.pdf --object 10 --filter --decode > stream_10_decoded.bin
<h2 id="poisk-vseh-javascript-obektov">Поиск всех JavaScript объектов</h2>
python3 pdf-parser.py document.pdf --search "/JS" --object
QPDF предоставляет командный интерфейс для структурного анализа и преобразования PDF документов.
Технический пример 3: Использование QPDF
Анализ структуры:
bash
<h2 id="proverka-struktury-pdf">Проверка структуры PDF</h2>
qpdf --check document.pdf
<h2 id="pokazat-informatsiyu-o-shifrovanii">Показать информацию о шифровании</h2>
qpdf --show-encryption document.pdf
<h2 id="pokazat-lineynost-dokumenta">Показать линейность документа</h2>
qpdf --show-linearization document.pdf
<h2 id="pokazat-obekty">Показать объекты</h2>
qpdf --show-object=5 document.pdf
Извлечение информации:
bash
<h2 id="izvlechenie-metadannyh">Извлечение метаданных</h2>
qpdf --json document.pdf > metadata.json
<h2 id="izvlechenie-vseh-obektov">Извлечение всех объектов</h2>
qpdf --qdf document.pdf output.pdf
<h2 id="sozdanie-nelinearizovannoy-versii">Создание нелинеаризованной версии</h2>
qpdf --linearize document.pdf linearized.pdf
ExifTool предоставляет универсальный интерфейс для работы с метаданными различных форматов, включая PDF.
Технический пример 4: Использование ExifTool для PDF
Базовое извлечение метаданных:
bash
<h2 id="pokazat-vse-metadannye">Показать все метаданные</h2>
exiftool document.pdf
<h2 id="pokazat-konkretnye-tegi">Показать конкретные теги</h2>
exiftool -Title -Author -Creator document.pdf
<h2 id="pokazat-metadannye-v-strukturirovannom-vide">Показать метаданные в структурированном виде</h2>
exiftool -G document.pdf
<h2 id="pokazat-tolko-xmp-metadannye">Показать только XMP метаданные</h2>
exiftool -XMP:All document.pdf
Экспорт и форматирование:
bash
<h2 id="eksport-v-xml">Экспорт в XML</h2>
exiftool -X document.pdf > metadata.xml
<h2 id="eksport-v-json">Экспорт в JSON</h2>
exiftool -j document.pdf > metadata.json
<h2 id="eksport-v-csv">Экспорт в CSV</h2>
exiftool -csv document.pdf > metadata.csv
<h2 id="pokazat-tolko-izmenennye-tegi">Показать только измененные теги</h2>
exiftool -f document.pdf
PDFtk предоставляет простой командный интерфейс для выполнения различных операций с PDF документами.
Технический пример 5: Использование PDFtk
Извлечение метаданных:
bash
<h2 id="izvlechenie-metadannyh">Извлечение метаданных</h2>
pdftk document.pdf dump_data output metadata.txt
<h2 id="izvlechenie-metadannyh-v-utf-8">Извлечение метаданных в UTF-8</h2>
pdftk document.pdf dump_data_utf8 output metadata_utf8.txt
Операции с документами:
bash
<h2 id="obedinenie-pdf-faylov">Объединение PDF файлов</h2>
pdftk file1.pdf file2.pdf cat output combined.pdf
<h2 id="razdelenie-pdf-na-stranitsy">Разделение PDF на страницы</h2>
pdftk document.pdf burst output page_%02d.pdf
<h2 id="izvlechenie-konkretnyh-stranits">Извлечение конкретных страниц</h2>
pdftk document.pdf cat 1-5 output pages_1-5.pdf
<h2 id="povorot-stranits">Поворот страниц</h2>
pdftk document.pdf cat 1-5E output rotated.pdf
PyPDF2 и pdfplumber являются Python библиотеками, которые предоставляют программный интерфейс для анализа PDF документов.
Технический пример 6: Использование PyPDF2
Базовое использование:
python
import PyPDF2
<h2 id="otkrytie-pdf-fayla">Открытие PDF файла</h2>
with open('document.pdf', 'rb') as file:
pdf_reader = PyPDF2.PdfReader(file)
# Информация о документе
print("Количество страниц:", len(pdf_reader.pages))
print("Метаданные:", pdf_reader.metadata)
# Извлечение текста
for page_num, page in enumerate(pdf_reader.pages):
text = page.extract_text()
print(f"Страница {page_num + 1}: {len(text)} символов")
# Проверка шифрования
if pdf_reader.is_encrypted:
print("Документ зашифрован")
Технический пример 7: Использование pdfplumber
Продвинутый анализ:
python
import pdfplumber
with pdfplumber.open('document.pdf') as pdf:
# Информация о документе
print("Количество страниц:", len(pdf.pages))
print("Метаданные:", pdf.metadata)
# Извлечение текста с сохранением структуры
for page in pdf.pages:
text = page.extract_text()
tables = page.extract_tables()
images = page.images
print(f"Страница {page.page_number}:")
print(f" Текст: {len(text)} символов")
print(f" Таблицы: {len(tables)}")
print(f" Изображения: {len(images)}")
Создание универсального скрипта для анализа:
python
#!/usr/bin/env python3
"""
Универсальный скрипт для анализа PDF документов
"""
import sys
import json
from pathlib import Path
def analyze_pdf_with_multiple_tools(pdf_path):
"""Анализ PDF с использованием нескольких инструментов"""
results = {
'file': str(pdf_path),
'tools': {}
}
# Анализ через PyPDF2
try:
import PyPDF2
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
results['tools']['PyPDF2'] = {
'pages': len(reader.pages),
'encrypted': reader.is_encrypted,
'metadata': dict(reader.metadata) if reader.metadata else None
}
except Exception as e:
results['tools']['PyPDF2'] = {'error': str(e)}
# Анализ через pdfplumber
try:
import pdfplumber
with pdfplumber.open(pdf_path) as pdf:
results['tools']['pdfplumber'] = {
'pages': len(pdf.pages),
'metadata': pdf.metadata
}
except Exception as e:
results['tools']['pdfplumber'] = {'error': str(e)}
return results
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 analyze_pdf.py <pdf_file>")
sys.exit(1)
pdf_path = Path(sys.argv[1])
if not pdf_path.exists():
print(f"Файл не найден: {pdf_path}")
sys.exit(1)
results = analyze_pdf_with_multiple_tools(pdf_path)
print(json.dumps(results, indent=2, ensure_ascii=False))
4. Базовые техники анализа PDF документов
Базовые техники анализа PDF документов являются фундаментом для любого криминалистического исследования. Эти техники позволяют экспертам получить первичное понимание структуры документа, извлечь основную информацию и выявить очевидные аномалии. В этом разделе мы рассмотрим основные методы анализа, которые должен знать каждый эксперт по цифровой криминалистике.
Первым шагом в анализе любого PDF документа является проверка его целостности и базовой структуры. Это позволяет определить, является ли файл валидным PDF документом, не поврежден ли он, и какие версии спецификации PDF он использует.
Технический пример 1: Проверка базовой структуры PDF
Использование qpdf для проверки:
bash
#!/bin/bash
PDF_FILE="document.pdf"
echo "=== Проверка структуры PDF ==="
echo ""
<h2 id="proverka-tselostnosti">Проверка целостности</h2>
echo "1. Проверка целостности:"
qpdf --check "$PDF_FILE" 2>&1
<h2 id="informatsiya-o-versii">Информация о версии</h2>
echo ""
echo "2. Версия PDF:"
strings "$PDF_FILE" | grep -i "^%PDF" | head -1
<h2 id="proverka-lineynosti">Проверка линейности</h2>
echo ""
echo "3. Линеаризация:"
qpdf --show-linearization "$PDF_FILE" 2>&1 | head -5
<h2 id="informatsiya-o-shifrovanii">Информация о шифровании</h2>
echo ""
echo "4. Шифрование:"
qpdf --show-encryption "$PDF_FILE" 2>&1
Использование Python для базовой проверки:
python
#!/usr/bin/env python3
"""
Базовая проверка структуры PDF документа
"""
import sys
from pathlib import Path
def check_pdf_structure(pdf_path):
"""Проверка базовой структуры PDF"""
results = {
'valid': False,
'version': None,
'size': 0,
'header': None,
'trailer': None
}
pdf_file = Path(pdf_path)
if not pdf_file.exists():
return results
results['size'] = pdf_file.stat().st_size
with open(pdf_file, 'rb') as f:
# Проверка заголовка
header = f.read(8)
if header.startswith(b'%PDF-'):
results['valid'] = True
results['header'] = header.decode('ascii', errors='ignore').strip()
# Извлечение версии
version_str = header[5:8].decode('ascii')
try:
results['version'] = float(version_str)
except:
pass
# Поиск трейлера
f.seek(-1024, 2) # Последние 1024 байта
trailer_data = f.read()
if b'trailer' in trailer_data:
results['trailer'] = True
return results
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 check_pdf.py <pdf_file>")
sys.exit(1)
results = check_pdf_structure(sys.argv[1])
print(f"Валидный PDF: {results['valid']}")
print(f"Версия: {results['version']}")
print(f"Размер: {results['size']} байт")
print(f"Заголовок: {results['header']}")
print(f"Трейлер найден: {results['trailer']}")
Извлечение базовой информации о документе является следующим важным шагом. Это включает получение метаданных, информации о количестве страниц, размере документа и других базовых характеристиках.
Технический пример 2: Извлечение базовой информации
Комплексный скрипт для извлечения информации:
python
#!/usr/bin/env python3
"""
Извлечение базовой информации из PDF документа
"""
import sys
import json
from datetime import datetime
from pathlib import Path
def extract_basic_info(pdf_path):
"""Извлечение базовой информации о PDF"""
info = {
'file': str(pdf_path),
'analysis_date': datetime.now().isoformat(),
'file_size': 0,
'pdf_version': None,
'pages': 0,
'encrypted': False,
'metadata': {},
'structure': {}
}
pdf_file = Path(pdf_path)
info['file_size'] = pdf_file.stat().st_size
# Анализ через PyPDF2
try:
import PyPDF2
with open(pdf_file, 'rb') as f:
reader = PyPDF2.PdfReader(f)
info['pages'] = len(reader.pages)
info['encrypted'] = reader.is_encrypted
if reader.metadata:
info['metadata'] = {
'title': reader.metadata.get('/Title', ''),
'author': reader.metadata.get('/Author', ''),
'subject': reader.metadata.get('/Subject', ''),
'creator': reader.metadata.get('/Creator', ''),
'producer': reader.metadata.get('/Producer', ''),
'creation_date': str(reader.metadata.get('/CreationDate', '')),
'modification_date': str(reader.metadata.get('/ModDate', ''))
}
except Exception as e:
info['error'] = str(e)
# Определение версии PDF
with open(pdf_file, 'rb') as f:
header = f.read(8)
if header.startswith(b'%PDF-'):
version_str = header[5:8].decode('ascii')
try:
info['pdf_version'] = float(version_str)
except:
pass
return info
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_info.py <pdf_file>")
sys.exit(1)
results = extract_basic_info(sys.argv[1])
print(json.dumps(results, indent=2, ensure_ascii=False))
Анализ объектов PDF является важной техникой для понимания внутренней структуры документа. PDF документы состоят из объектов, которые содержат различные элементы: текст, изображения, шрифты, аннотации и другие данные.
Технический пример 3: Анализ объектов PDF
Использование pdf-parser:
bash
#!/bin/bash
PDF_FILE="document.pdf"
echo "=== Анализ объектов PDF ==="
echo ""
<h2 id="statistika-po-obektam">Статистика по объектам</h2>
echo "1. Статистика объектов:"
python3 pdf-parser.py "$PDF_FILE" --stats
<h2 id="poisk-vseh-obektov-s-javascript">Поиск всех объектов с JavaScript</h2>
echo ""
echo "2. Объекты с "
python3 pdf-parser.py "$PDF_FILE" --search "/JS" --object
<h2 id="poisk-obektov-s-potokami">Поиск объектов с потоками</h2>
echo ""
echo "3. Объекты с потоками:"
python3 pdf-parser.py "$PDF_FILE" --stats | grep -i stream
<h2 id="izvlechenie-konkretnogo-obekta">Извлечение конкретного объекта</h2>
echo ""
echo "4. Извлечение объекта 5:"
python3 pdf-parser.py "$PDF_FILE" --object 5
Python скрипт для анализа объектов:
python
#!/usr/bin/env python3
"""
Анализ объектов PDF документа
"""
import sys
import re
from collections import defaultdict
def analyze_pdf_objects(pdf_path):
"""Анализ объектов в PDF"""
objects_info = {
'total_objects': 0,
'object_types': defaultdict(int),
'streams': [],
'javascript_objects': [],
'embedded_files': []
}
with open(pdf_path, 'rb') as f:
content = f.read()
# Поиск всех объектов
object_pattern = re.compile(rb'(\d+)\s+(\d+)\s+obj')
objects = object_pattern.findall(content)
objects_info['total_objects'] = len(objects)
# Поиск потоков
stream_pattern = re.compile(rb'(\d+)\s+(\d+)\s+obj.*?stream', re.DOTALL)
streams = stream_pattern.findall(content)
objects_info['streams'] = [f"{s[0].decode()} {s[1].decode()}" for s in streams]
# Поиск JavaScript
js_pattern = re.compile(rb'/JS\s+(\d+)\s+(\d+)\s+R', re.IGNORECASE)
js_refs = js_pattern.findall(content)
objects_info['javascript_objects'] = [f"{j[0].decode()} {j[1].decode()}" for j in js_refs]
# Поиск встроенных файлов
embedded_pattern = re.compile(rb'/EmbeddedFiles', re.IGNORECASE)
if embedded_pattern.search(content):
objects_info['embedded_files'] = True
return objects_info
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 analyze_objects.py <pdf_file>")
sys.exit(1)
results = analyze_pdf_objects(sys.argv[1])
print(f"Всего объектов: {results['total_objects']}")
print(f"Потоков: {len(results['streams'])}")
print(f"JavaScript объектов: {len(results['javascript_objects'])}")
if results['javascript_objects']:
print(f" Объекты: {', '.join(results['javascript_objects'])}")
print(f"Встроенные файлы: {results['embedded_files']}")
Извлечение текста из PDF документов является одной из наиболее распространенных задач. Различные инструменты предоставляют различные методы извлечения текста с разной точностью.
Технический пример 4: Извлечение текста
Использование различных методов:
python
#!/usr/bin/env python3
"""
Извлечение текста из PDF различными методами
"""
import sys
from pathlib import Path
def extract_text_pypdf2(pdf_path):
"""Извлечение текста через PyPDF2"""
import PyPDF2
text_content = []
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
for page_num, page in enumerate(reader.pages):
text = page.extract_text()
text_content.append({
'page': page_num + 1,
'text': text,
'length': len(text)
})
return text_content
def extract_text_pdfplumber(pdf_path):
"""Извлечение текста через pdfplumber"""
import pdfplumber
text_content = []
with open(pdf_path, 'rb') as pdf_file:
with pdfplumber.open(pdf_file) as pdf:
for page in pdf.pages:
text = page.extract_text()
text_content.append({
'page': page.page_number,
'text': text or '',
'length': len(text) if text else 0
})
return text_content
def extract_text_comparison(pdf_path):
"""Сравнение методов извлечения текста"""
results = {
'pypdf2': extract_text_pypdf2(pdf_path),
'pdfplumber': extract_text_pdfplumber(pdf_path)
}
return results
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_text.py <pdf_file>")
sys.exit(1)
results = extract_text_comparison(sys.argv[1])
print("=== Сравнение методов извлечения текста ===")
for method, pages in results.items():
total_chars = sum(p['length'] for p in pages)
print(f"\n{method}:")
print(f" Страниц: {len(pages)}")
print(f" Всего символов: {total_chars}")
5. Анализ метаданных PDF документов
Анализ метаданных PDF документов является одним из наиболее важных аспектов криминалистического исследования. Метаданные могут содержать критически важную информацию об авторе документа, дате создания и модификации, программном обеспечении, использованном для создания документа, истории редактирования и другие данные, которые могут быть использованы как доказательства в расследованиях.
PDF документы могут содержать метаданные в различных форматах: стандартные метаданные PDF, XMP метаданные, метаданные в Info словаре, а также пользовательские метаданные. Каждый тип метаданных может содержать различную информацию и требует специальных техник для извлечения и анализа.
Технический пример 1: Извлечение стандартных метаданных PDF
Использование PyPDF2:
python
#!/usr/bin/env python3
"""
Извлечение стандартных метаданных PDF через PyPDF2
"""
import sys
import PyPDF2
from datetime import datetime
def extract_standard_metadata(pdf_path):
"""Извлечение стандартных метаданных"""
metadata = {}
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
if reader.metadata:
# Стандартные поля метаданных
standard_fields = {
'/Title': 'title',
'/Author': 'author',
'/Subject': 'subject',
'/Keywords': 'keywords',
'/Creator': 'creator',
'/Producer': 'producer',
'/CreationDate': 'creation_date',
'/ModDate': 'modification_date',
'/Trapped': 'trapped'
}
for pdf_key, metadata_key in standard_fields.items():
value = reader.metadata.get(pdf_key)
if value:
# Обработка дат
if 'date' in metadata_key and isinstance(value, PyPDF2.generic.IndirectObject):
try:
value = str(value)
except:
pass
metadata[metadata_key] = str(value) if value else None
return metadata
def parse_pdf_date(date_str):
"""Парсинг даты в формате PDF"""
if not date_str:
return None
# Формат PDF даты: D:YYYYMMDDHHmmSSOHH'mm
# Пример: D:20260115143000+03'00
try:
if date_str.startswith('D:'):
date_str = date_str[2:]
year = int(date_str[0:4])
month = int(date_str[4:6])
day = int(date_str[6:8])
hour = int(date_str[8:10]) if len(date_str) > 8 else 0
minute = int(date_str[10:12]) if len(date_str) > 10 else 0
second = int(date_str[12:14]) if len(date_str) > 12 else 0
return datetime(year, month, day, hour, minute, second)
except:
return None
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_metadata.py <pdf_file>")
sys.exit(1)
metadata = extract_standard_metadata(sys.argv[1])
for key, value in metadata.items():
print(f"{key}: {value}")
Технический пример 2: Извлечение XMP метаданных
Использование ExifTool для XMP:
bash
#!/bin/bash
PDF_FILE="document.pdf"
echo "=== XMP метаданные ==="
echo ""
<h2 id="izvlechenie-vseh-xmp-metadannyh">Извлечение всех XMP метаданных</h2>
exiftool -XMP:All "$PDF_FILE"
<h2 id="konkretnye-xmp-polya">Конкретные XMP поля</h2>
echo ""
echo "=== Конкретные XMP поля ==="
exiftool -XMP:CreatorTool -XMP:CreateDate -XMP:ModifyDate "$PDF_FILE"
<h2 id="eksport-xmp-v-xml">Экспорт XMP в XML</h2>
exiftool -X -XMP:All "$PDF_FILE" > xmp_metadata.xml
Python скрипт для извлечения XMP:
python
#!/usr/bin/env python3
"""
Извлечение XMP метаданных из PDF
"""
import sys
import re
import xml.etree.ElementTree as ET
from pathlib import Path
def extract_xmp_metadata(pdf_path):
"""Извлечение XMP метаданных"""
xmp_data = {}
with open(pdf_path, 'rb') as f:
content = f.read()
# Поиск XMP пакета
xmp_pattern = re.compile(rb'<x:xmpmeta.*?</x:xmpmeta>', re.DOTALL)
xmp_matches = xmp_pattern.findall(content)
for xmp_raw in xmp_matches:
try:
xmp_xml = xmp_raw.decode('utf-8', errors='ignore')
root = ET.fromstring(xmp_xml)
# Поиск в различных пространствах имен
namespaces = {
'x': 'adobe:ns:meta/',
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'dc': 'http://purl.org/dc/elements/1.1/',
'xmp': 'http://ns.adobe.com/xap/1.0/',
'pdf': 'http://ns.adobe.com/pdf/1.3/'
}
# Извлечение Dublin Core метаданных
for dc_elem in root.findall('.//dc:title', namespaces):
xmp_data['dc_title'] = dc_elem.text
for dc_elem in root.findall('.//dc:creator/rdf:Seq/rdf:li', namespaces):
if 'dc_creators' not in xmp_data:
xmp_data['dc_creators'] = []
xmp_data['dc_creators'].append(dc_elem.text)
# Извлечение XMP базовых метаданных
for xmp_elem in root.findall('.//xmp:CreateDate', namespaces):
xmp_data['xmp_create_date'] = xmp_elem.text
for xmp_elem in root.findall('.//xmp:ModifyDate', namespaces):
xmp_data['xmp_modify_date'] = xmp_elem.text
for xmp_elem in root.findall('.//xmp:CreatorTool', namespaces):
xmp_data['xmp_creator_tool'] = xmp_elem.text
except Exception as e:
xmp_data['error'] = str(e)
return xmp_data
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_xmp.py <pdf_file>")
sys.exit(1)
xmp_metadata = extract_xmp_metadata(sys.argv[1])
for key, value in xmp_metadata.items():
print(f"{key}: {value}")
Технический пример 3: Комплексное извлечение всех метаданных
Универсальный скрипт:
python
#!/usr/bin/env python3
"""
Комплексное извлечение всех типов метаданных из PDF
"""
import sys
import json
import subprocess
from pathlib import Path
def extract_all_metadata(pdf_path):
"""Извлечение всех типов метаданных"""
metadata = {
'file': str(pdf_path),
'standard_pdf': {},
'xmp': {},
'exiftool': {},
'custom': {}
}
# Стандартные метаданные PDF через PyPDF2
try:
import PyPDF2
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
if reader.metadata:
metadata['standard_pdf'] = dict(reader.metadata)
except Exception as e:
metadata['standard_pdf_error'] = str(e)
# Метаданные через ExifTool
try:
result = subprocess.run(
['exiftool', '-j', pdf_path],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
exif_data = json.loads(result.stdout)
if exif_data:
metadata['exiftool'] = exif_data[0]
except Exception as e:
metadata['exiftool_error'] = str(e)
# Поиск пользовательских метаданных
try:
with open(pdf_path, 'rb') as f:
content = f.read()
# Поиск пользовательских полей
custom_pattern = re.compile(rb'/([A-Za-z0-9_]+)\s+\(([^)]+)\)', re.IGNORECASE)
custom_matches = custom_pattern.findall(content)
if custom_matches:
metadata['custom'] = {
match[0].decode('utf-8', errors='ignore'):
match[1].decode('utf-8', errors='ignore')
for match in custom_matches[:20] # Ограничение
}
except Exception as e:
metadata['custom_error'] = str(e)
return metadata
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_all_metadata.py <pdf_file>")
sys.exit(1)
all_metadata = extract_all_metadata(sys.argv[1])
print(json.dumps(all_metadata, indent=2, ensure_ascii=False))
Анализ метаданных на предмет аномалий и признаков модификации является важной частью криминалистического исследования.
Технический пример 4: Обнаружение аномалий в метаданных
Скрипт для анализа:
python
#!/usr/bin/env python3
"""
Обнаружение аномалий в метаданных PDF
"""
import sys
import re
from datetime import datetime
from pathlib import Path
def analyze_metadata_anomalies(pdf_path):
"""Анализ метаданных на аномалии"""
anomalies = []
try:
import PyPDF2
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
if reader.metadata:
metadata = reader.metadata
# Проверка несоответствия дат
creation_date = metadata.get('/CreationDate')
mod_date = metadata.get('/ModDate')
if creation_date and mod_date:
try:
# Упрощенная проверка дат
if str(creation_date) > str(mod_date):
anomalies.append({
'type': 'date_inconsistency',
'description': 'Дата создания позже даты модификации',
'creation': str(creation_date),
'modification': str(mod_date)
})
except:
pass
# Проверка подозрительных полей Creator/Producer
creator = metadata.get('/Creator', '')
producer = metadata.get('/Producer', '')
suspicious_tools = ['hack', 'crack', 'modify', 'edit']
for tool in suspicious_tools:
if tool.lower() in creator.lower() or tool.lower() in producer.lower():
anomalies.append({
'type': 'suspicious_tool',
'description': f'Подозрительное имя инструмента: {tool}',
'creator': creator,
'producer': producer
})
# Проверка на отсутствие стандартных полей
required_fields = ['/Title', '/Author', '/Creator', '/Producer']
missing_fields = [field for field in required_fields if field not in metadata]
if missing_fields:
anomalies.append({
'type': 'missing_fields',
'description': 'Отсутствуют стандартные поля метаданных',
'missing': missing_fields
})
except Exception as e:
anomalies.append({
'type': 'error',
'description': f'Ошибка при анализе: {str(e)}'
})
return anomalies
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 analyze_anomalies.py <pdf_file>")
sys.exit(1)
anomalies = analyze_metadata_anomalies(sys.argv[1])
if anomalies:
print("=== Обнаруженные аномалии ===")
for anomaly in anomalies:
print(f"\nТип: {anomaly['type']}")
print(f"Описание: {anomaly['description']}")
if 'details' in anomaly:
print(f"Детали: {anomaly['details']}")
else:
print("Аномалии не обнаружены")
6. Извлечение скрытой информации из PDF
Извлечение скрытой информации из PDF документов является одной из наиболее важных задач криминалистического анализа. PDF документы могут содержать множество скрытых элементов: встроенные файлы, скрытый текст, комментарии и аннотации, JavaScript код, зашифрованные данные, водяные знаки и другие элементы, которые не видны при обычном просмотре документа. Обнаружение и извлечение этой информации может предоставить критически важные доказательства для расследований.
Встроенные файлы в PDF документах могут содержать дополнительные документы, изображения, исполняемые файлы или другие данные, которые были встроены в документ. Эти файлы могут быть скрыты от обычного пользователя и требуют специальных техник для извлечения.
Технический пример 1: Извлечение встроенных файлов
Использование PyPDF2:
python
#!/usr/bin/env python3
"""
Извлечение встроенных файлов из PDF
"""
import sys
import PyPDF2
from pathlib import Path
def extract_embedded_files(pdf_path):
"""Извлечение встроенных файлов"""
embedded_files = []
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
# Поиск встроенных файлов
if '/Names' in reader.trailer:
names = reader.trailer['/Names']
if '/EmbeddedFiles' in names:
embedded_files_list = names['/EmbeddedFiles']
# Обработка списка встроенных файлов
for file_obj in embedded_files_list:
if isinstance(file_obj, dict):
filename = file_obj.get('/F', 'unknown')
file_data = file_obj.get('/EF', {})
embedded_files.append({
'filename': filename,
'data': file_data
})
return embedded_files
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_embedded.py <pdf_file>")
sys.exit(1)
files = extract_embedded_files(sys.argv[1])
print(f"Найдено встроенных файлов: {len(files)}")
for file_info in files:
print(f" Файл: {file_info['filename']}")
Использование pdf-parser:
bash
#!/bin/bash
PDF_FILE="document.pdf"
echo "=== Поиск встроенных файлов ==="
<h2 id="poisk-obektov-s-vstroennymi-faylami">Поиск объектов с встроенными файлами</h2>
python3 pdf-parser.py "$PDF_FILE" --search "/EmbeddedFiles" --object
<h2 id="poisk-obektov-s-faylami">Поиск объектов с файлами</h2>
python3 pdf-parser.py "$PDF_FILE" --search "/F " --object
Извлечение скрытого текста является важной техникой, так как PDF документы могут содержать текст, который не отображается при обычном просмотре, но присутствует в структуре документа.
Технический пример 2: Извлечение скрытого текста
Анализ всех текстовых объектов:
python
#!/usr/bin/env python3
"""
Извлечение скрытого текста из PDF
"""
import sys
import PyPDF2
import re
def extract_all_text_objects(pdf_path):
"""Извлечение всех текстовых объектов, включая скрытые"""
all_text = []
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
# Извлечение видимого текста
for page_num, page in enumerate(reader.pages):
visible_text = page.extract_text()
all_text.append({
'page': page_num + 1,
'type': 'visible',
'text': visible_text
})
# Поиск скрытого текста в потоках
content = f.read()
text_pattern = re.compile(rb'\((.*?)\)', re.DOTALL)
text_matches = text_pattern.findall(content)
for match in text_matches:
try:
text = match.decode('utf-8', errors='ignore')
if text.strip() and len(text) > 10:
all_text.append({
'page': 'unknown',
'type': 'hidden',
'text': text
})
except:
pass
return all_text
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_hidden_text.py <pdf_file>")
sys.exit(1)
texts = extract_all_text_objects(sys.argv[1])
hidden_texts = [t for t in texts if t['type'] == 'hidden']
print(f"Найдено скрытых текстовых объектов: {len(hidden_texts)}")
for text_obj in hidden_texts[:5]: # Показать первые 5
print(f"\nСкрытый текст: {text_obj['text'][:100]}...")
Извлечение комментариев и аннотаций может предоставить информацию о процессе создания документа и изменениях, внесенных в него.
Технический пример 3: Извлечение комментариев и аннотаций
Скрипт для извлечения:
python
#!/usr/bin/env python3
"""
Извлечение комментариев и аннотаций из PDF
"""
import sys
import PyPDF2
import re
def extract_annotations(pdf_path):
"""Извлечение комментариев и аннотаций"""
annotations = []
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
for page_num, page in enumerate(reader.pages):
if '/Annots' in page:
annots = page['/Annots']
for annot_ref in annots:
try:
annot = annot_ref.get_object()
if '/Contents' in annot:
content = annot['/Contents']
annotations.append({
'page': page_num + 1,
'type': str(annot.get('/Subtype', 'Unknown')),
'content': str(content),
'author': str(annot.get('/T', 'Unknown'))
})
except:
pass
return annotations
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_annotations.py <pdf_file>")
sys.exit(1)
annots = extract_annotations(sys.argv[1])
print(f"Найдено аннотаций: {len(annots)}")
for annot in annots:
print(f"\nСтраница {annot['page']}, Тип: {annot['type']}")
print(f"Автор: {annot['author']}")
print(f"Содержание: {annot['content'][:200]}...")
7. Анализ структуры и объектов PDF
Анализ структуры и объектов PDF документов является фундаментальной техникой криминалистического исследования. Понимание внутренней структуры PDF позволяет экспертам обнаруживать аномалии, признаки модификации, скрытые элементы и потенциальные угрозы безопасности. PDF документы имеют сложную структуру, состоящую из объектов, потоков, словарей и других элементов, которые требуют детального анализа.
PDF документ состоит из нескольких основных компонентов: заголовок с версией PDF, тело документа, содержащее объекты, таблица перекрестных ссылок (xref), трейлер и дополнительные элементы. Каждый объект в PDF имеет уникальный номер и может содержать различные типы данных: словари, массивы, потоки, строки, числа и другие.
Технический пример 1: Анализ общей структуры PDF
Использование pdf-parser:
bash
#!/bin/bash
PDF_FILE="document.pdf"
echo "=== Анализ структуры PDF ==="
echo ""
<h2 id="statistika-po-dokumentu">Статистика по документу</h2>
echo "1. Статистика:"
python3 pdf-parser.py "$PDF_FILE" --stats
<h2 id="informatsiya-o-versii">Информация о версии</h2>
echo ""
echo "2. Версия PDF:"
head -1 "$PDF_FILE"
<h2 id="poisk-treylera">Поиск трейлера</h2>
echo ""
echo "3. Трейлер:"
tail -20 "$PDF_FILE" | grep -i trailer
<h2 id="poisk-tablitsy-perekrestnyh-ssylok">Поиск таблицы перекрестных ссылок</h2>
echo ""
echo "4. Таблица xref:"
strings "$PDF_FILE" | grep -i "^xref" | head -5
Python скрипт для анализа структуры:
python
#!/usr/bin/env python3
"""
Анализ структуры PDF документа
"""
import sys
import re
from collections import defaultdict
def analyze_pdf_structure(pdf_path):
"""Анализ структуры PDF"""
structure = {
'version': None,
'objects': [],
'xref_tables': [],
'trailers': [],
'object_types': defaultdict(int)
}
with open(pdf_path, 'rb') as f:
content = f.read()
# Определение версии
version_match = re.search(rb'%PDF-(\d\.\d)', content)
if version_match:
structure['version'] = version_match.group(1).decode()
# Поиск всех объектов
object_pattern = re.compile(rb'(\d+)\s+(\d+)\s+obj')
objects = object_pattern.findall(content)
structure['objects'] = [
{'number': int(obj[0]), 'generation': int(obj[1])}
for obj in objects
]
# Поиск таблиц xref
xref_pattern = re.compile(rb'xref\s+(\d+)\s+(\d+)', re.IGNORECASE)
xref_matches = xref_pattern.findall(content)
structure['xref_tables'] = [
{'start': int(x[0]), 'count': int(x[1])}
for x in xref_matches
]
# Поиск трейлеров
trailer_pattern = re.compile(rb'trailer\s*<<(.*?)>>', re.DOTALL)
trailers = trailer_pattern.findall(content)
structure['trailers'] = [t.decode('utf-8', errors='ignore')[:200] for t in trailers]
return structure
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 analyze_structure.py <pdf_file>")
sys.exit(1)
structure = analyze_pdf_structure(sys.argv[1])
print(f"Версия PDF: {structure['version']}")
print(f"Всего объектов: {len(structure['objects'])}")
print(f"Таблиц xref: {len(structure['xref_tables'])}")
print(f"Трейлеров: {len(structure['trailers'])}")
Анализ объектов позволяет понять содержимое документа и обнаружить аномалии.
Технический пример 2: Детальный анализ объектов
Извлечение информации об объектах:
python
#!/usr/bin/env python3
"""
Детальный анализ объектов PDF
"""
import sys
import re
def analyze_objects_detailed(pdf_path):
"""Детальный анализ объектов"""
objects_info = []
with open(pdf_path, 'rb') as f:
content = f.read()
# Поиск всех объектов с их содержимым
object_pattern = re.compile(
rb'(\d+)\s+(\d+)\s+obj\s+(.*?)\s+endobj',
re.DOTALL
)
matches = object_pattern.findall(content)
for match in matches:
obj_num = int(match[0])
obj_gen = int(match[1])
obj_content = match[2]
obj_info = {
'number': obj_num,
'generation': obj_gen,
'has_stream': b'stream' in obj_content,
'size': len(obj_content),
'types': []
}
# Определение типов в объекте
if b'/Type' in obj_content:
type_match = re.search(rb'/Type\s*/(\w+)', obj_content)
if type_match:
obj_info['types'].append(type_match.group(1).decode())
if b'/Subtype' in obj_content:
subtype_match = re.search(rb'/Subtype\s*/(\w+)', obj_content)
if subtype_match:
obj_info['types'].append(subtype_match.group(1).decode())
objects_info.append(obj_info)
return objects_info
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 analyze_objects_detailed.py <pdf_file>")
sys.exit(1)
objects = analyze_objects_detailed(sys.argv[1])
print(f"Проанализировано объектов: {len(objects)}")
# Статистика по типам
streams_count = sum(1 for obj in objects if obj['has_stream'])
print(f"Объектов с потоками: {streams_count}")
# Показать первые 10 объектов
for obj in objects[:10]:
print(f"\nОбъект {obj['number']} (gen {obj['generation']}):")
print(f" Размер: {obj['size']} байт")
print(f" Поток: {'Да' if obj['has_stream'] else 'Нет'}")
if obj['types']:
print(f" Типы: {', '.join(obj['types'])}")
8. Обнаружение модификаций и подделок
Обнаружение модификаций и подделок в PDF документах является критически важной задачей криминалистического анализа. Эксперты должны уметь выявлять признаки того, что документ был изменен после создания, определить, какие части документа были модифицированы, и установить подлинность документа. Современные техники позволяют обнаруживать различные типы модификаций: изменения текста, добавление или удаление страниц, модификация метаданных, внедрение вредоносного кода и другие.
Признаки модификации могут проявляться в различных аспектах документа: несоответствия в метаданных, аномалии в структуре объектов, следы редактирования в истории версий, несоответствия в датах создания и модификации, признаки использования инструментов редактирования и другие индикаторы.
Технический пример 1: Обнаружение несоответствий в метаданных
Скрипт для анализа:
python
#!/usr/bin/env python3
"""
Обнаружение несоответствий в метаданных как признак модификации
"""
import sys
import PyPDF2
from datetime import datetime
import re
def detect_metadata_inconsistencies(pdf_path):
"""Обнаружение несоответствий в метаданных"""
inconsistencies = []
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
if reader.metadata:
metadata = reader.metadata
# Проверка дат
creation_date = metadata.get('/CreationDate')
mod_date = metadata.get('/ModDate')
if creation_date and mod_date:
try:
# Парсинг дат PDF
def parse_pdf_date(date_str):
if isinstance(date_str, str) and date_str.startswith('D:'):
date_str = date_str[2:]
year = int(date_str[0:4])
month = int(date_str[4:6])
day = int(date_str[6:8])
return datetime(year, month, day)
return None
creation = parse_pdf_date(str(creation_date))
modification = parse_pdf_date(str(mod_date))
if creation and modification:
if creation > modification:
inconsistencies.append({
'type': 'date_anomaly',
'description': 'Дата создания позже даты модификации',
'creation': str(creation_date),
'modification': str(mod_date)
})
except:
pass
# Проверка несоответствий Creator/Producer
creator = str(metadata.get('/Creator', ''))
producer = str(metadata.get('/Producer', ''))
# Поиск признаков редактирования
editing_tools = ['Adobe Acrobat', 'PDF Editor', 'Modify', 'Edit']
if any(tool.lower() in producer.lower() for tool in editing_tools):
inconsistencies.append({
'type': 'editing_tool_detected',
'description': 'Обнаружены признаки использования инструментов редактирования',
'producer': producer
})
return inconsistencies
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 detect_modifications.py <pdf_file>")
sys.exit(1)
inconsistencies = detect_metadata_inconsistencies(sys.argv[1])
if inconsistencies:
print("=== Обнаруженные несоответствия ===")
for inc in inconsistencies:
print(f"\nТип: {inc['type']}")
print(f"Описание: {inc['description']}")
else:
print("Несоответствия не обнаружены")
Технический пример 2: Анализ структуры на признаки модификации
Обнаружение структурных аномалий:
python
#!/usr/bin/env python3
"""
Обнаружение структурных аномалий как признак модификации
"""
import sys
import re
from collections import Counter
def detect_structural_anomalies(pdf_path):
"""Обнаружение структурных аномалий"""
anomalies = []
with open(pdf_path, 'rb') as f:
content = f.read()
# Проверка множественных трейлеров (признак модификации)
trailer_count = len(re.findall(rb'trailer\s*<<', content, re.IGNORECASE))
if trailer_count > 1:
anomalies.append({
'type': 'multiple_trailers',
'description': f'Обнаружено {trailer_count} трейлеров (норма: 1)',
'severity': 'high'
})
# Проверка множественных таблиц xref
xref_count = len(re.findall(rb'^xref\s+', content, re.MULTILINE))
if xref_count > 1:
anomalies.append({
'type': 'multiple_xref',
'description': f'Обнаружено {xref_count} таблиц xref (норма: 1)',
'severity': 'high'
})
# Проверка пропусков в нумерации объектов
object_pattern = re.compile(rb'(\d+)\s+(\d+)\s+obj')
objects = object_pattern.findall(content)
object_numbers = [int(obj[0]) for obj in objects]
if object_numbers:
max_obj = max(object_numbers)
expected_range = set(range(1, max_obj + 1))
actual_range = set(object_numbers)
missing = expected_range - actual_range
if missing and len(missing) > max_obj * 0.1: # Более 10% пропусков
anomalies.append({
'type': 'object_numbering_gaps',
'description': f'Обнаружены значительные пропуски в нумерации объектов',
'missing_count': len(missing),
'severity': 'medium'
})
# Проверка на наличие старых и новых объектов (признак добавления)
if len(object_numbers) > 0:
# Объекты с generation > 0 могут указывать на модификацию
generations = [int(obj[1]) for obj in objects]
if max(generations) > 0:
anomalies.append({
'type': 'object_generations',
'description': 'Обнаружены объекты с generation > 0 (возможная модификация)',
'max_generation': max(generations),
'severity': 'medium'
})
return anomalies
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 detect_structural_anomalies.py <pdf_file>")
sys.exit(1)
anomalies = detect_structural_anomalies(sys.argv[1])
if anomalies:
print("=== Обнаруженные структурные аномалии ===")
for anomaly in anomalies:
print(f"\nТип: {anomaly['type']}")
print(f"Описание: {anomaly['description']}")
print(f"Серьезность: {anomaly['severity']}")
else:
print("Структурные аномалии не обнаружены")
9. Анализ JavaScript и встроенных скриптов
Анализ JavaScript и встроенных скриптов в PDF документах является критически важным аспектом криминалистического исследования, особенно в контексте безопасности. PDF документы могут содержать JavaScript код, который может выполнять различные действия: от простых интерактивных функций до потенциально вредоносных операций. Обнаружение, извлечение и анализ JavaScript кода позволяет экспертам выявлять потенциальные угрозы безопасности и понимать поведение документа.
JavaScript в PDF может быть встроен различными способами: как часть действий документа, в аннотациях, в событиях страниц, в формах и других элементах. Каждый тип встраивания требует различных техник для обнаружения и извлечения.
Технический пример 1: Обнаружение JavaScript в PDF
Использование peepdf:
bash
#!/bin/bash
PDF_FILE="document.pdf"
echo "=== Поиск JavaScript в PDF ==="
<h2 id="interaktivnyy-analiz-cherez-peepdf">Интерактивный анализ через peepdf</h2>
peepdf -i "$PDF_FILE" --search js
<h2 id="izvlechenie-javascript-koda">Извлечение JavaScript кода</h2>
peepdf -i "$PDF_FILE" --extract-js
Python скрипт для обнаружения:
python
#!/usr/bin/env python3
"""
Обнаружение и извлечение JavaScript из PDF
"""
import sys
import re
import PyPDF2
def extract_javascript(pdf_path):
"""Извлечение JavaScript кода из PDF"""
js_code_blocks = []
# Метод 1: Поиск через PyPDF2
try:
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
# Поиск в действиях документа
if '/OpenAction' in reader.trailer:
open_action = reader.trailer['/OpenAction']
# Обработка действия
pass
# Поиск в страницах
for page_num, page in enumerate(reader.pages):
if '/AA' in page: # Additional Actions
aa = page['/AA']
# Обработка действий
pass
except Exception as e:
print(f"Ошибка PyPDF2: {e}")
# Метод 2: Прямой поиск в бинарном содержимом
with open(pdf_path, 'rb') as f:
content = f.read()
# Поиск объектов с JavaScript
js_pattern = re.compile(rb'/JS\s+(\d+)\s+(\d+)\s+R', re.IGNORECASE)
js_refs = js_pattern.findall(content)
for obj_num, obj_gen in js_refs:
# Поиск содержимого объекта
obj_pattern = re.compile(
rb'{} {}\s+obj\s+(.*?)\s+endobj'.format(
obj_num.decode() if isinstance(obj_num, bytes) else str(obj_num),
obj_gen.decode() if isinstance(obj_gen, bytes) else str(obj_gen)
),
re.DOTALL
)
obj_match = obj_pattern.search(content)
if obj_match:
obj_content = obj_match.group(1)
# Поиск потока с JavaScript
stream_pattern = re.compile(rb'stream\s+(.*?)\s+endstream', re.DOTALL)
stream_match = stream_pattern.search(obj_content)
if stream_match:
stream_data = stream_match.group(1)
try:
js_code = stream_data.decode('utf-8', errors='ignore')
js_code_blocks.append({
'object': f"{obj_num} {obj_gen}",
'code': js_code
})
except:
pass
return js_code_blocks
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 extract_javascript.py <pdf_file>")
sys.exit(1)
js_blocks = extract_javascript(sys.argv[1])
print(f"Найдено JavaScript блоков: {len(js_blocks)}")
for i, block in enumerate(js_blocks, 1):
print(f"\n=== Блок {i} (Объект {block['object']}) ===")
print(block['code'][:500]) # Первые 500 символов
Технический пример 2: Анализ JavaScript на вредоносность
Скрипт для анализа:
python
#!/usr/bin/env python3
"""
Анализ JavaScript кода на потенциальную вредоносность
"""
import sys
import re
def analyze_javascript_security(js_code):
"""Анализ JavaScript кода на подозрительные паттерны"""
threats = []
# Подозрительные функции и методы
suspicious_patterns = {
'eval': r'\beval\s*\(',
'exec': r'\bexec\s*\(',
'unescape': r'\bunescape\s*\(',
'fromCharCode': r'\bfromCharCode\s*\(',
'document.write': r'document\.write\s*\(',
'window.open': r'window\.open\s*\(',
'XMLHttpRequest': r'\bXMLHttpRequest\b',
'ActiveXObject': r'\bActiveXObject\b',
'WScript.Shell': r'WScript\.Shell',
'FileSystemObject': r'FileSystemObject',
'ShellExecute': r'ShellExecute',
'base64': r'atob\s*\(',
'hex_decode': r'hex.*decode',
'obfuscated': r'[a-zA-Z_$][a-zA-Z0-9_$]{20,}', # Длинные имена переменных
}
for threat_name, pattern in suspicious_patterns.items():
matches = re.findall(pattern, js_code, re.IGNORECASE)
if matches:
threats.append({
'type': threat_name,
'description': f'Обнаружен подозрительный паттерн: {threat_name}',
'matches': len(matches),
'examples': matches[:3] # Первые 3 примера
})
# Проверка на обфускацию
if len(js_code) > 1000 and len(re.findall(r'[a-zA-Z_$][a-zA-Z0-9_$]{15,}', js_code)) > 10:
threats.append({
'type': 'obfuscation',
'description': 'Возможная обфускация кода',
'severity': 'high'
})
# Проверка на использование внешних ресурсов
url_patterns = [
r'https?://[^\s\'"]+',
r'ftp://[^\s\'"]+',
r'file://[^\s\'"]+'
]
for pattern in url_patterns:
urls = re.findall(pattern, js_code)
if urls:
threats.append({
'type': 'external_resources',
'description': 'Обнаружены ссылки на внешние ресурсы',
'urls': urls[:5]
})
return threats
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 analyze_js_security.py <js_code_file>")
sys.exit(1)
with open(sys.argv[1], 'r', encoding='utf-8', errors='ignore') as f:
js_code = f.read()
threats = analyze_javascript_security(js_code)
if threats:
print("=== Обнаруженные угрозы ===")
for threat in threats:
print(f"\nТип: {threat['type']}")
print(f"Описание: {threat['description']}")
else:
print("Угрозы не обнаружены")
10. Работа с зашифрованными PDF документами
Работа с зашифрованными PDF документами представляет особую задачу в криминалистическом анализе. Многие PDF документы защищены паролями или используют шифрование для ограничения доступа к содержимому. Эксперты должны уметь определять тип шифрования, анализировать защищенные документы и, при наличии законных оснований, работать с зашифрованными документами для извлечения информации.
PDF документы могут использовать различные методы защиты: шифрование на основе паролей пользователя и владельца, шифрование с использованием сертификатов, защита от копирования и печати, и другие методы. Каждый тип защиты требует различных подходов для анализа.
Технический пример 1: Определение типа шифрования
Использование qpdf:
bash
#!/bin/bash
PDF_FILE="document.pdf"
echo "=== Анализ шифрования PDF ==="
<h2 id="informatsiya-o-shifrovanii">Информация о шифровании</h2>
qpdf --show-encryption "$PDF_FILE"
Python скрипт для анализа:
python
#!/usr/bin/env python3
"""
Анализ шифрования PDF документа
"""
import sys
import PyPDF2
import re
def analyze_encryption(pdf_path):
"""Анализ типа и параметров шифрования"""
encryption_info = {
'encrypted': False,
'encryption_type': None,
'user_password_required': False,
'owner_password_required': False,
'permissions': {},
'algorithm': None
}
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
encryption_info['encrypted'] = reader.is_encrypted
if reader.is_encrypted:
# Информация о шифровании
if hasattr(reader, 'decrypt'):
# Попытка определить тип шифрования
encryption_info['user_password_required'] = True
# Анализ разрешений
if hasattr(reader, 'getNumPages'):
try:
# Попытка доступа без пароля
num_pages = len(reader.pages)
encryption_info['owner_password_required'] = False
except:
encryption_info['owner_password_required'] = True
# Дополнительный анализ через бинарный поиск
with open(pdf_path, 'rb') as f:
content = f.read()
# Поиск информации о шифровании в трейлере
encryption_pattern = re.compile(rb'/Encrypt\s+(\d+)\s+(\d+)\s+R', re.IGNORECASE)
encrypt_match = encryption_pattern.search(content)
if encrypt_match:
encryption_info['encryption_object'] = f"{encrypt_match.group(1)} {encrypt_match.group(2)}"
# Поиск алгоритма шифрования
if b'/V' in content:
v_match = re.search(rb'/V\s+(\d+)', content)
if v_match:
encryption_info['algorithm_version'] = int(v_match.group(1))
if b'/R' in content:
r_match = re.search(rb'/R\s+(\d+)', content)
if r_match:
encryption_info['revision'] = int(r_match.group(1))
return encryption_info
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 analyze_encryption.py <pdf_file>")
sys.exit(1)
enc_info = analyze_encryption(sys.argv[1])
print(f"Зашифрован: {enc_info['encrypted']}")
if enc_info['encrypted']:
print(f"Требуется пароль пользователя: {enc_info['user_password_required']}")
print(f"Требуется пароль владельца: {enc_info['owner_password_required']}")
if 'algorithm_version' in enc_info:
print(f"Версия алгоритма: {enc_info['algorithm_version']}")
Технический пример 2: Работа с защищенными PDF
Скрипт для работы с паролями:
python
#!/usr/bin/env python3
"""
Работа с защищенными PDF документами
"""
import sys
import PyPDF2
def decrypt_pdf(pdf_path, password=None, output_path=None):
"""Расшифровка PDF документа"""
try:
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
if not reader.is_encrypted:
print("Документ не зашифрован")
return True
# Попытка расшифровки
if password:
if reader.decrypt(password):
print("Успешная расшифровка")
# Сохранение расшифрованного документа
if output_path:
writer = PyPDF2.PdfWriter()
for page in reader.pages:
writer.add_page(page)
with open(output_path, 'wb') as out_file:
writer.write(out_file)
print(f"Расшифрованный документ сохранен: {output_path}")
return True
else:
print("Неверный пароль")
return False
else:
# Попытка без пароля (для документов только с паролем владельца)
try:
# Проверка доступа
num_pages = len(reader.pages)
print("Доступ получен без пароля пользователя")
return True
except:
print("Требуется пароль")
return False
except Exception as e:
print(f"Ошибка: {e}")
return False
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 decrypt_pdf.py <pdf_file> [password] [output_file]")
sys.exit(1)
pdf_file = sys.argv[1]
password = sys.argv[2] if len(sys.argv) > 2 else None
output = sys.argv[3] if len(sys.argv) > 3 else None
decrypt_pdf(pdf_file, password, output)
11. Продвинутые техники криминалистического анализа
Продвинутые техники криминалистического анализа PDF документов включают комплексные методы исследования, которые выходят за рамки базового анализа. Эти техники позволяют экспертам обнаруживать сложные случаи модификации, анализировать поведение документов, восстанавливать удаленную информацию и проводить глубокий анализ для судебных разбирательств.
Анализ истории версий документа является важной техникой для обнаружения модификаций. PDF документы могут содержать информацию о предыдущих версиях, которая может быть использована для восстановления истории изменений.
Технический пример 1: Анализ истории версий
Скрипт для анализа:
python
#!/usr/bin/env python3
"""
Анализ истории версий PDF документа
"""
import sys
import PyPDF2
import re
from datetime import datetime
def analyze_version_history(pdf_path):
"""Анализ истории версий документа"""
history = {
'versions': [],
'modifications': [],
'timeline': []
}
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
# Анализ метаданных на наличие истории
if reader.metadata:
metadata = reader.metadata
# Извлечение дат
creation_date = metadata.get('/CreationDate')
mod_date = metadata.get('/ModDate')
if creation_date:
history['timeline'].append({
'event': 'creation',
'date': str(creation_date),
'description': 'Создание документа'
})
if mod_date and mod_date != creation_date:
history['timeline'].append({
'event': 'modification',
'date': str(mod_date),
'description': 'Модификация документа'
})
# Поиск признаков множественных версий
if '/Version' in metadata:
history['versions'].append({
'version': metadata['/Version'],
'date': str(mod_date) if mod_date else None
})
# Поиск в структуре документа
with open(pdf_path, 'rb') as f:
content = f.read()
# Поиск множественных трейлеров (признак инкрементальных обновлений)
trailers = re.findall(rb'trailer\s*<<(.*?)>>', content, re.DOTALL)
if len(trailers) > 1:
history['modifications'].append({
'type': 'incremental_update',
'description': f'Обнаружено {len(trailers)} трейлеров - возможны инкрементальные обновления',
'count': len(trailers)
})
# Поиск объектов с generation > 0
object_pattern = re.compile(rb'(\d+)\s+(\d+)\s+obj')
objects = object_pattern.findall(content)
generations = [int(obj[1]) for obj in objects]
if max(generations) > 0:
history['modifications'].append({
'type': 'object_regeneration',
'description': 'Обнаружены объекты с generation > 0',
'max_generation': max(generations),
'affected_objects': sum(1 for g in generations if g > 0)
})
return history
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 analyze_version_history.py <pdf_file>")
sys.exit(1)
history = analyze_version_history(sys.argv[1])
print("=== История версий ===")
print(f"Версий: {len(history['versions'])}")
print(f"Модификаций: {len(history['modifications'])}")
print(f"Событий в таймлайне: {len(history['timeline'])}")
if history['timeline']:
print("\nТаймлайн:")
for event in history['timeline']:
print(f" {event['event']}: {event['date']} - {event['description']}")
Восстановление удаленной информации является продвинутой техникой, которая может быть использована для извлечения данных, которые были удалены или перезаписаны в документе.
Технический пример 2: Восстановление удаленной информации
Скрипт для восстановления:
python
#!/usr/bin/env python3
"""
Восстановление удаленной информации из PDF
"""
import sys
import re
from pathlib import Path
def recover_deleted_content(pdf_path):
"""Восстановление удаленной информации"""
recovered = {
'deleted_objects': [],
'orphaned_streams': [],
'fragments': []
}
with open(pdf_path, 'rb') as f:
content = f.read()
# Поиск объектов, на которые нет ссылок (удаленные объекты)
# Это упрощенный пример - полный анализ требует парсинга всей структуры
# Поиск потоков без объектов
stream_pattern = re.compile(rb'stream\s+(.*?)\s+endstream', re.DOTALL)
streams = stream_pattern.findall(content)
for i, stream_data in enumerate(streams):
# Попытка декодирования
try:
# Попытка различных декодирований
decoded = stream_data.decode('utf-8', errors='ignore')
if len(decoded) > 50: # Минимальный размер
recovered['orphaned_streams'].append({
'index': i,
'size': len(stream_data),
'preview': decoded[:200]
})
except:
pass
# Поиск фрагментов текста вне объектов
text_pattern = re.compile(rb'\((.*?)\)', re.DOTALL)
text_matches = text_pattern.findall(content)
for match in text_matches:
try:
text = match.decode('utf-8', errors='ignore')
if len(text) > 20 and text.strip():
recovered['fragments'].append({
'text': text[:100],
'length': len(text)
})
except:
pass
return recovered
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 recover_deleted.py <pdf_file>")
sys.exit(1)
recovered = recover_deleted_content(sys.argv[1])
print(f"Найдено удаленных объектов: {len(recovered['deleted_objects'])}")
print(f"Найдено потерянных потоков: {len(recovered['orphaned_streams'])}")
print(f"Найдено фрагментов: {len(recovered['fragments'])}")
12. Интеграция с другими инструментами криминалистики
Интеграция инструментов анализа PDF с другими инструментами цифровой криминалистики позволяет создавать комплексные рабочие процессы для расследований. Эксперты могут комбинировать результаты анализа PDF с данными из других источников, использовать специализированные инструменты для дополнительного анализа и создавать единые отчеты для судебных разбирательств.
Интеграция с инструментами анализа метаданных позволяет получать более полную картину о документе, комбинируя информацию из различных источников.
Технический пример 1: Интеграция с ExifTool
Скрипт для комплексного анализа:
python
#!/usr/bin/env python3
"""
Интеграция анализа PDF с ExifTool
"""
import sys
import json
import subprocess
import PyPDF2
def comprehensive_pdf_analysis(pdf_path):
"""Комплексный анализ PDF с использованием нескольких инструментов"""
results = {
'pypdf2': {},
'exiftool': {},
'combined': {}
}
# Анализ через PyPDF2
try:
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
results['pypdf2'] = {
'pages': len(reader.pages),
'encrypted': reader.is_encrypted,
'metadata': dict(reader.metadata) if reader.metadata else {}
}
except Exception as e:
results['pypdf2']['error'] = str(e)
# Анализ через ExifTool
try:
result = subprocess.run(
['exiftool', '-j', pdf_path],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
exif_data = json.loads(result.stdout)
if exif_data:
results['exiftool'] = exif_data[0]
except Exception as e:
results['exiftool']['error'] = str(e)
# Объединение результатов
if results['pypdf2'].get('metadata') and results['exiftool']:
results['combined'] = {
'title': results['pypdf2']['metadata'].get('/Title') or results['exiftool'].get('Title'),
'author': results['pypdf2']['metadata'].get('/Author') or results['exiftool'].get('Author'),
'creator': results['pypdf2']['metadata'].get('/Creator') or results['exiftool'].get('Creator'),
'producer': results['pypdf2']['metadata'].get('/Producer') or results['exiftool'].get('Producer')
}
return results
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 comprehensive_analysis.py <pdf_file>")
sys.exit(1)
results = comprehensive_pdf_analysis(sys.argv[1])
print(json.dumps(results, indent=2, ensure_ascii=False))
Интеграция с базами данных позволяет хранить результаты анализа и создавать базы знаний для расследований.
Технический пример 2: Сохранение результатов в базу данных
Скрипт для работы с SQLite:
python
#!/usr/bin/env python3
"""
Сохранение результатов анализа PDF в базу данных
"""
import sys
import sqlite3
import json
import hashlib
from pathlib import Path
import PyPDF2
def create_database(db_path):
"""Создание базы данных для хранения результатов"""
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS pdf_analyses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
file_hash TEXT UNIQUE,
file_path TEXT,
file_size INTEGER,
pages INTEGER,
encrypted INTEGER,
metadata TEXT,
analysis_date TEXT,
analyst TEXT
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS pdf_findings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
analysis_id INTEGER,
finding_type TEXT,
description TEXT,
severity TEXT,
FOREIGN KEY (analysis_id) REFERENCES pdf_analyses(id)
)
''')
conn.commit()
return conn
def save_analysis_results(conn, pdf_path, analyst='Unknown'):
"""Сохранение результатов анализа"""
# Вычисление хеша файла
with open(pdf_path, 'rb') as f:
file_hash = hashlib.sha256(f.read()).hexdigest()
# Анализ PDF
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
pages = len(reader.pages)
encrypted = 1 if reader.is_encrypted else 0
metadata = json.dumps(dict(reader.metadata) if reader.metadata else {})
file_size = Path(pdf_path).stat().st_size
cursor = conn.cursor()
cursor.execute('''
INSERT OR REPLACE INTO pdf_analyses
(file_hash, file_path, file_size, pages, encrypted, metadata, analysis_date, analyst)
VALUES (?, ?, ?, ?, ?, ?, datetime('now'), ?)
''', (file_hash, str(pdf_path), file_size, pages, encrypted, metadata, analyst))
analysis_id = cursor.lastrowid
conn.commit()
return analysis_id
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 save_to_db.py <pdf_file> [db_file]")
sys.exit(1)
pdf_file = sys.argv[1]
db_file = sys.argv[2] if len(sys.argv) > 2 else 'pdf_analyses.db'
conn = create_database(db_file)
analysis_id = save_analysis_results(conn, pdf_file)
print(f"Результаты сохранены в базу данных. ID анализа: {analysis_id}")
conn.close()
13. Автоматизация анализа PDF документов
Автоматизация анализа PDF документов позволяет экспертам эффективно обрабатывать большие объемы документов, стандартизировать процессы анализа и создавать воспроизводимые рабочие процессы. Автоматизация особенно важна при массовом анализе документов в рамках крупных расследований или при регулярном мониторинге.
Создание автоматизированных скриптов для массового анализа позволяет обрабатывать множество документов одновременно и генерировать сводные отчеты.
Технический пример 1: Массовый анализ PDF документов
Скрипт для автоматизации:
python
#!/usr/bin/env python3
"""
Автоматизированный массовый анализ PDF документов
"""
import sys
import os
import json
from pathlib import Path
import PyPDF2
from datetime import datetime
def analyze_pdf_file(pdf_path):
"""Анализ одного PDF файла"""
try:
with open(pdf_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
result = {
'file': str(pdf_path),
'size': os.path.getsize(pdf_path),
'pages': len(reader.pages),
'encrypted': reader.is_encrypted,
'metadata': dict(reader.metadata) if reader.metadata else {},
'analysis_date': datetime.now().isoformat(),
'status': 'success'
}
return result
except Exception as e:
return {
'file': str(pdf_path),
'status': 'error',
'error': str(e)
}
def batch_analyze_pdfs(directory, output_file='batch_results.json'):
"""Массовый анализ PDF файлов в директории"""
results = []
pdf_files = list(Path(directory).rglob('*.pdf'))
print(f"Найдено PDF файлов: {len(pdf_files)}")
for i, pdf_file in enumerate(pdf_files, 1):
print(f"Анализ {i}/{len(pdf_files)}: {pdf_file.name}")
result = analyze_pdf_file(pdf_file)
results.append(result)
# Сохранение результатов
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(results, f, indent=2, ensure_ascii=False)
# Статистика
successful = sum(1 for r in results if r['status'] == 'success')
errors = len(results) - successful
print(f"\n=== Статистика ===")
print(f"Успешно проанализировано: {successful}")
print(f"Ошибок: {errors}")
print(f"Результаты сохранены в: {output_file}")
return results
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 batch_analyze.py <directory> [output_file]")
sys.exit(1)
directory = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else 'batch_results.json'
batch_analyze_pdfs(directory, output_file)
Создание автоматизированных отчетов позволяет стандартизировать процесс документирования результатов анализа.
Технический пример 2: Генерация автоматических отчетов
Скрипт для создания отчетов:
python
#!/usr/bin/env python3
"""
Автоматическая генерация отчетов по анализу PDF
"""
import sys
import json
from pathlib import Path
from datetime import datetime
def generate_html_report(analysis_results, output_file='report.html'):
"""Генерация HTML отчета"""
html = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Отчет по анализу PDF</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 20px; }}
h1 {{ color: #333; }}
.file-info {{ background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px; }}
.metadata {{ margin: 10px 0; }}
.metadata-item {{ margin: 5px 0; }}
.error {{ color: red; }}
.success {{ color: green; }}
</style>
</head>
<body>
<h1>Отчет по анализу PDF документов</h1>
<p>Дата создания: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
<p>Всего файлов: {len(analysis_results)}</p>
"""
for result in analysis_results:
if result['status'] == 'success':
html += f"""
<div class="file-info">
<h2>{Path(result['file']).name}</h2>
<div class="metadata">
<div class="metadata-item"><strong>Размер:</strong> {result['size']} байт</div>
<div class="metadata-item"><strong>Страниц:</strong> {result['pages']}</div>
<div class="metadata-item"><strong>Зашифрован:</strong> {'Да' if result['encrypted'] else 'Нет'}</div>
"""
if result['metadata']:
html += "<h3>Метаданные:</h3>"
for key, value in result['metadata'].items():
html += f"<div class='metadata-item'><strong>{key}:</strong> {value}</div>"
html += """
</div>
</div>
"""
else:
html += f"""
<div class="file-info">
<h2>{Path(result['file']).name}</h2>
<div class="error">Ошибка: {result.get('error', 'Unknown error')}</div>
</div>
"""
html += """
</body>
</html>
"""
with open(output_file, 'w', encoding='utf-8') as f:
f.write(html)
print(f"Отчет сохранен: {output_file}")
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 generate_report.py <results_json> [output_html]")
sys.exit(1)
results_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else 'report.html'
with open(results_file, 'r', encoding='utf-8') as f:
results = json.load(f)
generate_html_report(results, output_file)
14. Отчетность и документирование результатов
Отчетность и документирование результатов анализа PDF документов являются критически важными аспектами криминалистического исследования. Качественные отчеты должны быть структурированными, понятными для различных аудиторий, содержать все необходимые детали и быть пригодными для использования в судебных разбирательствах.
Структура отчета должна включать введение с описанием целей анализа, методологию исследования, детальные результаты анализа, выводы и рекомендации, а также приложения с техническими деталями.
Технический пример 1: Создание структурированного отчета
Скрипт для генерации отчета:
python
#!/usr/bin/env python3
"""
Создание структурированного отчета по анализу PDF
"""
import sys
import json
from pathlib import Path
from datetime import datetime
def create_structured_report(analysis_data, output_file='analysis_report.md'):
"""Создание структурированного отчета в Markdown"""
report = f"""# Отчет по криминалистическому анализу PDF документа
<h2 id="1-informatsiya-ob-analize">1. Информация об анализе</h2>
- Дата анализа: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
- Анализируемый файл: {analysis_data.get('file', 'N/A')}
- Размер файла: {analysis_data.get('size', 0)} байт
- Версия PDF: {analysis_data.get('pdf_version', 'N/A')}
<h2 id="2-bazovaya-informatsiya">2. Базовая информация</h2>
- Количество страниц: {analysis_data.get('pages', 0)}
- Зашифрован: {'Да' if analysis_data.get('encrypted') else 'Нет'}
- Требуется пароль: {'Да' if analysis_data.get('password_required') else 'Нет'}
<h2 id="3-metadannye">3. Метаданные</h2>
"""
if analysis_data.get('metadata'):
report += "### 3.1. Стандартные метаданные PDF\n\n"
metadata = analysis_data['metadata']
for key, value in metadata.items():
report += f"- {key}: {value}\n"
if analysis_data.get('xmp_metadata'):
report += "\n### 3.2. XMP метаданные\n\n"
xmp = analysis_data['xmp_metadata']
for key, value in xmp.items():
report += f"- {key}: {value}\n"
report += """
<h2 id="4-analiz-struktury">4. Анализ структуры</h2>
"""
if analysis_data.get('structure'):
structure = analysis_data['structure']
report += f"- Всего объектов: {structure.get('total_objects', 0)}\n"
report += f"- Объектов с потоками: {structure.get('streams_count', 0)}\n"
report += f"- JavaScript объектов: {len(structure.get('javascript_objects', []))}\n"
report += """
<h2 id="5-obnaruzhennye-anomalii">5. Обнаруженные аномалии</h2>
"""
if analysis_data.get('anomalies'):
for anomaly in analysis_data['anomalies']:
report += f"### {anomaly.get('type', 'Unknown')}\n\n"
report += f"- Описание: {anomaly.get('description', 'N/A')}\n"
report += f"- Серьезность: {anomaly.get('severity', 'N/A')}\n\n"
else:
report += "Аномалии не обнаружены.\n\n"
report += """
<h2 id="6-vyvody">6. Выводы</h2>
"""
if analysis_data.get('conclusions'):
for conclusion in analysis_data['conclusions']:
report += f"- {conclusion}\n"
report += """
<h2 id="7-rekomendatsii">7. Рекомендации</h2>
"""
if analysis_data.get('recommendations'):
for recommendation in analysis_data['recommendations']:
report += f"- {recommendation}\n"
report += f"""
<h2 id="8-prilozheniya">8. Приложения</h2>
<h3 id="8-1-tehnicheskie-detali">8.1. Технические детали</h3>
Полные технические детали анализа сохранены в файле: `{analysis_data.get('technical_details_file', 'N/A')}`
<h3 id="8-2-metodologiya">8.2. Методология</h3>
Использованные инструменты:
- PyPDF2
- ExifTool
- pdf-parser
- QPDF
*Отчет сгенерирован автоматически*
"""
with open(output_file, 'w', encoding='utf-8') as f:
f.write(report)
print(f"Отчет сохранен: {output_file}")
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python3 create_report.py <analysis_json> [output_file]")
sys.exit(1)
analysis_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else 'analysis_report.md'
with open(analysis_file, 'r', encoding='utf-8') as f:
analysis_data = json.load(f)
create_structured_report(analysis_data, output_file)
15. Практические примеры и кейсы
Практические примеры и кейсы демонстрируют применение техник анализа PDF документов в реальных сценариях расследований. Эти примеры помогают экспертам понять, как применять различные техники в различных ситуациях и какие результаты можно ожидать.
Кейс 1: Обнаружение модификации документа
Сценарий: Необходимо определить, был ли изменен PDF документ после его создания.
Шаги анализа:
1. Извлечение метаданных и сравнение дат создания и модификации
2. Анализ структуры на наличие множественных трейлеров
3. Проверка объектов на generation > 0
4. Сравнение метаданных Creator и Producer
Кейс 2: Обнаружение скрытого JavaScript
Сценарий: Подозрение на наличие вредоносного JavaScript кода в PDF документе.
Шаги анализа:
1. Поиск объектов с JavaScript через pdf-parser
2. Извлечение JavaScript кода
3. Анализ кода на подозрительные паттерны
4. Проверка на обфускацию и вредоносные функции
Кейс 3: Восстановление метаданных
Сценарий: Необходимо восстановить информацию об авторе документа из поврежденного PDF.
Шаги анализа:
1. Анализ структуры документа
2. Поиск метаданных в различных форматах (стандартные, XMP)
3. Восстановление из резервных копий объектов
4. Сравнение результатов из различных источников
16. Часто задаваемые вопросы (FAQ)
В этом разделе собраны ответы на наиболее часто задаваемые вопросы об анализе PDF документов, которые помогут быстро найти решение типичных проблем и лучше понять процесс криминалистического исследования.
Вопрос 1: Какие инструменты необходимы для начала анализа PDF документов?
Ответ: Для начала рекомендуется установить базовые инструменты: PyPDF2 или pdfplumber для Python, ExifTool для метаданных, pdf-parser для структурного анализа, и QPDF для проверки целостности. Эти инструменты покрывают большинство задач базового анализа.
Вопрос 2: Как определить, был ли изменен PDF документ?
Ответ: Признаки модификации включают несоответствия в датах создания и модификации, множественные трейлеры, объекты с generation > 0, несоответствия в метаданных Creator/Producer, и аномалии в структуре документа. Подробнее см. раздел Обнаружение модификаций и подделок.
Вопрос 3: Можно ли извлечь метаданные из зашифрованного PDF?
Ответ: Метаданные обычно не шифруются и могут быть извлечены даже из зашифрованных документов. Однако для доступа к содержимому документа потребуется пароль. Используйте инструменты вроде ExifTool для извлечения метаданных без пароля.
Вопрос 4: Как обнаружить JavaScript в PDF документе?
Ответ: Используйте инструменты вроде peepdf или pdf-parser для поиска объектов с JavaScript. JavaScript обычно находится в объектах с типом /JS или в действиях документа. Подробнее см. раздел Анализ JavaScript и встроенных скриптов.
Вопрос 5: Что делать, если PDF документ поврежден?
Ответ: Используйте QPDF для проверки и восстановления структуры документа. QPDF может исправить многие типы повреждений и создать валидный PDF файл. Также можно попробовать извлечь отдельные объекты и потоки вручную.
Вопрос 6: Как извлечь встроенные файлы из PDF?
Ответ: Встроенные файлы можно найти через поиск объектов с типом /EmbeddedFiles. Используйте PyPDF2 или pdf-parser для извлечения этих объектов и сохранения встроенных файлов. Подробнее см. раздел Извлечение скрытой информации из PDF.
Вопрос 7: Можно ли автоматизировать анализ множества PDF файлов?
Ответ: Да, можно создать скрипты на Python для массового анализа. Используйте циклы для обработки всех файлов в директории и сохраняйте результаты в структурированном формате (JSON, база данных). Подробнее см. раздел Автоматизация анализа PDF документов.
Вопрос 8: Как создать отчет по анализу PDF?
Ответ: Используйте структурированный подход: соберите все результаты анализа, создайте шаблон отчета (Markdown, HTML, или PDF), и заполните его данными. Включите методологию, результаты, выводы и рекомендации. Подробнее см. раздел Отчетность и документирование результатов.
Вопрос 9: Какие метаданные наиболее важны для расследований?
Ответ: Наиболее важными являются даты создания и модификации, информация об авторе (Author, Creator), программное обеспечение (Producer), и история изменений. XMP метаданные также могут содержать дополнительную информацию. Подробнее см. раздел Анализ метаданных PDF документов.
Вопрос 10: Как обнаружить вредоносный код в PDF?
Ответ: Ищите JavaScript код, который использует подозрительные функции (eval, unescape, fromCharCode), обращается к внешним ресурсам, или обфусцирован. Используйте специализированные инструменты вроде peepdf для анализа безопасности. Подробнее см. раздел Анализ JavaScript и встроенных скриптов.
Вопрос 11: Можно ли восстановить удаленную информацию из PDF?
Ответ: Частично. Удаленные объекты могут оставаться в файле, но не быть связанными со структурой. Можно искать потерянные потоки и фрагменты текста, но полное восстановление не всегда возможно. Подробнее см. раздел Продвинутые техники криминалистического анализа.
Вопрос 12: Как интегрировать анализ PDF с другими инструментами?
Ответ: Используйте API инструментов для программного доступа, сохраняйте результаты в стандартных форматах (JSON, XML), и используйте базы данных для хранения и сопоставления данных. Подробнее см. раздел Интеграция с другими инструментами криминалистики.
Вопрос 13: Какие форматы отчетов лучше использовать?
Ответ: Выбор зависит от аудитории. Markdown подходит для технических отчетов, HTML для веб-презентации, PDF для официальных документов. Важно сохранять исходные данные в структурированном формате (JSON) для дальнейшего анализа.
Вопрос 14: Как обеспечить воспроизводимость анализа?
Ответ: Документируйте все используемые инструменты и их версии, сохраняйте скрипты анализа, фиксируйте параметры запуска, и создавайте резервные копии исходных файлов. Используйте версионирование для скриптов и конфигураций.
Вопрос 15: Какие правовые аспекты нужно учитывать при анализе PDF?
Ответ: Всегда получайте законное разрешение на анализ документов, соблюдайте требования к конфиденциальности, документируйте все действия, и следуйте процедурам сохранения доказательств. Результаты анализа должны быть пригодны для использования в судебных разбирательствах.
---
**⚠️ Дисклеймер:** Статья носит информационно-образовательный характер и не содержит инструкций для совершения противоправных действий.