解题步骤
首先对main函数进行分析,可以看出主要的内容都在创建的线程中。线程之间通过全局变量实现同步,静态分析即可看出执行顺序。
线程一:
使用rc4初始化block,key为MessageBoxA,长度为0x3478,之后信号量变为3。
线程三:
使用base32加密block中的内容
线程二:
用来进行反调试的线程,原理很简单,就是定时校验代码段的完整性,在线程启动前将断点打好就可以绕过。还有查看drx7寄存器的状态来判断硬件断点。
知道这些就没必要一个一个加密进行分析了,直接打断点看一看这个资源加密(或者该说是解密后的样子,定位到最后一个对该资源地址操作的地址,在线程六中打断点即可看到资源被解密成了一个pe文件,在线程六中作为子进程启动。
将该pe文件dump出来即可进行分析,子进程用到了MapViewOfFile函数,实现对输入的访问,对输入的后半段进行tea加密后,与密文进行比较,返回比较结果。
输入的其余部分在线程七中进行tea加密,两段tea差别在于key不一样,对两段tea进行解密即可得到flag。
一些收获
提升进程权限
提升权限代码,要对一个任意进程给予相应的权限,要修改进程的访问令牌,首先要获得进程的访问令牌,通过以下代码可以获取访问令牌
1
| OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)
|
之后对令牌进行检查和修改
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
| #include <windows.h> #include <stdio.h> #pragma comment(lib, "advapi32.lib")
BOOL SetPrivilege( HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege ) { TOKEN_PRIVILEGES tp; LUID luid;
if ( !LookupPrivilegeValue( NULL, lpszPrivilege, &luid ) ) { printf("LookupPrivilegeValue error: %u\n", GetLastError() ); return FALSE; }
tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0;
if ( !AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) { printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); return FALSE; }
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{ printf("The token does not have the specified privilege. \n"); return FALSE; }
return TRUE; }
|
检测硬件断点
这段代码首先会用GetThreadContext来获取drx7寄存器的值,判断是否存在硬件断点,判断存在硬件断点后,试图去掉硬件断点,也就是给drx7赋值为0,如果不行就退出进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| int sub_4015E0() { HANDLE CurrentThread; CONTEXT Context;
memset(&Context.Dr0, 0, 0x2C8u); Context.ContextFlags = 65599; CurrentThread = GetCurrentThread(); if ( !GetThreadContext(CurrentThread, &Context) || !Context.Dr7 ) return 0; Context.Dr7 = 0; SetThreadContext(CurrentThread, &Context); Context.ContextFlags = 65599; if ( GetThreadContext(CurrentThread, &Context) ) { if ( Context.Dr7 ) ExitProcess(0xFFFFFF9D); } return 1; }
|