跳转到帖子
  • 游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

    赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

    TheHackerWorld官方

渗透基础——获得域用户的登录信息


尖REN

推荐的帖子

0x00 前言

在域渗透中,获得了域控制器权限后,需要获得域用户的登录信息,包括域用户登录的互联网协议(互联网协议)地址和登录时间。通常使用的方法是查看域控制器的登录日志(事件id=4624)。然而,人工从登录日志(事件id=4624)中筛选出域用户登录的互联网协议(互联网协议)地址和登录时间需要耗费大量时间,不仅无效数据多,而且需要多次判断,所以我们需要编写程序来实现这个功能。

在实际使用过程中,为了能够适配多种环境,还需要支持本地和多种协议的远程登录。于是本文将要分享我的实现方法,开源两个工具,记录细节。

0x01 简介

本文将要介绍以下内容:

通过EventLogSession实现

通过WMI实现

开源代码

0x02 通过EventLogSession实现

通过查询资料发现,通过EventLogSession不仅支持解析本地日志内容,还支持通过位置遥控(远程位置控制)远程解析日志,下面介绍关于EventLogSession的开发细节

1.输出Eventid=4624的日志内容

升c调实现代码:

使用系统;

使用系统诊断。事件。读者

命名空间测试1

{

班级计划

{

静态void Main(string[] args)

{

var session=新事件日志会话();

字符串LogName=' Security

string XPath query=' *[系统/事件id=4624]';

事件日志查询事件日志查询=新事件日志查询(日志名,路径类型。日志名,XPathQuery)

{

会话=会话,

TolerateQueryErrors=true,

ReverseDirection=true

};

使用(事件日志读取器事件日志读取器=新事件日志读取器(事件日志查询))

{

eventLogReader .求(系统10 . IO。SeekOrigin.Begin,0);

{

事件记录事件数据=事件日志阅读器.ReadEvent();

if (eventData==null)

打破;

控制台WriteLine(eventData .格式描述());

事件数据dispose();

}而(真);

}

}

}

}

以上代码能够查询本地日志并输出日志的完整内容

2.xml格式解析

为了便于提取内容,可以选择将输出内容转换为可扩展标记语言格式

关键代码:

控制台WriteLine(eventData .to XML());

输出内容示例:

DC 1。测试。com s-1-0-0-0x0s-1-5-21-254706111-4049838133-2416586677-2102测试1测试0xa 222 FB 53 ntl mssp NTLM { 0000000-000

从可扩展标记语言格式中,可直接提取出EventRecordID,关键代码:

XML文档XML doc=new XML document();

xmldoc .LoadXml(eventData .to XML());

XmlNodeList recordid=xmldoc .GetElementsByTagName(“event recordid”);

控制台WriteLine(recordid[0])InnerText);

提取目标用户名需要先取出数据的内容,再做一个筛选,关键代码:

XmlNodeList data=xmldoc .GetElementsByTagName(' Data ');

foreach(数据中的XmlNode值)

{

如果(值外部XML。包含(“目标用户名”))

{

控制台WriteLine(值InnerText);

}

}

这里我们一共需要筛选出以下属性:

TargetUserSid

目标域名

目标用户名

互联网协议(Internet Protocol)地址

在做字符匹配时,由于格式固定,所以我们可以从固定偏移位置得到对应的属性,避免多次判断,提高查询效率

关键代码:

XmlNodeList data=xmldoc .GetElementsByTagName(' Data ');

String targetUserSid=data[4].内部文本

String targetDomainName=data[6].内部文本

String targetUserName=data[5].内部文本

String ipAddress=data[18].内部文本

3.筛选判断条件

为了筛选出有效登录信息,这里对targetUserSid和互联网协议(Internet Protocol)地址的长度做了判断,targetUserSid长度需要大于9、知识产权地址长度需要大于8

关键代码:

XmlNodeList data=xmldoc .GetElementsByTagName(' Data ');

String targetUserSid=data[4].内部文本

String targetDomainName=data[6].内部文本

String targetUserName=data[5].内部文本

String ipAddress=data[18].内部文本

if (targetUserSid .长度9地址.长度8)

{

控制台WriteLine(目标用户id);

控制台WriteLine(目标域名);

控制台WriteLine(目标用户名);

控制台WriteLine(IP地址);

}

4.支持筛选指定时间内的日志

可以通过修改搜索条件实现,关键代码:

字符串XPath查询='(事件/系统/事件id=4624)和事件/系统/创建时间/@ System time=' 2022-01-26t 02:30:39 '和事件/系统/时间创建/@ System time=' 2022-01-26t 02:31:00 ';

至此,通过EventLogSession解析本地登录日志的实现代码如下:

使用系统;

使用系统诊断。事件。读者

使用系统. Xml

命名空间测试1

