Гайд [Reverse-Engineering] Отлавливаем системные вызовы в инжекторе nelfo

Murasaki
Разработчик
Статус
Онлайн
Регистрация
18 Мар 2020
Сообщения
431
Реакции[?]
870
Поинты[?]
206K
Шалом, снова.
Беру подопытного из этой темы: *тык*
Я был крайне удивлён тем, что особо-то никто и не писал о своих успехах с этим крякми.
Решил сам глянуть, посмотреть шо да как устроено. Оказалось намного хитровыебаннее, чем я ожидал.
Эта статья могла бы выйти чуть пораньше не затупив я на одном месте, но начнём по порядку.
1. Обфускация кода
2. Системные вызовы х32
2.1. Даем пизды Патчим трюк с потоком
3. Нахождение "DLL"


1. Обфускация кода
Обфускация здесь состоит в том, чтобы сравнивать два регистра общегоназначения, затем в зависимости от вида джампа будь-то jne && je джампится на нужный шелл или же на другую проверку регистров, где тоже будет сидеть cmp и какой-нибудь джамп. Или же перейти на следующую инструкцию где уже сидит jmp, который джампит на другую проверку обфускатора (или опять же на шелл), и так вас будет кидать туда-сюда, периодически выполняя нужный программе код

Вот пример кода, который я описал только что

Пример джампа обфускатора.png
Код:
cmp eax, ebp
je meme_obf ; Проверка проходит, джампимся на meme_obf
jmp 0x8F1C7C

; some code

meme_obf:
cmp ebp, eax
jne 0x8F2B54 ; Проверка не проходит, не джампимся, идем к jmp
jmp 0x8F1C7C ; джамп на шелл
Не сказать, что эта обфускация вызвала у меня какие-то серьезные проблемы с анализом кода, ибо внимание я зацикливал не на трассировку кода, а на вызовы для инжекта.


2. Системные вызовы х32
Переходим к моей любимой части этого крякми. А именно системные вызовы. Зная, кто автор крякми несложно было догадаться, что скорее всего тут не будут вызываться функции из WinAPI (кроме GetProcAddress, он нужен для того чтобы взять адрес Wow64Transition).
Берем адрес Wow64Transition.png

Немного теории:

Возможно не все читающие эту статью знают о принципе работы системных вызовов в 32-битной среде.
В 64-битной было всё понятно, смотря лишь таблицу системных номеров в нтдлл.
А в 32-битной появляется какой-то колл.
Приведу пример простого системного вызова​
Код:
MOV EAX, 50 ; Системный номер = 50 = NtProtectVirtualMemory
MOV EDX, Wow64TransitionAddress
CALL EDX
RET 14
В EAX суется всеми нами известный системный номер, затем в EDX суем адрес Wow64Transition и вызываем его.
Wow64Transition делает джамп в дллку wow64cpu.dll где выполняется уже x64 код и уже там происходит системный вызов. Всё верно, для того чтобы совершить системный вызов в х32 программе надо перейти в х64-битную среду. И необязательно кстати сувать адрес Wow64Transition, можно обойтись и __KiFastSystemCall, суть его в том чтобы вызывать sysenter, по итогу системный вызов все равно будет выполнен, а в регистр EAX будет записан результат вызова (обычно 0, если все прошло хорошо, типо как с GetLastError логика)

Закончили с теорией, перейдем к системным вызовам в крякми.
Байт-код вызова регистра EDX: FF D2, с этим байткодом начинаем искать этот паттерн в крякми.
Находим 12 системных вызовов
Системные вызовы.png

