Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
BlackLotus-Z2A-Challenge — BlackLotus-Z2A-Challenge, здесь пока ничего нет, пожалуйста, проходите мимо | Kitploit
Инструменты/GitHubGitHub/spiralbl0ck/blacklotus-z2a-challenge
Статический анализОбратная инженерияАнализ вредоносных программCTFОбучение и Образование
GitHubspiralbl0ck/blacklotus-z2a-challenge

BlackLotus-Z2A-Challenge

BlackLotus-Z2A-Challenge, здесь пока ничего нет, пожалуйста, проходите мимо

Репозиторий

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
323 лет назадЕщё не проверено

BlackLotus-Z2A-Challenge

BlackLotus-Z2A-Challenge, здесь пока ничего нет, проходите мимо

Прежде всего Capture23

Исключительно в эстетических целях я бесстыдно позаимствую (украду) :)) из решения @darthmaulware(Ryan “DM” Smith) правила детектирования YARA, чтобы всё выглядело профессионально. Загляните в его твиттер, он чертовски классный! P.S. Райан, пожалуйста, не злись, что я это украл :))) и спасибо за поддержку в Discord :)

Также посмотрите его работу :)

https://gitlab.com/malre-rcs/zero2automated/-/blob/main/solutions/bi_weekly_challenge/BlackLotus_20230321/BlackLotus_HTTP_Downloader.ipynb``` rule Blacklotus_HTTP_Downloader { meta: description = "Rule to detect Blacklotus HTTP Downloader" author = "Darth Maulware" sha256 = "d68f668b4240f9518e4f80499d93d8c5a1eddece0771658c33ae916cc54f5a66"

root@kitploit:~
    strings:
        $opcode1 = {48 89 4C 24 08 48 89 54 24 10 4C}
        $opcode2 = {89 44 24 18 4C 89 4C 24 20 48 83}
        $opcode3 = {EC 28 B9 31 62 D7 2E 90 90 E8 ??}
        $opcode4 = {?? ?? ?? 48 83 C4 28 48 8B 4C 24}
        $opcode5 = {08 48 8B 54 24 10 4C 8B 44 24 18}
        $opcode6 = {4C 8B 4C 24 20 4C 8B D1 90 90}

    condition:
        (uint16(0) == 0x5a4d and filesize < 500KB and all of them)

}

