Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

• • •

Slide 4

Slide 4 text

• • • • • •

Slide 5

Slide 5 text

• •

Slide 6

Slide 6 text

• • • • • •

Slide 7

Slide 7 text

• • • • • •

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

• • • • • • •

Slide 10

Slide 10 text

• • • • • • • •

Slide 11

Slide 11 text

• • • •

Slide 12

Slide 12 text

• • MOV EBX, EAX ADD EAX, $0x4 … MOV EBX, EAX ADD EAX, $0x4 … • • • mov_i32 ebx, eax movi_i32 tmp1, 0x4 add_i32 eax, tmp1

Slide 13

Slide 13 text

• • • • • • •

Slide 14

Slide 14 text

• • • •

Slide 15

Slide 15 text

• • • •

Slide 16

Slide 16 text

• • •

Slide 17

Slide 17 text

• • • • •

Slide 18

Slide 18 text

Slide 19

Slide 19 text

Slide 20

Slide 20 text

Slide 21

Slide 21 text

Slide 22

Slide 22 text

• • • • • • • •

Slide 23

Slide 23 text

• • • • • ☓ ☓ ☓ ☓

Slide 24

Slide 24 text

• • ☓ ☓ ☓ ☓

Slide 25

Slide 25 text

• • ☓ ☓ ☓ ☓

Slide 26

Slide 26 text

http://sycurelab.ecs.syr.edu/image/overall_decaf.jpg

Slide 27

Slide 27 text

• • sudo apt-get install qemu binutils-dev libboost-all-dev sudo apt-get build-dep qemu git clone [email protected]:sycurelab/DECAF.git cd DECAF/decaf/ ./configure make # QEMUの中間表現でテイント解析(後述)を行う ./configure -–enable-tcg-taint # QEMUの中間表現をロギングする ./configure -–enable-tcg-ir-log # VMIの無効化 ./configure –-disable-vmi

Slide 28

Slide 28 text

• • qemu-img create -f qcow2 ${IMAGE_FILE}.qcow2 ${SIZE}G qemu-system-i386 -m 1024 -drive file=${IMAGE_FILE}.qcow2 -cdrom ${DISK}.iso cd ${HOME}/DECAF/decaf/i386-softmmu/ ./qemu-system-i386 -monitor stdio -m 1024 -drive file=${IMAGE_FILE}.qcow2

Slide 29

Slide 29 text

import subprocess, os, fcntl, time def input_cmd(p, cmd): if not cmd.endswith("¥n"): cmd += "¥n" p.stdin.write(cmd) p.stdin.write("MARK¥n") while True: time.sleep(0.1) try: s = p.stdout.read() except Exception, e: continue print s if "unknown command: 'MARK'" in s: break def main(): decaf_path = raw_input("Enter the root directory of DECAF (i386-softmmu/qemu-system-i386 should be there):") image_path = raw_input("Enter the image path:") os.chdir(decaf_path) p = subprocess.Popen(args=“i386-softmmu/qemu-system-i386 {image_path} -m 512 -monitor stdio”.format(image_path=image_path), stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) fl = fcntl.fcntl(p.stdout, fcntl.F_GETFL) fcntl.fcntl(p.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK) time.sleep(3) input_cmd(p, "ps") input_cmd(p, "help") if __name__ == '__main__': main()

Slide 30

Slide 30 text

• • modprobe nbd qemu-nbd -c /dev/nbd0 ${IMAGE_FILE}.qcow2 /sbin/fdisk -l /dev/nbd0 # /mnt/にWindowsのディレクトリ構造がそのまま展開される mount -o loop,offset=$((63*512)) /dev/nbd0 /mnt/ umount /mnt qemu-nbd -d /dev/nbd0 rmmod nbd

Slide 31

Slide 31 text

• • # QEMUのコンソールから (qemu) savevm ${SNAPSHOT} (qemu) loadvm ${SNAPSHOT} qemu-img snapshot -l ${IMAGE_FILE}.qcow2

Slide 32

Slide 32 text

• ls ${HOME}/DECAF/decaf/plugins callbacktests/ hookapitests/ keylogger/ min_apitracer/ tracecap/ unpacker/

Slide 33

Slide 33 text

• • cd ${HOME}/DECAF/decaf/plugins/${PLUGIN} ./configure –-decaf-path=${HOME}/DECAF/decaf/ make # 標準入出力からコマンドを通じて操作 ./qemu-system-i386 -monitor stdio -m 1024 -drive file=${IMAGE_FILE}.qcow2 # コマンド一覧表示 (qemu) help # プラグインのロード (qemu) load_plugin ${HOME}/DECAF/decaf/plugins/${PLUGIN}/${PLUGIN}.so # プラグインのアンロード (qemu) load_plugin

Slide 34

Slide 34 text