Снизу вверх перечислю системные номера, которые я нашел:​
Форматирование (BB-код):
1. MOV EAX, 50 ; NtProtectVirtualMemory
2. MOV EAX, 3A ; NtWriteVirtualMemory
3. MOV EAX, D004 ; NtWaitForSingleObject
4. MOV EAX, D ; NtSetInformationThread
5. MOV EAX, 70052 ; NtResumeThread
6. MOV EAX, 25 ; NtQueryInformationThread
7. MOV EAX, 50 ; NtProtectVirtualMemory
8. MOV EAX, 26 ; NtOpenProcess
9. MOV EAX, 1E ; NtFreeVirtualMemory
10. MOV EAX, 60034 ; NtDelayExecution
11. MOV EAX, С1 ; NtCreateThreadEx
12. MOV EAX, 18 ; NtAllocateVirtualMemory
Однако, было еще одно место где используются системные вызовы. Но до ЕР оно заполнено 00 (После вызова ЕР это кстати все происходит, забыл просто написать)
Почему же заполнено 00? Да потому что в это место постоянно перезаписывается системный номер для дальнейшего системного вызова, понял я это из-за того что мой трамполайн хук исчез бесследно. Ещё что привлекло мое внимание это сам адрес, который сидит в EDX и вызывается. Да, там был Wow64Transition, однако он находился не на своем месте. По дефолту Wow64Transition находится в выделенной памяти ntdll, а здесь он находился не только вне нтдлл, да еще и вначале секции .data нашего крякми :) Теперь то становится понятно для чего брался адрес, после взятия адреса байты из Wow64Transition записывались в начало .data, первый по патерну CALL EDX в списке вызывал NtProtectVirtualMemory чтобы в оригинальном Wow64Transition поменять протект памяти в секции .data,и затем уже там выполнялись сами системные вызовы.


Т.к. место где перезаписывался постоянно системный номер был на одном и том же адресе, то ничего не мешало выйти на место, где совершается вызов


Самые внимательные возможно заметили, что уже не в первый раз мелькает адрес DWORD PTR DS:[C000B0] :) Он палился, когда мы брали адрес для Wow64Transition, а теперь он палится и перед вызовом нашего шеллкода. Если перейти к нему, то мы там как раз и увидим перезаписанный Wow64Transition.
Сами алгоритмы перезаписи системных номеров и Wow64Transition палить особо смысла нет, но те кто захочет посмотреть поставьте просто бряк на доступ в начало секции .data.

2.1. Патчим трюк с потоком
Ну здесь всё просто, если просмотреть список системных вызовов, которые я кидал до этого, то можно понять что в мануальном Wow64Transition закидывался системный номер 0xD с параметром 0x11 (ThreadHideFromDebugger) и потом несколько раз вызывался NtQueryInformationThread тоже с 0x11 параметром. Поэтому ставить мемори бряки == самоубийство для дебаггера
Но, вам ничего не мешает поставить ret в начале обоих функции, найдя их по паттерну FF D2 :)

3. Нахождение "DLL"
Изначальный инжектор пренадлежит Zer0Memory, сразу скажу для тех, кто ожидал здесь увидеть зафикшенную длл, никакой дллки в крякми нет и не будет, берется часть кода из экзешника с месседжбоксом и записывается в Target.exe
Есть одна проблема, которая мне покоя всё же не даёт и надеюсь получить ответ от автора в телеге, дело в том что 3A никогда не светился в том месте, где происходил вызов настоящего шеллкода с последующей заменой системного номера. Но если занопать место где лежит 3A, то инжекта не будет, а аппаратные бряки на доступ к нему ни в какую не палят доступ. Возможно проблема в моём билде винды, а возможно что я где-то пропустил важный момент и где-то происходил ещё один шеллкод (например в конце секции .data, ибо там частенько менялись байты).

ОБНОВЛЕНО:
Место где записывается память я нашёл, не мог найти из-за одного трюка нельфо, однако я про него вам не поведую :)

По итогу логику этого инжектора я понял (за исключением одного момента), очень понравилось разбирать этот крякми, надеюсь автор когда-нибудь выпустит ещё один подобный крякми, если появится время. Ну и вроде как я тут не все мемы успел расписать, ну ничо

Подписывайтесь на мой бложик:
Пожалуйста, авторизуйтесь для просмотра ссылки.

И ещё спасибо моей команде (easton, Arting) я вас люблю!!

nelfo57 <3

Всего доброго! :)

 
Последнее редактирование:
ima sippin lean
Забаненный
Статус
Оффлайн
Регистрация
6 Май 2020
Сообщения
495
Реакции[?]
380
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
произошел кряк вибс клаба
 
