portswigger oauth 关卡详解 taro Posted on Mar 11 2023 ## 授权码模式 ### 授权码模式中的csrf #### 流程分析 这里的经典场景是应用绑定社交账户。 从用户的角度触发是这样的 用户登录应用账户 --> 点击绑定社交账户 --> 社交平台登录授权 --> 跳转回应用绑定成功 那么抓包看一下 ![](/api/file/getImage?fileId=6403184e243fdc000e000163) 我们找几个重点的包 `my-account` 页面 ![](/api/file/getImage?fileId=6403184e243fdc000e000161) 这个 `Attach a social profile` 对应的链接为 `https://oauth-0a3d00bf038180e4c1cff141020a000b.oauth-server.net/auth?client_id=dqlwiompxhihj6m7uypbs&redirect_uri=https://0a69006f03a28053c1f4f39100f00092.web-security-academy.net/oauth-linking&response_type=code&scope=openid profile email` 根据我们所了解到的内容,`response_type=code` 即是授权码认证。 点击这个链接跳转到 `http://oauth-0a3d00bf038180e4c1cff141020a000b.oauth-server.net/interaction/8kVSJUlvuZY7HJieYov7w` (社交账户登录页面) ![](/api/file/getImage?fileId=6403184e243fdc000e000160) 输入社交账户的用户名密码`peter.wiener:hotdog`,跳转至`https://oauth-0a3d00bf038180e4c1cff141020a000b.oauth-server.net/auth/8kVSJUlvuZY7HJieYov7w` ![](/api/file/getImage?fileId=6403184e243fdc000e000162) 跳转至 `https://oauth-0a3d00bf038180e4c1cff141020a000b.oauth-server.net/interaction/8kVSJUlvuZY7HJieYov7w` ![](/api/file/getImage?fileId=6403184e243fdc000e000166) 这里在登录之前是登录表单页面,在社交账户登录成功后显示的是确认页面。点击确认后跳转`https://oauth-0a3d00bf038180e4c1cff141020a000b.oauth-server.net/auth/8kVSJUlvuZY7HJieYov7w`,(猜测这个`auth/8kVSJUlvuZY7HJieYov7w` 是根据 Referer来判断是)然后接着跳转到`https://0a69006f03a28053c1f4f39100f00092.web-security-academy.net/oauth-linking?code=QFk9Hf_G3-AI8Hi58S05eHW_JBN35J2oSHOKDDAJqez` 。 ![](/api/file/getImage?fileId=6403184e243fdc000e000167) ![](/api/file/getImage?fileId=6403184e243fdc000e000164) 流程图 ![](/api/file/getImage?fileId=6404498f243fdc000e0001a2) #### 攻击面 攻击面在最后一步,`/oauth-linking?code=QFk9Hf_G3-AI8Hi58S05eHW_JBN35J2oSHOKDDAJqez` 这个 code 就是所谓的`授权码`。 这里可能出现的情况是诱导用户绑定我们授权码,这样我们的社交账户绑定的即是受害用户的身份。 #### 操作流程 抓到oauth-link 这个包后,drop 掉 ![](/api/file/getImage?fileId=640457fd243fdc000e0001aa) 我们拿到授权码`zar4eoMX7W48K9ptWp4xwWOJRKWhpTbB1K2QPBwkRB2` 诱导用户点击我们的授权码。 ![](/api/file/getImage?fileId=640457fd243fdc000e0001a9) 点击 `Derliver to Victim` 随后重新用社交账户登录,多一个`Admin panel` 删除`Carlos` 用户 ![](/api/file/getImage?fileId=640457fd243fdc000e0001ab) ### 泄露授权码和访问令牌 #### 流程分析 这里的场景是利用社交账户登录。 ![](/api/file/getImage?fileId=6404604b243fdc000e0001ac) 首先点击`https://0a9c00f3036377bac32316fd0082000c.web-security-academy.net/social-login` 跳转到社交账户登录,确认后又跳转回 `https://0a9c00f3036377bac32316fd0082000c.web-security-academy.net/oauth-callback?code=dO1CxaaYUYCXaIn3gfS371ok9Fl8jJmPqqcbQZRYv8h` 跟上面的流程差不多。 #### 攻击面 本次的攻击面在第二部分,`redirect_uri` 的判定过松,所以我们可以让 `oauth-server` 将授权码发送给任意URL。 那么这个授权码有什么作用呢?我们看到最后一个请求`/oauth-callback?code=dO1CxaaYUYCXaIn3gfS371ok9Fl8jJmPqqcbQZRYv8h` 这里服务端做了什么呢? 服务端拿到了这个授权码,然后用授权码向`oauth-server`换取 access_token ,如果成功获取到 access_token ,则说明授权码有效,登录成功。 所以我们要做的,就是劫持这个授权码! #### 操作流程 制作payload,让用户将最后一步的code 返回给我们的恶意服务器 ![](/api/file/getImage?fileId=6404604b243fdc000e0001ae) ![](/api/file/getImage?fileId=6404604b243fdc000e0001ad) 拿到授权码,直接请求授权码登录的URL `/oauth-callback?code=khM06PuRib-Lr3c9-sL-D_zAuSotEcYnfGZYCZz3Rsf` 登录成功 和上次一样,登录后台,删除用户 ![](/api/file/getImage?fileId=6404604b243fdc000e0001af) ## token模式 ### token 模式泄露 `access_token` #### 流程分析 本靶场非授权码模式,是`资源拥有者凭据许可` 即,直接向浏览器发送 `access_token` , 包流程如下 ![](/api/file/getImage?fileId=640468e4243fdc000e0001b2) 关注到`response_type=token` 和之前授权码方式不同的在于,最后`/auth/r4KPYMJomXjVpe136Msr1` 返回了`https://0a58001003bbfe4cc06818a400b200a9.web-security-academy.net/oauth-callback#access_token=4-YhfkM-2x0_baaZkF8IL0Q49TgoFOJIjAjn1Q13QOy&expires_in=3600&token_type=Bearer&scope=openid profile email` 第三方应用获取url中的`access_token`,创建跨域请求,访问授权资源服务,获取到邮箱、用户名,再用这个邮箱和用户+token进行绑定。 ![](/api/file/getImage?fileId=640468e4243fdc000e0001b1) ![](/api/file/getImage?fileId=64047247243fdc000e0001b3) #### 攻击面 重点关注一下认证请求,`https://oauth-0a5c004803d6fe47c067165502340039.oauth-server.net/auth?client_id=u9ifk5br137avflp45rai&redirect_uri=https://0a58001003bbfe4cc06818a400b200a9.web-security-academy.net/oauth-callback&response_type=token&nonce=219495871&scope=openid%20profile%20email`. 所以这里如果我们能控制 `redirect_uri` 是不是可以将`access_token`发到我们的恶意服务器上,拿着这个`access_token`我们可以登录。 但是认证处做了校验,只能当前域名当前路径,但是能通过`../../ ` 绕过路径的限制,我们可以通过xss把当前页面获取到的`token`发送到我们的服务器上。 ### 操作流程 k8s分享 Oauth2.0 授权码详解