Kiterunner:基于API上下文智能发现,革新Web安全路径扫描
1. 项目概述:为什么我们需要Kiterunner?
如果你做过Web应用的安全测试或者渗透测试,肯定对“目录爆破”或“路径扫描”不陌生。从早期的dirb、DirBuster,到后来的gobuster、dirsearch,这些工具的核心逻辑几十年没变:拿一个包含成千上万条常见路径(如/admin、/backup、/config.php)的字典文件,像机关枪一样对着目标网站疯狂请求,然后看哪些路径返回了“200 OK”而不是“404 Not Found”。
这个方法在过去静态页面和简单MVC框架的时代,效果拔群。但今天,我们面对的是什么样的Web应用?是前后端彻底分离,后端纯粹提供RESTful API的单页应用(SPA);是大量使用/api/v1/users/{id}这种动态路径的微服务架构;是接口参数藏在请求头、JSON Body里,光看URL根本猜不出来的现代API。你再用dirsearch去扫一个Vue.js + Node.js API构建的应用,很可能扫到天荒地老,除了几个静态资源,一个有效的API端点都找不到。这就是传统工具的“失明”时刻。
Kiterunner(简称kr)的出现,就是为了解决这个痛点。它不再是一个简单的“路径字典爆破器”,而是一个“基于上下文的API内容发现引擎”。这个概念有点抽象,我打个比方:传统工具像是一个背熟了所有可能门牌号的小偷,挨家挨户去推门;而Kiterunner则像一个聪明的侦探,它研究了这个小区(现代Web开发生态)里大多数房子的建筑图纸(Swagger/OpenAPI文档),知道客厅(/api/login)通常朝南,卧室(/api/user/{id})的门是木质的,厨房(/api/orders)的窗户比较大。然后它去侦查一个新房子(目标应用)时,会根据这些已知的“上下文特征”,去尝试打开那些“最像客厅门”的门,而不是盲目地推每一个可能的门缝。
简单说,Kiterunner通过分析海量真实的API文档(主要是Swagger规范),学习到了现代Web应用如何命名接口、如何放置参数(是在路径里/{id}还是在查询字符串里?id=)、使用哪些HTTP方法(GET、POST、PUT、DELETE)、甚至需要哪些特定的请求头(如Authorization: Bearer)。它利用这些学到的“知识”或“模式”,智能地为目标应用构造出高成功率的探测请求。所以,它的核心价值在于:能发现那些传统字典里根本没有,但实际应用中却广泛存在的API端点,特别是那些隐藏的、未公开的、甚至是开发人员忘记关闭调试接口的API。
对于安全工程师、渗透测试人员、红队队员,乃至开发人员自己(用于检查API暴露面),Kiterunner都是一个能极大提升效率、拓宽攻击面的利器。接下来,我会带你从零开始,在10分钟内上手这个工具,并深入理解其背后的原理和实战技巧。
2. 核心原理拆解:Kiterunner的“智能”从何而来?
在深入命令行之前,我们必须搞清楚Kiterunner凭什么比老牌工具更“聪明”。它的“智能”并非来自魔法,而是建立在扎实的数据分析和模式归纳之上。理解这一点,你才能用好它,而不是把它当另一个gobuster来用。
2.1 从“路径空间”到“内容空间”的范式转移
传统扫描工具关注的是“路径空间”。它们的目标是找到存在于服务器文件系统或路由映射中的特定字符串序列,比如/admin/login.php。这个方法的局限性很明显:它严重依赖字典的完备性,且无法理解路径的语义和结构。
Kiterunner则转向了“内容空间”的发现。它认为,现代应用的核心是“内容”(数据、资源、操作),而API是访问这些内容的通道。因此,它的目标是发现“能够交互的内容”,而不仅仅是“一个能返回200的URL”。一个返回{"error": "Missing API key"}的/api/v1/data端点,比一个返回200的/robots.txt在安全测试中更有价值,因为前者暴露了一个需要特定条件(API密钥)才能访问的功能入口。
2.2 知识库的构建:海量API文档分析
这是Kiterunner的基石。AssetNote团队从GitHub、公共互联网上爬取并整理了数万个符合Swagger/OpenAPI规范的API描述文件。这些文件(通常是swagger.json或openapi.yaml)以结构化的方式完整描述了一个API的所有细节:
- 路径(Path):
/api/v1/users - 操作(Operation):
GET,POST - 参数(Parameters): 它们的位置(
path,query,header,body)、名称(user_id,limit)、数据类型(string,integer)。 - 请求体(Request Body): JSON Schema,定义了POST/PUT请求需要发送的数据结构。
- 响应(Responses): 可能的HTTP状态码和返回数据结构。
通过批量分析这些文档,Kiterunner能够统计出:
- 高频路径模式:比如,用户登录接口叫
/login、/auth、/api/v1/session的概率远高于叫/user_authenticate。 - 参数命名习惯:分页参数通常叫
page和size或limit和offset;用户ID参数常叫id、user_id、userId。 - HTTP方法语义关联:
GET /users是获取列表,POST /users是创建用户,PUT /users/{id}是更新用户,DELETE /users/{id}是删除用户。这种RESTful约定被广泛遵循。 - 身份验证模式:哪些接口需要
Authorization头,其值的常见格式是什么(Bearer <token>,Basic <credentials>)。
2.3 请求的智能构造与重放
Kiterunner内置了一个庞大的“路由字典”(如routes-large.kite),但这个字典里的条目不是简单的字符串,而是携带了上下文信息的“路由模板”。
例如,一个条目可能不是简单的/api/user/{id},而是:
模板: /api/user/{user_id} 方法: GET 参数: user_id (路径参数,类型: string) 可能的请求头: Authorization: Bearer {token}当Kiterunner扫描目标https://example.com时,它会:
- 模板实例化:将模板中的变量替换为根据类型生成的合理值。
{user_id}可能被替换为123、me、admin等。 - 构造完整请求:根据方法、实例化后的路径、以及可能需要的请求头,构造出一个完整的HTTP请求。
- 发送并分析响应:发送请求,并不仅仅检查状态码。它会综合评估响应状态码、响应体长度、响应时间、以及响应内容中的关键词(如
error,invalid,success),来判断这个请求是否“命中”了一个有意义的端点。
更重要的是,Kiterunner的scan模式会记录所有发送的请求。你可以用kr replay命令,精确地重放任何一个它发送过的请求,查看请求和响应的原始细节。这相当于给了你一双“透视眼”,让你能看到工具到底是如何试探目标的,对于分析模糊的响应结果至关重要。
2.4 与传统工具的直观对比
让我们用个简单的例子来感受区别。假设目标有一个管理用户信息的API:
GET /api/v1/users- 列出用户(需要管理员token)PUT /api/v1/users/{uid}- 更新用户信息(需要JSON body)DELETE /api/v1/admin/users/{uid}- 删除用户(路径中有admin)
传统工具(如dirsearch): 使用字典wordlist.txt,内容包含/admin,/api,/users,/v1等。它可能会组合出:
GET /admin-> 404GET /api-> 404 (可能是个默认路由,但没信息)GET /users-> 404GET /v1-> 404 它很难自动组合出/api/v1/users,更不可能知道应该用PUT方法并发送JSON数据去测试/api/v1/users/123。
Kiterunner: 它的知识库里可能有/api/{version}/users这个模式,知道{version}常为v1,v2。它会:
- 尝试
GET /api/v1/users, 返回403(Forbidden,因为没带token)。这是一个有效发现!它知道这个端点存在,只是被拒绝了。 - 尝试
PUT /api/v1/users/123, 并自动生成一个符合常见用户对象结构的JSON占位体(如{"name":"test"}),返回401(Unauthorized)。又一个发现! - 尝试
DELETE /api/v1/admin/users/456, 因为它的模式库里也有/admin嵌套在路径中的常见组合。
Kiterunner不仅能找到更多端点,还能告诉你访问这些端点需要什么条件(缺token、参数不对),这为后续的渗透测试提供了清晰的突破口。
3. 环境准备与快速安装
理论讲完,我们动手。Kiterunner是Go语言编写的,安装非常方便。以下方法适用于大多数Linux/macOS系统,Windows用户建议使用WSL2以获得最佳体验。
3.1 安装Go语言环境(如果尚未安装)
Kiterunner依赖Go环境来编译或运行。打开终端,执行以下命令安装Go(以Ubuntu/Debian为例):
# 下载最新版的Go安装包(请前往 https://go.dev/dl/ 查看最新版本号替换) wget https://go.dev/dl/go1.21.0.linux-amd64.tar.gz # 删除旧版本(如果有) sudo rm -rf /usr/local/go # 解压到 /usr/local sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz # 将Go二进制目录添加到PATH环境变量 echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc # 如果你用的是zsh,则执行: echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.zshrc # 使环境变量生效 source ~/.bashrc # 或 source ~/.zshrc # 验证安装 go version看到类似go version go1.21.0 linux/amd64的输出即表示成功。
3.2 安装Kiterunner
有了Go环境,安装Kiterunner就一行命令:
go install github.com/assetnote/kiterunner/cmd/kr@latest这条命令会从GitHub下载最新的Kiterunner源码并编译,将可执行文件kr安装到$GOPATH/bin目录下(通常是~/go/bin/)。
注意:确保
$GOPATH/bin也在你的系统PATH中。通常go install会自动处理,但如果没有,可以手动添加:echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bashrc然后source ~/.bashrc。
安装完成后,验证一下:
kr version你应该能看到Kiterunner的版本信息。
3.3 获取字典文件(Kite文件)
Kiterunner的强大依赖于其专用的字典文件(.kite文件)。这些文件包含了从真实API中学习到的路由模板,体积较大。你需要从AssetNote的发布页面下载。
# 创建一个目录存放字典文件 mkdir -p ~/kiterunner-wordlists cd ~/kiterunner-wordlists # 下载字典文件。这里以 routes-large.kite 为例,它是常用的综合字典。 # 你需要从 https://github.com/assetnote/kiterunner#wordlists 找到最新的下载链接。 # 以下链接可能随时间变化,请以官方仓库为准。 wget https://wordlists-cdn.assetnote.io/data/kiterunner/routes-large.kite wget https://wordlists-cdn.assetnote.io/data/kiterunner/routes-small.kite # 你也可以下载针对特定框架的字典,如: wget https://wordlists-cdn.assetnote.io/data/kiterunner/aspnet-api-v2.kite wget https://wordlists-cdn.assetnote.io/data/kiterunner/spring-boot.kiteroutes-small.kite约2MB,包含约30万条路由,适合快速扫描。routes-large.kite约50MB,包含约700万条路由,是最全面也是资源消耗最大的字典。
实操心得:初次使用或对单个目标进行初步侦察时,建议先用
routes-small.kite。如果目标是一个大型、复杂的应用(如一个SaaS平台),再考虑使用routes-large.kite。直接上大型字典可能会产生大量请求,对目标造成压力,也可能会触发WAF(Web应用防火墙)的防护规则。
4. 基础扫描与结果解读
安装就绪,字典在手,我们现在开始第一次扫描。假设我们的测试目标是http://testphp.vulnweb.com(这是一个故意设计有漏洞的练习网站,适合学习)。
4.1 执行你的第一次扫描
使用kr scan命令,指定目标URL和字典文件:
kr scan http://testphp.vulnweb.com -w ~/kiterunner-wordlists/routes-small.kitescan: 是Kiterunner的核心扫描命令。-w: 指定要使用的字典文件(-w代表wordlist)。- 目标URL:可以是
http://或https://开头,也可以跟上端口号如:8080。
运行命令后,你会看到终端开始滚动输出。Kiterunner会显示扫描进度、已发送请求数、预估剩余时间,以及实时发现的结果。
4.2 理解扫描输出
Kiterunner的默认输出是彩色的,非常直观。以下是一个示例输出片段:
2024/05/27 10:15:33 开始扫描 http://testphp.vulnweb.com 使用字典: /home/user/kiterunner-wordlists/routes-small.kite [+] 发现 http://testphp.vulnweb.com/AJAX [状态: 200] [长度: 2741] [词: ajax] [+] 发现 http://testphp.vulnweb.com/comment [状态: 200] [长度: 1502] [词: comment] [+] 发现 http://testphp.vulnweb.com/login [状态: 200] [长度: 1890] [词: login] [+] 发现 http://testphp.vulnweb.com/api/v1/user [状态: 403] [长度: 234] [词: api-v1-user] [+] 发现 http://testphp.vulnweb.com/admin [状态: 401] [长度: 456] [词: admin]每一行[+]表示一个潜在的发现。关键信息包括:
- 完整URL:工具实际探测的地址。
- 状态码:HTTP响应状态码。请特别注意,Kiterunner不仅报告200!
200 OK: 成功访问,内容存在。403 Forbidden: 禁止访问。这通常意味着端点存在,但你没有权限(比如缺token)。这是一个极强的存在性信号。401 Unauthorized: 未授权。端点存在,需要认证。405 Method Not Allowed: 方法不允许。例如,你用了POST方法去请求一个只接受GET的端点。这也说明这个路径是存在的。500 Internal Server Error: 服务器内部错误。这通常意味着你触发了后端代码逻辑,可能因为参数错误。这也是一个重要的发现,可能泄露错误信息。
- 长度:响应体的字节长度。对比不同请求的长度变化,有时能发现规律。
- 词:这是触发该发现的字典条目中的“关键词”,帮助你回溯是哪个模式命中了目标。
注意事项:不要只盯着
200状态码。在现代API安全测试中,403、401、500甚至400(Bad Request)都可能比一个返回静态页面的200更有价值,因为它们证明了后端应用逻辑处理了该请求。
4.3 使用重放(Replay)功能深入分析
扫描结果中的/api/v1/user返回了403,这很有趣。我们想知道Kiterunner具体是怎么请求它的。这时就需要replay功能。
首先,你需要让扫描输出更详细的信息,或者将扫描结果保存下来。最常用的方法是使用-o或--output参数将结果保存为JSON格式:
kr scan http://testphp.vulnweb.com -w ~/kiterunner-wordlists/routes-small.kite -o results.json扫描结束后,results.json文件里会记录所有请求和响应的详细信息。
现在,我们想重放/api/v1/user这个请求。我们需要找到它在结果文件中对应的“请求指纹”。一个更直接的方法是在扫描时使用-x或--request参数,它会为每个发现的请求生成一个唯一的ID并显示出来。但为了演示,我们假设我们已经从results.json里找到了这个请求的ID,或者我们直接用路径来重放。
Kiterunner的replay命令需要从一个包含请求数据的文件(如上面生成的results.json)中读取并重放。但更简单的方式是,我们可以用kr brute命令的输出来模拟。不过,对于单个请求的详细分析,我推荐一个工作流:
- 使用
-j输出JSON行:这样每一行都是一个独立的JSON对象,方便用grep查找。kr scan http://testphp.vulnweb.com -w routes-small.kite -j | tee scan_results.jsonl - 查找特定请求:
输出会是一个JSON对象,其中包含一个grep "/api/v1/user" scan_results.jsonlid字段。 - 使用ID进行重放:
kr replay -i scan_results.jsonl --id <这里填入上一步找到的ID>replay命令会漂亮地打印出该请求的所有细节:- 请求方法(GET, POST等)
- 完整URL
- 所有请求头(包括Kiterunner可能自动添加的,如
Content-Type) - 请求体(如果是POST/PUT)
- 响应的状态码、头部和完整响应体
通过重放,你就能清晰地看到,工具是否添加了特殊的头部,发送了什么参数,以及服务器返回的具体错误信息是什么。这对于判断下一步攻击方向(如是否需要添加认证头、参数如何构造)至关重要。
5. 高级用法与实战技巧
掌握了基础扫描,我们来解锁Kiterunner更强大的能力,让它适应复杂的实战环境。
5.1 调整扫描速度与并发
默认情况下,Kiterunner的并发速度比较保守,以避免压垮目标或触发防护。但在可控环境(如内部测试)或需要快速扫描时,可以调整。
# 增加并发 worker 数量,加快扫描速度 kr scan http://target.com -w routes-small.kite -x 50 # -x 或 --concurrency 指定并发数,默认值较低(如10) # 限制每秒请求数 (QPS) kr scan http://target.com -w routes-small.kite -d 100ms # -d 或 --delay 指定每个worker在请求间的延迟,100ms意味着每个worker每秒最多发10个请求。避坑技巧:对生产环境或未知目标进行扫描时,务必谨慎使用高并发。建议先以默认设置或
-x 10 -d 200ms开始,观察目标响应和网络状况。过快的请求速率极易触发IP封锁、WAF规则或导致目标服务不可用,这在渗透测试中是不专业且可能违法的行为。
5.2 使用自定义请求头与认证
很多API需要认证令牌或特定的HTTP头才能正常响应。Kiterunner允许你注入这些信息。
# 添加自定义请求头 kr scan http://target.com -w routes-small.kite -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." kr scan http://target.com -w routes-small.kite -H "X-API-Key: your-secret-key-here" -H "User-Agent: MySecurityScanner/1.0" # 从文件中读取请求头(适用于复杂的头部配置) # 创建一个文件 headers.txt,内容如下: # Authorization: Bearer token123 # X-Custom-Header: value # Content-Type: application/json kr scan http://target.com -w routes-small.kite --header-file headers.txt-H参数可以多次使用,以添加多个头部。这对于测试需要JWT令牌、API密钥或特定会话Cookie的接口非常有用。
5.3 针对特定HTTP方法进行扫描
默认情况下,Kiterunner会根据字典中的模板使用相应的HTTP方法(GET, POST, PUT, DELETE等)。但你可以强制只使用某一种方法,这在某些场景下很实用。
# 只使用GET方法进行扫描(类似于传统目录扫描) kr scan http://target.com -w routes-small.kite -m GET # 只使用POST方法扫描(用于寻找可能的数据提交端点) kr scan http://target.com -w routes-small.kite -m POST实战场景:当你发现一个
/api/users端点返回405 Method Not Allowed(GET方法)时,可以尝试用-m POST、-m PUT等再次扫描该路径,看看其他方法是否开放。
5.4 组合使用:暴力破解(Brute)模式
kr scan是智能的、基于上下文的扫描。而kr brute则更接近传统工具,但它针对路径中的变量部分(如{id})进行了优化,可以进行暴力破解。
# 对一个已知的路径模式进行暴力破解 # 假设你通过扫描发现了 /api/users/{id} 模式,想爆破id kr brute http://target.com -w ~/SecLists/Discovery/Web-Content/numbers.txt -m GET -p /api/users/§§ # -p 指定路径,§§ 是占位符,会被字典中的词替换 # 这里使用了SecLists字典中的数字列表 # 同时爆破路径中的多个位置 kr brute http://target.com -w usernames.txt -m GET -p /api/users/§§/profile -p /api/users/§§/settingsbrute模式适合在scan模式发现潜在模式后,进行更深度的、定向的枚举。例如,发现/api/v1/products/{product_id}后,用常见ID列表去爆破。
5.5 结果过滤与导出
扫描结果可能很多,需要过滤出真正有用的信息。
# 只显示状态码为 200, 403, 401 的请求 kr scan http://target.com -w routes-small.kite --filter-status 200,403,401 # 排除某些状态码,比如排除所有的404 kr scan http://target.com -w routes-small.kite --exclude-status 404 # 根据响应体长度过滤,例如只显示长度大于100且小于5000的响应 kr scan http://target.com -w routes-small.kite --filter-length 100-5000 # 将结果以JSON格式输出到文件,便于后续用jq等工具分析 kr scan http://target.com -w routes-small.kite -o results.json # 然后可以使用 jq 进行高级查询,例如找出所有返回403的POST请求 # jq '.[] | select(.status == 403 and .method == "POST")' results.json--filter-status和--exclude-status是清理结果、聚焦重点的利器。
6. 常见问题排查与性能优化
在实际使用中,你可能会遇到一些问题。这里总结一些常见情况和解决方案。
6.1 扫描速度慢或卡住
- 原因1:字典文件过大。
routes-large.kite有700万条路由,即使并发不高,总量也很大。- 解决:先用
routes-small.kite。或者使用-q(quiet)模式减少屏幕输出,能略微提升速度。考虑使用-d和-x参数找到速度和稳定性的平衡点。
- 解决:先用
- 原因2:网络延迟或目标响应慢。
- 解决:适当增加
-d延迟,减少-x并发数,避免因超时重试导致的雪崩效应。使用--timeout参数(默认10秒)调整单个请求的超时时间。
- 解决:适当增加
- 原因3:DNS解析问题。
- 解决:使用IP地址而非域名进行扫描,或者在
/etc/hosts文件中做好解析。
- 解决:使用IP地址而非域名进行扫描,或者在
6.2 大量请求返回相同的错误(如429 Too Many Requests)
- 原因:触发了目标的速率限制(Rate Limiting)或WAF规则。
- 解决:立即停止扫描!大幅降低请求频率(例如
-d 1000ms -x 2)。在渗透测试授权范围内,应遵守目标设定的速率限制。可以考虑使用--proxy参数通过代理池分散请求源。
- 解决:立即停止扫描!大幅降低请求频率(例如
6.3 工具报告“no matches found”或发现极少
- 原因1:目标应用确实非常规或高度定制,不在Kiterunner的知识库模式内。
- 解决:尝试结合传统字典(如
SecLists中的raft-large-*.txt)使用kr brute模式。或者,如果目标有公开的API文档(Swagger UI),可以尝试用其他工具(如swagger2postman)将其转换为Kiterunner能理解的格式(虽然kr不直接支持导入,但可以借鉴其路径)。
- 解决:尝试结合传统字典(如
- 原因2:扫描深度不够。
- 解决:Kiterunner默认扫描可能只覆盖常见前缀。确保目标URL正确(是否遗漏了端口、子路径?)。对于大型应用,可能需要从不同入口点(如
/api/,/v1/,/admin/)分别扫描。
- 解决:Kiterunner默认扫描可能只覆盖常见前缀。确保目标URL正确(是否遗漏了端口、子路径?)。对于大型应用,可能需要从不同入口点(如
- 原因3:需要特定认证。
- 解决:使用
-H参数添加必要的认证头(Cookie, Authorization等)。先手动在浏览器或curl中登录获取有效令牌。
- 解决:使用
6.4 如何更新字典文件?
Kiterunner的字典文件是独立的,工具本身通过go install更新。字典需要手动从AssetNote的CDN或GitHub Releases页面下载,覆盖旧的.kite文件即可。关注其官方GitHub仓库的更新公告。
6.5 在管道中与其他工具协作
Kiterunner可以很好地融入自动化工作流。
# 1. 扫描并将发现的URL(仅状态码为200的)提取出来,交给其他工具(如nuclei)进行漏洞扫描 kr scan http://target.com -w routes-small.kite --filter-status 200 | grep -oP 'http[s]?://[^ ]+' | nuclei -t ~/nuclei-templates/ # 2. 将JSON结果转换为其他格式 kr scan http://target.com -w routes-small.kite -o results.json cat results.json | jq -r '.[] | select(.status == 403) | .url' > forbidden_urls.txt # 这将所有403的URL保存到一个文件,方便后续手动测试权限绕过。7. 实战案例:剖析一个现代SPA应用
让我们构想一个实战场景:你获得授权,对一个内部开发的新型员工管理系统(前端是React,后端是Go + Gin框架的RESTful API)进行安全评估。已知其访问地址是https://hr.internal-company.com。
第一步:初步侦察与智能扫描
kr scan https://hr.internal-company.com -w ~/kiterunner-wordlists/routes-small.kite -H "User-Agent: InternalSecurityAudit/1.0" -o initial_scan.json我们添加了一个自定义User-Agent以示友好,并将结果保存。
第二步:分析扫描结果查看initial_scan.json或用grep过滤:
- 发现大量
/api/v1/前缀的端点返回401 Unauthorized。这证实了它是API驱动的应用,且需要认证。 - 发现
/api/v1/auth/login返回200和405。200可能是登录页面(GET),405说明它不接受其他方法(比如HEAD)。 - 发现
/api/v1/admin/users返回403 Forbidden。这是一个高价值目标(管理员功能)。 - 发现
/api/v1/profile/{userID}返回400 Bad Request(因为{userID}被替换成了随机字符串)。这暴露了一个带路径参数的端点。
第三步:深入探测与重放
- 测试登录端点:我们重放
/api/v1/auth/login的POST请求(通过replay找到其ID),发现它期望一个JSON body:{"username": "", "password": ""}。这为我们提供了暴力破解或凭证填充的潜在入口点(需在授权范围内)。 - 测试管理员端点:重放
/api/v1/admin/users的GET请求,响应是{"error": "JWT token required"}。这明确了需要JWT令牌。 - 爆破路径参数:针对
/api/v1/profile/{userID},我们使用kr brute和常见ID列表进行爆破,试图遍历员工ID。kr brute https://hr.internal-company.com -w ~/wordlists/common_ids.txt -m GET -p /api/v1/profile/§§ -H "Authorization: Bearer <假设我们通过其他手段获得了一个低权限token>"
第四步:组合信息,扩大战果如果我们通过某种方式(比如弱口令)获得了一个普通用户的JWT令牌,我们就可以:
- 用这个令牌作为
-H "Authorization: Bearer <token>",重新运行kr scan。这次,之前很多401的端点可能会变成200或403,暴露出更多的用户功能接口。 - 仔细检查这些新暴露的接口,寻找权限提升漏洞(如IDOR、功能滥用等)。
通过这个案例,你可以看到Kiterunner如何系统性地从一个简单的域名开始,层层递进,揭示出整个Web应用的API结构轮廓,为后续的深入测试铺平道路。它不是一个“一招制敌”的漏洞利用工具,而是一个强大的“侦察兵”,能帮你画出尽可能完整的目标攻击面地图。在现代Web应用安全测试中,清晰的攻击面地图往往比一两个孤立的漏洞更重要。