Пользователь
Статус
Оффлайн
Регистрация
12 Дек 2019
Сообщения
316
Реакции[?]
61
Поинты[?]
2K
Ничего не понял но очень интересно! Молодец колба!
 
Эксперт
Статус
Оффлайн
Регистрация
22 Мар 2020
Сообщения
2,191
Реакции[?]
484
Поинты[?]
3K
Шалом, снова.
Беру подопытного из этой темы: *тык*
Я был крайне удивлён тем, что особо-то никто и не писал о своих успехах с этим крякми.
Решил сам глянуть, посмотреть шо да как устроено. Оказалось намного хитровыебаннее, чем я ожидал.
Эта статья могла бы выйти чуть пораньше не затупив я на одном месте, но начнём по порядку.
1. Обфускация кода
2. Системные вызовы х32
2.1. Даем пизды Патчим трюк с потоком
3. Нахождение "DLL"


1. Обфускация кода
Обфускация здесь состоит в том, чтобы сравнивать два регистра общегоназначения, затем в зависимости от вида джампа будь-то jne && je джампится на нужный шелл или же на другую проверку регистров, где тоже будет сидеть cmp и какой-нибудь джамп. Или же перейти на следующую инструкцию где уже сидит jmp, который джампит на другую проверку обфускатора (или опять же на шелл), и так вас будет кидать туда-сюда, периодически выполняя нужный программе код

Вот пример кода, который я описал только что

Посмотреть вложение 179499
Код:
cmp eax, ebp
je meme_obf ; Проверка проходит, джампимся на meme_obf
jmp 0x8F1C7C

; some code

meme_obf:
cmp ebp, eax
jne 0x8F2B54 ; Проверка не проходит, не джампимся, идем к jmp
jmp 0x8F1C7C ; джамп на шелл
Не сказать, что эта обфускация вызвала у меня какие-то серьезные проблемы с анализом кода, ибо внимание я зацикливал не на трассировку кода, а на вызовы для инжекта.


2. Системные вызовы х32
Переходим к моей любимой части этого крякми. А именно системные вызовы. Зная, кто автор крякми несложно было догадаться, что скорее всего тут не будут вызываться функции из WinAPI (кроме GetProcAddress, он нужен для того чтобы взять адрес Wow64Transition).
Посмотреть вложение 179506

Немного теории:

Возможно не все читающие эту статью знают о принципе работы системных вызовов в 32-битной среде.
В 64-битной было всё понятно, смотря лишь таблицу системных номеров в нтдлл.
А в 32-битной появляется какой-то колл.
Приведу пример простого системного вызова​
Код:
MOV EAX, 50 ; Системный номер = 50 = NtProtectVirtualMemory
MOV EDX, Wow64TransitionAddress
CALL EDX
RET 14
В EAX суется всеми нами известный системный номер, затем в EDX суем адрес Wow64Transition и вызываем его.
Wow64Transition делает джамп в дллку wow64cpu.dll где выполняется уже x64 код и уже там происходит системный вызов. Всё верно, для того чтобы совершить системный вызов в х32 программе надо перейти в х64-битную среду. И необязательно кстати сувать адрес Wow64Transition, можно обойтись и __KiFastSystemCall, суть его в том чтобы вызывать sysenter, по итогу системный вызов все равно будет выполнен, а в регистр EAX будет записан результат вызова (обычно 0, если все прошло хорошо, типо как с GetLastError логика)

Закончили с теорией, перейдем к системным вызовам в крякми.
Байт-код вызова регистра EDX: FF D2, с этим байткодом начинаем искать этот паттерн в крякми.
Находим 12 системных вызовов
Посмотреть вложение 179509

