四、通过管理员创建进程的流程
在第一篇中大致了解了每一个进程都有一个权限之后,这里简单了解一下管理员进程的创建。
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、最后就写到这里,具体怎么利用之后“有时间”再说
