JVBotelho/skewrun
GitHub: JVBotelho/skewrun
Skewrun 是一款红队 AD 时间发现工具,通过多协议提取域控制器时间偏移并注入目标进程,解决 Kerberos 时钟偏移导致的认证失败问题。
Stars: 0 | Forks: 0
# Skewrun
[](https://github.com/JVBotelho/skewrun/actions/workflows/ci.yml)
[](https://crates.io/crates/skewrun)
`skewrun` 是一款专为红队设计的 Active Directory 时间发现工具包。它通过网络协议(CLDAP、SMB、NTP、Kerberos、NTLM)动态解析域控制器(Domain Controller)的时间,并通过 `libfaketime`(`LD_PRELOAD`)执行命令,从而欺骗被执行的程序,使其使用精确的 DC 时间。
这能解决 Kerberos `KRB_AP_ERR_SKEW`(Clock Skew Too Great)错误。当你的 Linux 攻击机时钟与目标 Windows 域之间存在严重的时间不同步时,它允许你运行诸如 Impacket 或 NetExec 等工具,**而无需 root 权限去更改系统时间**。
## 架构:库优先
从 `v0.9.0` 版本开始,Skewrun 采用了库优先的架构:
- **`ad-time`**:一个纯粹的 Rust 库 crate,能够隐蔽地从 AD 协议中提取时间。它可以原生嵌入到其他 Rust 植入物(implants)或工具中。
- **`skewrun`**:一个 CLI 二进制程序,负责编排 `ad-time` 库,并使用 `libfaketime` 包装目标进程。
## 安装
```
# 预编译的 static binary(无需 Rust toolchain)
wget https://github.com/JVBotelho/skewrun/releases/latest/download/skewrun-x86_64-linux-musl
chmod +x skewrun-x86_64-linux-musl
sudo mv skewrun-x86_64-linux-musl /usr/local/bin/skewrun
# 来自 crates.io
cargo install skewrun
# 来自 source
git clone https://github.com/JVBotelho/skewrun && cd skewrun && cargo build --release
```
*注意:你的系统必须安装 `libfaketime`(例如,通过 `apt-get install libfaketime` 安装)。*
## 用法
```
# Default behavior(依次尝试 CLDAP -> SMB -> NTP)
skewrun 10.10.10.100 -- impacket-getTGT -dc-ip 10.10.10.100 domain.local/user:pass
# 强制指定 methods
skewrun 10.10.10.100 -m cldap,ntlm,kerberos -- netexec smb 10.10.10.100
# 仅打印 offset(适用于 shell scripting)
skewrun 10.10.10.100 --print-offset
# Offline mode:手动提供已知的 offset
skewrun --offset "+3.450s" -- impacket-getTGT ...
```
## 作为库使用
```
use ad_time::protocols::cldap::CldapSource;
use ad_time::time_src::TimeSource;
use std::time::Duration;
fn main() -> Result<(), Box> {
let src = CldapSource;
let addr = "10.10.10.100:389".parse()?;
let offset_us = src.fetch(addr, Duration::from_secs(3))?;
println!("DC offset: {} µs", offset_us);
Ok(())
}
```
每个协议模块(`kerberos`、`ntlm`、`cldap`、`smb`、`ntp`)都是独立的,可以提取出来用于自定义的红队工具开发。
## 工作原理
Skewrun 会查询 DC 以计算出精确到微秒的时间偏移量 `(DC_Time - Local_Time)`。接着,它会设置 `FAKETIME` 环境变量,并使用 `LD_PRELOAD` 将 `libfaketime` 注入到目标命令中。
### FAKETIME 的局限性(静态二进制文件)
`LD_PRELOAD` 依赖于拦截动态链接的 `libc` 调用(如 `clock_gettime`)。如果你尝试在**静态编译的二进制文件**(例如许多 Go 或 Rust 工具)上使用 `skewrun`,`libfaketime` 将无法成功挂钩(hook)时间相关函数,并且会静默失败。如果 Skewrun 检测到你在尝试运行静态二进制文件,它会向你发出警告。
## 取证噪声与规避
我们的目标是融入标准的 Windows 网络流量中,并尽量减少在 DC 上留下的取证痕迹。
| 方法 | 协议 | 端口 | OPSEC 注意事项(EDR/NDR 可见性) |
|--------|----------|------|-----------------------------------|
| **cldap**(默认) | CLDAP | UDP/389 | **极具隐蔽性**。被普遍允许。发送标准的 LDAP `rootDSE` 诊断查询(以 `objectClass=*` 为基础搜索),与 `ldapsearch`、PowerShell AD cmdlet 以及监控工具的基准行为一致。通过混入常见的管理员属性稀释了属性列表,并随机化 `timeLimit` 以破坏静态 NDR 签名。 |
| **smb**(默认) | SMB2 | TCP/445 | **隐蔽**。从 `SMB2 NEGOTIATE` 响应中提取时间。协商支持 SMB 3.1.1 与 `PREAUTH_INTEGRITY_CAPABILITIES` (SHA-512),与 Windows 10/11 客户端的行为相匹配。 |
| **ntp**(默认) | SNTP | UDP/123 | **标准**。原生 RFC 4330。属于任何客户端都极有可能发送的预期流量。 |
| **ntlm** | SMB2 | TCP/445 | **隐蔽**。利用 `SMB2 SESSION_SETUP` 获取包含 `MsvAvTimestamp` 的 NTLM Type 2 Challenge。在到达 Type 3 之前断开 TCP 连接,这意味着**不会生成 Event ID 4625(Logon Failure)**。模拟 Windows 10/11 的标志位。 |
| **kerberos** | Kerberos | TCP/88 | **动静很大(极易被检测)**。为一个不存在的用户发送 `AS-REQ`。编码了正确的双组件 `sname`,轮换 `cname`(使用如 *admnistrator* 这样的拼写错误),将 `till` 设置为 Windows 硬编码常量 `20370913024805Z`(并非基于本地时钟运算 —— 见 ADR-0002),并随机化 `nonce`。无论审计策略如何,始终会生成 Event 4768/0x6(未知主体的预身份验证失败),并且会被导出至 SIEM。如果 `cname` 恰好匹配了配置的诱饵账号触发器,可能会引发蜜罐账号告警。 |
## 测试
```
cargo test # unit + property tests
cargo +nightly fuzz run fuzz_parse_krb_error # Linux/macOS only
```
所有面向网络的解析器(`parse_krb_error`、`parse_cldap_search_response`、`parse_ntlm_type2`、
`parse_negotiate_response`、`parse_ntp_timestamp`)均使用
[proptest](https://github.com/proptest-rs/proptest) 进行了属性测试,以保证其防 panic 的安全性,
并在 CI 环境中进行了模糊测试(fuzz-tested)。
BER 整数编码已针对 DER 最小化和符号正确性进行了验证,覆盖了完整的 `i32` 范围,
并根据 RFC 4120 涵盖了负数的 etype 值。
模糊测试目标(Fuzz targets)和语料库位于 `fuzz/` 目录下。
## 许可证
根据你的选择,采用 [MIT](LICENSE-MIT) 或 [Apache 2.0](LICENSE-APACHE) 双重许可。
标签:Active Directory, HTTP, Plaso, Rust, 可视化界面, 时间同步, 网络流量审计, 通知系统