Снизу вверх перечислю системные номера, которые я нашел:​
Форматирование (BB-код):
1. MOV EAX, 50 ; NtProtectVirtualMemory
2. MOV EAX, 3A ; NtWriteVirtualMemory
3. MOV EAX, D004 ; NtWaitForSingleObject
4. MOV EAX, D ; NtSetInformationThread
5. MOV EAX, 70052 ; NtResumeThread
6. MOV EAX, 25 ; NtQueryInformationThread
7. MOV EAX, 50 ; NtProtectVirtualMemory
8. MOV EAX, 26 ; NtOpenProcess
9. MOV EAX, 1E ; NtFreeVirtualMemory
10. MOV EAX, 60034 ; NtDelayExecution
11. MOV EAX, С1 ; NtCreateThreadEx
12. MOV EAX, 18 ; NtAllocateVirtualMemory
Однако, было еще одно место где используются системные вызовы. Но до ЕР оно заполнено 00 (После вызова ЕР это кстати все происходит, забыл просто написать)
Почему же заполнено 00? Да потому что в это место постоянно перезаписывается системный номер для дальнейшего системного вызова, понял я это из-за того что мой трамполайн хук исчез бесследно. Ещё что привлекло мое внимание это сам адрес, который сидит в EDX и вызывается. Да, там был Wow64Transition, однако он находился не на своем месте. По дефолту Wow64Transition находится в выделенной памяти ntdll, а здесь он находился не только вне нтдлл, да еще и вначале секции .data нашего крякми :) Теперь то становится понятно для чего брался адрес, после взятия адреса байты из Wow64Transition записывались в начало .data, первый по патерну CALL EDX в списке вызывал NtProtectVirtualMemory чтобы в оригинальном Wow64Transition поменять протект памяти в секции .data,и затем уже там выполнялись сами системные вызовы.


Т.к. место где перезаписывался постоянно системный номер был на одном и том же адресе, то ничего не мешало выйти на место, где совершается вызов


Самые внимательные возможно заметили, что уже не в первый раз мелькает адрес DWORD PTR DS:[C000B0] :) Он палился, когда мы брали адрес для Wow64Transition, а теперь он палится и перед вызовом нашего шеллкода. Если перейти к нему, то мы там как раз и увидим перезаписанный Wow64Transition.
Сами алгоритмы перезаписи системных номеров и Wow64Transition палить особо смысла нет, но те кто захочет посмотреть поставьте просто бряк на доступ в начало секции .data.

2.1. Патчим трюк с потоком
Ну здесь всё просто, если просмотреть список системных вызовов, которые я кидал до этого, то можно понять что в мануальном Wow64Transition закидывался системный номер 0xD с параметром 0x11 (ThreadHideFromDebugger) и потом несколько раз вызывался NtQueryInformationThread тоже с 0x11 параметром. Поэтому ставить мемори бряки == самоубийство для дебаггера
Но, вам ничего не мешает поставить ret в начале обоих функции, найдя их по паттерну FF D2 :)

3. Нахождение "DLL"
Изначальный инжектор пренадлежит Zer0Memory, сразу скажу для тех, кто ожидал здесь увидеть зафикшенную длл, никакой дллки в крякми нет и не будет, берется часть кода из экзешника с месседжбоксом и записывается в Target.exe
Есть одна проблема, которая мне покоя всё же не даёт и надеюсь получить ответ от автора в телеге, дело в том что 3A никогда не светился в том месте, где происходил вызов настоящего шеллкода с последующей заменой системного номера. Но если занопать место где лежит 3A, то инжекта не будет, а аппаратные бряки на доступ к нему ни в какую не палят доступ. Возможно проблема в моём билде винды, а возможно что я где-то пропустил важный момент и где-то происходил ещё один шеллкод (например в конце секции .data, ибо там частенько менялись байты).

ОБНОВЛЕНО:
Место где записывается память я нашёл, не мог найти из-за одного трюка нельфо, однако я про него вам не поведую :)

По итогу логику этого инжектора я понял (за исключением одного момента), очень понравилось разбирать этот крякми, надеюсь автор когда-нибудь выпустит ещё один подобный крякми, если появится время. Ну и вроде как я тут не все мемы успел расписать, ну ничо

Подписывайтесь на мой бложик:
Пожалуйста, авторизуйтесь для просмотра ссылки.

И ещё спасибо моей команде (easton, Arting) я вас люблю!!

nelfo57 <3

Всего доброго! :)

очередная полезная тема от колби, красава!
 
