vnegrea/ldaplookup
GitHub: vnegrea/ldaplookup
一个加固的、自包含的 LDAP 查询工具,用于增强 LDAP 查询的安全性。
Stars: 0 | Forks: 0
# ldaplookup
一个加固的、自包含的 LDAP 查询工具。生成无运行时依赖的静态链接二进制文件。凭据要么在目标机器上密封(推荐)要么在构建时嵌入——操作员可以选择每个构建的模式。
## 功能
- **零依赖性**:单个静态二进制文件,无需运行时库(无 libldap,无 ldapsearch)
- **便携性**:在任何 Linux 系统上运行,无需安装
- **安全的凭据处理**:凭据在构建时被混淆并嵌入,永远不会暴露在进程表或环境变量中
- **部署锁定**:限制执行到特定的主机名和路径,如果复制到其他地方,则二进制文件将变得无用([查看详情](#runtime-locks))
- **篡改保护**:内置对调试和分析的抵抗力([查看详情](#tamper-protection))
- **双模式**:使用 `ldaplookup` 查询用户,使用 `ldaplookupg` 查询组
- **智能查询**:数字输入自动按 uidNumber/gidNumber 查询
## ⚠️ 使用此工具的时机
此工具直接在二进制文件中嵌入 LDAP 凭据。在使用之前,请考虑以下替代方案:
**首选替代方案:**
- **Kerberos/GSSAPI**:使用基于票据的认证,没有存储的秘密。如果您的环境支持 Kerberos,这是推荐的方法。
- **秘密管理平台**:企业级解决方案提供更好的审计跟踪、凭据轮换和访问控制。
**此工具可能适用的情况:**
- 在许多系统上并行自动化,其中秘密管理平台可能会遇到速率限制或延迟
- 不支持 GSSAPI 认证的 LDAP 服务
- 没有集中式秘密基础设施的环境
- 需要自包含、无依赖的二进制文件的情况
**此工具不是:**
- 正确的秘密管理的替代品
- 对逆向工程免疫(混淆≠加密)
- 适用于公共或不受信任的系统
**建议**:始终启用主机名和路径锁定以最大化保护。
## 🔒 加固
### 构建时混淆
Go 生成原生机器码二进制文件。与分发源或易于反编译的工件相比,这可能会增加逆向工程的难度,但它并不能阻止逆向工程。此工具通过使用 [garble](https://github.com/burrowers/garble),一个构建包装器,通过随机化符号名称、混淆字符串字面量以及删除/修改元数据来添加另一层。
构建使用 garble 的标志、Go 的构建系统、Go 链接器和环境变量:
| 标志 | 来源 | 目的 |
|------|--------|---------|
| `-literals` | garble | 混淆字符串字面量,防止简单的字符串提取 |
| `-tiny` | garble | 删除调试信息和运行时恐慌/跟踪输出,阻碍分析 |
| `-seed` | garble | 使用确定性的随机化以实现可重复构建 |
| `-trimpath` | go build | 从二进制文件中删除本地文件系统路径 |
| `-buildid=` | go linker | 删除 Go 构建ID以阻碍版本指纹识别 |
| `GOGARBLE='*'` | env var | 混淆所有包包括依赖项 |
### 密封凭据(推荐)
密封凭据通过将密码**完全不在二进制文件中**来防止二进制分析。
**工作原理:**
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ BUILD │ │ DEPLOY │ │ SEAL │
│ No password │ ───► │ Copy binary │ ───► │ --seal │
│ embedded │ │ to target │ │ encrypts pw │
└─────────────┘ └─────────────┘ └──────┬──────┘
│
▼
┌─────────────┐
│ .seal file │
│ AES-256-GCM │
│machine-bound│
└─────────────┘
```
密码使用以下密钥加密:
- 目标机器的唯一 ID (`/etc/machine-id`)
- 构建时生成的随机盐
- 部署目录路径
- 运行用户的 UID
- 二进制本身的 SHA-256 哈希
**这意味着:**
- 二进制文件不包含可提取的密码
- `.seal` 文件在任何其他机器、任何其他用户或任何其他路径上都是无用的
- 移动、复制或升级二进制文件会破坏解密 - 替换二进制文件后重新运行 `--seal`
- 每个用户都有自己的密封文件 (`.seal.`)
**凭据轮换:**
```
./ldaplookup --seal # Prompts to overwrite if .seal exists
```
**选择模式(在运行 `build.sh` 时选择):**
| | 模式 1 - 密封(推荐) | 模式 2 - 嵌入(旧版) |
|---|---|---|
| 密码位置 | 目标机器上的加密 `.seal`;永远不会在二进制文件中 | 二进制文件内的 XOR 混淆 |
| 静态分析抵抗力 | 高 - 密钥绑定到机器、用户、路径和二进制文件 | 低 - 可从二进制文件中恢复 |
| 部署 | 需要在目标机器上运行 `--seal` 一次 | 单个工件,无需部署后步骤 |
两种模式都从相同的源构建;您为每个构建选择一个。
### 运行时锁定
**主机名锁定**:通过 DNS 验证限制执行到特定的服务器。
1. 在构建时,指定受信任的 DNS 服务器 IP 和允许的主机名
2. 在运行时,二进制文件查询受信任的 DNS 服务器以解析其自身的 hostname 并验证它是否与允许列表匹配
使用您控制的 DNS 服务器至关重要。它防止攻击者在受损害的系统上欺骗 hostname 解析。如果验证失败,将触发 [篡改保护](#tamper-protection)。
**重要提示**:主机名匹配是精确的。使用 **FQDN**(例如,`myserver.umich.edu`),而不仅仅是短名称。
要检查系统将返回的内容,请运行:`hostname -f`
您可以提供多个 FQDN(逗号分隔)以供具有多个主机名的系统使用:`server1.umich.edu,server2.umich.edu`
**已知限制**:DNS 步骤确认 *允许的 FQDN* 通过您的受信任 DNS 服务器解析;它并不以密码学方式证明本地主机的身份是那个 FQDN。请将其与路径锁定和操作系统级别的访问控制一起使用,以实现多层次防御。
**路径锁定**:限制执行到特定的部署目录。
1. 在构建时,指定允许的部署路径(例如,`/opt/ldaplookup`)
2. 在运行时,二进制文件验证其可执行路径是否与允许的位置匹配
这防止了二进制文件被复制到其他地方并执行。如果验证失败,将触发 [篡改保护](#tamper-protection)。
### 篡改保护
内置的篡改抵抗力可以防止分析和未经授权的使用。
**自我毁灭行为**
| 触发器 | 操作 | 原因 |
|---------|--------|--------|
| 主机名不匹配 | 二进制文件删除自身 | 未授权的主机 |
| 路径不匹配 | 二进制文件删除自身 | 非法移动/复制 |
| 检测到调试器 | 二进制文件删除自身 | 分析尝试 |
**注意**:自我毁灭是尽力而为。删除可能会在只读文件系统、不可变(`chattr +i`)文件、硬链接二进制文件或运行用户没有对二进制文件目录的写访问权限的情况下失败。将锁定视为强大的威慑,而不是硬性保证。
### 最佳实践
- 使用 `chmod 110` 并根据需要打开
- 使用具有只读权限的专用 LDAP 服务帐户
- 仅在受信任、受访问控制的系统上部署
- 如果二进制文件被破坏,请轮换凭据
## 📦 在本地安装 Go(Linux)
**注意**:如果您已经安装并配置了 Go(`go version` 的工作),请跳过此部分。构建脚本将自动安装 garble。
如果系统范围内没有 Go 并且您不想全局安装它,请使用包含的辅助脚本:
```
./install-go-local.sh # Downloads and installs Go + garble
source ~/myGo/env.sh # Activate in current terminal
./test_build.sh # Verify build works
./build.sh # Build with real credentials
```
该脚本安装到 `~/myGo/` 并创建一个环境文件。要使其永久,请将 `source ~/myGo/env.sh` 添加到您的 `~/.bashrc`。
## 构建
```
./build.sh
```
您将需要输入:
- 安全免责声明确认(输入 'yes' 以继续)
- LDAP 服务器 URL(例如,`ldaps://ldap.umich.edu`)
- 用户搜索基(例如,`ou=People,dc=umich,dc=edu`)
- 组搜索基(例如,`ou=User Groups,ou=Groups,dc=umich,dc=edu`)
- 绑定 DN(完整区分名,例如,`cn=App01,ou=Applications,o=services` - 而不仅仅是 `cn=App01`)
- 绑定密码
- 主机名锁定(默认启用)
- 路径锁定(默认启用)
- 是否生成新的混淆种子
### 测试构建
要验证构建过程是否正常工作,而无需真实凭据:
```
./test_build.sh
```
此脚本使用虚拟测试数据构建,验证二进制文件已创建并执行,然后清理。
### 部署
构建生成 `ldaplookup` 和符号链接 `ldaplookupg`。要部署:
```
# 复制二进制文件到目标位置
cp ldaplookup /path/to/destination/
# 为组查找创建符号链接
ln -s ldaplookup /path/to/destination/ldaplookupg
# 如果使用密封凭证(默认),在目标机器上密封
/path/to/destination/ldaplookup --seal
# 提示时输入LDAP密码
```
二进制文件检测其调用名称。当以 `ldaplookupg` 调用时,它查询组而不是用户。
**注意**:如果您在构建期间使用了旧版嵌入凭据,则不需要 `--seal` 步骤。
### 混淆种子
构建脚本提示是否生成新的混淆种子。种子控制 garble 如何随机化混淆。相同的种子产生相同的混淆输出。
**何时保留现有种子(回答 N):**
- 使用相同的凭据重建
- 您希望二进制哈希保持一致
- 避免被端点安全工具检测为“新”二进制文件
**何时生成新种子(回答 Y):**
- 凭据已更改
- 您希望防止差异分析(比较两个二进制文件以识别模式)
- 将部署到新的环境,其中新的指纹是可接受的
**权衡**:新种子产生一个完全不同的二进制文件,这提供了更好的保护,以防止通过比较进行逆向工程。然而,端点检测和响应(EDR)工具可能会将其标记为未知二进制文件,直到在您的环境中重新基线化。
种子存储在 `.garble_seed`(git 忽略)中,并在后续构建中重用,除非您选择重新生成它。
## 使用
```
# 按uid查找用户
./ldaplookup
# 按uidNumber查找用户(自动检测)
./ldaplookup 12345
# 按名称查找组
./ldaplookupg
# 按gidNumber查找组(自动检测)
./ldaplookupg 1001
# 特定属性
./ldaplookup uid displayName uidNumber
./ldaplookupg cn gidNumber memberUid
```
### 示例
```
# 获取用户的所有属性
./ldaplookup jsmith
# 获取特定用户属性
./ldaplookup jsmith uid uidNumber mail
# 按名称获取组
./ldaplookupg staff
# 按gidNumber获取组
./ldaplookupg 1001
```
## 要求
- Go 1.25.10+(补丁级别很重要:早期的 1.25.x 有已知的 crypto/tls 和 crypto/x509 建议)
- [garble](https://github.com/burrowers/garble),固定:`GOTOOLCHAIN=local go install mvdan.cc/garble@v0.15.0`(必须与上述 Go 版本匹配)
- openssl(用于生成种子)
标签:GSSAPI, LDAP, Streamlit, 主机锁定, 二进制安全, 云资产清单, 代码分析, 依赖注入, 便携性, 凭证管理, 反篡改, 安全防护, 审计, 提示词模板, 无依赖, 日志审计, 网络调试, 自动化, 访问控制, 逆向工程, 静态链接