![【技术原创】渗透基础——获得域用户的登录信息 【技术原创】渗透基础——获得域用户的登录信息]()
0x00 前言
在域渗透中,获得了域控制器权限后,需要获得域用户的登录信息,包括域用户登录的IP地址和登录时间。通常使用的方法是查看域控制器的登录日志(Eventid=4624)。然而,人工从登录日志(Eventid=4624)中筛选出域用户登录的IP地址和登录时间需要耗费大量时间,不仅无效数据多,而且需要多次判断,所以我们需要编写程序来实现这个功能。
在实际使用过程中,为了能够适配多种环境,还需要支持本地和多种协议的远程登录。于是本文将要分享我的实现方法,开源两个工具,记录细节。
![【技术原创】渗透基础——获得域用户的登录信息 【技术原创】渗透基础——获得域用户的登录信息]()
0x01 简介
本文将要介绍以下内容:
通过EventLogSession实现
通过WMI实现
开源代码
![【技术原创】渗透基础——获得域用户的登录信息 【技术原创】渗透基础——获得域用户的登录信息]()
0x02 通过EventLogSession实现
通过查询资料发现,通过EventLogSession不仅支持解析本地日志内容,还支持通过RPC远程解析日志,下面介绍关于EventLogSession的开发细节
1.输出Eventid=4624的日志内容
C Sharp实现代码:
using System;using System.Diagnostics.Eventing.Reader;namespace Test1{ class Program { static void Main(string[] args) { var session = new EventLogSession(); string LogName = "Security"; string XPathQuery = "*[System/EventID=4624]"; EventLogQuery eventLogQuery = new EventLogQuery(LogName, PathType.LogName, XPathQuery) { Session = session, TolerateQueryErrors = true, ReverseDirection = true }; using (EventLogReader eventLogReader = new EventLogReader(eventLogQuery)) { eventLogReader.Seek(System.IO.SeekOrigin.Begin, 0); do { EventRecord eventData = eventLogReader.ReadEvent(); if (eventData == null) break; Console.WriteLine(eventData.FormatDescription()); eventData.Dispose(); } while (true); } } }}
以上代码能够查询本地日志并输出日志的完整内容
2.xml格式解析
为了便于提取内容,可以选择将输出内容转换为xml格式
关键代码:
Console.WriteLine(eventData.ToXml());
输出内容示例:
从xml格式中,可直接提取出EventRecordID,关键代码:
XmlDocument xmldoc = new XmlDocument();xmldoc.LoadXml(eventData.ToXml());XmlNodeList recordid = xmldoc.GetElementsByTagName("EventRecordID");Console.WriteLine(recordid[0].InnerText);
提取TargetUserName需要先取出Data的内容,再做一个筛选,关键代码:
XmlNodeList data = xmldoc.GetElementsByTagName("Data");foreach (XmlNode value in data){ if (value.OuterXml.Contains("TargetUserName")) { Console.WriteLine(value.InnerText); }}
这里我们一共需要筛选出以下属性:
TargetUserSid
TargetDomainName
TargetUserName
IpAddress
在做字符匹配时,由于格式固定,所以我们可以从固定偏移位置得到对应的属性,避免多次判断,提高查询效率
关键代码:
XmlNodeList data = xmldoc.GetElementsByTagName("Data");String targetUserSid = data[4].InnerText;String targetDomainName = data[6].InnerText;String targetUserName = data[5].InnerText;String ipAddress = data[18].InnerText;
3.筛选判断条件
为了筛选出有效登录信息,这里对targetUserSid和ipAddress的长度做了判断,targetUserSid长度需要大于9,ipAddress长度需要大于8
关键代码:
XmlNodeList data = xmldoc.GetElementsByTagName("Data");String targetUserSid = data[4].InnerText;String targetDomainName = data[6].InnerText;String targetUserName = data[5].InnerText;String ipAddress = data[18].InnerText;if (targetUserSid.Length > 9 && ipAddress.Length > 8){ Console.WriteLine(targetUserSid); Console.WriteLine(targetDomainName); Console.WriteLine(targetUserName); Console.WriteLine(ipAddress);}
4.支持筛选指定时间内的日志
可以通过修改搜索条件实现,关键代码:
string XPathQuery = "(Event/System/EventID=4624) and Event/System/TimeCreated/@SystemTime >= '2022-01-26T02:30:39' and Event/System/TimeCreated/@SystemTime = '2022-01-26T02:30:39' and Event/System/TimeCreated/@SystemTime =20210526 AND TimeGenerated=20210526 AND TimeGenerated<=20220426"; ManagementScope s = new ManagementScope("root\CIMV2"); SelectQuery q = new SelectQuery(queryString); ManagementObjectSearcher mos = new ManagementObjectSearcher(s, q); int flagTotal = 0; int flagExist = 0; foreach (ManagementObject o in mos.Get()) { flagTotal++; String Message = o.GetPropertyValue("Message").ToString(); int pos1 = Message.LastIndexOf("Security ID"); int pos2 = Message.LastIndexOf("Account Name"); int pos3 = Message.LastIndexOf("Account Domain"); int pos4 = Message.LastIndexOf("Logon ID"); int pos5 = Message.LastIndexOf("Source Network Address"); int pos6 = Message.LastIndexOf("Source Port"); int length1 = pos2 - pos1 - 16; int length2 = pos4 - pos3 - 20; int length3 = pos3 - pos2 - 17; int length4 = pos6 - pos5 - 27; if (length1 < 0 || length2 < 0 || length3 < 0 || length4 < 0) continue; String targetUserSid = Message.Substring(pos1+14, length1); String targetDomainName = Message.Substring(pos3 + 17, length2); String targetUserName = Message.Substring(pos2 + 15, length3); String ipAddress = Message.Substring(pos5 + 24, length4); { Console.WriteLine("[+] EventRecordID: " + o.GetPropertyValue("RecordNumber")); Console.WriteLine(" TimeCreated : " + o.GetPropertyValue("TimeGenerated")); Console.WriteLine(" UserSid: " + targetUserSid); Console.WriteLine(" DomainName: " + targetDomainName); Console.WriteLine(" UserName: " + targetUserName); Console.WriteLine(" IpAddress: " + ipAddress); flagExist++; } } Console.WriteLine("Total: " + flagTotal + ", Exist: " + flagExist); } }}
5.支持远程登录
关键代码:
var opt = new ConnectionOptions(); ;opt.Username = "TEST\Administrator";opt.Password = "Password@123";ManagementScope s = new ManagementScope("\\192.168.1.1\root\CIMV2", opt);
将以上代码整合,得出最终代码,代码已上传至github,地址如下:
https://github.com/3gstudent/Homework-of-C-Sharp/blob/master/SharpGetUserLoginIPWMI.cs
代码支持以下功能:
可使用csc.exe进行编译,支持3.5和4.0
支持本地和远程日志解析,远程日志解析使用WMI方式
支持判断条件,可筛选指定日期
自动提取信息:EventRecordID、TimeCreated、UserSid、DomainName、UserName和IpAddress
![【技术原创】渗透基础——获得域用户的登录信息 【技术原创】渗透基础——获得域用户的登录信息]()
0x04 小结
本文介绍了获得域用户登录信息的实现细节,开源两个工具SharpGetUserLoginIPRPC.cs和SharpGetUserLoginIPWMI.cs,在通信效率上,RPC要快于WMI。
原文始发于微信公众号(嘶吼专业版):【技术原创】渗透基础——获得域用户的登录信息
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论