关于父进程和子进程的关系(UAC 绕过思路)

关于父进程和子进程的关系(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;


这里有个没有公开的PROC_THREAD_ATTRIBUTE_LIST 结构,这个结构须要通过InitializeProcThreadAttributeList() 函数来进行初始化,通过UpdateProcThreadAttribute()函数加入设置属性。我们仅仅须要加入PROC_THREAD_ATTRIBUTE_PROCESS 属性。而且提供一个(有足够权限的)进程句柄。就能能设置这个被创建进程的父进程,这里也仿照黑防上贴下部分代码:

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;


以上就是伪造explorer.exe为calc.exe的父进程。 假设你调试的程序检測父进程,直接用以上的办法启动它,当然父进程就是他检測同意的父进程喽, 这里启动时要注意的是设置CREATE_SUSPEND 就是创建挂起,然后在创建后使用ResumeThread恢复就能够顺利调试了。

所以说进程的父进程不一定是进程的创建者,所以那一群依据父进程来看进程是否可信的杀软就呵呵了。 可是这里说下 360 这个绕只是,原因是啥哪? 记得我开篇时说过道高一尺,魔高一丈吗?事实上在MSDN中还有个函数PsSetCreateProcessNotifyRoutine(), 这个函数就是设置监控回调函数,而且接受一个指向PS_CREARTE_NOTIFY_INFO的结构的指针, 通常我们所觉得的ParentProcesId 成员为父进程的PID。可是这个结构有一个成员为CreateThreadId,当中的CreatingThreadId->UniqueProcess 为真正进程的创建者(也就是CreateProcess* 函数的调用者)。用这样的办法推断父进程才是真正的父进程。
这里參考文献是杂志《黑客防线》。我也不想学习了知识装起来。所以学习始终是学无止境!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108568.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 数据库原理期末考试题(经典题型)「建议收藏」

    数据库原理期末考试题(经典题型)「建议收藏」数据库原理期末考试题(经典题型)

  • phpstorm PhpStorm 2021.3.20 激活码 3月最新注册码

    phpstorm PhpStorm 2021.3.20 激活码 3月最新注册码,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • SpringCloud SpringCloud与Dubbo的区别

    SpringCloud SpringCloud与Dubbo的区别(1)SpringCloud与Dubbo的服务治理框架全局性对比(2)最大的区别:SpringCloud抛弃了Dubbo的RPC通信,采用了基于HTTP的REST方式。严格来说,这两种方式各有优劣,虽然从一定程度上来说,后者牺牲了服务调用的性能,但是也避免了RPC带来的问题,并且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸协议,不存在代码的强依赖性,这在强调快速演化稍…

  • vue的table表格_vue elementui表格

    vue的table表格_vue elementui表格新入职的公司让我学习下Vue,以前没怎么学过,最近开始学习,记录下每天学习的内容,借鉴了很多前辈们的资料,如有冒犯,还请原谅。开始我做的是动态表格,但是发现不会调整宽度,于是就改成了下面的样子,用着更舒服一些。先记录下来,免的以后想用找不到。先看下效果图。本人比较懒,就写了一行,下面上代码。<template> <el-table:data=”tableDa…

  • 各大免费邮箱邮件群发账户SMTP服务器配置及SMTP发送量限制情况

    各大免费邮箱邮件群发账户SMTP服务器配置及SMTP发送量限制情况分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!点击浏览教程网络产品推广和新闻消息推送时,经常用到的工具就是用客户邮箱发送邮件了,如果是要发送的邮件量非常大的话,一般的建议是搭建自己的邮局服务器,或者是花钱购买专业的邮件群发服务,免费邮箱的SMTP适合少量的邮件群发需求。例如Wordpress的评论邮件通知功能,每天要发送的邮件数量…

  • 对Spring的IOC和AOP的理解,可做面试题用「建议收藏」

    对Spring的IOC和AOP的理解,可做面试题用「建议收藏」IOC:控制反转,也叫DI依赖注入,它并不是一种技术实现,而是一种设计思想。在实际项目开发中,我们往往是通过类与类之间的相互协作来完成特定的业务逻辑,这个时候,每个类都要管理与自己有交互的类的引用和依赖,这就使得代码的维护异常困难并且耦合度过高,而IOC的出现正是为了解决这个问题,IOC将类与类的依赖关系写在配置文件中,程序在运行时根据配置文件动态加载依赖的类,降低的类与类之间的耦合度。它的原…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号