• • • // plugin_cmds.h { .name = "do_callbacktests", .args_type = "procname:s?", .mhandler.cmd = do_callbacktests, .params = "[procname]", .help = "Run the tests with program [procname]“ }, // callbacktests.c static mon_cmd_t callbacktests_term_cmds[] = { #include "plugin_cmds.h" {NULL, NULL, }, };

Slide 35

Slide 35 text

• // callbacktests.c plugin_interface_t* init_plugin(void) { callbacktests_interface.mon_cmds = callbacktests_term_cmds; callbacktests_interface.plugin_cleanup = &callbacktests_cleanup; //initialize the plugin callbacktests_init(); return (&callbacktests_interface); }

Slide 36

Slide 36 text

// callbacktests.c static int callbacktests_init(void) { DECAF_output_init(NULL); DECAF_printf("Hello World¥n"); //register for process create and process remove events processbegin_handle = VMI_register_callback(VMI_CREATEPROC_CB, &callbacktests_loadmainmodule_callback, NULL); removeproc_handle = VMI_register_callback(VMI_REMOVEPROC_CB, &callbacktests_removeproc_callback, NULL); targetname[0] = '¥0'; targetcr3 = 0; targetpid = (uint32_t)(-1); do_callbacktests(NULL, NULL); return (0); } •

Slide 37

Slide 37 text

• // callbacktests.c static void callbacktests_loadmainmodule_callback(VMI_Callback_Params* params) { char procname[64]; uint32_t pid; //DECAF_printf("Process with pid = %d and cr3 = %u was just created¥n", params->lmm.pid, params->lmm.cr3); VMI_find_process_by_cr3_c(params->cp.cr3, procname, 64, &pid); if (strcmp(targetname, procname) == 0) { targetpid = pid; targetcr3 = params->cp.cr3; runTests(); } }

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

// windows_vmi.h #define KPCR_OFFSET 0x1c #define KDVB_OFFSET 0x34 // base on KPCR #define PSLM_OFFSET 0x70 #define PSAPH_OFFSET 0x78 // base on KDVB

Slide 41

Slide 41 text

// windows_vmi.cpp static process * find_new_process(CPUState *env, uint32_t cr3) { uint32_t kdvb, psAPH, curr_proc, next_proc; process *pe; DECAF_read_mem(env, gkpcr + KDVB_OFFSET, 4, &kdvb); DECAF_read_mem(env, kdvb + PSAPH_OFFSET, 4, &psAPH); DECAF_read_mem(env, psAPH, 4, &curr_proc); while (curr_proc != 0 && curr_proc != psAPH) { uint32_t pid, proc_cr3; uint32_t curr_proc_base = curr_proc - handle_funds[GuestOS_index].offset->PSAPL_OFFSET; DECAF_read_mem(env, curr_proc_base + handle_funds[GuestOS_index].offset->PSAPID_OFFSET, 4, &pid); if (VMI_find_process_by_pid(pid) != NULL) //we have seen this process goto next; DECAF_read_mem(env, curr_proc_base + 0x18, 4, &proc_cr3); if(cr3 != proc_cr3) //This is a new process, but not the current one. Skip it! goto next; //This is the one we are looking for pe = new process(); pe->EPROC_base_addr = curr_proc_base; pe->pid = pid; pe->cr3 = proc_cr3; DECAF_read_mem(env, curr_proc_base + handle_funds[GuestOS_index].offset->PSAPNAME_OFFSET, NAMESIZE, pe->name); DECAF_read_mem(env, curr_proc_base + handle_funds[GuestOS_index].offset->PSAPPID_OFFSET, 4, &pe->parent_pid); VMI_create_process(pe); return pe; next: DECAF_read_mem(env, curr_proc, 4, &next_proc); if (curr_proc == next_proc) { //why do we need this check? break; } curr_proc = next_proc; } return NULL; }

Slide 42

Slide 42 text

Slide 43

Slide 43 text

• MOV EBX, EAX ADD EAX, $0x4 mov_i32 ebx, eax movi_i32 tmp1, 0x4 add_i32 eax, tmp1 mov_i32 ebx, eax mov_i32 taint_ebx, taint_eax movi_i32 tmp1, 0x4 movi_i32 tmp51, 0x0 add_i32 eax, tmp1 MOV ESI, $0x4 MOV EDI, $0x0 ADD EAX, ESI

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

• • • • • • • • •

Slide 46

Slide 46 text

• • • • • • • • static void block_begin_callback(DECAF_Callback_Params* params) { uint32_t eip,eax; if(params->bb.env->cr[3]!=target_cr3) break; eip =cpu_single_env->eip; eax =cpu_single_env->regs[R_EAX]; DECAF_printf("EIP = 0x%08x ¥n",eip); DECAF_printf("EAX = 0x%08x ¥n",eax); }

