| 87 | | logmsg(LOG_NOISY, 1, "CPU emulation - Possible start of shellcode detected at offset %u.\n", offset); |
|---|
| | 145 | logmsg(LOG_NOISY, 1, "CPU Emulation - Possible start of shellcode detected at offset %u.\n", offset); |
|---|
| | 146 | |
|---|
| | 147 | emu_free(e); |
|---|
| | 148 | |
|---|
| | 149 | // prepare emu for running shellcode |
|---|
| | 150 | e = emu_new(); |
|---|
| | 151 | |
|---|
| | 152 | if ((opts.scode = malloc(attack->a_conn.payload.size)) == NULL) { |
|---|
| | 153 | logmsg(LOG_ERR, 1, "CPU Emulation Error - Unable to allocate memory: %s\n", strerror(errno)); |
|---|
| | 154 | exit(EXIT_FAILURE); |
|---|
| | 155 | } |
|---|
| | 156 | memcpy(opts.scode, attack->a_conn.payload.data, attack->a_conn.payload.size); |
|---|
| | 157 | |
|---|
| | 158 | opts.offset = offset; |
|---|
| | 159 | opts.size = attack->a_conn.payload.size; |
|---|
| | 160 | |
|---|
| | 161 | // set registers to the initial values |
|---|
| | 162 | struct emu_cpu *cpu = emu_cpu_get(e); |
|---|
| | 163 | struct emu_memory *mem = emu_memory_get(e); |
|---|
| | 164 | |
|---|
| | 165 | int j; |
|---|
| | 166 | for ( j=0;j<8;j++ ) emu_cpu_reg32_set(cpu,j , 0); |
|---|
| | 167 | |
|---|
| | 168 | emu_memory_write_dword(mem, 0xef787c3c, 4711); |
|---|
| | 169 | emu_memory_write_dword(mem, 0x0, 4711); |
|---|
| | 170 | emu_memory_write_dword(mem, 0x00416f9a, 4711); |
|---|
| | 171 | emu_memory_write_dword(mem, 0x0044fcf7, 4711); |
|---|
| | 172 | emu_memory_write_dword(mem, 0x00001265, 4711); |
|---|
| | 173 | emu_memory_write_dword(mem, 0x00002583, 4711); |
|---|
| | 174 | emu_memory_write_dword(mem, 0x00e000de, 4711); |
|---|
| | 175 | emu_memory_write_dword(mem, 0x01001265, 4711); |
|---|
| | 176 | emu_memory_write_dword(mem, 0x8a000066, 4711); |
|---|
| | 177 | |
|---|
| | 178 | // set flags |
|---|
| | 179 | emu_cpu_eflags_set(cpu, 0); |
|---|
| | 180 | |
|---|
| | 181 | // write code to offset |
|---|
| | 182 | int static_offset = CODE_OFFSET; |
|---|
| | 183 | emu_memory_write_block(mem, static_offset, opts.scode, opts.size); |
|---|
| | 184 | |
|---|
| | 185 | // set eip to code |
|---|
| | 186 | emu_cpu_eip_set(emu_cpu_get(e), static_offset + opts.offset); |
|---|
| | 187 | emu_cpu_reg32_set(emu_cpu_get(e), esp, 0x0012fe98); |
|---|
| | 188 | |
|---|
| | 189 | // run code in emulated CPU |
|---|
| | 190 | run(e); |
|---|
| | 191 | |
|---|
| | 200 | |
|---|
| | 201 | |
|---|
| | 202 | // run detected asm code on emulated CPU |
|---|
| | 203 | int run(struct emu *e) { |
|---|
| | 204 | int j, ret; |
|---|
| | 205 | uint32_t eipsave; |
|---|
| | 206 | struct emu_cpu *cpu = emu_cpu_get(e); |
|---|
| | 207 | struct emu_env *env = emu_env_new(e); |
|---|
| | 208 | |
|---|
| | 209 | if (env == NULL) { |
|---|
| | 210 | logmsg(LOG_ERR, 1, "CPU Emulation Error - %s.\n", emu_strerror(e)); |
|---|
| | 211 | return -1; |
|---|
| | 212 | } |
|---|
| | 213 | |
|---|
| | 214 | logmsg(LOG_NOISY, 1, "CPU Emulation - Preparing function hooks.\n"); |
|---|
| | 215 | |
|---|
| | 216 | emu_env_w32_export_hook(env, "ExitProcess", user_hook_ExitProcess, NULL); |
|---|
| | 217 | emu_env_w32_export_hook(env, "ExitThread", user_hook_ExitThread, NULL); |
|---|
| | 218 | emu_env_w32_export_hook(env, "CreateProcessA", user_hook_CreateProcess, NULL); |
|---|
| | 219 | emu_env_w32_export_hook(env, "WaitForSingleObject", user_hook_WaitForSingleObject, NULL); |
|---|
| | 220 | |
|---|
| | 221 | emu_env_w32_load_dll(env->env.win,"ws2_32.dll"); |
|---|
| | 222 | emu_env_w32_export_hook(env, "accept", user_hook_accept, NULL); |
|---|
| | 223 | emu_env_w32_export_hook(env, "bind", user_hook_bind, NULL); |
|---|
| | 224 | emu_env_w32_export_hook(env, "closesocket", user_hook_closesocket, NULL); |
|---|
| | 225 | emu_env_w32_export_hook(env, "connect", user_hook_connect, NULL); |
|---|
| | 226 | emu_env_w32_export_hook(env, "listen", user_hook_listen, NULL); |
|---|
| | 227 | emu_env_w32_export_hook(env, "recv", user_hook_recv, NULL); |
|---|
| | 228 | emu_env_w32_export_hook(env, "send", user_hook_send, NULL); |
|---|
| | 229 | emu_env_w32_export_hook(env, "socket", user_hook_socket, NULL); |
|---|
| | 230 | emu_env_w32_export_hook(env, "WSASocketA", user_hook_WSASocket, NULL); |
|---|
| | 231 | |
|---|
| | 232 | opts.steps = 1000000; |
|---|
| | 233 | |
|---|
| | 234 | // run the code |
|---|
| | 235 | logmsg(LOG_NOISY, 1, "CPU Emulation - Running code...\n"); |
|---|
| | 236 | |
|---|
| | 237 | struct emu_hashtable *eh = NULL; |
|---|
| | 238 | for (eipsave=0, j=0;j<opts.steps;j++ ) { |
|---|
| | 239 | if (cpu->repeat_current_instr == false) eipsave = emu_cpu_eip_get(emu_cpu_get(e)); |
|---|
| | 240 | |
|---|
| | 241 | struct emu_env_hook *hook = NULL; |
|---|
| | 242 | |
|---|
| | 243 | ret = 0; |
|---|
| | 244 | |
|---|
| | 245 | if ((hook = emu_env_w32_eip_check(env)) != NULL) { |
|---|
| | 246 | if (hook->hook.win->fnhook == NULL) { |
|---|
| | 247 | logmsg(LOG_DEBUG, 1, "CPU Emulation - Unhooked call to %s.\n", hook->hook.win->fnname); |
|---|
| | 248 | break; |
|---|
| | 249 | } |
|---|
| | 250 | } else { |
|---|
| | 251 | if ((ret = emu_cpu_parse(emu_cpu_get(e))) == -1) { |
|---|
| | 252 | logmsg(LOG_WARN, 1, "CPU Emulation Warning - CPU Error: %s", emu_strerror(e)); |
|---|
| | 253 | break; |
|---|
| | 254 | } |
|---|
| | 255 | if (log_level == LOG_DEBUG) { |
|---|
| | 256 | emu_log_level_set(emu_logging_get(e),EMU_LOG_DEBUG); |
|---|
| | 257 | logDebug(e, "%s\n", cpu->instr_string); |
|---|
| | 258 | emu_log_level_set(emu_logging_get(e),EMU_LOG_NONE); |
|---|
| | 259 | } |
|---|
| | 260 | } |
|---|
| | 261 | } |
|---|
| | 262 | if (eh != NULL) emu_hashtable_free(eh); |
|---|
| | 263 | |
|---|
| | 264 | return 0; |
|---|
| | 265 | } |
|---|
| | 266 | |
|---|
| | 267 | |
|---|
| | 268 | // (W32 API) function hooks |
|---|
| | 269 | uint32_t user_hook_ExitProcess(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 270 | va_list vl; |
|---|
| | 271 | int exitcode; |
|---|
| | 272 | |
|---|
| | 273 | va_start(vl, hook); |
|---|
| | 274 | |
|---|
| | 275 | exitcode = va_arg(vl, int); |
|---|
| | 276 | |
|---|
| | 277 | va_end(vl); |
|---|
| | 278 | |
|---|
| | 279 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking ExitProcess() call.\n"); |
|---|
| | 280 | |
|---|
| | 281 | opts.steps = 0; |
|---|
| | 282 | return 0; |
|---|
| | 283 | } |
|---|
| | 284 | |
|---|
| | 285 | |
|---|
| | 286 | uint32_t user_hook_ExitThread(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 287 | va_list vl; |
|---|
| | 288 | int exitcode; |
|---|
| | 289 | |
|---|
| | 290 | va_start(vl, hook); |
|---|
| | 291 | |
|---|
| | 292 | exitcode = va_arg(vl, int); |
|---|
| | 293 | |
|---|
| | 294 | va_end(vl); |
|---|
| | 295 | |
|---|
| | 296 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking ExitThread() call.\n"); |
|---|
| | 297 | |
|---|
| | 298 | opts.steps = 0; |
|---|
| | 299 | return 0; |
|---|
| | 300 | |
|---|
| | 301 | } |
|---|
| | 302 | |
|---|
| | 303 | uint32_t user_hook_socket(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 304 | va_list vl; |
|---|
| | 305 | int domain, type, protocol; |
|---|
| | 306 | |
|---|
| | 307 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking socket() call.\n"); |
|---|
| | 308 | |
|---|
| | 309 | va_start(vl, hook); |
|---|
| | 310 | |
|---|
| | 311 | domain = va_arg(vl, int); |
|---|
| | 312 | type = va_arg(vl, int); |
|---|
| | 313 | protocol = va_arg(vl, int); |
|---|
| | 314 | |
|---|
| | 315 | va_end(vl); |
|---|
| | 316 | |
|---|
| | 317 | return socket(domain, type, protocol); |
|---|
| | 318 | } |
|---|
| | 319 | |
|---|
| | 320 | |
|---|
| | 321 | |
|---|
| | 322 | uint32_t user_hook_bind(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 323 | va_list vl; |
|---|
| | 324 | int s; |
|---|
| | 325 | struct sockaddr *saddr; |
|---|
| | 326 | socklen_t saddrlen; |
|---|
| | 327 | struct sockaddr_in *si; |
|---|
| | 328 | |
|---|
| | 329 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking bind() call.\n"); |
|---|
| | 330 | |
|---|
| | 331 | va_start(vl, hook); |
|---|
| | 332 | |
|---|
| | 333 | s = va_arg(vl, int); |
|---|
| | 334 | saddr = va_arg(vl, struct sockaddr *); |
|---|
| | 335 | saddrlen = va_arg(vl, socklen_t); |
|---|
| | 336 | |
|---|
| | 337 | if (opts.override.bind.host != NULL) { |
|---|
| | 338 | si = (struct sockaddr_in *) saddr; |
|---|
| | 339 | si->sin_addr.s_addr = inet_addr(opts.override.bind.host); |
|---|
| | 340 | } |
|---|
| | 341 | |
|---|
| | 342 | if (opts.override.connect.port > 0) { |
|---|
| | 343 | si = (struct sockaddr_in *) saddr; |
|---|
| | 344 | si->sin_port = htons(opts.override.bind.port); |
|---|
| | 345 | } |
|---|
| | 346 | |
|---|
| | 347 | va_end(vl); |
|---|
| | 348 | |
|---|
| | 349 | return bind(s, saddr, saddrlen); |
|---|
| | 350 | } |
|---|
| | 351 | |
|---|
| | 352 | |
|---|
| | 353 | uint32_t user_hook_connect(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 354 | va_list vl; |
|---|
| | 355 | int s; |
|---|
| | 356 | struct sockaddr *saddr; |
|---|
| | 357 | struct sockaddr_in *si; |
|---|
| | 358 | socklen_t saddrlen; |
|---|
| | 359 | |
|---|
| | 360 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking connect() call.\n"); |
|---|
| | 361 | |
|---|
| | 362 | va_start(vl, hook); |
|---|
| | 363 | |
|---|
| | 364 | s = va_arg(vl, int); |
|---|
| | 365 | saddr = va_arg(vl, struct sockaddr *); |
|---|
| | 366 | |
|---|
| | 367 | if (opts.override.connect.host != NULL) { |
|---|
| | 368 | si = (struct sockaddr_in *) saddr; |
|---|
| | 369 | si->sin_addr.s_addr = inet_addr(opts.override.connect.host); |
|---|
| | 370 | } |
|---|
| | 371 | |
|---|
| | 372 | if (opts.override.connect.port > 0) { |
|---|
| | 373 | si = (struct sockaddr_in *) saddr; |
|---|
| | 374 | si->sin_port = htons(opts.override.connect.port); |
|---|
| | 375 | } |
|---|
| | 376 | |
|---|
| | 377 | saddrlen = va_arg(vl, socklen_t); |
|---|
| | 378 | |
|---|
| | 379 | va_end(vl); |
|---|
| | 380 | |
|---|
| | 381 | return connect(s, saddr, saddrlen); |
|---|
| | 382 | } |
|---|
| | 383 | |
|---|
| | 384 | uint32_t user_hook_WaitForSingleObject(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 385 | va_list vl; |
|---|
| | 386 | int32_t hHandle; |
|---|
| | 387 | int status; |
|---|
| | 388 | |
|---|
| | 389 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking WaitForSingleObject() call.\n"); |
|---|
| | 390 | |
|---|
| | 391 | va_start(vl, hook); |
|---|
| | 392 | |
|---|
| | 393 | hHandle = va_arg(vl, int32_t); |
|---|
| | 394 | va_arg(vl, int32_t); |
|---|
| | 395 | |
|---|
| | 396 | va_end(vl); |
|---|
| | 397 | |
|---|
| | 398 | for(;;) { |
|---|
| | 399 | if (waitpid(hHandle, &status, WNOHANG) != 0) break; |
|---|
| | 400 | sleep(1); |
|---|
| | 401 | } |
|---|
| | 402 | |
|---|
| | 403 | return 0; |
|---|
| | 404 | } |
|---|
| | 405 | |
|---|
| | 406 | uint32_t user_hook_WSASocket(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 407 | va_list vl; |
|---|
| | 408 | int domain, type, protocol; |
|---|
| | 409 | |
|---|
| | 410 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking WSASocket() call.\n"); |
|---|
| | 411 | |
|---|
| | 412 | va_start(vl, hook); |
|---|
| | 413 | |
|---|
| | 414 | domain = va_arg(vl, int); |
|---|
| | 415 | type = va_arg(vl, int); |
|---|
| | 416 | protocol = va_arg(vl, int); |
|---|
| | 417 | va_arg(vl, int); |
|---|
| | 418 | va_arg(vl, int); |
|---|
| | 419 | va_arg(vl, int); |
|---|
| | 420 | |
|---|
| | 421 | va_end(vl); |
|---|
| | 422 | |
|---|
| | 423 | return socket(domain, type, protocol); |
|---|
| | 424 | } |
|---|
| | 425 | |
|---|
| | 426 | uint32_t user_hook_CreateProcess(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 427 | va_list vl; |
|---|
| | 428 | char *pszCmdLine; |
|---|
| | 429 | STARTUPINFO *psiStartInfo; |
|---|
| | 430 | PROCESS_INFORMATION *pProcInfo; |
|---|
| | 431 | |
|---|
| | 432 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking CreateProcess() call.\n"); |
|---|
| | 433 | |
|---|
| | 434 | va_start(vl, hook); |
|---|
| | 435 | |
|---|
| | 436 | va_arg(vl, char *); // pszImageName |
|---|
| | 437 | pszCmdLine = va_arg(vl, char *); |
|---|
| | 438 | va_arg(vl, void *); // psaProcess |
|---|
| | 439 | va_arg(vl, void *); // psaThread |
|---|
| | 440 | va_arg(vl, char *); // fInheritHandles |
|---|
| | 441 | va_arg(vl, uint32_t); // fdwCreate |
|---|
| | 442 | va_arg(vl, void *); // pvEnvironment |
|---|
| | 443 | va_arg(vl, char *); // pszCurDir |
|---|
| | 444 | psiStartInfo = va_arg(vl, STARTUPINFO *); |
|---|
| | 445 | pProcInfo = va_arg(vl, PROCESS_INFORMATION *); |
|---|
| | 446 | |
|---|
| | 447 | va_end(vl); |
|---|
| | 448 | |
|---|
| | 449 | if (pszCmdLine && strncasecmp(pszCmdLine, "cmd", 3) == 0) { |
|---|
| | 450 | pid_t pid; |
|---|
| | 451 | |
|---|
| | 452 | logmsg(LOG_NOISY, 1, "CPU Emulation - Forking connection handler.\n"); |
|---|
| | 453 | if ((pid = fork()) == 0) { |
|---|
| | 454 | // child code |
|---|
| | 455 | dup2(psiStartInfo->hStdInput, fileno(stdin)); |
|---|
| | 456 | dup2(psiStartInfo->hStdOutput, fileno(stdout)); |
|---|
| | 457 | dup2(psiStartInfo->hStdError, fileno(stderr)); |
|---|
| | 458 | |
|---|
| | 459 | system("/bin/sh -c \"cd ~/.wine/drive_c/; wine 'c:\\windows\\system32\\cmd_orig.exe' \""); |
|---|
| | 460 | |
|---|
| | 461 | exit(EXIT_SUCCESS); |
|---|
| | 462 | } else { |
|---|
| | 463 | // parent code |
|---|
| | 464 | pProcInfo->hProcess = pid; |
|---|
| | 465 | } |
|---|
| | 466 | } |
|---|
| | 467 | return 1; |
|---|
| | 468 | } |
|---|
| | 469 | |
|---|
| | 470 | uint32_t user_hook_accept(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 471 | va_list vl; |
|---|
| | 472 | int s; |
|---|
| | 473 | struct sockaddr *saddr; |
|---|
| | 474 | socklen_t *saddrlen; |
|---|
| | 475 | |
|---|
| | 476 | |
|---|
| | 477 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking accept() call.\n"); |
|---|
| | 478 | |
|---|
| | 479 | va_start(vl, hook); |
|---|
| | 480 | |
|---|
| | 481 | s = va_arg(vl, int); |
|---|
| | 482 | saddr = va_arg(vl, struct sockaddr *); |
|---|
| | 483 | saddrlen = va_arg(vl, socklen_t *); |
|---|
| | 484 | |
|---|
| | 485 | va_end(vl); |
|---|
| | 486 | |
|---|
| | 487 | return accept(s, saddr, saddrlen); |
|---|
| | 488 | } |
|---|
| | 489 | |
|---|
| | 490 | uint32_t user_hook_closesocket(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 491 | va_list vl; |
|---|
| | 492 | int s; |
|---|
| | 493 | |
|---|
| | 494 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking closesocket() call.\n"); |
|---|
| | 495 | |
|---|
| | 496 | va_start(vl, hook); |
|---|
| | 497 | |
|---|
| | 498 | s = va_arg(vl, int); |
|---|
| | 499 | |
|---|
| | 500 | va_end(vl); |
|---|
| | 501 | |
|---|
| | 502 | return close(s); |
|---|
| | 503 | } |
|---|
| | 504 | |
|---|
| | 505 | uint32_t user_hook_listen(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 506 | va_list vl; |
|---|
| | 507 | int s, backlog; |
|---|
| | 508 | |
|---|
| | 509 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking listen() call.\n"); |
|---|
| | 510 | |
|---|
| | 511 | va_start(vl, hook); |
|---|
| | 512 | |
|---|
| | 513 | s = va_arg(vl, int); |
|---|
| | 514 | backlog = va_arg(vl, int); |
|---|
| | 515 | |
|---|
| | 516 | va_end(vl); |
|---|
| | 517 | |
|---|
| | 518 | return listen(s, backlog); |
|---|
| | 519 | } |
|---|
| | 520 | |
|---|
| | 521 | uint32_t user_hook_recv(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 522 | va_list vl; |
|---|
| | 523 | int s, len, flags; |
|---|
| | 524 | char *buf; |
|---|
| | 525 | |
|---|
| | 526 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking recv() call.\n"); |
|---|
| | 527 | |
|---|
| | 528 | va_start(vl, hook); |
|---|
| | 529 | |
|---|
| | 530 | s = va_arg(vl, int); |
|---|
| | 531 | buf = va_arg(vl, char *); |
|---|
| | 532 | len = va_arg(vl, int); |
|---|
| | 533 | flags = va_arg(vl, int); |
|---|
| | 534 | |
|---|
| | 535 | va_end(vl); |
|---|
| | 536 | |
|---|
| | 537 | return recv(s, buf, len, flags); |
|---|
| | 538 | } |
|---|
| | 539 | |
|---|
| | 540 | uint32_t user_hook_send(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 541 | va_list vl; |
|---|
| | 542 | int s, len, flags; |
|---|
| | 543 | char *buf; |
|---|
| | 544 | |
|---|
| | 545 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking send() call.\n"); |
|---|
| | 546 | |
|---|
| | 547 | va_start(vl, hook); |
|---|
| | 548 | |
|---|
| | 549 | s = va_arg(vl, int); |
|---|
| | 550 | buf = va_arg(vl, char *); |
|---|
| | 551 | len = va_arg(vl, int); |
|---|
| | 552 | flags = va_arg(vl, int); |
|---|
| | 553 | |
|---|
| | 554 | va_end(vl); |
|---|
| | 555 | |
|---|
| | 556 | return send(s, buf, len, flags); |
|---|
| | 557 | } |
|---|
| | 558 | |
|---|
| | 559 | uint32_t user_hook_exit(struct emu_env *env, struct emu_env_hook *hook, ...) { |
|---|
| | 560 | va_list vl; |
|---|
| | 561 | int code; |
|---|
| | 562 | |
|---|
| | 563 | logmsg(LOG_NOISY, 1, "CPU Emulation - Hooking exit() call.\n"); |
|---|
| | 564 | |
|---|
| | 565 | va_start(vl, hook); |
|---|
| | 566 | |
|---|
| | 567 | code = va_arg(vl, int); |
|---|
| | 568 | |
|---|
| | 569 | va_end(vl); |
|---|
| | 570 | |
|---|
| | 571 | opts.steps = 0; |
|---|
| | 572 | |
|---|
| | 573 | return 0; |
|---|
| | 574 | } |
|---|