{

班级计划

{

静态void Main(string[] args)

{

var session=新事件日志会话();

字符串LogName=' Security

字符串XPath查询='(事件/系统/事件id=4624)和事件/系统/创建时间/@ System time=' 2022-01-26t 02:30:39 '和事件/系统/时间创建/@ System time=' 2022-01-26t 02:31:00 ';

事件日志查询事件日志查询=新事件日志查询(日志名,路径类型。日志名,XPathQuery)

{

会话=会话,

TolerateQueryErrors=true,

ReverseDirection=true

};

int flag total=0;

int标志存在=0;

使用(事件日志读取器事件日志读取器=新事件日志读取器(事件日志查询))

{

eventLogReader .求(系统10 . IO。SeekOrigin.Begin,0);

{

事件记录事件数据=事件日志阅读器.ReadEvent();

if (eventData==null)

打破;

标志总数;

XML文档XML doc=new XML document();

xmldoc .LoadXml(eventData .to XML());

XmlNodeList recordid=xmldoc .GetElementsByTagName(“event recordid”);

XmlNodeList data=xmldoc .GetElementsByTagName(' Data ');

String targetUserSid=data[4].内部文本

String targetDomainName=data[6].内部文本

String targetUserName=data[5].内部文本

String ipAddress=data[18].内部文本

if (targetUserSid .长度9地址.长度8)

{

控制台WriteLine("[]event recordid:' recordid[0]" .InnerText);

控制台WriteLine('创建时间:'事件数据.创建时间);

控制台WriteLine('用户id:'目标用户id ');

控制台WriteLine('域名:'目标域名');

控制台WriteLine('用户名:‘目标用户名’);

控制台WriteLine(' IP地址:' IP地址');

标志存在;

}

事件数据dispose();

}而(真);

控制台WriteLine('Total: ' flagTotal ',Exist:' flag Exist));

}

}

}

}

5.支持远程登录

关键代码:

字符串服务器=' 192。168 .1 .1 ';

字符串domain=' TEST

字符串用户='管理员

字符串password=' Password @ 123

安全字符串secure pwd=new secure string();

foreach(密码中的字符c)

{

securePwd .AppendChar(c);

}

var session=new EventLogSession(服务器,域,用户,securePwd,SessionAuthentication .协商);

将以上代码整合,得出最终代码,代码已上传至github,地址如下:

https://github。com/3g student/home-of-C-Sharp/blob/master/sharpgetuserloginiprc。铯

代码支持以下功能:

可使用csc.exe进行编译,支持3.5和4.0

支持本地和远程日志解析,远程日志解析使用位置遥控(远程位置控制)方式

支持判断条件,可筛选指定日期

自动提取信息:事件记录身份证,创建时间、用户身份证,域名、用户名和互联网协议(Internet Protocol)地址

0x03 通过WMI实现

1.wmi语法测试

查询语法和属性名称可以借助wbemtest进行研究,关于wbemtest的用法可参考之前的文章《渗透基础——WMIC的使用》

查询安全性日志需要管理员权限运行wbemtest

点击询问.

查询所有安全性日志:

Select * from Win32_NTLogEvent其中日志文件='安全'

查询Eventid=4672的所有日志:

Select * from Win32_NTLogEvent其中日志文件='安全'和事件代码=4624

查询EventRecordID=113438的日志:

Select * from Win32_NTLogEvent其中日志文件='安全'和记录编号=113438

结合以上信息,我们不难写出wmic的查询命令:

wmic/namespace:\ \ root \ CIM v2路径win32 _ ntlog事件其中日志文件='安全'和记录编号=113438 '

筛选出我们需要的信息:

wmic/namespace:\ \ root \ CIM v2 path win32 _ ntlog event where ' log file=' Security ' AND event code=4624 ' get record number,TimeGenerated,Message

记录号对应为EventRecordID,TimeGenerated为日志创建时间,消息中需要筛选出以下内容:

安全身份证明

帐户域

帐户名

源网络地址

筛选功能我们可以通过批处理或者Powershell实现,但是考虑到兼容性和后续利用接口的统一,这里同样选择升c调实现

2.输出RecordNumber=131的日志内容

实现代码:

使用系统;

使用系统。管理;

命名空间测试2

{

班级计划

{

静态void Main(string[] args)

{

字符串查询string=' SELECT * FROM Win32 _ ntlog event Where log file=' Security ' AND record number=131 ';

管理范围s=新的管理范围(' root \ \ CIM v2 ');

select query q=new select query(查询字符串);

管理对象搜索器mos=新管理对象搜索器(s,q);

foreach(mos中的管理对象o .Get())

{

属性数据收集搜索器Properties=o . Properties

foreach(搜索属性中的属性数据sp)

{

控制台WriteLine('Name={0,-20},Value={1,-20} ',sp。姓名,sp .值);

}

}

}

}

}

从输出结果中发现,同wmic的命令执行结果相同:

记录号对应为EventRecordID,TimeGenerated为日志创建时间,消息中需要筛选出以下内容:

安全身份证明

帐户域

帐户名

源网络地址

3.筛选判断条件

为了筛选出有效登录信息,这里对targetUserSid和互联网协议(Internet Protocol)地址的长度做了判断,targetUserSid长度需要大于9、知识产权地址长度需要大于8

关键代码:

string Message=o . GetPropertyValue(' Message ').ToString();

int pos1=消息LastIndexOf(“安全ID”);

int pos2=消息LastIndexOf('帐户名');

int pos3=消息LastIndexOf(“帐户域");

int pos4=消息LastIndexOf(“登录ID”);

int pos5=消息LastIndexOf(“源网络地址");

int pos6=消息LastIndexOf(“源端口");

int length 1=pos 2-pos 1-16;

int length 2=pos 4-pos 3-20;

int length 3=pos 3-pos 2-17;

int length 4=pos 6-pos 5-27;

如果(长度1 0 ||长度2 0 ||长度3 0 ||长度4 0)

继续;

String targetUserSid=Message .子串(pos1 14,长度1);

String targetDomainName=Message .子串(pos3 17,长度2);

字符串目标用户名=消息.子串(pos2 15,长度3);

字符串ipAddress=Message .子串(pos5 24,长度4);

if (targetUserSid .长度9地址.长度8)

{

控制台WriteLine('[]EventRecordID:' o . GetPropertyValue('记录号'));

控制台WriteLine(' time created:' o . GetPropertyValue(' time generated '));

控制台WriteLine('用户id:'目标用户id ');

控制台WriteLine('域名:'目标域名');

控制台WriteLine('用户名:‘目标用户名’);

控制台WriteLine(' IP地址:' IP地址');

}

4.支持筛选指定时间内的日志

可以通过修改搜索条件实现,关键代码:

字符串查询string=' SELECT * FROM Win32 _ ntlog event Where log file=' Security ' AND event code=4624 AND time generated=20210526 AND time generated=20220426 ';

至此,通过WMI解析本地登录日志的实现代码如下:

使用系统;

使用系统。管理;

命名空间测试2

{

班级计划

{

静态void Main(string[] args)

{

字符串查询string=' SELECT * FROM Win32 _ ntlog event Where log file=' Security ' AND event code=4624 AND time generated=20210526 AND time generated=20220426 ';

管理范围s=新的管理范围(' root \ \ CIM v2 ');

select query q=new select query(查询字符串);

管理对象搜索器mos=新管理对象搜索器(s,q);

int flag total=0;

int标志存在=0;

foreach(mos中的管理对象o .Get())

{

标志总数;

string Message=o . GetPropertyValue(' Message ').ToString();

int pos1=消息LastIndexOf(“安全ID”);

int pos2=消息LastIndexOf('帐户名');

int pos3=消息LastIndexOf(“帐户域");

int pos4=消息LastIndexOf(“登录ID”);

int pos5=消息LastIndexOf(“源网络地址");

int pos6=消息LastIndexOf(“源端口");

int length 1=pos 2-pos 1-16;

int length 2=pos 4-pos 3-20;

int length 3=pos 3-pos 2-17;

int length 4=pos 6-pos 5-27;

如果(长度1 0 ||长度2 0 ||长度3 0 ||长度4 0)

继续;

String targetUserSid=Message .子串(pos1 14,长度1);

String targetDomainName=Message .子串(pos3 17,长度2);

字符串目标用户名=消息.子串(pos2 15,长度3);

字符串ipAddress=Message .子串(pos5 24,长度4);

{

控制台WriteLine('[]EventRecordID:' o . GetPropertyValue('记录号'));

控制台WriteLine(' time created:' o . GetPropertyValue(' time generated '));

控制台WriteLine('用户id:'目标用户id ');

控制台WriteLine('域名:'目标域名');

控制台WriteLine('用户名:‘目标用户名’);

控制台WriteLine(' IP地址:' IP地址');

标志存在;

}

}

控制台WriteLine('Total: ' flagTotal ',Exist:' flag Exist));

}

}

}

5.支持远程登录

关键代码:

var opt=新连接选项();

选择。用户名='测试\ \管理员;

选择Password=' Password @ 123

管理范围s=新的管理范围(' \ \ \ \ 192。168 .1 .1 \ \ root \ \ CIM v2 ',opt);

将以上代码整合,得出最终代码,代码已上传至github,地址如下:

https://github。com/3g student/home-of-C-Sharp/blob/master/sharpgetuserloginipwmi。铯

代码支持以下功能:

可使用csc.exe进行编译,支持3.5和4.0

支持本地和远程日志解析,远程日志解析使用WMI方式

支持判断条件,可筛选指定日期

自动提取信息:事件记录身份证,创建时间、用户身份证,域名、用户名和互联网协议(Internet Protocol)地址

0x04 小结

本文介绍了获得域用户登录信息的实现细节,开源两个工具SharpGetUserLoginIPRPC.cs和SharpGetUserLoginIPWMI.cs,在通信效率上,RPC要快于WMI。

留下回复

链接帖子
意见的链接
分享到其他网站

黑客攻防讨论组

黑客攻防讨论组

    You don't have permission to chat.
    • 最近浏览   0位会员

      • 没有会员查看此页面。
    ×
    ×
    • 创建新的...