软件沙箱技术 – 安全分析沙箱Cuckoo Sandbox
2016-01-15 14:48
344 查看
1.Cockoo的功能
Cockoo Sandbox是开源安全沙箱,基于GPLv3。目的是恶意软件(malware analysis)分析。使用的时候将待分析文件丢到沙箱内,分析结束后输出报告。很多安全设备提供商所谓云沙箱是同类技术,一些所谓Anti-APT产品也是这个概念。和传统AV软件的静态分析相比,Cuckoo动态检测。扔到沙箱的可执行文件会被执行,文档会被打开,运行中检测。和不少开源软件学而优则仕一样,Cookoo搞了一个产品,Red
Dragon。这种方式也是挺好的一种做开源软件的运营方式,Snort的SourceFire不就是被思科十几亿收购了吗。
Cuckoo它可以分析的内容有:
1.Windows可执行文件,DLL文件
2.PDF,MSOffice文档
3.URL和HTML文档
4.PHP脚本,VB脚本
5.CPL文件
6.ZIP文件,Jar文件
7.Python文件
可以看出,只是Windows平台,外加一些脚本和文件。
Cuckoo的分析结果包含如下内容:
1.函数以及API调用的Call Trace
2.应用拷贝和删除的文件
3.选定进程的内存镜像
4.分析机的full memory dump
5.恶意软件执行时的截屏
6.分析机产生的网络流量
2.部署和使用
下图是Cuckoo的部署,其实很简单,分为host和guests。
Host(管理机)
负责
管理guests
启动分析工作
网络流量收集等。
host依赖一些开源软件,例如
tcpdump用于Guest网络拦截
Volatility用于内存的dump
Guest(虚拟机)
Guest是通用的虚拟机,Xen、VirtualBox等。它运行Cuckoo的Agent,接收Host发过来的任务(文件)运行后获取信息。
Agent是跨平台的(就是Python脚本)可以运行在Windows、Linux和MAC OS上。它实际是是一个XMLRPC server,等待连接。
Cuckoo使用
Cuckoo提供了python命令行工具。
1.使用cuckoo.py启动引擎。
2.使用submit.py像cuckoo提交待分析应用。
3.引擎会和虚拟机中的Agent通信,运行应用。
4.分析结束后,结果输出到特定目录。
3.Hook引擎
cuckoo使用了通用虚拟机做Guest,本身也没有隔离机制和访问控制机制。它特殊的地方就是Hook机制。核心模块cuckoomon(Cuckoo Sandbox Monitor)的源码在这里。它的作用是Hook在可执行程序上,拦截执行流程。
形式上它是一个DLL,会被inject到待分析的恶意软件和它创建的所有进程中。所谓动态分析,就是Hook后的API,在线收集的运行时信息。主要有两个步骤:
3.1 DLL注入
注入是使用Python实现的,流程如下:
1.使用CreateProcess(CREATE SUSPENDED)启动应用
2.使用CreateRemoteThread和QueueUserAPC API调用LoadLibrary注入cuckoomon.dll。
3.Resume进程的主线程
参照下面代码
3.2 API Hook
1.上一步中主线程恢复后,因为APC callback,Cuckoo Monitor首先被执行。
2.初始化并且安装Hook
Cuckoo对ntdll.dll, kernel32.dll, advapi32.dll,shell32.dll,msvcrt.dll,user32.dll,wininet.dll,ws2_32.dll,mswsock.dll中的170+API进行hook
3.通知分析模块Analyzer(通过命名管道),应用启动。
4.Log将会通过实现配置好的TCP/IP端口发送给Host。
下面是添加Hook的代码:
int hook_api(hook_t *h, int type) { // table with all possible hooking types static struct { int(*hook)(hook_t *h, unsigned char *from, unsigned char *to); int len; } hook_types[] = { /* HOOK_JMP_DIRECT */ {&hook_api_jmp_direct, 5}, /* HOOK_NOP_JMP_DIRECT
*/ {&hook_api_nop_jmp_direct, 6}, /* HOOK_HOTPATCH_JMP_DIRECT */ {&hook_api_hotpatch_jmp_direct, 7}, /* HOOK_PUSH_RETN */ {&hook_api_push_retn, 6}, /* HOOK_NOP_PUSH_RETN */ {&hook_api_nop_push_retn, 7}, /* HOOK_JMP_INDIRECT */ {&hook_api_jmp_indirect, 6},
/* HOOK_MOV_EAX_JMP_EAX */ {&hook_api_mov_eax_jmp_eax, 7}, /* HOOK_MOV_EAX_PUSH_RETN */ {&hook_api_mov_eax_push_retn, 7}, /* HOOK_MOV_EAX_INDIRECT_JMP_EAX */ {&hook_api_mov_eax_indirect_jmp_eax, 7}, /* HOOK_MOV_EAX_INDIRECT_PUSH_RETN */ {&hook_api_mov_eax_indirect_push_retn,
7}, #if HOOK_ENABLE_FPU /* HOOK_PUSH_FPU_RETN */ {&hook_api_push_fpu_retn, 11}, #endif /* HOOK_SPECIAL_JMP */ {&hook_api_special_jmp, 7}, }; // is this address already hooked? if(h->is_hooked != 0) { return 0; } // resolve the address to hook unsigned char
*addr = h->addr; if(addr == NULL && h->library != NULL && h->funcname != NULL) { addr = (unsigned char *) GetProcAddress(GetModuleHandleW(h->library), h->funcname); } if(addr == NULL) { return -1; } int ret = -1; // check if this is a valid hook type if(type
>= 0 && type < ARRAYSIZE(hook_types)) { // determine whether we're running under win7, if so, we might have to // follow a short relative jmp and an indirect jump before reaching // the real address OSVERSIONINFO os_info = {sizeof(OSVERSIONINFO)}; if(GetVersionEx(&os_info)
&& os_info.dwMajorVersion == 6 && os_info.dwMinorVersion == 1) { // windows 7 has a DLL called kernelbase.dll which basically acts // as a layer between the program and kernel32 (and related?) it // allows easy hotpatching of a set of functions which is why
// there's a short relative jump and an indirect jump. we want to // resolve the address of the real function, so we follow these // two jumps. if(!memcmp(addr, "\xeb\x05", 2) && !memcmp(addr + 7, "\xff\x25", 2)) { addr = **(unsigned char ***)(addr + 9); }
// the following applies for "inlined" functions on windows 7, // some functions are inlined into kernelbase.dll, rather than // kernelbase.dll jumping to e.g. kernel32.dll. for these // functions there is a short relative jump, followed by the // inlined
function. if(!memcmp(addr, "\xeb\x02", 2) && !memcmp(addr - 5, "\xcc\xcc\xcc\xcc\xcc", 5)) { // step over the short jump and the relative offset addr += 4; } } DWORD old_protect; // make the address writable if(VirtualProtect(addr, hook_types[type].len, PAGE_EXECUTE_READWRITE,
&old_protect)) { if(hook_create_trampoline(addr, hook_types[type].len, h->tramp)) { hook_store_exception_info(h); uint8_t special = 0; if(h->allow_hook_recursion == 1) { special = 1; } hook_create_pre_tramp(h, special); // insert the hook (jump from the api
to the // pre-trampoline) ret = hook_types[type].hook(h, addr, h->pre_tramp); // if successful, assign the trampoline address to *old_func if(ret == 0) { *h->old_func = h->tramp; // successful hook is successful h->is_hooked = 1; } } // restore the old protection
VirtualProtect(addr, hook_types[type].len, old_protect, &old_protect); } } return ret; }
4.躲避的应对
前面软件加壳技术介绍的时候有部分内容关于躲避。恶意软件会创建自进程,在子进程中做实际工作。对于类似Cuckoo这样的动态分析工具就要处理这种情况,在子进程中启动cuckoomon。下图就是应对流程,Monitor在监控到样本创建进程的时候,也会模拟初始化启动时候cuckoo做的事情,显示suspend,然后通知Analyzer。由后者进行DLL的注入。
From 【5】
前文也介绍过进程注入,也就是恶意软件利用周知进程,例如IE,运行自己的恶意逻辑,解决的方法类似。只是监控的不是CreateProcess而是OpenProcess。
【参考】
1.官方网站,http://www.cuckoosandbox.org/
2.Cuckoo Sandbox Book,http://cuckoo.readthedocs.org/en/latest/
3.Hooking functions with Cuckoobox’s hooking engine,http://living-security.blogspot.com/2014/07/hooking-functions-with-cuckooboxs.html
4.开源软件 cuckoo sandbox学习(二) 核心拦截模块源代码导读, http://sevemal.blog.51cto.com/8627322/1397666
5.Haow Sandbox, Cuckoo Sandbox Internal, http://recon.cx/2013/slides/recon2013-Jurriaan%20Bremer-Haow%20do%20I%20sandbox.pdf
Cockoo Sandbox是开源安全沙箱,基于GPLv3。目的是恶意软件(malware analysis)分析。使用的时候将待分析文件丢到沙箱内,分析结束后输出报告。很多安全设备提供商所谓云沙箱是同类技术,一些所谓Anti-APT产品也是这个概念。和传统AV软件的静态分析相比,Cuckoo动态检测。扔到沙箱的可执行文件会被执行,文档会被打开,运行中检测。和不少开源软件学而优则仕一样,Cookoo搞了一个产品,Red
Dragon。这种方式也是挺好的一种做开源软件的运营方式,Snort的SourceFire不就是被思科十几亿收购了吗。
Cuckoo它可以分析的内容有:
1.Windows可执行文件,DLL文件
2.PDF,MSOffice文档
3.URL和HTML文档
4.PHP脚本,VB脚本
5.CPL文件
6.ZIP文件,Jar文件
7.Python文件
可以看出,只是Windows平台,外加一些脚本和文件。
Cuckoo的分析结果包含如下内容:
1.函数以及API调用的Call Trace
2.应用拷贝和删除的文件
3.选定进程的内存镜像
4.分析机的full memory dump
5.恶意软件执行时的截屏
6.分析机产生的网络流量
2.部署和使用
下图是Cuckoo的部署,其实很简单,分为host和guests。
Host(管理机)
负责
管理guests
启动分析工作
网络流量收集等。
host依赖一些开源软件,例如
tcpdump用于Guest网络拦截
Volatility用于内存的dump
Guest(虚拟机)
Guest是通用的虚拟机,Xen、VirtualBox等。它运行Cuckoo的Agent,接收Host发过来的任务(文件)运行后获取信息。
Agent是跨平台的(就是Python脚本)可以运行在Windows、Linux和MAC OS上。它实际是是一个XMLRPC server,等待连接。
Cuckoo使用
Cuckoo提供了python命令行工具。
1.使用cuckoo.py启动引擎。
2.使用submit.py像cuckoo提交待分析应用。
3.引擎会和虚拟机中的Agent通信,运行应用。
4.分析结束后,结果输出到特定目录。
3.Hook引擎
cuckoo使用了通用虚拟机做Guest,本身也没有隔离机制和访问控制机制。它特殊的地方就是Hook机制。核心模块cuckoomon(Cuckoo Sandbox Monitor)的源码在这里。它的作用是Hook在可执行程序上,拦截执行流程。
形式上它是一个DLL,会被inject到待分析的恶意软件和它创建的所有进程中。所谓动态分析,就是Hook后的API,在线收集的运行时信息。主要有两个步骤:
3.1 DLL注入
注入是使用Python实现的,流程如下:
1.使用CreateProcess(CREATE SUSPENDED)启动应用
2.使用CreateRemoteThread和QueueUserAPC API调用LoadLibrary注入cuckoomon.dll。
3.Resume进程的主线程
参照下面代码
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 | classProcess: """Windows process.""" def inject(self,dll=os.path.join("dll","cuckoomon.dll"),apc=False): """Cuckoo DLL injection. @param dll: Cuckoo DLL path. @param apc: APC use. """ ifself.pid==0: log.warning("No valid pid specified, injection aborted") returnFalse ifnotself.is_alive(): log.warning("The process with pid %d is not alive, injection " "aborted"%self.pid) returnFalse dll=randomize_dll(dll) ifnotdll ornotos.path.exists(dll): log.warning("No valid DLL specified to be injected in process " "with pid %d, injection aborted"%self.pid) returnFalse arg=KERNEL32.VirtualAllocEx(self.h_process, None, len(dll)+1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE) ifnotarg: log.error("VirtualAllocEx failed when injecting process with " "pid %d, injection aborted (Error: %s)" %(self.pid,get_error_string(KERNEL32.GetLastError()))) returnFalse bytes_written=c_int(0) ifnotKERNEL32.WriteProcessMemory(self.h_process, arg, dll+"\x00", len(dll)+1, byref(bytes_written)): log.error("WriteProcessMemory failed when injecting process " "with pid %d, injection aborted (Error: %s)" %(self.pid,get_error_string(KERNEL32.GetLastError()))) returnFalse kernel32_handle=KERNEL32.GetModuleHandleA("kernel32.dll") load_library=KERNEL32.GetProcAddress(kernel32_handle, "LoadLibraryA") config_path=os.path.join(os.getenv("TEMP"),"%s.ini"%self.pid) with open(config_path,"w")asconfig: cfg=Config("analysis.conf") config.write("host-ip={0}\n".format(cfg.ip)) config.write("host-port={0}\n".format(cfg.port)) config.write("pipe={0}\n".format(PIPE)) config.write("results={0}\n".format(PATHS["root"])) config.write("analyzer={0}\n".format(os.getcwd())) config.write("first-process={0}\n".format(Process.first_process)) Process.first_process=False ifapc orself.suspended: log.info("Using QueueUserAPC injection") ifnotself.h_thread: log.info("No valid thread handle specified for injecting " "process with pid %d, injection aborted"%self.pid) returnFalse ifnotKERNEL32.QueueUserAPC(load_library,self.h_thread,arg): log.error("QueueUserAPC failed when injecting process " "with pid %d (Error: %s)" %(self.pid, get_error_string(KERNEL32.GetLastError()))) returnFalse log.info("Successfully injected process with pid %d"%self.pid) else: event_name="CuckooEvent%d"%self.pid self.event_handle=KERNEL32.CreateEventA(None, False, False, event_name) ifnotself.event_handle: log.warning("Unable to create notify event..") returnFalse log.info("Using CreateRemoteThread injection") new_thread_id=c_ulong(0) thread_handle=KERNEL32.CreateRemoteThread(self.h_process, None, 0, load_library, arg, 0, byref(new_thread_id)) ifnotthread_handle: log.error("CreateRemoteThread failed when injecting "+ "process with pid %d (Error: %s)"%(self.pid, get_error_string(KERNEL32.GetLastError()))) KERNEL32.CloseHandle(self.event_handle) self.event_handle=None returnFalse else: KERNEL32.CloseHandle(thread_handle) returnTrue |
3.2 API Hook
1.上一步中主线程恢复后,因为APC callback,Cuckoo Monitor首先被执行。
2.初始化并且安装Hook
Cuckoo对ntdll.dll, kernel32.dll, advapi32.dll,shell32.dll,msvcrt.dll,user32.dll,wininet.dll,ws2_32.dll,mswsock.dll中的170+API进行hook
3.通知分析模块Analyzer(通过命名管道),应用启动。
4.Log将会通过实现配置好的TCP/IP端口发送给Host。
下面是添加Hook的代码:
int hook_api(hook_t *h, int type) { // table with all possible hooking types static struct { int(*hook)(hook_t *h, unsigned char *from, unsigned char *to); int len; } hook_types[] = { /* HOOK_JMP_DIRECT */ {&hook_api_jmp_direct, 5}, /* HOOK_NOP_JMP_DIRECT
*/ {&hook_api_nop_jmp_direct, 6}, /* HOOK_HOTPATCH_JMP_DIRECT */ {&hook_api_hotpatch_jmp_direct, 7}, /* HOOK_PUSH_RETN */ {&hook_api_push_retn, 6}, /* HOOK_NOP_PUSH_RETN */ {&hook_api_nop_push_retn, 7}, /* HOOK_JMP_INDIRECT */ {&hook_api_jmp_indirect, 6},
/* HOOK_MOV_EAX_JMP_EAX */ {&hook_api_mov_eax_jmp_eax, 7}, /* HOOK_MOV_EAX_PUSH_RETN */ {&hook_api_mov_eax_push_retn, 7}, /* HOOK_MOV_EAX_INDIRECT_JMP_EAX */ {&hook_api_mov_eax_indirect_jmp_eax, 7}, /* HOOK_MOV_EAX_INDIRECT_PUSH_RETN */ {&hook_api_mov_eax_indirect_push_retn,
7}, #if HOOK_ENABLE_FPU /* HOOK_PUSH_FPU_RETN */ {&hook_api_push_fpu_retn, 11}, #endif /* HOOK_SPECIAL_JMP */ {&hook_api_special_jmp, 7}, }; // is this address already hooked? if(h->is_hooked != 0) { return 0; } // resolve the address to hook unsigned char
*addr = h->addr; if(addr == NULL && h->library != NULL && h->funcname != NULL) { addr = (unsigned char *) GetProcAddress(GetModuleHandleW(h->library), h->funcname); } if(addr == NULL) { return -1; } int ret = -1; // check if this is a valid hook type if(type
>= 0 && type < ARRAYSIZE(hook_types)) { // determine whether we're running under win7, if so, we might have to // follow a short relative jmp and an indirect jump before reaching // the real address OSVERSIONINFO os_info = {sizeof(OSVERSIONINFO)}; if(GetVersionEx(&os_info)
&& os_info.dwMajorVersion == 6 && os_info.dwMinorVersion == 1) { // windows 7 has a DLL called kernelbase.dll which basically acts // as a layer between the program and kernel32 (and related?) it // allows easy hotpatching of a set of functions which is why
// there's a short relative jump and an indirect jump. we want to // resolve the address of the real function, so we follow these // two jumps. if(!memcmp(addr, "\xeb\x05", 2) && !memcmp(addr + 7, "\xff\x25", 2)) { addr = **(unsigned char ***)(addr + 9); }
// the following applies for "inlined" functions on windows 7, // some functions are inlined into kernelbase.dll, rather than // kernelbase.dll jumping to e.g. kernel32.dll. for these // functions there is a short relative jump, followed by the // inlined
function. if(!memcmp(addr, "\xeb\x02", 2) && !memcmp(addr - 5, "\xcc\xcc\xcc\xcc\xcc", 5)) { // step over the short jump and the relative offset addr += 4; } } DWORD old_protect; // make the address writable if(VirtualProtect(addr, hook_types[type].len, PAGE_EXECUTE_READWRITE,
&old_protect)) { if(hook_create_trampoline(addr, hook_types[type].len, h->tramp)) { hook_store_exception_info(h); uint8_t special = 0; if(h->allow_hook_recursion == 1) { special = 1; } hook_create_pre_tramp(h, special); // insert the hook (jump from the api
to the // pre-trampoline) ret = hook_types[type].hook(h, addr, h->pre_tramp); // if successful, assign the trampoline address to *old_func if(ret == 0) { *h->old_func = h->tramp; // successful hook is successful h->is_hooked = 1; } } // restore the old protection
VirtualProtect(addr, hook_types[type].len, old_protect, &old_protect); } } return ret; }
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 | inthook_api(hook_t *h,inttype) { // table with all possible hooking types staticstruct{ int(*hook)(hook_t *h,unsignedchar*from,unsignedchar*to); intlen; }hook_types[]={ /* HOOK_JMP_DIRECT */{&hook_api_jmp_direct,5}, /* HOOK_NOP_JMP_DIRECT */{&hook_api_nop_jmp_direct,6}, /* HOOK_HOTPATCH_JMP_DIRECT */{&hook_api_hotpatch_jmp_direct,7}, /* HOOK_PUSH_RETN */{&hook_api_push_retn,6}, /* HOOK_NOP_PUSH_RETN */{&hook_api_nop_push_retn,7}, /* HOOK_JMP_INDIRECT */{&hook_api_jmp_indirect,6}, /* HOOK_MOV_EAX_JMP_EAX */{&hook_api_mov_eax_jmp_eax,7}, /* HOOK_MOV_EAX_PUSH_RETN */{&hook_api_mov_eax_push_retn,7}, /* HOOK_MOV_EAX_INDIRECT_JMP_EAX */ {&hook_api_mov_eax_indirect_jmp_eax,7}, /* HOOK_MOV_EAX_INDIRECT_PUSH_RETN */ {&hook_api_mov_eax_indirect_push_retn,7}, #if HOOK_ENABLE_FPU /* HOOK_PUSH_FPU_RETN */{&hook_api_push_fpu_retn,11}, #endif /* HOOK_SPECIAL_JMP */{&hook_api_special_jmp,7}, }; // is this address already hooked? if(h->is_hooked!=0){ return0; } // resolve the address to hook unsignedchar*addr=h->addr; if(addr==NULL&&h->library!=NULL&&h->funcname!=NULL){ addr=(unsignedchar*)GetProcAddress(GetModuleHandleW(h->library), h->funcname); } if(addr==NULL){ return-1; } intret=-1; // check if this is a valid hook type if(type>=0&&type<ARRAYSIZE(hook_types)){ // determine whether we're running under win7, if so, we might have to // follow a short relative jmp and an indirect jump before reaching // the real address OSVERSIONINFO os_info={sizeof(OSVERSIONINFO)}; if(GetVersionEx(&os_info)&&os_info.dwMajorVersion==6&& os_info.dwMinorVersion==1){ // windows 7 has a DLL called kernelbase.dll which basically acts // as a layer between the program and kernel32 (and related?) it // allows easy hotpatching of a set of functions which is why // there's a short relative jump and an indirect jump. we want to // resolve the address of the real function, so we follow these // two jumps. if(!memcmp(addr,"\xeb\x05",2)&& !memcmp(addr+7,"\xff\x25",2)){ addr=**(unsignedchar***)(addr+9); } // the following applies for "inlined" functions on windows 7, // some functions are inlined into kernelbase.dll, rather than // kernelbase.dll jumping to e.g. kernel32.dll. for these // functions there is a short relative jump, followed by the // inlined function. if(!memcmp(addr,"\xeb\x02",2)&& !memcmp(addr-5,"\xcc\xcc\xcc\xcc\xcc",5)){ // step over the short jump and the relative offset addr+=4; } } DWORD old_protect; // make the address writable if(VirtualProtect(addr,hook_types[type].len,PAGE_EXECUTE_READWRITE, &old_protect)){ if(hook_create_trampoline(addr,hook_types[type].len,h->tramp)){ hook_store_exception_info(h); uint8_t special=0; if(h->allow_hook_recursion==1){ special=1; } hook_create_pre_tramp(h,special); // insert the hook (jump from the api to the // pre-trampoline) ret=hook_types[type].hook(h,addr,h->pre_tramp); // if successful, assign the trampoline address to *old_func if(ret==0){ *h->old_func=h->tramp; // successful hook is successful h->is_hooked=1; } } // restore the old protection VirtualProtect(addr,hook_types[type].len,old_protect, &old_protect); } } returnret; } |
4.躲避的应对
前面软件加壳技术介绍的时候有部分内容关于躲避。恶意软件会创建自进程,在子进程中做实际工作。对于类似Cuckoo这样的动态分析工具就要处理这种情况,在子进程中启动cuckoomon。下图就是应对流程,Monitor在监控到样本创建进程的时候,也会模拟初始化启动时候cuckoo做的事情,显示suspend,然后通知Analyzer。由后者进行DLL的注入。
From 【5】
前文也介绍过进程注入,也就是恶意软件利用周知进程,例如IE,运行自己的恶意逻辑,解决的方法类似。只是监控的不是CreateProcess而是OpenProcess。
【参考】
1.官方网站,http://www.cuckoosandbox.org/
2.Cuckoo Sandbox Book,http://cuckoo.readthedocs.org/en/latest/
3.Hooking functions with Cuckoobox’s hooking engine,http://living-security.blogspot.com/2014/07/hooking-functions-with-cuckooboxs.html
4.开源软件 cuckoo sandbox学习(二) 核心拦截模块源代码导读, http://sevemal.blog.51cto.com/8627322/1397666
5.Haow Sandbox, Cuckoo Sandbox Internal, http://recon.cx/2013/slides/recon2013-Jurriaan%20Bremer-Haow%20do%20I%20sandbox.pdf
相关文章推荐
- WebService:JAX-WS实现WebService
- 几张SVG矢量图看明所有操作系统之间的演进关系
- JavaWeb实现文件上传与下载的方法
- iftop安装教程和一些参数和命令
- 对 c\c++ char类型的理解
- 前端开发,浮动元素居中技巧
- Spark学习之基础相关组件(1)
- php常用类和方法(笔记)
- Spark学习之基础相关组件(1)
- Linux CentOS 6 64位系统安装Git工具环境教程
- 【哈工大oj】1037 - 组合数末尾的零(位运算,好题)
- hashCode散列码
- SQL存储过程
- JVM学习笔记(三)---类加载器补充
- mysql学习(1):win_64位下载,安装,配置mysql-5-winx64详细步骤
- 如何使用 Docker、ECS、Terraform 重建基础架构?
- CRC校验算法及实现 C
- WdatePicker 日历控件使用方法+基本常用方法
- Swift中文教程(五)控制流
- Redis数据类型与基本操作