root@kitploit:~
Также, из эстетических соображений, я всё равно украду и это, потому что выглядит круто :) снова извини, Райан, пожалуйста, не злись на меня :)```
        C:\\Users\\REM\\Desktop>capa.exe -f pe -r capa-rules-5.0.0 d68f668b4240f9518e4f80499d93d8c5a1eddece0771658c33ae916cc54f5a66.exe
        matching: 100%|████████| 124/124 [00:02<00:00, 46.96 functions/s, skipped 1 library functions (0%)]

        +------------------------+------------------------------------------------------------------------------------+
        | ATT&CK Tactic          | ATT&CK Technique                                                                   |
        |------------------------+------------------------------------------------------------------------------------|
        | DEFENSE EVASION        | Obfuscated Files or Information T1027                                              |
        | DISCOVERY              | Process Discovery T1057                                                            |
        | EXECUTION              | Shared Modules T1129                                                               |
        +------------------------+------------------------------------------------------------------------------------+

        +-----------------------------+-------------------------------------------------------------------------------+
        | MBC Objective               | MBC Behavior                                                                  |
        |-----------------------------+-------------------------------------------------------------------------------|
        | ANTI-BEHAVIORAL ANALYSIS    | Debugger Detection::Process Environment Block BeingDebugged [B0001.035]       |
        |                             | Debugger Detection::Process Environment Block NtGlobalFlag [B0001.036]        |
        | CRYPTOGRAPHY                | Encrypt Data::RC4 [C0027.009]                                                 |
        |                             | Generate Pseudo-random Sequence::RC4 PRGA [C0021.004]                         |
        | DATA                        | Encode Data::XOR [C0026.002]                                                  |
        | DEFENSE EVASION             | Obfuscated Files or Information::Encoding-Standard Algorithm [E1027.m02]      |
        +-----------------------------+-------------------------------------------------------------------------------+

        +------------------------------------------------------+------------------------------------------------------+
        | CAPABILITY                                           | NAMESPACE                                            |
        |------------------------------------------------------+------------------------------------------------------|
        | execute syscall instruction (35 matches)             | anti-analysis                                        |
        | check for PEB BeingDebugged flag (2 matches)         | anti-analysis/anti-debugging/debugger-detection      |
        | check for PEB NtGlobalFlag flag                      | anti-analysis/anti-debugging/debugger-detection      |
        | encode data using XOR (2 matches)                    | data-manipulation/encoding/xor                       |
        | encrypt data using RC4 PRGA (2 matches)              | data-manipulation/encryption/rc4                     |
        | get process heap flags                               | host-interaction/process                             |
        | get ntdll base address (3 matches)                   | linking/runtime-linking                              |
        | parse PE header (2 matches)                          | load-code/pe                                         |
        | resolve function by parsing PE exports (2 matches)   | load-code/pe                                         |
        +------------------------------------------------------+------------------------------------------------------+

tbh если честно, на твоём месте я бы не доверял capa на 100% (по крайней мере в этом конкретном случае), потому что здесь указано, что сэмпл использует rc4, хотя на самом деле он использует aes, но не суть, как уже упоминалось, это чисто для эстетики :)

Before we start you will encounter through this report a lot of

1

Пожалуйста, игнорируй это, так как IDA не может корректно дизассемблировать это в ассемблере; это

1

И это роняет отладчик? Почему?

Потому что здесь идёт попытка записи по адресу 0, что в фольклоре хакеров известно как запись по нулевому указателю, и это когда-то широко эксплуатировалось для получения CE (code execution), но сейчас это, очевидно, смягчено.

И из-за текущей защиты, если попытаться записать по адресу 0, процесс — в нашем случае малварь, а следом и отладчик — упадёт.

Теперь, если мы откроем это в IDA

1

Я переименовал каждую функцию, чтобы было понятно, какую логику она выполняет. Давай начнём с первой функции — do_syscall() Capture23

Мы сразу замечаем использование сисколов — это известный метод, который усложняет жизнь аналитику при динамическом анализе.

Для тех, кто не знаком с сисколами в Windows, вот классное видео от oalabs(https://www.youtube.com/watch?v=Uba3SQH2jNE). Пожалуйста, посмотри его, потому что я тоже смотрел, и оно очень помогло мне понять, что происходит в этой функции.

Если мы посмотрим на «псевдокод», который построила IDA, то увидим, что он выглядит так

Capture4

Если мы статически посмотрим на solve_hash, это выглядит так

1

2

С точки зрения псевдокода это выглядит так

4

Пожалуйста, обратись к solve_hash.py, чтобы увидеть мою «эмуляцию» этого, на случай если хочешь посмотреть на кусочек автоматизации и узнать, как разрешаются сисколы с помощью алгоритма поиска по хэшу. Но тем не менее это часть проекта SysWhispers2, или, по крайней мере, я предполагаю, что авторы малвари использовали его как вдохновение. В любом случае, для лучшего понимания обратись к видео oalabs выше.

В любом случае, функция anti_debug легко обходится и хорошо известна(https://anti-debug.checkpoint.com/techniques/debug-flags.html#manual-checks-ntglobalflag). Способ обхода — установить ScyllaHide и включить NtGlobalFlag (что должно быть включено по умолчанию, если используешь x86dbg). Тем не менее, вот что нужно проверить

4

А так выглядит «псевдо-функция» анти-отладки

4

Довольно просто, если спросишь меня.

Далее у нас функция check_inmemory_ldr, которая выглядит так

1

2

Теперь, для целей анализа функции, если мы вежливо попросим x86dbg, то сможем увидеть, что если мы выполним до инструкции syscall, x86dbg любезно покажет нам, какой именно сискол будет исполнен. В нашем случае

2

Исходя из текущего контекста, можно предположить, что Ntsetinformationthread будет использоваться как некий анти-аналитический трюк. Конечно же, если быстро загуглить, мы найдём это https://ntquery.wordpress.com/tag/ntqueryinformationthread/

К счастью, легко обходится — просто пропатчить nop+ret :)

=============================================================================

Дальше по порядку выполнения идёт следующая функция:

4

Снова, если мы посмотрим, что она делает

Capture4

Она просто проверяет флаг в TEB, чтобы узнать, отлаживается ли текущий процесс (в нашем случае exe). Это опять же легко обходится, так как это известный метод(https://anti-debug.checkpoint.com/techniques/debug-flags.html#manual-checks-peb-beingdebugged-flag), тем же способом, что и с ScyllaHide, только теперь нужно отметить
Capturez

что должно быть включено по умолчанию

=============================================================================

Теперь custom_hash2_and_aplib_possible, которая выглядит так

2

А с точки зрения графа

3

Пожалуйста, обратись к decompress_aplib.py, чтобы увидеть «эмуляцию» этой функции.

Исследуя get_ntdll_and_unhook2, видим вот что

1

2

С точки зрения графа это выглядит так

1

Неплохо :))

Немного вернувшись назад, у нас есть aplib_decompress, теперь это выглядит так

1

С точки зрения статического анализа кода это выглядит так

1

2

3

4

Хм, немного объемно, но ничего страшного, народ, это реально сделать :)

Если использовать скрипт-эмуляцию aplib_decompress.py, то в итоге получится что-то вроде этого

1

Клёвая вещь, которую я не замечал в других блогах/анализах, вот: если снова взглянуть на псевдокод IDA для ntdll_and_unhook2

1

вы увидите интересный memcpy

в какой-то момент, когда я занимался динамическим анализом, я заметил, что загружается ещё одна dll, которая была другой версией ntdll

1

если посмотреть в отладчике, это выглядит так

1

Мне не удалось определить, что было захучено/пропатчено, но если кто-то знает, пожалуйста, сделайте pull request и отредактируйте этот документ. Также в попытках найти, что хукается, я попробовал сделать bindiff между двумя ntdll и, к сожалению, ничего не нашёл. Но возможно, это потому, что я уже делал дифф на системной dll, которая была заражена, так что это был не чистый запуск, возможно, поэтому ¯_(ツ)_/¯

1

=============================================================================

Продолжая процесс анализа, среди необъяснённых функций у нас есть some_hasing и ntquertyinformationprocess_anti_debug — они ещё не были разобраны. check_if_being_debug_through_teb и anti_debug уже были объяснены, к счастью, потому что они использовались в вышеуказанной функции/функциях, так что, пожалуйста, перечитайте предыдущие разделы, если хотите освежить знания о них. Я хотел бы начать с ntquertyinformationprocess_anti_debug, а затем закончить some_hasing.

Исследуя её, мы видим, что одна и та же функция вызывается 3 раза.

1234

А с точки зрения ассемблера

1

2

Для удобства я уже назвал её — ntquertyinformationprocess_ProcessDebugPort. Откуда я знал, что вызываемые функции — это ntquertyinformationprocess_ProcessDebugPort? При их изучении видна уже встречавшаяся нам функция/известные нам алгоритмы

1

А что насчёт комментариев в IDA? Ну, если поискать ntqueryinformationprocess в Google, мы наткнёмся на хороший ресурс по анти-отладке(https://anti-debug.checkpoint.com/techniques/debug-flags.html). Если следовать дальше, можно увидеть, что в ней объясняется: в зависимости от определённых значений, передаваемых в качестве параметров в эту функцию, её можно использовать как метод анти-отладки.

Например, для первого вызова мы можем увидеть в отладчике следующие аргументы стека

1

Если теперь мы пойдём и проверим страницу MSDN для ntqueryinformationprocess

1

Тот же процесс повторяется для следующих двух сисколов

2

где 0x1e относится к методу анти-отладки ProcessDebugObjectHandle(https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software)

и, наконец, ProcessDebugFlags

2

Так как же их обойти?! Прими таблетку спокойствия, братан, потому что ScyllaHide прикрывает нас

obama-pew

Как видите

1

Итак, мы в безопасности! Не совсем. ScyllaHide прикрывает нас для первых двух сисколов, но последний сискол нам придётся сделать вручную! И что же мне делать??? Ну, решение простое! Мы выходим из этой функции, то есть из всей ntquertyinformationprocess_anti_debug, и устанавливаем eax в 0. Итак, при нормальных обстоятельствах это выглядит так

1

А с нашей «помощью» это выглядит так, и мы спокойно даём выполнению идти дальше :)

1

=============================================================================

Теперь some_hasing — ты уже знаешь эту процедуру

1

А теперь псевдокод

2

Мы замечаем странную вещь. Псевдокод IDA здесь пасует... потому что, если проследить по графу после call_syscall, там ещё есть инструкции для дизассемблирования. Так что же нам теперь делать? Ну, мы будем полагаться на отладчик, чтобы динамически проанализировать этот код...

Итак, мы видим, что сискол, который она выполняет, — это

1

Теперь, если поискать ntquerydefaultlocale, Google показывает, что это недокументированное API, принимающее 2 аргумента(http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FLocale%2FNtQueryDefaultLocale.html). Круто, и что оно делает? Оно возвращает текущий Locale Identifier. Круто, а что такое Locale Identifier? Из MSDN (https://learn.microsoft.com/en-us/windows/win32/intl/locale-identifiers) это 32-битное значение, состоящее из идентификатора языка и идентификатора порядка сортировки. Если кратко — на каком языке говорят на этом ПК :)

Затем она проверяет, не завершилось ли API с ошибкой, и если не завершилось, берёт значение, возвращённое ntquerydefaultlocale, вычитает 0x419 и сравнивает его с 0x26 (вероятно, константой), как видно на картинке ниже.

1

Если оно не меньше или не равно 0x26, то сравнивает с 0x818, иначе делает то же сравнение с 0x819, как хорошо видно

2

Так что тут происходит? И почему именно эти константы? Ладно, буду прямолинейным. Перебирая разные константы, я наткнулся на эту статью(https://www.cnblogs.com/DirWang/p/17281690.html#autoid-8-0-0): исследователь уже проанализировал BlackLotus лучше, чем смог бы я. И, как кто-то однажды сказал: «В анализе малвари нельзя сжульничать, можно лишь облегчить себе работу». Итак, исследователь говорит, что, по сути, эта функция проверяет конкретные константы, определяющие, на каком языке говорят на компьютере. В своей статье он даёт ссылку на вот этот документ(https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-LCID/[MS-LCID].pdf) — что-то вроде стандартного документа Microsoft со всеми идентификаторами языков.

Теперь, используя нашу хацкерскую l33t-логику, можно предположить, что 0x26 — это что-то вроде смещения, то есть 0x26 следующих языковых идентификаторов после 0x419, а именно:

2

Если также заглянуть в этот документ, можно увидеть, что 0x818 соответствует

2

а 0x819 —

2

А из предыдущих «расследований»/онлайн-отчётов мы знаем, что эта малварь не запускалась на определённых ПК из определённых регионов мира, так что можно сделать вывод: эта функция проверяет, из какого региона заражённая машина.

=============================================================================

Безумный ham00brg33r до сих пор, братан, что дальше? Мы подаём функцию some_more_syscall. Ага! Итак, что у нас тут, ага! Вот она

1

Мы хотим больше! Конечно, чувак!

2

3jgukd

1

Хм

1

Итак, проверяем, присутствует ли kernel debugger(https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi/system_information_class.htm)(0x23), чек-чек!

Так что, ага! У нас тут pcr(piles and combinations party)

2

=============================================================================

Теперь, если мы исследуем функцию iterate_over_modules(), она выглядит так

1

С точки зрения «псевдокода» это выглядит так

2

С точки зрения отдельного взгляда, ассемблер и псевдокод IDA совпадают, так в чём же логика этой функции? Ну, всё довольно просто: она перебирает загруженные в память модули (dll) и сверяет их со списком хэшей :) v4[0] = 0x1E7EACEF; v4[1] = 0x4468A620; v4[2] = 0x68536B95; v4[3] = 0x73EBBB53; v4[4] = 0xDA165168; v4[5] = 0xB24D33A7; v4[6] = 0xB1E2CEC6; v4[7] = 0x5136992; v4[8] = 0x98C500D9; v4[9] = 0x3E0169B6;

И если ни одна dll в памяти не найдена с таким же хэшем, возвращается 0, иначе 1, и мы роняем отладчик. Исходя из этого можно сказать, что это ещё один метод анти-анализа. Верно, но как насчёт каждого из значений хэшей? Что ж, снова сжульничаю (как кто-то однажды сказал: в анализе малвари нельзя сжульничать, можно лишь облегчить себе жизнь :) ). Вышеупомянутый азиатский исследователь был так любезен, что предоставил нам список значений, на основе которых были получены эти хэши

sbiedll.dll dbghelp.dll api_log.dll dir_watch.dll pstorec.dll vmcheck.dll wpespy.dll cmdvrt64.dll avghookx.dll snxhk.dll

Теперь, чтобы динамически убедиться, соответствуют ли какие-либо значения упомянутым dll

2

И, конечно же, соответствует :)

Но как я пришёл к выводу, что алгоритмы проверяют именно эти значения? Ну, когда я эмулировал часть этой малвари, мне пришлось заново реализовать iterate_over_module_name_and_hash (в файле solve_hash_syscalls.py), и в этой функции у нас есть

1

где x (передаваемый аргумент) в данном случае — это v2, массив (указатель) значений, который инкрементируется (насколько он указывает в массиве), пока не совпадёт с одним из уже упомянутых выше значений. Вот это скороговорка :P

Круто! Дальше.

=============================================================================

iterate_over_modules2 — в целом та же история

1

И псевдокод

2

В целом та же история, только другие хэши :)

v5[0] = 0x7D73878E; v5[1] = 0xEF36424B; v5[2] = 0xAF64BC2B; v5[3] = 0x1DBBC879; v5[4] = 0xAE6D1D56; v5[5] = 0x7B3242F2; v5[6] = 0x14D922B9; v5[7] = 0x4C92DF53;

которые соответствуют

sample.exe bot.exe sandbox.exe malware.exe test.exe klavme.exe myapp.exe testapp.exe

=============================================================================

iterate_over_modules3 — здесь та же история

1

И псевдокод

2

Та же история, другие хэши :)v4[0] = 0x42D12D59; v4[1] = 0xEC5D7AA; v4[2] = 0x861E460F; v4[3] = 0x84BCC8DB; v4[4] = 0x6474D72B; v4[5] = 0xB8B9C504; v4[6] = 0x69A0620E; v4[7] = 0x6017EE43; v4[8] = 0xE93BE2E0; v4[9] = 0x149EFC55; v4[10] = 0xE3FA84A4; v4[11] = 0x7CFDD7AF; v4[12] = 0x5B098C67; v4[13] = 0x2F1FB18E; v4[14] = 0xFE8F2B18;

которые соответствуют

prl_cc.exe prl_tools.exe qemu-ga.exe vmtoolsd.exe vmwaretray.exe vmwareuser.exe VGAuthService.exe vmacthlp.exe vboxservice.exe vboxtray.exe VMSrvc.exe VMUSrvc.exe xenservice.exe

=============================================================================

Anti_debug_measure_1 — в итоге я переименовал его в anti_debug_measure2_RtlAddVectoredExceptionHandler_int3. Почему — увидите через минуту. Итак, выглядит это так

1

А с точки зрения псевдокода это выглядит так

1

Итак, что это, чёрт возьми, такое? Ну, по сути, создаётся обработчик исключений для __debugbreak (int 3), который будет выполнять код при каждом срабатывании int3. Я продолжил поиски и наткнулся на это

(https://blog.lexfo.fr/dridex-malware.html) — классный ресурс, который даёт нам понять, что это просто анти-отладочный механизм, и в нашем случае мы просто запускаем эту функцию, игнорируем sub_13F2820D0, которая срабатывает при каждом выполнении int3, и патчим eax в 0 :) Так что исполнение в памяти выглядит так :)

До патча

1

После патча

1

После этого выходите из функции, а также меняете rax/eax на 0, чтобы пропустить переход jne, ведущий к падению отладчика

1

=============================================================================

Anti_debug_measure_2 — позже я переименовал его в anti_debug_measure2_RtlAddVectoredExceptionHandler_int2

1

2

Опять ничего нового под солнцем — то же самое, просто перехват другого int/syscall, на этот раз int2. Тот же трюк для обхода: используем динамическое патчирование возвращаемого значения :)

Если поискать в Google «анти-анализ 2dh», появится куча материалов, так что да, можно использовать это как справочник, чтобы узнать больше; я не потратил на это много времени :)

В случае с этим, даже если попытаться выполнить шаг с обходом (step over), вы окажетесь на ret, как здесь

1

а чтобы обойти это, просто выполняем до return, и всё готово :)

=============================================================================

Итак, теперь подходим к anti_debug_measure_heap, который я позже переименовал в iterate_over_current_process_and_check_again_hases

1

И классная особенность этой функции в том, что внутри iterate_over_current_process_and_hash_check используется ntquerysysteminformation для вывода списка всех запущенных процессов. Вот как выглядит iterate_over_current_process_and_hash_check

1

2

Круто, но как, чёрт возьми, я пришёл к выводу, что iterate_over_current_process_and_hash_check делает то, что следует из названия? Ну, во-первых, это вызов ntquerysysteminformation: если поискать в Google, видно, что он используется для получения списка запущенных процессов. А затем я просто сделал обоснованное предположение на основе следующего фрагмента кода LODWORD(v4) = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, 8u, v10); v3 = v4; v5 = ntquerysysteminformation(); v6 = v3; .... memcpy(v9, v6[8], *(v6 + 28)); v9[*(v6 + 28) >> 1] = 0; if ( some_hash_0x1003F(v9) == a1 ) что он копирует список процессов, перебирает каждый и сравнивает каждый хэш из предыдущего массива с тем, какой процесс запущен. И снова респект исследовательскому блогу того азиата, потому что я без понятия, как он, чёрт возьми, додумался до реальных имён значений массива v4. Пожалуйста, обращайтесь к iterate_over_modules.py, если хотите посмотреть, как я это эмулировал.

P.S. Если отлаживать эту функцию динамически, вы снова наткнётесь на int 2d, и решение такое же, как описано выше, только нужно выполнять до return 0xf раз, что по сути проходит по куче (heap), и после этого, если хотите быть уверенными, что вы дошли до return из iterate_over_current_process_and_check_again_hases, просто поставьте br в конце этой функции — и вы в безопасности :)

============================================================================= anti_debug_measure_heap

1

2

1

Так что да, нам повезло, что это не так уж велико, и более того, мы уже реализовали demangle_strings. Теперь я переписал это для массивов побольше — пожалуйста, смотрите anti_debug_measure.py.

это, по сути, сверяет с``` \Registry\Machine\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters \Registry\Machine\SYSTEM\ControlSet001\Services\vioscsi \Registry\Machine\SYSTEM\ControlSet001\Services\VirtIO-FS Service \Registry\Machine\SYSTEM\ControlSet001\Services\VirtioSerial \Registry\Machine\SYSTEM\ControlSet001\Services\BALLOON \Registry\Machine\SYSTEM\ControlSet001\Services\BalloonService \Registry\Machine\SYSTEM\ControlSet001\Services\netkvm \Registry\Machine\SOFTWARE\VMware, Inc.\VMware Tools \Registry\Machine\HARDWARE\ACPI\DSDT\VBOX__ \Registry\Machine\HARDWARE\ACPI\FADT\VBOX__ \Registry\Machine\HARDWARE\ACPI\RSDT\VBOX__ \Registry\Machine\SOFTWARE\Oracle\VirtualBox Guest Additions \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxGuest \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxMouse \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxService \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxSF \Registry\Machine\SYSTEM\ControlSet001\Services\VBoxVideo

