从开始到放弃,手搓 Go 类 ADFind

摸鱼项目

前言

最近研究了一下委派攻击:

  1. 非约束性委派
  2. 约束性委派
  3. 基于资源的约束性委派

设置在 RBCD 阶段,设置创建机器账户、设置委派的环节尤其麻烦,经过测试 Windows Server 2012 R2 的远程设置 RBCD 的失败率比较高(使用项目:https://github.com/Jumbo-WJB/SharpAllowedToAct-Modify),信息收集也比较繁琐

尤其大部分工具为 C# 编写,依赖于 .Net 环境,所以就用 Go 写了一个跨平台项目

LDAP 前置内容

域内是使用 LDAP 协议,所以使用了 Go 的开源库:

github.com/go-ldap/ldap/v3

根据攻击手法,参考了下面工具的思路:

  1. ADExplorer.exe
  2. ldp.exe
  3. ADFind.exe

尤其是ADFind的单个查询(-sc)思路,在作者给出的 Usage Docs 中体现得很全面

https://www.joeware.net/freetools/tools/adfind/usage.htm

d2b5ca33bd20250513164825

当然,本项目的注重点是快速的信息收集和攻击手法的条件查询,肯定无法媲美ADFind,只是会方便一点个人的使用习惯

说回来 LDAP 协议,一般流程是:设置账密,进行绑定(绑定账户的权限不同,查询权限不同)

参考:https://www.cnblogs.com/guangdelw/p/18762260

// LoginBind 登录绑定LDAP管理员账户,返回一个LDAP连接对象和可能的错误信息
func LoginBind(config *LdapConfig) (*ldap.Conn, error) {
	// 使用DialURL函数连接到LDAP服务器,同时配置TLS以跳过证书验证(不建议在生产环境中使用)
	l, err := ldap.DialURL(ldapURL, ldap.DialWithTLSConfig(&tls.Config{InsecureSkipVerify: true}))
	if err != nil {
		// 如果连接失败,触发恐慌并返回错误
		panic(err)
		return nil, err
	}
	// 使用SimpleBind方法进行简单绑定,提供绑定用户的DN和密码
	_, err = l.SimpleBind(
		&ldap.SimpleBindRequest{
			Username: config.BindUserDn,
			Password: config.BindUserPassword,
		},
	)
	if err != nil {
		// 如果绑定失败,打印错误信息并返回错误
		fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
		return nil, err
	}
	// 绑定成功,返回LDAP连接对象
	return l, nil
}

如果是项目使用建议使用 Bind() 自定义会更好

LDAP 查询语法

使用 ADFind 的时候经常会见到类似下面的语法

adfind -b dc=joehome,dc=net -f "objectcategory=computer"

其中的 “objectcategory=computer” 就是查询的 LDAP 语法,内置特定的查询语法可以快速构建需要的查询信息的函数,例如:

var QueriesMap = map[string]Query{
	"Users": {
		Filter:     "(ObjectClass=user)",
		Attributes: []string{"sAMAccountName", "userAccountControl"},
	},
	"Computers": {
		Filter:     "(ObjectClass=computer)",
		Attributes: []string{"name", "operatingSystem"},
	},
}

LDAP 查询方式

Go-LDAP 提供了三种查询方式

URL:https://github.com/go-ldap/ldap/blob/0c1c6ca95d80daf7ee1ac5425438d2f9406a7aa0/v3/client.go#L36C1-L38C90

查询:Search(*SearchRequest) (*SearchResult, error)
异步查询:SearchAsync(ctx context.Context, searchRequest *SearchRequest, bufferSize int) Response
自动翻页查询:SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error)

LDAP 特殊字段解析

参考 ADFind 的实现

d2b5ca33bd20250513170254

关于目前遇到的特殊字段解析的 Go 实现,我均放在了博客中:LDAP 特殊字段解析

实际运行截图,且有log文件保存:

d2b5ca33bd20250513170647

且可以导出为 CSV:

d2b5ca33bd20250513170935

目前项目尚未开源,后继会陆续更新项目和文章记录开发过程,师傅们有建议可以留言

 

 

© 版权声明
THE END
喜欢就支持一下吧
点赞48 分享
评论 共1条

请登录后发表评论

    请登录后查看评论内容