Отримання та аналіз вмісту пам’яті в ОС Linux
У цій статті ми розглянемо спосіб віддаленого отримання образу пам'яті за допомогою LiME в системі на базі CentOS 6.5 x64.
Автор: Ден Кебен (Dan Caban)
Раніше образ пам'яті в системах на базі ОС Linux можна отримати безпосередньо (за допомогою утиліти dd) з файлів псевдопристроїв, таких як /dev/mem та /dev/kmem. В останніх версіях ядра доступ до цих пристроїв став обмеженим та/або повністю виключеним. Щоб дослідники і системні адміністратори могли отримати необмежений доступ, були розроблені модулі, які, наприклад, доступні в проектах fmem і LiME (Linux Memory Extractor).
У цій статті ми розглянемо спосіб віддаленого отримання образу пам'яті за допомогою LiME в системі на базі CentOS 6.5 x64.
LiME – модуль ядра, що завантажується (Loadable Kernel Module, LKM). Модулі, що завантажуються, зазвичай розробляються з метою розширення функціоналу ядра. Модуль можна додати за допомогою облікового запису з привілеями суперкористувача. При встановленні модуля слід бути обережним, оскільки некоректне його встановлення несе потенційні ризики для цільової системи. З іншого боку, LiME має ряд безперечних переваг:
- Скомпільований модуль досить невеликого розміру.
- Процедура установки не потребує перезавантаження.
- Модуль легко додається або видаляється.
- Отриманий дамп пам'яті можна завантажити без запису на локальний диск цільової системи.
- Дамп пам'яті сумісний із фреймворком Volatility.
Підготовка до роботи
Оскільки LiME розповсюджується у вигляді вихідних текстів, спочатку необхідно його скомпілювати. Всю доступну інформацію можна легко знайти в інтернеті, але перед цим рекомендую вам пошукати скомпіловані версії модуля абоскомпілювати та протестувати його на віртуальній машині.
У будь-якому випадку для початку необхідно дізнатися версію ядра на цільовій машині.
]$ uname -a Linux localhost.localdomain 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
Скомпільовані версії LiME-модулів можна взяти в Linux Forensics Tools Repository at Cert.org (цей ресурс заслуговує на довіру). Там зберігаються RPM-репозитарії аналітичних утиліт для Red Hat Enterprise Linux, CentOS та Fedora.
Щоб знайти скомпільований модуль для певної версії ядра та операційної системи, зайдіть на Cert і знайдіть «repoview» для цільової операційної системи
Малюнок 1: Розділ із репозитаріями для CentOS
Далі зайдіть у розділ «applications/forensics tools» та відкрийте документацію для «lime-kernel-objects».
На момент написання статті в репозитарії були скомпільовані версії для наступних версій ядер (під ОС CentOS 6/RHEL 6):
2.6.32-71 2.6.32-71.14.1 2.6.32-71.18.1 2.6.32-71.24.1 2.6.32-71.29.1 2.6. 32-71.7.1 2.6.32-131.0.15 2.6.32-220 2.6.32-279 2.6.32-358.0.1 2.6.32-358.11. 1 2.6.32-358.14.1 2.6.32-358.18.1 2.6.32-358.2.1 2.6.32-358.23.2 2.6.32-358.6. 1 2.6.32-431 2.6.32-431.1.2.0.1 2.6.32-431.3.1
Виявилося, що під мою версію ядра ще не існує скомпілованих модулів. Доведеться зробити трохи більше рухів тіла.
Я встановив на віртуальній машині CentOS 6.5 x64 з останньою версією ядра (2.6.32-431.5.1.el6.x86_64).
]$ yum update [root@vmtest
Після оновлення ядра перезавантажуємо віртуальну машину.
Тепер нам потрібні відповідні заголовки та вихідники ядра, а також утиліти для компіляції.
]$ yum install gcc gcc-c++ kernel-headers kernel-source
Тепер ми готові до завантаження та компіляції модуля LiME!
]# mkdir lime; cd lime [root@vmtest lime]# wget https://lime-forensics.googlecode.com/files/lime-forensics-1.1-r17.tar.gz [root@vmtest lime]# tar - xzvf lime-forensics-1.1-r17.tar.gz [root@vmtest lime]# cd src [root@vmtest src]# make …. make -C /lib/modules/2.6.32-431.5.1.el6.x86_64/build M=/root/lime/src modules … [root@vmtest src]# ls lime* .ko lime-2.6.32-431.5.1.el6.x86_64.ko
Після компіляції модуля завантажимо його на віртуальній машині та вивантажимо пам'ять у локальний файл. Налаштування модуля виглядають так:
]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=/root/mem.img format=lime"
Образ пам'яті буде вивантажений у файл /root/mem.img, а формат "lime" сумісний із фреймворком volatility.
Я перевірив параметри створеного образу (відповідність розміру та обсягу пам'яті, виділеного під віртуальну машину, і навіть на коректність вмісту образу).
]# ls -lah /root/mem.img -r--r--r--. 1 root root 1.0G Mar 9 08:11 /root/mem.img [root@vmtest
]# strings /root/mem.img head -n 3 EMiL root (hd0,0) kernel /vmlinuz-2.6.32-431.5.1.el6.x86_64 ro root=/dev/ mapper/vg_livecd-lv_root rd_NO_LUKS
Видаляємо модуль ядра за допомогою простої команди:
Отримання образу через інтернет
Після успішних тестів повернемося до нашої первісної задачі: захоплення пам'яті на сервері з ОС CentOS та завантаження отриманого образу через інтернет. Я завантажив модуль на підконтрольний сервер, а потім скачав його через протокол HTTP:
LiME дозволяє записувати образи на локальний диск. Натомість ми можемо створити TCP-сервіс приза допомогою аргументу path=tcp:4444.
]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=tcp:4444 format=lime"
Якщо, наприклад, ми знаходимося всередині клієнтської мережі або порт 4444 доступний через інтернет, за допомогою netcat я можу з'єднатися із сервером та завантажити образ пам'яті на свій комп'ютер.
]# nc target.server.com 4444 > /home/dan/evidence/evidence.lime.img
Оскільки цільовий сервер знаходиться в інтернеті, на якому встановлено фаєрвол, до процесу отримання образу слід підходити творчіше.
Помнете, як я завантажував модуль на цільовий сервер через HTTP (80-й порт)? Це означає, що фаєрвол дозволяє вихідні TCP-з'єднання через цей порт.
Крок 1: налаштовуємо сервер netcat на нашій машині, щоб він прослуховував 80-й порт.
]# nc –l 80 > /home/dan/evidence/evidence.lime.img
Крок 2: Запускаємо модуль LiME та конфігуруємо його на очікування TCP-з'єднань на 4444 порту.
]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=tcp:4444 format=lime"
Крок 3: Створюємо ланцюжок передачі образу пам'яті на мою машину.
]# nc localhost 4444 nc 60.70.80.90 80
Тепер, коли образ опинився на моїй машині, можна розпочати його аналіз.
Нижче показано наочну схему процесу передачі образу:

