• 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文件如下

    1. [
    2. uuid(201ef99a-7fa0-444c-9399-19ba84f12a1a),
    3. version(1.0),
    4. ]
    5. interface boo
    6. {
    7. typedef struct _MONITOR_POINT {
    8. long MonitorLeft;
    9. long MonitorRight;
    10. } MONITOR_POINT;
    11. typedef struct _APP_STARTUP_INFO {
    12. wchar_t* lpszTitle;
    13. long dwX;
    14. long dwY;
    15. long dwXSize;
    16. long dwYSize;
    17. long dwXCountChars;
    18. long dwYCountChars;
    19. long dwFillAttribute;
    20. long dwFlags;
    21. short wShowWindow;
    22. struct _MONITOR_POINT MonitorPoint;
    23. } APP_STARTUP_INFO;
    24. typedef struct _APP_PROCESS_INFORMATION {
    25. unsigned __int3264 ProcessHandle;
    26. unsigned __int3264 ThreadHandle;
    27. long ProcessId;
    28. long ThreadId;
    29. } APP_PROCESS_INFORMATION;
    30. long RAiLaunchAdminProcess(
    31. handle_t hBinding,
    32. [in][unique][string] wchar_t* ExecutablePath,
    33. [in][unique][string] wchar_t* CommandLine,
    34. [in]long StartFlags,
    35. [in]long CreationFlags,
    36. [in][string] wchar_t* CurrentDirectory,
    37. [in][string] wchar_t* WindowStation,
    38. [in]struct _APP_STARTUP_INFO* StartupInfo,
    39. [in]unsigned __int3264 hWnd,
    40. [in]long Timeout,
    41. [out]struct _APP_PROCESS_INFORMATION* ProcessInformation,
    42. [out]long* ElevationType);
    43. }

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

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

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

  • 相关阅读:
    RS-232协议详解:深入理解与实际应用
    luffy-(7)
    C++ 协程 学习笔记
    MySQL 基础知识(一)之数据库和 SQL 概述
    DITTEL控制器维修SENSITRON6-2AE
    MySQL主从分离读写复制
    Redis分区/分片详解
    TensorBoard可视化处理案例简析
    计算机二级备考:Word 部分_2 排版
    【UE5.1 角色练习】09-物体抬升、抛出技能 - part1
  • 原文地址:https://blog.csdn.net/lyshark_lyshark/article/details/126793150