root@kitploit:~
Теперь get_oem_key

![1](https://assets.kitploit.com/production/public/readmes/44337/2a188d30cf6be94954d1432a2928bc11c0546da19b9092e5dfc7d2c195e47d54.png)

![2](https://assets.kitploit.com/production/public/readmes/44337/aa44c5cb77b983c38dfa6be61b9ed0482df4082a81ebe73c7f295dd43844669f.png)

![3](https://assets.kitploit.com/production/public/readmes/44337/6227b500e17378e4f4682e86ce1928898be52b0781b496156ce8a975f4ae1226.png)

![4](https://assets.kitploit.com/production/public/readmes/44337/67227ce4e2999496337e5894b1990937f519ebf72574d20532e6ea9a2170f864.png)

![5](https://assets.kitploit.com/production/public/readmes/44337/82fa372a01bbc8dba4d2dec1b0a0ca46836c9c9cd514aecb8637ebcfd6059435.png)

![1](https://assets.kitploit.com/production/public/readmes/44337/24973f6832bf4752014bfe5f77dbc75b2a5254e5ed809b980f98803d35464824.png)

![2](https://assets.kitploit.com/production/public/readmes/44337/b976c0dad1e2b872649a6df1b61d19b220863b0cb770feb5caa92c93ffa9bad7.png)

Сначала он демангулирует строку до```
 \Registry\Machine\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0
 \Registry\Machine\SYSTEM\ControlSet001\Control\SystemInformation
 \Registry\Machine\HARDWARE\Description\System
 Identifier
 SystemManufacturer
 SystemBiosVersion
 VMWARE
 QEMU
 VBOX

И затем запрашивает
\Registry\Machine\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 \Registry\Machine\SYSTEM\ControlSet001\Control\SystemInformation \Registry\Machine\HARDWARE\Description\System

и проверяет их значения на соответствие qemu, vbox, VMWARE, как видно в сниппете IDA и окне x86 :)

1

2

Как видно из первого сниппета, он проверяет vmware на соответствие значениям, которые хранились в моей виртуальной машине на момент анализа :)

не большая проблема, просто выполните эту функцию до ret и измените eax при возврате на 0 :) чтобы обойти этот метод анти-анализа :)

=============================================================================

теперь get_oem_from_firmware

1

2

3

4

5

Теперь кое-что интересное: мы видим, что эта функция начинается с sub_13F267288(), которой передаётся 0x52534D42 в качестве параметра. Если поискать это значение в Google, вы найдёте много классных вопросов на разных форумах, например (https://ru.stackoverflow.com/questions/778618/c-%D0%9A%D0%B0%D0%BA-%D0%B4%D0%BE%D1%81%D1%82%D0%B0%D1%82%D1%8C-%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D1%8E-%D0%BE%D0%B1-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0%D1%85-%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0-%D0%BD%D0%B5-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F-wmi) (https://msdn-whiteknight.github.io/answers/html/tools/html/ru.stackoverflow.com/posts/780170.html) (https://www.maldun.com/analysis/YXNkZmRzZmFkc2Y2NDEwNjlkc2Zhc2RmYXNkZg==/) или это (https://github.com/digitalocean/go-smbios/blob/master/smbios/stream_windows.go), но самое интересное, что после прочтения этого и поиска RSMB вы можете наткнуться на это https://evasions.checkpoint.com/techniques/firmware-tables.html, что объясняет нам, что это метод анти-анализа :) Круто, так что же это делает?

Сначала дампит таблицу прошивки SMBIOS, затем деманглит строку, первая строка — qemu, затем вызывает sub_13F2655E0 с параметрами: демангленная строка и таблица прошивки. Из статического анализа

1

2

точнее, if ( v4 != v5) — я пришёл к выводу, что это что-то вроде реализации strcmp: он проверяет содержимое таблицы прошивки на соответствие демангленной строке. Как видно в отладчике

1 r8 — указатель на таблицу прошивки, и что ещё интереснее, мы видим, что бла-бла-бла ... virtualbox — это имя, найденное в таблице прошивки, а rcx — qemu, так что можно смело сказать, что это реализация типа strcmp. И, конечно, как видно, мы в безопасности :) от этой проверки

1

Теперь этот процесс повторяется для строк VirtualBox, vbox, VBOX, VMware :) В общем, решение для обхода этой проверки — выполнить функцию до ret, пропатчить eax и продолжить анализ :)

============================================================================

Круто, теперь check_oem_key ()

1

2

3

1

2

3

Так что же это делает? Ну, тот же трюк, что объяснялся ранее, но на этот раз с таблицей ACPI. Что я имею в виду? Лучше прочитайте эти 14 слайдов (https://dc4420.org/slides/2015-11-24/acpi_vm_detect.pdf), там объяснено лучше, но тот же дешёвый трюк :)) на этот раз против BOCHS, BXPC, VMWARE

1

2

============================================================================

Я хочу начать с функции anti_debug_processor_Timing(), а затем закончить check_for_flags(). Итак

1

Вот как это выглядит. Итак, что оно делает? Оно читает текущее значение временной метки процессора, затем берёт имя процессора (в нашем случае GenuineIntel), затем вычитает полученную временную метку из имени процессора и просто проверяет, больше ли результат, чем 19999.

После rdtsc

1

после cpuid

1

Как видно, строка разбита на 3 регистра

1

И в нашем случае мы видим, что «fail» эту проверку и устанавливаем eax в 1

1

Решение для этой анти-проверки — просто вернуться из функции и пропатчить eax в 0 :)

============================================================================

Теперь entry_to_peb()

1

2

3

4

5

6

7

С точки зрения псевдокода

1

2

3

Итак, до проверки if нет ничего нового, мы уже видели такой тип алгоритма, так в чём дело? Если вы перейдёте к уже упомянутому разбору азиатского исследователя, вы увидите, что в нём говорится, что он проверяет, больше ли версия Windows, чем win7/server 2008 r2. Но как он пришёл к этой идее? Если мы прочитаем http://waleedassar.blogspot.com/2012/08/major-minorsubsystemversion.html, он говорит

1

также если вы прочитаете и это :)

https://reverseengineering.stackexchange.com/questions/26157/how-to-show-kuser-shared-data-members-in-decompiled-c-code

и примените то, что здесь сказано: он автоматически приводится к структуре KUSER_SHARED_DATA, но здесь мой IDA был багован во время анализа, так что что есть, то есть :)

чтобы не утомлять вас повторением примерно того же алгоритма, вот итоговые извлечённые и демангленные строки функции :) это был утомительный процесс, так как делалось с помощью отладчика :) мне было лень эмулировать это``` user32.dll advapi32.dll Rpcrt4.dll bcrypt.dll ole32.dll Cabinet.dll

CreateWindowExW
ShutdownBlockReasonCreate
ShutdownBlockReasonDestroy
DestroyWindow CloseHandle
CreateProcessW InitializeProcThreadAttributeList
UpdateProcThreadAttribute LoadAppInitDlls Sleep
GetExitCodeProcess
MoveFileExW
OpenSCManagerW OpenServiceW
QueryServiceStatus
StartServiceW
CloseServiceHandle
GetUserNameW
ConvertSidToStringSidW
LookupAccountNameW
CreateWellKnownSid
LookupPrivilegeValueW
ConvertStringSecurityDescriptorToSecurityDescriptorW
RpcStringBindingComposeW
RpcBindingFromStringBindingW
RpcStringFreeW RpcBindingSetOption
RpcBindingSetAuthInfoExW
RpcBindingFree
NdrClientCall2
NdrClientCall3
BCryptOpenAlgorithmProvider
BCryptSetProperty
BCryptGenerateSymmetricKey
BCryptDecrypt
BCryptDestroyKey
BCryptCloseAlgorithmProvider
BCryptGetProperty BCryptGenRandom
CoCreateInstance
CoInitializeEx
CoUninitialize CoInitializeSecurity
CoSetProxyBlanket
if >win7/server 2008 r2 { CreateDecompressor
CloseDecompressor Decompress
}

root@kitploit:~
И на этом первая половина задачи по анализу blacklotus завершена. 

============================================================================

Для второй половины

Вид ассемблера

![1](https://assets.kitploit.com/production/public/readmes/44337/f509798bf72f72025531efc98bbd0a850e571d003e3a39b7ac2e6438d1da93c8.png)

Вид псевдокода

![1](https://assets.kitploit.com/production/public/readmes/44337/23fafc5104114ff3d2086230e1be3d9b2dbe1660120b55ad100af0c8a12baec5.png)

Мы начнём разбор с функции some_hash()

============================================================================

Вид графа

![1](https://assets.kitploit.com/production/public/readmes/44337/2c8d738be9b2f025155521050ba0ea68aaeebd7cf3bd9a5c4fcd122c24722712.png)

Вид ассемблера

![1](https://assets.kitploit.com/production/public/readmes/44337/04fb6139172c8f4fab8898395d505ad40b8ba52051ca387a2ec93ffe56ff8674.png)

![2](https://assets.kitploit.com/production/public/readmes/44337/7133eb6348241a56009a6a0d1ce87c26a840bbbc2da99bd459b40c8f5654d366.png)

![3](https://assets.kitploit.com/production/public/readmes/44337/1f60aef395eccf029138d3ca7bcbccafd5328b5056bcae635deabadb8005e2c0.png)

Вид псевдокода

![1](https://assets.kitploit.com/production/public/readmes/44337/3ae95f232939daab4e4b2b68fa31d94150b4e9b69abd0cd324e5ecc4f8ffe14b.png)
Скачать инструмент