Малюнок 2: Схема передачі образу пам'яті на віддалений хост
Аналіз пам'яті за допомогою Volatility
У Volatility є безліч профілів для парсингу дампів пам'яті, але ці конфігурації переважно корисні при аналізі образів взятих у Windows. Щоб виконати аналіз дампа взятого з Лінукса, ми повинні створити новий профіль, який точно відповідає операційній системі, версії ядра та архітектурі. Повернемося у віртуальній машині для того, щоб зібрати всю необхіднуінформацію для створення профілю. Нам потрібно:
- символи налагодження (System.map*)
- Необхідний доступ до тестової віртуальної машини з тією ж архітектурою, версією ядра і операційною системою.
Для початку створимо папку, в яку складуватимемо всі необхідні файли.
mkdir -p volatility-profile/boot/ mkdir -p volatility-profile/volatility/tools/linux/
Тепер скопіюємо символи налагодження, що знаходяться в CentOS в директорії /boot/. Необхідно знайти файл System.map*, відповідний версії ядра, яку було запущено під час отримання дампа пам'яті (2.6.32-431.5.1.el6.x86_64).
]# cd /boot/ [root@vmtest boot]# ls -lah System.map* -rw-r--r--. 1 root root 2.5M Feb 11 20:07 System.map-2.6.32-431.5.1.el6.x86_64 -rw-r--r--. 1 root root 2.5M Nov 21 22:40 System.map-2.6.32-431.el6.x86_64
Копіюємо відповідний файл System.map у раніше створену папку.
[root@vmtest boot]# cp System.map-2.6.32-431.5.1.el6.x86_64
/volatility-profile/boot/ Одна з вимог компіляції файлів ядра (vtypes) – наявність бібліотеки libdwarf. В інших операційних системах її можна отримати за допомогою apt-get чи yum. У CentOS 6.5 необхідно скомпілювати вихідні джерела, взяті з Fedora Project. Інші пакети, необхідні для компіляції, повинні бути встановлені під час компіляції LiME (див. розділ «Підготовка до роботи»).
[root@vmtest boot]# cd
]# mkdir libdwarf [root@vmtest libdwarf]# cd libdwarf/ [root@vmtest libdwarf]# wgethttp://pkgs.fedoraproject.org/repo/pkgs/libdwarf/libdwarf-20140208.tar.gz /4dc74e08a82fa1d3cab6ca6b9610761e/libdwarf-20140208.tar.gz warf -20140208.tar.gz [root@vmtest dwarf-20140208]# cd dwarf-20140208/ [root@vmtest dwarf-20140208]#./configure [root@vmtest make [root@vmtest dwarfdump]# cd dwarfdump [root@vmtest dwarfdump]# make install
Копіюємо вихідники Volatility і скомпілюємо структури ядра.
[root@vmtest dwarfdump]# cd
]# mkdir volatility [root@vmtest
]# cd volatility [root@vmtest volatility]# cd volatility [root@vmtest volatility]# wget https://volatility.googlecode.com/files/volatility-2.3.1.tar.gz [root@vmtest volatility]# tar -xzvf volatility-2.3.1.tar.gz [root@vmtest volatility]# cd volatility-2.3.1/tools/linux/ [root@vmtest linux] # make
Після успішної компіляції скопіюємо файл (module.dwarf), що вийшов, в папку профілю.
[root@vmtest linux]# cp module.dwarf
Запаковуємо обидва файли в ZIP-архів (згідно з вимогами Volatility).
[root@vmtest linux]# cd
/volatility-profile/ [root@vmtest volatility-profile]# zip CentOS-6.5-2.6.32-431.5.1.el6.x86_64.zip boot/System.map-2.6.32-431.5. 1.el6.x86_64 volatility/tools/linux/module.dwarf adding: boot/System.map-2.6.32-431.5.1.el6.x86_64 (deflated 80%) adding: volatility/tools/ linux/module.dwarf (deflated 90%)
Отриманий архів на своїй машині можна було б скопіювати в стандартну папку, призначену для зберігання профілів, проте щоб уникнути їхньої втрати під час оновлень, я створив окрему директорію та послався на неї під час запуску volatility.
Далі бачимо, що Volatility розпізнав нову директорію дляплагінів.
dan@investigativelaptop evidence]# vol.py --plugins=/home/dan/.volatility/profiles/ --info grep -i profile grep -i linux Volatility Foundation Volatility Framework 2.3.1 LinuxCentOS-6_5 -2_6_32-431_5_1_el6_x86_64x64 - A Profile for Linux CentOS-6.5-2.6.32-431.5.1.el6.x86_64 x64
Запускаємо плагіни з префіксом linux, які йдуть у складі Volatility, для аналізу пам'яті.