KODOK:面向漏洞赏金猎人的高级JavaScript安全扫描器

KODOK是一款基于Go语言的高性能JavaScript安全扫描器,专门为漏洞赏金猎人设计。它通过7种路径提取方法、递归深度扫描、30多种密钥模式检测和SSRF保护等功能,帮助安全研究人员从JavaScript文件中发现隐藏的API端点、认证令牌和敏感信息。

KODOK:面向漏洞赏金猎人的高级JavaScript安全扫描器

引言

在现代Web应用程序中,JavaScript文件是敏感信息的宝库。API端点、认证令牌、数据库凭据和内部服务URL通常隐藏在客户端代码中。传统工具由于模式匹配有限或缺乏深度递归能力,可能会错过这些发现。

KODOK是一款基于Go的高性能扫描器,专门设计用于通过以下方式从JavaScript文件中提取最大价值:

  • 使用7种不同检测方法的多层路径提取
  • 具有可配置深度的递归发现,用于跟踪JS依赖关系
  • 30多种具有基于熵验证的密钥模式
  • SSRF保护获取,防止内部网络暴露
  • 带有通配符的域范围控制,实现精确目标控制

与简单的基于正则表达式的工具不同,KODOK结合了并发处理、智能去重和全面的模式匹配,以发现其他人遗漏的隐藏资产。

为什么选择KODOK?

问题

漏洞赏金猎人和安全研究人员面临共同挑战:

  • 数量:现代Web应用程序加载数十个JavaScript文件
  • 混淆:路径隐藏在连接、模板文字和对象属性中
  • 递归:JS文件导入其他JS文件创建深度依赖链
  • 时间:手动分析无法扩展
  • 误报:通用正则表达式产生噪音

解决方案

KODOK通过以下方式解决这些问题:

1
2
3
输入URL → 并发工作器 → 深度提取 → 密钥检测 → 结构化输出
                    ↓                    ↓                  ↓
              去重处理      7种模式类型    熵验证

安装

1
2
3
4
5
git clone https://github.com/rhyru9/kodok.git
cd kodok
go build -o kodok cmd/kodok/main.go
chmod +x kodok
sudo mv kodok /usr/local/bin/

核心功能

1. 多方法路径提取

KODOK使用7种互补的提取技术:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 方法1:字符串字面量
const api = '/api/v1/users';

// 方法2:模板文字
const url = `/graphql/${query}`;

// 方法3:对象属性
const config = { apiUrl: '/api/data', endpoint: '/v2/users' };

// 方法4:函数调用
fetch('/api/posts');
axios.get('https://api.example.com/data');

// 方法5:路由器配置
router.push({ pathname: '/dashboard' });

// 方法6:启发式模式
// 自动检测:/api/*, /v[0-9]+/*, /graphql/*, /oauth/* 等

// 方法7:连接字符串
const base = 'https://api.example.com';
const endpoint = base + '/users' + '?limit=10';

结果:提取其他人遗漏的路径,保留查询参数和片段。

2. 递归深度扫描

1
kodok -u https://target.com/app.js -deep -depth 3

行为

1
2
3
4
5
6
7
深度0:app.js(输入)
    ↓ 发现:vendor.js, utils.js
深度1:vendor.js, utils.js
    ↓ 发现:api-client.js, auth.js
深度2:api-client.js, auth.js
    ↓ 发现:config.js
深度3:config.js

每个级别指数级增加覆盖范围,同时智能缓存防止重新扫描。

3. 带验证的密钥检测

30多种模式覆盖:

  • 云提供商:AWS (AKIA*, ASIA*), Google (AIza*), Azure
  • 支付:Stripe (sk_live_), Midtrans, Square
  • 版本控制系统:GitHub (ghp_, gho_), GitLab (glpat-), NPM
  • 通信:Slack, Discord, Telegram, SendGrid
  • 通用:JWT, Bearer令牌, Basic Auth, 数据库URL

熵过滤:

1
2
3
4
// 拒绝低熵误报
if calculateEntropy(value) < 2.5 {
    return false // 跳过 "password123", "test1234" 等
}

示例输出:

1
2
3
4
5
6
{
  "type": "AWS Access Key ID",
  "value": "AKIA****MPLE",
  "context": "const key = 'AKIAIOSFODNN7EXAMPLE'",
  "line": 42
}

4. 带通配符的域范围控制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 精确匹配
kodok -f urls.txt -ad "target.com"

# 子域通配符(包括基础域)
kodok -f urls.txt -ad "*.target.com"

# 匹配:target.com, api.target.com, cdn.api.target.com

# 多个模式
kodok -f urls.txt -ad "*.target.com,*.cdn.target.com,partner.com"

实现:

1
2
3
4
5
6
7
if strings.HasPrefix(pattern, "*.") {
    suffix := pattern[2:] // "example.com"
    // 匹配 "example.com" 和 "sub.example.com"
    if host == suffix || strings.HasSuffix(host, "."+suffix) {
        return true
    }
}

5. SSRF保护

自动阻止危险目标:

1
2
3
4
5
6
7
// 自动阻止
http://localhost/             // 环回地址
http://127.0.0.1/            // 环回地址
http://192.168.1.1/          // 私有网络 (RFC 1918)
http://169.254.169.254/      // AWS元数据
http://metadata.google.internal/  // GCP元数据
http://kubernetes.default.svc/    // K8s API

实际工作流程

工作流程1:独立发现

1
2
3
4
5
6
7
8
# 基本扫描
kodok -u https://target.com/app.js

# 深度扫描与域范围
kodok -u https://target.com/app.js \
  -deep -depth 5 \
  -ad "*.target.com" \
  -workers 15

工作流程2:与侦察工具集成

KODOK在与URL发现工具结合时表现出色:

使用Waymore(Wayback Machine)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 发现历史JS文件
waymore -i target.com -mode U -oU waymore_urls.txt

# 过滤JS文件
grep "\.js" waymore_urls.txt > js_files.txt

# 使用KODOK扫描
kodok -f js_files.txt \
  -deep -depth 3 \
  -ad "*.target.com" \
  -o waymore_results

为什么有效:Wayback Machine捕获具有不同端点、凭据和调试代码的旧版本。

使用Katana(爬虫)

1
2
3
4
5
6
7
8
9
# 爬取目标并提取JS
katana -u https://target.com -d 5 -jc -jsl -o katana_urls.txt

# 扫描发现的JS文件
kodok -f katana_urls.txt \
  -deep -depth 2 \
  -ad "*.target.com" \
  -workers 20 \
  -o katana_results

为什么有效:Katana找到具有当前端点和活动令牌的实时JS文件。

使用GAU(获取所有URL)

1
2
3
4
5
6
7
8
# 从多个来源聚合URL
gau target.com | grep "\.js" | sort -u > gau_js.txt

# 全面扫描
kodok -f gau_js.txt \
  -deep -depth 4 \
  -ad "*.target.com,*.cdn.target.com" \
  -o gau_results

组合管道

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 完整侦察管道
echo "target.com" | \
  gau | grep "\.js" | \
  sort -u | \
  kodok -deep -depth 3 -ad "*.target.com" -o comprehensive_scan

# 或组合多个来源
cat <(gau target.com) \
    <(waybackurls target.com) \
    <(katana -u https://target.com -jc -silent) | \
  grep "\.js" | sort -u | \
  kodok -deep -depth 3 -ad "*.target.com" -workers 25 -o final_results

工作流程3:认证扫描

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 带认证头
kodok -f urls.txt \
  -H "Authorization:Bearer eyJhbGc..." \
  -deep -depth 3 \
  -ad "*.target.com"

# 多个头
kodok -f urls.txt \
  -H "Authorization:Bearer token,X-API-Key:key123" \
  -ad "*.target.com"

工作流程4:大规模狩猎

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 高效处理1000+ URL
cat massive_js_list.txt | \
  kodok \
    -workers 30 \
    -cache 50000 \
    -timeout 45 \
    -deep -depth 2 \
    -ad "*.target.com" \
    -o large_scale_results

# 监控进度
kodok -f massive_js_list.txt -v -workers 30

理解输出

JSON输出结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
  "summary": {
    "total_urls": 150,
    "success_count": 145,
    "failed_count": 5,
    "total_paths": 1247,
    "total_secrets": 8,
    "total_time": "3m45s"
  },
  "results": [
    {
      "url": "https://target.com/app.js",
      "paths": [
        "/api/v1/users",
        "/api/v1/posts", 
        "/graphql/query",
        "https://internal-api.target.com/data"
      ],
      "secrets": [
        {
          "type": "AWS Access Key ID",
          "value": "AKIA****WXYZ",
          "context": "const AWS_KEY = 'AKIAIOSFODNN7EXAMPLE'",
          "line": 127
        }
      ],
      "path_count": 4,
      "secret_count": 1,
      "depth": 0,
      "status_code": 200,
      "duration": "1.2s"
    }
  ]
}

TXT输出(用于管道)

1
2
3
4
5
6
https://target.com/api/v1/users
https://target.com/api/v1/posts
https://target.com/graphql/query
https://internal-api.target.com/data
https://target.com/oauth/token
...

用法

1
2
3
4
5
6
7
8
# 验证发现的端点
cat kodok_results.txt | httpx -status-code -title

# 探测漏洞
cat kodok_results.txt | nuclei -t exposures/

# 检查状态码
cat kodok_results.txt | parallel -j 20 'curl -I -s {} | head -1'

高级用法

速率限制和隐身

1
2
3
4
5
6
# 对速率限制目标的慢速扫描
kodok -f urls.txt \
  -workers 3 \
  -timeout 90 \
  -retries 5 \
  -deep -depth 2

内存受限环境

1
2
3
4
5
# 减少内存占用
kodok -f huge_list.txt \
  -workers 5 \
  -cache 5000 \
  -depth 1

批处理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 分割大输入
split -l 100 js_urls.txt batch_

# 并行处理
for batch in batch_*; do
  kodok -f $batch -o results_$(basename $batch) &
done
wait

# 合并结果
cat results_*.txt | sort -u > final_urls.txt

真实世界漏洞赏金场景

场景1:查找隐藏的管理面板