Slide 47

Slide 47 text

• • • •

Slide 48

Slide 48 text

• •

Slide 49

Slide 49 text

• • • •

Slide 50

Slide 50 text

• • •

Slide 51

Slide 51 text

• • DECAF_Handle VMI_register_callback(procmod_callback_type_t cb_type, procmod_callback_func_t cb_func, int *cb_cond ); int VMI_unregister_callback(procmod_callback_type_t cb_type, DECAF_Handle handle); DECAF_Handle DECAF_register_callback( DECAF_callback_type_t cb_type, DECAF_callback_func_t cb_func, int *cb_cond ); int DECAF_unregister_callback(DECAF_callback_type_t cb_type, DECAF_Handle handle);

Slide 52

Slide 52 text

• DECAF_Handle DECAF_registerOptimizedBlockBeginCallback( DECAF_callback_func_t cb_func, int *cb_cond, gva_t addr, OCB_t type); DECAF_Handle DECAF_registerOptimizedBlockEndCallback( DECAF_callback_func_t cb_func, int *cb_cond, gva_t from, gva_t to); int DECAF_unregisterOptimizedBlockBeginCallback(DECAF_Handle handle); int DECAF_unregisterOptimizedBlockEndCallback(DECAF_Handle handle);

Slide 53

Slide 53 text

• uintptr_t hookapi_hook_function_byname(const char *mod,const char *func,int is_global,target_ulong cr3, hook_proc_t fnhook,void *opaque,uint32_t sizeof_opaque); void hookapi_remove_hook(uintptr_t handle); uintptr_t hookapi_hook_return(target_ulong pc,hook_proc_t fnhook, void *opaque, uint32_t sizeof_opaque); uintptr_t hookapi_hook_function(int is_global, target_ulong pc, target_ulong cr3, hook_proc_t fnhook, void *opaque, uint32_t sizeof_opaque );

Slide 54

Slide 54 text

