Thruqe/embers
GitHub: Thruqe/embers
记录了对 downr.org 前后端 API 通信机制的逆向分析过程,并提供了一个复现该流程的 Go 客户端。
Stars: 0 | Forks: 0
# downr.org API 逆向工程笔记
关于 downr.org 前端如何与其后端通信的简要研究日志,以及一个复现该流程的极简 Go 客户端。
## 背景
`https://downr.org/` 提供的是一个静态的 React 应用(托管于 Netlify),没有任何服务端渲染的内容——原始 HTML 只是一个 JS 外壳。所有实际的工作都是在 bundle 加载完毕后于客户端完成的。
## 寻找 session 机制
使用普通的 `net/http` 对 `/` 发起 GET 请求永远不会返回 `Set-Cookie` 响应头,尽管 Firefox 明显为该域名保存了一个 `sess` cookie。以下是追踪其来源的步骤:
1. 对比了 Go 和 Firefox 之间的原始请求/响应头——排除了 User-Agent、Accept 响应头以及 HTTP/2 协商作为原因的可能性。
2. 注意到 Firefox 的 cookie 是在 **Cookies** 标签页下作为一种*请求* cookie 出现的,而不是在特定加载中新生成的 `Set-Cookie`——这意味着它是之前被设置的,只是在此处被重新发送。
3. 测试了与缓存相关的理论(ETag/304 处理、Netlify 边缘缓存),因为响应显示了 `Cache-Status: "Netlify Edge"; hit`。通过缓存破坏查询参数进行了排除——`/` 仍然没有返回 cookie。
4. 下载并反混淆了该应用的打包 JS 文件(`/static/js/main..js`),并对 `fetch(`、`/api/`、`sess` 和 `credentials: include` 进行了搜索。
## 前端的实际行为
该 bundle 暴露了两个 endpoint,均为 Netlify serverless function:
- **`GET /.netlify/functions/analytics`** —— 调用一次以接收 `sess` cookie(`HttpOnly`、`Secure`、`SameSite=Strict`)。前端缓存了此调用,因此每次页面加载只会触发一次。
- **`POST /.netlify/functions/nyt`** —— 实际的下载器 endpoint。将 `{"url": ""}` 作为 JSON 发送,需要上一步获取的 `sess` cookie,并返回元数据及直接的媒体链接。
### 重试行为
前端的下载处理程序具有特定的错误处理机制,值得复现:
| 响应 | 含义 | 前端行为 |
| ---------------------------------- | ----------- | ------------------------------------------------------------------------------ |
| `200` | 成功 | 解析并显示媒体 |
| `403` + body `user_retry_required` | Session 拒绝 | 清除 session 状态,重新请求 `analytics`,并重试 `nyt` 调用**一次** |
| `403` + 其他 body | 被拦截 | 显示“禁止访问”,不重试 |
| `429` | 触发限流 | 显示减速提示信息,不重试 |
## Go 实现
一个极简的客户端(`GetCookie` + `MakeRequest`)实现了以下功能:
- 使用 `net/http/cookiejar.Jar`,以便 session cookie 能在两次调用之间自动持久化。
- 发送匹配的请求头(`Referer`、`Origin`、`Content-Type`),使其看起来像正常的浏览器请求。
- 复现了 bundle 中遇到 `user_retry_required` 时重试一次的逻辑。
```
jar, _ := cookiejar.New(nil)
client := &http.Client{Jar: jar}
GetCookie(client)
result, err := MakeRequest(client, mediaURL, false)
```
## 注意事项 / 警告
- 此方法之所以有效,是因为除了 session cookie 之外,这些 endpoint 都是公开且无需认证的——不涉及任何 API key。
- `sess` cookie 的 payload 是一个经过签名、base64 编码的数据块,包含了调用者的 IP 和过期时间,因此 cookie 无法在不同的 IP/session 之间转移使用。
- 存在访问频率限制(`429`),因此请勿滥用该 endpoint。
- 这样做只是为了个人了解该网站的运作方式,而不是为了构建一个竞争性服务——尽管其 API 表面在网络流量中很容易被观察到,但 downr.org 自身的前端是专有的。
标签:API, EVTX分析, Go, Netlify, Ruby工具, 云资产清单, 日志审计, 逆向工程