Так недавно я изучал языки программирования низкого уровня (такие как Assembly, который, по моему мнению, является просто символическим двоичным кодом), и наткнулся на Shellcoding (например, «\ x4D …» и т. Д.). Я обнаружил, что вы можете ввести Shellcode в приложение C / C ++, а затем выполнить его — мой вопрос, возможно ли сгенерировать Shellcode из существующего приложения exe и затем использовать этот сгенерированный Shellcode в приложении C / C ++? Я неправильно понял возможности Shellcoding? Большое спасибо — человек с очень ограниченными знаниями о программировании низкого уровня
Можно ли сгенерировать Shellcode из существующего приложения exe, а затем использовать этот сгенерированный Shellcode в приложении C / C ++
Ответ: Нет. Shellcode не зависит от базы, исполняемый PE-файл имеет огромное количество заголовков и т. Д., Вы не можете выполнить его до выполнения некоторых действий /
Shellcode — это очень большой вопрос.
Прежде всего, вам нужно знать, что адреса функций внешних библиотек, таких как kernel32, user32 libs и т. Д., Хранятся в таблице адресов импорта, которая заполняется загрузчиком windows во время запуска. Вся работа с памятью осуществляется по адресам, которые вычисляются на этапе компиляции. Так что вам нужно найти адреса самостоятельно.
Для вызова функций из шеллкода у вас должен быть собственный загрузчик адресов функций. Этот загрузчик должен загрузить библиотеку kernel32.dll, найти функцию GetProcAddress и заполнить IAT
Вы не знаете, по какому адресу будет загружен ваш шелл-код, вы можете узнать его по такому коду, вызывая «delta-offset»
call delta
delta:
pop ebp
sub ebp,offset delta
Теперь в ebp смещение к реальным адресам, поэтому для получения переменной адреса функции необходимо добавить смещение, например:
lea eax, [variable]
add eax, ebp; adding a delta-offset
mov ecx, dword ptr DS:[eax]
Чтобы скомпилировать код для будущего использования, вы должны использовать что-то вроде FASM, после компиляции используйте редактор WinHex -> copy -> copy all -> GREP C source
И вы получите что-то вроде «\ x00 \ x28» и т. Д., Чтобы вызвать его, вам нужно установить права на выполнение для вашего массива шелл-кода и изменить EIP с помощью таких обработчиков команд, как jmp / call / etc
Есть пример, который показывает в Windows-системе Hello, World MessageBox
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <windows.h>int
main(void)
{
char *shellcode = "\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b""\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09""\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d""\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03""\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81""\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04""\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03""\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3""\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68""\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68""\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9""\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65""\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01""\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68""\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68""\x72\x6c\x64\x21\x68\x6f\x20\x57\x6f\x68""\x48\x65\x6c\x6c\x8b\xcc\x57\x57\x51\x57""\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c""\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78""\x69\x74\x54\x53\xff\xd6\x57\xff\xd0";
DWORD why_must_this_variable;
BOOL ret = VirtualProtect (shellcode, strlen(shellcode),
PAGE_EXECUTE_READWRITE, &why_must_this_variable);
if (!ret) {
printf ("VirtualProtect\n");
return EXIT_FAILURE;
}
printf("strlen(shellcode)=%d\n", strlen(shellcode));
((void (*)(void))shellcode)();
return EXIT_SUCCESS;
}
Вы, наверное, ищете алгоритм RunPE. Этот алгоритм может выполнять PE исполняемый файл внутри другого. Вы открываете другой процесс, копируете разделы, заполняете IAT-таблицу и возобновляете целевой процесс с новой точки входа. Это метод ввода кода, использованный моей вредоносной программой. Поэтому я не буду объяснять, как это реализовать
Shellcode это машинный код, который используется в качестве полезной нагрузки эксплойта (например, переполнение буфера). В зависимости от эксплойта, с которым он используется, он может иметь ограничения, такие как максимальная длина или определенные байтовые значения (например, ноль), которые не допускаются. Не существует однозначного ответа на вопрос, каким может быть шеллкод.
В общем, хотя: да, в принципе возможно встроить полную программу в шеллкод. Он может принимать форму небольшой оболочки (возможно, написанной от руки на ассемблере), которая записывает программу в новую .exe
файл, а затем запускает его, или он может использовать более сложные методы, чтобы заменить текущую программу в памяти. Вероятно, существуют автоматизированные инструменты для создания такого шелл-кода, хотя я не знаю ничего конкретного.
Однако тон вашего вопроса заставляет меня думать, что вы, возможно, неправильно понимаете что-то важное:
Я обнаружил, что вы можете ввести Shellcode в приложение C / C ++ и затем выполнить его
Это ошибка, а не фича. Возможность вставлять новый код в работающую программу, где эта программа специально не предназначена для этого, является серьезным недостатком безопасности. Подобные вещи были причиной многих нарушений безопасности в течение десятилетий, и разработчики тратят немало усилий, пытаясь предотвратить это.
Если возможно ввести шеллкод в программу, программа не работает.