• PassUAC的简单实现(二)


    四、通过管理员创建进程的流程

    在第一篇中大致了解了每一个进程都有一个权限之后,这里简单了解一下管理员进程的创建。

    https://github.com/xyddnljydd/PassUAC

    首先来感受一下进程的创建步骤:

    1、右键管理员启动一个进程

    2、会弹出一个对话框,询问用户是否要以管理员的身份打开进程

    3、当点击是之后会打开一个管理员身份创建的进程,点击否则什么也没有发生一样,且进程树也是挂载explore下面的

    4、实际真的是这么简单的吗?explore创建一个弹窗,询问用户是否要创建进程,得到用户的许可之后创建管理员身份的进程?这里要既然要做验证可以直接附加到explore进程上面去,对ntdll!NtCreateUserProcess下一个断点就行了。

    5、可以发现这个弹窗出来了,但是没有断下,说明创建这个对话框的进程并不是explore,那是什么进程?

    6、最简单的当时写一个进程回调的驱动,看一下是谁创建的,但是有的兄弟对驱动开发不是很了解,所以这里利用ProcMon来监控一下,”犯人“是谁?从下图中可以看到是svchost进程启动了consent进程,从进程的描述大致也能知道就是用来画界面的。

    7、现在知道了是svchost创建的,但是这个是系统的服务我们该如何去分析这个东西,这里在拓展一些知识,不知道小伙伴有没有写过服务程序,就是用scm系列的api注册一个服务,然后启动,可以选择开机启动还是手动启动。其中有一些服务叫做共享服务,这类服务通常是dll,而加载这些服务的就是svchost进程。

    8、那么从上述描述中我们知道了Svchost就是弹出对话框的那个进程,其中Svchost中的某个服务完成了上面的操作,那么直接附加到该进程,下断点就能知道到底是那个dll在处理这些流程,从下面的栈中得到了两个有用的信息。

    1)处理UAC事件的服务是appinfo这个共享进程(这里面有很多细节,没有说,比如对话框它等待多久之后会消失,哪些白名单不弹框之类的,感兴趣可以自己去看一下)

    2)appinfo服务是通过RPC接收和发送事件的(其实是ALPC,但是ALPC是RPC的子类)

    9、那么思路也逐渐清晰起来,当用户右键管理员创建进程的时候,explore会发送一个RPC事件给appinfo这个服务进程,当appinfo收到这个事件之后会创建一个对话框询问是否真的要创建一个进程,当用户点击是之后,才将进程真正的创建起来,下图是函数第二次断下的时候,可以看到,在我点击是之后appinfo以管理身份创建了KmdManager进程

    10、既然能够通过RPC的方式发送请求,那么我们是否可以不通过explore,直接给appinfo发消息,创建进程,当然是可以的,这块只需要定义函数的原型,将它写入到一个idl文件和acf文件,就能直接使用了,查找函数原型和idl的定义在之前写的文件替换漏洞有说明,这里就不在赘述了,定义的idl文件如下

    [
    	uuid(201ef99a-7fa0-444c-9399-19ba84f12a1a),
    	version(1.0),
    ]
    interface boo
    {
    
    	typedef struct _MONITOR_POINT {
    		long MonitorLeft;
    		long MonitorRight;
    	} MONITOR_POINT;
    
    	typedef struct _APP_STARTUP_INFO {
    		wchar_t* lpszTitle;
    		long dwX;
    		long dwY;
    		long dwXSize;
    		long dwYSize;
    		long dwXCountChars;
    		long dwYCountChars;
    		long dwFillAttribute;
    		long dwFlags;
    		short wShowWindow;
    		struct _MONITOR_POINT MonitorPoint;
    	} APP_STARTUP_INFO;
    
    	typedef struct _APP_PROCESS_INFORMATION {
    		unsigned __int3264 ProcessHandle;
    		unsigned __int3264 ThreadHandle;
    		long  ProcessId;
    		long  ThreadId;
    	} APP_PROCESS_INFORMATION;
    
    	long RAiLaunchAdminProcess(
    		handle_t hBinding,
    		[in][unique][string] wchar_t* ExecutablePath,
    		[in][unique][string] wchar_t* CommandLine,
    		[in]long StartFlags,
    		[in]long CreationFlags,
    		[in][string] wchar_t* CurrentDirectory,
    		[in][string] wchar_t* WindowStation,
    		[in]struct _APP_STARTUP_INFO* StartupInfo,
    		[in]unsigned __int3264 hWnd,
    		[in]long Timeout,
    		[out]struct _APP_PROCESS_INFORMATION* ProcessInformation,
    		[out]long* ElevationType);
    
    }

    11、接口的定义处理好之后来看一看我们感兴趣的参数,其实就是第三个参数StartFlags,这个标志位代表是按照管理员方式启动一个进程还是非管理员,0是非管理员。

    12、好了这里我们直接把flag改为1,启动进程试试看,会发现还是有UAC的弹窗出现,置为0虽然能创建进程,但是是一个非管理员权限的进程,也没有什么用(想要尝试的话,只想要把github上的代码拉下来调用对应的AicLaunchAdminProcess函数就行)

    13、最后就写到这里,具体怎么利用之后“有时间”再说

  • 相关阅读:
    iscsi: 多路径
    Paxos算法分析
    ceph实践: 搭建环境
    ocfs2: 搭建环境
    设计模式:Context模式
    Ceph剖析:Leader选举
    Ceph剖析:定时器safetimer的实现
    nfs:环境搭建
    Ceph剖析:数据分布之CRUSH算法与一致性Hash
    Linux命令小结:crontab/netstat/iostat/sar
  • 原文地址:https://www.cnblogs.com/csnd/p/16675589.html
Copyright © 2020-2023  润新知