Закончился Nuit Du Hack CTF 2014 – Qualifications.
Мне удалось решить всего четыре таска из разный категорий Big Momma (Misc 200), Here kitty kitty ! (Steganalysis 50), Carbonara (Crypto 50) и Data extraction (Forensics 300). Причем последний сдать не успел.
Именно о нем мы и поговорим сегодня. Первая причина: таск решило всего 10 команд. Причина вторая: хотя таск и относится к категории Forensics, но фактически вся основная работа лежит в реверсе.
Задание выглядело так.
Data extraction
On a machine infected by Jupiter malware, some documents were transfered through the network.
Score 300
Link http://static.nuitduhack.com/Jupiter.pcap
Первая часть таска действительно свойственна форенсику, так как предстоит извлечь информацию из pcap файла. Воспользуемся как всегда Wireshark'ом . Во втором TCP потоке можно найти исполняемый файл виндовс переданный по сети.
Установим фильтр «tcp.stream eq 2» и через Menu->Analyze -> Follow TCP Stream (ПКМ -> Follow TCP Stream) получаем данные потока (весь обмен). Как видно из заголовков, был запрошен и успешно получен файл H5N1.exe (длина 261923).
Сохраним поток в файл и вырежем из него наш сэмпл. Начало определяется сигнатурой 'MZ', конец определяется, известной нам длиной файла.
Прежде чем приступить к изучению, обратим внимание на то, что это малварь (machine infected by Jupiter malware). «Береженого Бог бережет», поэтому проверим файл на virustotal на всякий случай (не одни мы такие умные и кто-то уже до нас его проверял, сервис сразу отдает отчет). Большинство заявили, что файл запакован MEW. Распакуем с помощью UnMEW (отлично распаковывается) и повторно проверим на virustotal. Ничего страшного :).
Приступим к изучению, с учетом того, что файл был запакован, его структура нарушена и IDA нам не очень помогла, сегмента два, импорт от распаковщика, сигнатуры автоматически не наложились да еще и писано на boost, сигнатур к которому в IDA нет. Про мытарства с реверсом рассказывать особенно нечего: кода много, код нормально не запускается ввиду того, что ждет ответа от своего сервера на 192.168.130.10.
Внимание!! Зверек себя копирует (на Win 7) по пути 'C:\Users\OKOB\AppData\Roaming\mssvc.exe' и ставит в автозапуск в реестре.
_0.ELO:00407A95 call SetAsVirus
Ворует он инфу только из PDF файлов обходя рекурсивно все каталоги, которые лежат ниже ‘C:/Users/OKOB/Documents’.
_0.ELO:00407A9E call FindPDF_Victims
Далее полный путь к файлу и тело файла преобразуется и передается по сети. Данных передаются пакетами, состоящими из блоков. Блоки двух типов: цифровые и текстовые (строковые). Каждый блок в пакете имеет номер. Номера блоков формируются по разному. Блоки объединены в пакеты (один цифровой блок и два строковых). Сформированные номера блоков в пакете 08h, 12h, 1Ah. Если представляемые цифровые данные или длина текстовых данных меньше 80h, то они представляются одним байтом, иначе двумя байтами. В первом блоке передается тип пакета (0\1), во втором блоке ключ «шифрования» и в третьем сами зашифрованные данные.
Посмотреть (поиметь) такие данные можно, сдампив в Wireshark'е TCP потоки 3…6 (фильтр «tcp.stream eq 3» и т.п.).
Код на Python, который восстанавливает из этих данных исходные PDF файлы представлен ниже.
Код принимает в качестве параметра имя файла дампа с данными, причем последний символ этого имени используется для формирования имени выходного файла (у меня это были цифры).Code:#!/usr/bin/env python #-*- coding:utf-8 -*- import sys if len(sys.argv) != 2: print 'Uses: python', sys.argv[0], '<xN>' print 'P.S.: flag in file "x3"' sys.exit(0) f = open(sys.argv[1],'rb') fo = open('out_%c.pdf'%sys.argv[1][1:2],'wb') fl = 1 while 1: try: xBlock = ord(f.read(1)) except: break #print xBlock if xBlock == 0x08: # block1 idx = ord(f.read(1)) if idx >= 0x80: idx &= ~0x80 idx += (ord(f.read(1)) << 7) #print 'index:', idx xBlock = ord(f.read(1)) #print xBlock if xBlock == 0x12: # block2 _len_key = ord(f.read(1)) #print 'len_key:', _len_key if fl == 1: key1 = f.read(_len_key) print 'key1:', key1 elif fl == 2: key2 = f.read(_len_key) print 'key2:', key2 else: key = f.read(_len_key) #print 'key:', key xBlock = ord(f.read(1)) #print xBlock if xBlock == 0x1A: # block3 _len = ord(f.read(1)) if _len >= 0x80: _len &= ~0x80 _len += (ord(f.read(1)) << 7) #print 'len:', _len block = f.read(_len) #print block if fl == 1: fn = '' for i in range(0,_len,2): fn += chr(int('0x'+block[i:i+2],16)^ord(key1[i/2%len(key1)])) print fn elif fl == 2: key_ = '' for i in range(len(key1)): key_ += chr(ord(key1[i])^ord(key2[i%len(key2)])) else: _out = '' for i in range(0, _len, 2): _out += chr(int('0x'+block[i:i+2],16)^ord(key_[i/2%len(key1)])) #print _out fo.write(_out) fl += 1 f.close() fo.close()
В результате оказалось, что зверьком с машины французов были украдены файлы:
C:/Documents and Settings/Administrateur/Mes documents/0DayWindows.pdf
C:/Documents and Settings/Administrateur/Mes documents/ARFID.pdf
C:/Documents and Settings/Administrateur/Mes documents/Confidential.pdf
C:/Documents and Settings/Administrateur/Mes documents/DLLH.pdf
В файле с красноречивым именем ‘Confidential.pdf’ и оказался флаг.
Содержание архива:
Jupiter.pcap – файл из задания;
H5N1.exe – исходны файл сэмпла;
H5N1_unp.exe – распакованный файл сэмпла;
Jupiter.py – файл декодера;
X1…x4 – дампы данных
NDH_F300.RAR
Результирующие PDF не прикладываю, т.к. они могут быть получены заинтересованными в полпинка.





Reply With Quote
Thanks