1
2
3
4
5
6
7
# 扫描主应用程序
kodok -u https://target.com/app.js -deep -depth 3 -v

# 输出包括:
# /admin/dashboard
# /internal/users/manage
# /debug/config

场景2:发现暂存/开发环境

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// KODOK从以下提取:
const environments = {
  prod: 'https://api.target.com',
  staging: 'https://staging-api.target.com',
  dev: 'https://dev-internal.target.com'
};

// 结果:
// https://staging-api.target.com(可能安全性较低)
// https://dev-internal.target.com(可能暴露调试信息)

场景3:泄露的API密钥

1
2
3
4
5
6
7
8
# 扫描并查找:
# - 废弃文件中的旧API密钥
# - 供应商捆绑包中的硬编码令牌
# - 配置文件中的数据库凭据
kodok -f wayback_js.txt -deep -o findings

# 在findings.json中检查"secrets"数组
jq '.results[].secrets[] | select(.type | contains("API"))' findings.json

场景4:子域发现

1
2
3
4
5
6
7
8
# 从JS提取内部子域
kodok -f js_files.txt -deep -depth 3 -o results

# 解析发现的域
cat results.txt | grep -oP 'https?://[^/]+' | sort -u > discovered_domains.txt

# 验证子域
cat discovered_domains.txt | httpx -probe

常见陷阱和解决方案

问题:结果太多

1
2
3
4
5
# 解决方案:使用域过滤
kodok -f urls.txt -ad "*.target.com" -deep

# 或限制深度
kodok -f urls.txt -depth 1

问题:缺少端点

1
2
3
4
5
# 解决方案:增加深度并使用详细模式
kodok -f urls.txt -deep -depth 5 -v

# 检查文件是否被获取
# 在JSON输出中查找"status_code": 200

问题:速率限制

1
2
# 解决方案:减少工作器并添加延迟
kodok -f urls.txt -workers 3 -timeout 90 -retries 5

问题:误报密钥

KODOK已经过滤常见误报:

  • “example”, “test”, “demo”, “placeholder”
  • 低熵字符串
  • 顺序模式 (123456, abcdef)

额外手动过滤

1
jq '.results[].secrets[] | select(.value | contains("example") | not)' results.json

最大影响提示

1. 组合多个来源

1
2
3
4
5
6
7
8
# 获取全面的URL列表
{
  waybackurls target.com
  gau target.com
  katana -u https://target.com -jc -silent
  gospider -s https://target.com -c 10 -d 3
} | grep "\.js" | sort -u | \
  kodok -deep -depth 3 -ad "*.target.com" -o comprehensive

2. 关注旧文件

Wayback Machine通常有:

  • 未压缩的源代码
  • 带注释的调试构建
  • 硬编码凭据
  • 废弃端点
1
2
waymore -i target.com -mode U | grep "\.js" | \
  kodok -deep -depth 2 -o wayback_gold

3. 检查供应商/第三方JS

供应商通常包括:

  • 他们服务的API密钥
  • 默认凭据
  • 示例配置
1
2
cat urls.txt | grep -E "(vendor|third-party|lib|plugins)" | \
  kodok -deep -depth 1 -o vendor_findings

4. 优先处理高价值文件

1
2
3
# 关注可能有密钥的文件
cat urls.txt | grep -E "(config|admin|auth|api|internal|private)" | \
  kodok -deep -depth 4 -v -o high_value

5. 后处理

1
2
3
4
5
6
7
8
# 仅提取高置信度密钥
jq '.results[].secrets[] | select(.type | contains("AWS") or contains("Stripe"))' results.json

# 查找所有数据库URL
grep -oP 'mongodb://[^"]+' results.json

# 获取唯一域
cat results.txt | grep -oP 'https?://[^/]+' | sort -u | httprobe

参考和相关工具

KODOK建立并补充了JavaScript安全分析生态系统:

  • LinkFinder — 基于Python的端点发现工具,使用正则表达式模式
  • JSScanner — 多个JS分析工具的Bash包装器
  • Subdomainizer — 从JavaScript文件提取子域的Python工具

KODOK通过以下方式区分自己:

  • 原生Go实现以获得更好性能
  • 具有可配置深度的递归深度扫描
  • 具有熵验证的全面密钥检测
  • 用于大规模操作的并发工作器池
  • 具有通配符支持的域过滤
  • 用于安全扫描的SSRF保护

结论

KODOK将JavaScript侦察从手动、耗时的过程转变为自动化、可扩展的操作。通过将其与Waymore、Katana和GAU等工具结合,漏洞赏金猎人可以:

  • 在历史和实时文件中发现隐藏端点
  • 提取简单正则表达式工具遗漏的密钥
  • 将分析扩展到数千个JavaScript文件
  • 通过域范围控制专注于高价值目标

无论您是在单个目标上进行狩猎还是管理大范围,KODOK都为现代JavaScript安全分析提供了所需的深度和精度。

开始使用kodok -u https://target.com/app.js -deep -depth 3 -v

仓库:https://github.com/rhyru9/kodok

KODOK是开源且积极维护的。欢迎贡献、错误报告和功能请求。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计