Keep Ev0lving, Stay Fatal
Эксперт
Статус
Оффлайн
Регистрация
6 Фев 2018
Сообщения
1,550
Реакции[?]
586
Поинты[?]
102K
Шалом, снова.
Беру подопытного из этой темы: *тык*
Я был крайне удивлён тем, что особо-то никто и не писал о своих успехах с этим крякми.
Решил сам глянуть, посмотреть шо да как устроено. Оказалось намного хитровыебаннее, чем я ожидал.
Эта статья могла бы выйти чуть пораньше не затупив я на одном месте, но начнём по порядку.
1. Обфускация кода
2. Системные вызовы х32
2.1. Даем пизды Патчим трюк с потоком
3. Нахождение "DLL"


1. Обфускация кода
Обфускация здесь состоит в том, чтобы сравнивать два регистра общегоназначения, затем в зависимости от вида джампа будь-то jne && je джампится на нужный шелл или же на другую проверку регистров, где тоже будет сидеть cmp и какой-нибудь джамп. Или же перейти на следующую инструкцию где уже сидит jmp, который джампит на другую проверку обфускатора (или опять же на шелл), и так вас будет кидать туда-сюда, периодически выполняя нужный программе код

Вот пример кода, который я описал только что

Посмотреть вложение 179499
Код:
cmp eax, ebp
je meme_obf ; Проверка проходит, джампимся на meme_obf
jmp 0x8F1C7C

; some code

meme_obf:
cmp ebp, eax
jne 0x8F2B54 ; Проверка не проходит, не джампимся, идем к jmp
jmp 0x8F1C7C ; джамп на шелл
Не сказать, что эта обфускация вызвала у меня какие-то серьезные проблемы с анализом кода, ибо внимание я зацикливал не на трассировку кода, а на вызовы для инжекта.


2. Системные вызовы х32
Переходим к моей любимой части этого крякми. А именно системные вызовы. Зная, кто автор крякми несложно было догадаться, что скорее всего тут не будут вызываться функции из WinAPI (кроме GetProcAddress, он нужен для того чтобы взять адрес Wow64Transition).
Посмотреть вложение 179506

Немного теории:

Возможно не все читающие эту статью знают о принципе работы системных вызовов в 32-битной среде.
В 64-битной было всё понятно, смотря лишь таблицу системных номеров в нтдлл.
А в 32-битной появляется какой-то колл.
Приведу пример простого системного вызова​
Код:
MOV EAX, 50 ; Системный номер = 50 = NtProtectVirtualMemory
MOV EDX, Wow64TransitionAddress
CALL EDX
RET 14
В EAX суется всеми нами известный системный номер, затем в EDX суем адрес Wow64Transition и вызываем его.
Wow64Transition делает джамп в дллку wow64cpu.dll где выполняется уже x64 код и уже там происходит системный вызов. Всё верно, для того чтобы совершить системный вызов в х32 программе надо перейти в х64-битную среду. И необязательно кстати сувать адрес Wow64Transition, можно обойтись и __KiFastSystemCall, суть его в том чтобы вызывать sysenter, по итогу системный вызов все равно будет выполнен, а в регистр EAX будет записан результат вызова (обычно 0, если все прошло хорошо, типо как с GetLastError логика)

Закончили с теорией, перейдем к системным вызовам в крякми.
Байт-код вызова регистра EDX: FF D2, с этим байткодом начинаем искать этот паттерн в крякми.
Находим 12 системных вызовов
Посмотреть вложение 179509

