本文章仅用于网络安全研究学习,请勿使用相关技术进行违法犯罪活动。声明:本文搬运自互联网,如您是原作者,请联系我们!
漏洞类型:奇妙的IDOR(不安全的直接对象引用)
今天我想分享一个在漏洞赏金项目中发现的安全问题。这个漏洞允许远程攻击者获取受害者的敏感个人信息,包括但不限于:
- 姓名
- 电子邮件地址
- 手机号码
- 公司信息
- 地理位置
- T恤尺码
- 以及其他多种与受害者相关的个人数据
介绍与目标发现
在寻找测试目标的过程中,我偶然遇到了一个子域名:sub.target.com。
这个Web应用主要用于管理公司相关的各类活动。乍一看,这个应用显得比较静态,功能有限,似乎没有太多可供测试的点。就在我几乎要放弃转向下一个目标时,我决定做最后一项检查:修改HTTP请求头。这一尝试立刻有了发现——服务器的CORS(跨源资源共享)配置存在错误。

深入探究CORS配置错误
服务器的响应头包含以下关键信息:
Content-Type: text/html -> (无需发送预检请求 Preflight)
Access-Control-Allow-Origin: https://d3do.com
Access-Control-Allow-Credentials: true
这意味着,来自 https://d3do.com 的脚本可以携带凭证(如Cookie)向该服务器发起跨域请求并读取响应。这为潜在的安全/渗透/逆向攻击打开了大门。
接下来,我需要确定应用的身份验证机制。注册后,系统生成了一个与我的账户关联的字符串,称为“确认号码”(Confirmation Number),它具有以下特征:
- 长度为11个字符
- 仅包含大写字母和数字(例如:
AAAAAAAAA11)
身份验证后的请求通常包含Cookie和x-app-auth: Bearer <Token>头部。然而,在对登录过程进行抓包分析时,我注意到一个特别的请求:
POST /some/path HTTP/1.1
Host: sub.target.com
Cookie: <Cookies>
x-app-auth: Bearer <token>
content-type: application/json
created-by:
app-event-id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
app-user-type: standard
httplogpageloadid: <uuid>
httplogrequestid: <uuid>
localized-validations: true
Referer: <referer>
{
"eventId": "<UUID-of-the-Event>",
"emailAddress": "duk33d@wearehackerone.com",
"confirmationNumber": "<My-Confirmation-Number>",
"inviteeId": "<User-UUID>"
}
这个请求的响应包含了我在注册时填写的所有个人身份信息(PII)。
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 6553
--SNIP--
{
"validationMessages": [],
"regCart": {
--SNIP--
"groupRegistration": false,
"volumeDiscountsInCartStatusType": "NO_VOLUME_DISCOUNT_IN_CART",
"eventRegistrations": [{
"eventRegistrationId": "13c616de-8197-4fa7-8702-9494b72d51ff",
"attendee": {
"personalInformation": {
"contactIdEncoded": "rXX_2SgEQ1G5sTThx2AxXQ",
"parentContactId": "00000000-0000-0000-0000-000000000000",
"contactId": "ad75ffd9-2804-4351-b9b1-34e1c760315d",
"firstName": "duke",
"lastName": "dedo",
"emailAddress": "duk33d@wearehackerone.com",
"sourceId": "14c04565071f4622aa7db50ea024eacf",
"company": "Hacker One",
"title": "Bug Hunter",
"primaryAddressType": "WORK",
"mobilePhone": "+XXXXXXXXXXXX",
"showOnMemberDirectoryFlag": false,
"customFields": [{
"questionId": "b169c7ab-84a5-4250-8656-18405731dd51",
"answers": [{
"answerType": "Choice",
"choice": "Egypt"
}]
}, {
"questionId": "5b8cc360-6157-4f33-be53-63ef5632e5fb",
"answers": [{
"answerType": "Choice",
"choice": "XL"
}]
}
--SNIP--
}
剥离身份验证,定位漏洞端点
为了弄清楚身份验证的具体逻辑,我开始逐一删除请求中的头部和Cookie,观察何时会返回 401 Unauthorized。令人意外的是,即使将请求精简到极致,我仍然能成功获取数据。
精简后的请求如下:
POST /some/path HTTP/1.1
Host: sub.target.com
Event-Id: <event-uid>
Content-Length: number
{
"eventId": "<event-uid>",
"emailAddress": "duk33d@wearehackerone.com",
"confirmationNumber": "<My-Confirmation-Number>",
"inviteeId": "<User-UUID>"
}
即使进一步移除 emailAddress 和 inviteeId 参数,只剩下 eventId 和 confirmationNumber,请求依然成功。

这说明,这个端点缺乏有效的身份验证,仅凭活动ID(event-uid)和确认号码就能查询到对应的注册者信息。这是一个典型的IDOR漏洞。此时,我暂存了这个发现,先回头处理CORS问题。
通过查看页面源代码,我确定身份验证实际上是由一个Cookie处理的。由于该Cookie没有设置 SameSite 属性,现代浏览器的默认行为是 Lax,这意味着它不会被跨域的JavaScript请求发送。但这与我们要利用的CORS场景并不冲突,因为我们的漏洞端点本身就不需要这个Cookie。
最初的思路:暴力破解确认号码
逻辑很直接:确认号码看起来不长(11位),我可以尝试暴力破解。我写了个脚本生成符合规则的确认号码列表并开始尝试。
但很快我就遇到了速率限制,大约在第5次请求时触发。
HTTP/2 422 Unprocessable Entity
...
// Other headers
...
{
"validationMessages": [
{
"severity": "Error",
"unLocalizedInternalMessage": "Number of failed attempts exceeded the throttle threshold limit",
"localizationKey": "REGAPI.THROTTLE_EXCEEDED",
"parametersMap": {},
"subValidationMessageList": []
}
]
}
我通过添加 X-Forwarded-For 请求头成功绕过了这个速率限制。至此,我掌握了一个存在“速率限制绕过”和“身份验证缺失”的端点,并提交了第一份报告。然而,我意识到这个漏洞的“杀伤力”有限。
转换思路:从“暴力破解”到“开源情报”
确认号码的字符集是36位(26个大写字母+10个数字),长度为11,那么总的组合数是36¹¹。

这是一个天文数字,纯粹暴力破解在现实中不可行。我预感到这份报告很可能被定为低危或信息类漏洞。因此,我需要寻找更有效的攻击路径。
考虑到这个应用是管理活动的,我很好奇参会者会获得什么样的徽章。于是,我在谷歌上搜索了“<company name> event badge”。
在翻看搜索结果时,我发现了一张活动参与者发布的自拍照。

徽章上清晰地印着一个二维码。出于好奇,我下载图片、裁剪出二维码并进行扫描。结果令人惊讶:二维码的内容正是那个11位的“确认号码”!
不过,仅有确认号码还无法获取PII,我还需要与之关联的event-uid。我从发布这张照片的社交媒体帖子中获取了发布日期,假设活动通常在前一天举行。

然后,我用谷歌搜索 “<company-name> event” 加上活动日期,成功找到了该活动的报名页面。虽然活动已结束,无法注册,但启动购票流程就足以让我从页面或网络请求中捕获到event-uid。
最后,我将这个event-uid和从二维码扫描得到的confirmation-number,一起提交到之前发现的漏洞端点,成功获取了该受害者的全部PII数据。

规模化攻击:寻找更多受害者
为了将这个漏洞的危害最大化,我开始系统地寻找更多受害者。我采用了以下几种OSINT(开源情报)方法:
-
使用话题标签(Hashtags)
第一个受害者的帖子使用了 #very_cool_event 标签。我直接在X(原Twitter)等平台的搜索栏中使用这个标签,滚动查找那些发布了包含徽章(尤其是带有二维码)照片的用户。

-
广泛谷歌搜索
为了不局限于已知平台,我使用了更宽泛的谷歌搜索语法:intext:#very_cool_event。这帮助我发现了更多使用该标签的论坛、博客和其他社交平台。
-
以图搜图
很多用户只拍徽章特写,没有自拍。我将这类徽章照片保存下来,使用谷歌的“以图搜图”功能,高效地找到了大量在不同平台发布同类照片的受害者。

通过结合CORS配置错误、未授权接口和OSINT搜集信息,我成功地将一个理论上难以利用的IDOR漏洞,变成了可以实际窃取大量用户敏感信息的严重威胁。基于此,我提交了第二份报告,并被评定为严重漏洞。
漏洞复现与总结
完整的攻击链可以总结为以下几步:
- 信息搜集:在社交媒体(如X、LinkedIn)使用活动相关话题标签搜索,或利用谷歌图片搜索。
- 获取凭证:找到公开分享的活动徽章照片,扫描上面的二维码,获得受害者的“确认号码”。
- 获取标识:根据帖子发布日期推断活动日期,并通过搜索找到该活动页面,从中获取
event-uid。
- 实施攻击:将
确认号码和event-uid作为参数,向存在IDOR和CORS配置错误的目标端点发起请求,直接获取受害者的完整PII数据。
这个案例生动地展示了,看似独立的中低危漏洞(如CORS配置问题、潜在的IDOR),在与人类行为(公开分享带二维码的证件照)和开源情报技术结合后,可能产生严重的安全/渗透/逆向威胁和数据泄露风险。我的发现也获得了同行 h1_analyst_sky 的认可。

对于企业而言,除了修复具体的IDOR和CORS漏洞外,对员工进行安全意识教育,提醒其勿在公开网络空间泄露包含敏感信息的实物凭证(如证件、工牌),同样至关重要。欢迎到 云栈社区 交流更多安全技术实践。