typedef struct { uint32_t call_stack[12]; //paramters and return address DECAF_Handle hook_handle; } NtCreateFile_hook_context_t; /* NTSTATUS NtCreateFile( _Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_opt_ PLARGE_INTEGER AllocationSize, _In_ ULONG FileAttributes, _In_ ULONG ShareAccess, _In_ ULONG CreateDisposition, _In_ ULONG CreateOptions, _In_ PVOID EaBuffer, _In_ ULONG EaLength ); */

Slide 55

Slide 55 text

static void my_loadmainmodule_callback(VMI_Callback_Params* params) { if(strcmp(params->cp.name,targetname)==0) { DECAF_printf("Process %s you spcecified starts ¥n",params->cp.name); target_cr3=params->cp.cr3; /// @ingroup hookapi /// install a hook at the function entry by specifying module name and function name /// @param mod module name that this function is located in /// @param func function name /// @param is_global flag specifies if this hook should be invoked globally or only in certain execution context (when should_monitor is true) /// @param cr3 the memory space that this hook is installed. 0 for all memory spaces. /// @param fnhook address of function hook /// @param opaque address of an opaque structure provided by caller (has to be globally allocated) /// @param sizeof_opaque size of the opaque structure (if opaque is an integer, not a pointer to a structure, sizeof_opaque must be zero) /// @return a handle that uniquely identifies this hook /// Note that the handle that is returned, might not actually be active yet - you can check the eip value of the handle to find out /// the default value is 0. ntcreatefile_handle = hookapi_hook_function_byname( "ntdll.dll", "NtCreateFile", 1, target_cr3, NtCreateFile_call, NULL, 0); } }

Slide 56

Slide 56 text

static void NtCreateFile_ret(void *param) { NtCreateFile_hook_context_t *ctx = (NtCreateFile_hook_context_t *)param; DECAF_printf("NtCreateFile exit:"); hookapi_remove_hook(ctx->hook_handle); uint32_t out_handle; DECAF_read_mem(NULL, ctx->call_stack[1], 4, &out_handle); DECAF_printf("out_handle=%08x¥n", out_handle); free(ctx); } static void NtCreateFile_call(void *opaque) { DECAF_printf("NtCreateFile entry¥n"); NtCreateFile_hook_context_t *ctx = (NtCreateFile_hook_context_t*) malloc(sizeof(NtCreateFile_hook_context_t)); if(!ctx) //run out of memory return; DECAF_read_mem(NULL, cpu_single_env->regs[R_ESP], 12*4, ctx->call_stack); ctx->hook_handle = hookapi_hook_return(ctx->call_stack[0], NtCreateFile_ret, ctx, sizeof(*ctx)); }

Slide 57

Slide 57 text

• /*given a virtual address of guest os, get the corresponded physical address */ gpa_t DECAF_get_phys_addr(CPUState* env, gva_t addr); DECAF_errno_t DECAF_memory_rw(CPUState* env, uint32_t addr, void *buf, int len,int is_write); DECAF_errno_t DECAF_memory_rw_with_cr3(CPUState* env, target_ulong cr3,gva_t addr, void *buf, int len, int is_write); DECAF_errno_t DECAF_read_mem(CPUState* env, gva_t vaddr, int len, void *buf); DECAF_errno_t DECAF_write_mem(CPUState* env, gva_t vaddr, int len, void *buf); DECAF_errno_t DECAF_read_mem_with_cr3(CPUState* env, target_ulong cr3,gva_t vaddr, int len, void *buf); DECAF_errno_t DECAF_write_mem_with_cr3(CPUState* env, target_ulong cr3,gva_t vaddr, int len, void *buf); DECAF_get_page_access(CPUState* env, gva_t addr);

Slide 58

Slide 58 text

• module * VMI_find_module_by_pc(target_ulong pc, target_ulong pgd, target_ulong *base); module * VMI_find_module_by_name(const char *name, target_ulong pgd, target_ulong *base); module * VMI_find_module_by_base(target_ulong pgd, uint32_t base); process * VMI_find_process_by_pid(uint32_t pid); process * VMI_find_process_by_pgd(uint32_t pgd); process* VMI_find_process_by_name(char *name);

Slide 59

Slide 59 text

• /// @ingroup semantics /// locate the module that a given instruction belongs to /// @param eip virtual address of a given instruction /// @param cr3 memory space id: physical address of page table /// @param proc process name (output argument) /// @param tm return tmodinfo_t structure extern int VMI_locate_module_c(gva_t eip, gva_t cr3, char proc[],tmodinfo_t *tm); extern int VMI_locate_module_byname_c(const char *name, uint32_t pid,tmodinfo_t * tm); extern int VMI_find_cr3_by_pid_c(uint32_t pid); extern int VMI_find_pid_by_cr3_c(uint32_t cr3); extern int VMI_find_pid_by_name_c(char* proc_name);

Slide 60

Slide 60 text

• /// @ingroup semantics /// find process given a memory space id /// @param cr3 memory space id: physical address of page table /// @param proc process name (output argument) /// @param pid process pid (output argument) /// @return number of modules in this process extern int VMI_find_process_by_cr3_c(uint32_t cr3, char proc_name[], size_t len, uint32_t *pid);

Slide 61

Slide 61 text

• /* find process name and CR3 using the PID as search key */ extern int VMI_find_process_by_pid_c(uint32_t pid, char proc_name[], size_t len, uint32_t *cr3); extern int VMI_get_proc_modules_c(uint32_t pid, uint32_t mod_no, tmodinfo_t *buf); extern int VMI_get_all_processes_count_c(void); /* Create array with info about all processes running in system */ extern int VMI_find_all_processes_info_c(size_t num_proc, procinfo_t *arr); //Aravind - added to get the number of loaded modules for the process. //This is needed to create the memory required by get_proc_modules extern int VMI_get_loaded_modules_count_c(uint32_t pid); //end - Aravind

Slide 62

Slide 62 text

• /// @ingroup semantics /// @return the current thread id. If for some reason, this operation / // is not successful, the return value is set to -1. /// This function only works in Windows XP for Now. extern int VMI_get_current_tid_c(CPUState* env); //0 unknown 1 windows 2 linux extern int VMI_get_guest_version_c(void);

Slide 63

Slide 63 text

• • • • git clone https://github.com/ntddk/geteip

Slide 64

Slide 64 text

• • • • • export SDL_VIDEO_X11_DGAMOUSE=0 gdb --args ${HOME}/DECAF/decaf/i386-softmmu/qemu-system-i386 -m 1024 -monitor stdio ${IMAGE_FILE}.qcow2 (gdb) handle SIG38 "nostop" "pass" "noprint” (gdb) r

Slide 65

Slide 65 text

• • • (qemu) x/10i $eip 0x7c917ab8: addl $0x2,0x18(%ebp) 0x7c917abc: inc %ecx 0x7c917abd: inc %ecx 0x7c917abe: test %dl,%dl 0x7c917ac0: jne 0x7c917a94 0x7c917ac2: xor %ecx,%ecx 0x7c917ac4: test %ecx,%ecx 0x7c917ac6: mov 0xc(%ebp),%ebx 0x7c917ac9: jne 0x7c917d2d 0x7c917acf: mov -0x4(%ebp),%eax

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

• •

Slide 68

Slide 68 text

• • • • • • • • •

Slide 69

Slide 69 text

• • • •

Slide 70

Slide 70 text

cmp eax, 0x7DF je 0xdeadbaad if(x!=2015) Invalid. ASSERT( INPUT_*_*_* =0hex7DF );

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

• •

Slide 73

Slide 73 text

• • •