Снизу вверх перечислю системные номера, которые я нашел:​
Форматирование (BB-код):
1. MOV EAX, 50 ; NtProtectVirtualMemory
2. MOV EAX, 3A ; NtWriteVirtualMemory
3. MOV EAX, D004 ; NtWaitForSingleObject
4. MOV EAX, D ; NtSetInformationThread
5. MOV EAX, 70052 ; NtResumeThread
6. MOV EAX, 25 ; NtQueryInformationThread
7. MOV EAX, 50 ; NtProtectVirtualMemory
8. MOV EAX, 26 ; NtOpenProcess
9. MOV EAX, 1E ; NtFreeVirtualMemory
10. MOV EAX, 60034 ; NtDelayExecution
11. MOV EAX, С1 ; NtCreateThreadEx
12. MOV EAX, 18 ; NtAllocateVirtualMemory
Однако, было еще одно место где используются системные вызовы. Но до ЕР оно заполнено 00 (После вызова ЕР это кстати все происходит, забыл просто написать)
Почему же заполнено 00? Да потому что в это место постоянно перезаписывается системный номер для дальнейшего системного вызова, понял я это из-за того что мой трамполайн хук исчез бесследно. Ещё что привлекло мое внимание это сам адрес, который сидит в EDX и вызывается. Да, там был Wow64Transition, однако он находился не на своем месте. По дефолту Wow64Transition находится в выделенной памяти ntdll, а здесь он находился не только вне нтдлл, да еще и вначале секции .data нашего крякми :) Теперь то становится понятно для чего брался адрес, после взятия адреса байты из Wow64Transition записывались в начало .data, первый по патерну CALL EDX в списке вызывал NtProtectVirtualMemory чтобы в оригинальном Wow64Transition поменять протект памяти в секции .data,и затем уже там выполнялись сами системные вызовы.


Т.к. место где перезаписывался постоянно системный номер был на одном и том же адресе, то ничего не мешало выйти на место, где совершается вызов


Самые внимательные возможно заметили, что уже не в первый раз мелькает адрес DWORD PTR DS:[C000B0] :) Он палился, когда мы брали адрес для Wow64Transition, а теперь он палится и перед вызовом нашего шеллкода. Если перейти к нему, то мы там как раз и увидим перезаписанный Wow64Transition.
Сами алгоритмы перезаписи системных номеров и Wow64Transition палить особо смысла нет, но те кто захочет посмотреть поставьте просто бряк на доступ в начало секции .data.

2.1. Патчим трюк с потоком
Ну здесь всё просто, если просмотреть список системных вызовов, которые я кидал до этого, то можно понять что в мануальном Wow64Transition закидывался системный номер 0xD с параметром 0x11 (ThreadHideFromDebugger) и потом несколько раз вызывался NtQueryInformationThread тоже с 0x11 параметром. Поэтому ставить мемори бряки == самоубийство для дебаггера
Но, вам ничего не мешает поставить ret в начале обоих функции, найдя их по паттерну FF D2 :)

3. Нахождение "DLL"
Изначальный инжектор пренадлежит Zer0Memory, сразу скажу для тех, кто ожидал здесь увидеть зафикшенную длл, никакой дллки в крякми нет и не будет, берется часть кода из экзешника с месседжбоксом и записывается в Target.exe
Есть одна проблема, которая мне покоя всё же не даёт и надеюсь получить ответ от автора в телеге, дело в том что 3A никогда не светился в том месте, где происходил вызов настоящего шеллкода с последующей заменой системного номера. Но если занопать место где лежит 3A, то инжекта не будет, а аппаратные бряки на доступ к нему ни в какую не палят доступ. Возможно проблема в моём билде винды, а возможно что я где-то пропустил важный момент и где-то происходил ещё один шеллкод (например в конце секции .data, ибо там частенько менялись байты).

ОБНОВЛЕНО:
Место где записывается память я нашёл, не мог найти из-за одного трюка нельфо, однако я про него вам не поведую :)

По итогу логику этого инжектора я понял (за исключением одного момента), очень понравилось разбирать этот крякми, надеюсь автор когда-нибудь выпустит ещё один подобный крякми, если появится время. Ну и вроде как я тут не все мемы успел расписать, ну ничо

Подписывайтесь на мой бложик:
Пожалуйста, авторизуйтесь для просмотра ссылки.

И ещё спасибо моей команде (easton, Arting) я вас люблю!!

nelfo57 <3

Всего доброго! :)

 
midnight.im
Администратор
Статус
Оффлайн
Регистрация
1 Июл 2015
Сообщения
1,648
Реакции[?]
2,172
Поинты[?]
162K
так этот чел же в вашей тусовке, вы че друг друга крякаете
а где ты видишь кряк? это анализ. человеку интересно изучать защиту. он описал приколы которые нашел. кому нужно тот можешь подцепить для себя некую информацию для дальнейшего использования в своих проектах
 
Сверху Снизу