diff --git a/content/posts/xss.md b/content/posts/xss.md index e6a30a9..28ed967 100644 --- a/content/posts/xss.md +++ b/content/posts/xss.md @@ -35,18 +35,26 @@ CSRF (Cross-Site Request Forgery CSRF) 是指跨站点请求伪造漏洞,目 ### 漏洞分析 {#漏洞分析} 这是一个非常经典的反射型XSS漏洞,我们在输入栏中输入user1,即在网址username=后面补充对应的用户名,可以发现存在user的情况下会给出user的profile,但若输入其他字符,则会显示一行信息表示user没有找到,如 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526tX9MWV.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526tX9MWV.png" >}} + 我们在浏览器中查看此时的网页源码,可以发现我们输入的数据被直接放入了User ... not found的中间,且在p标签内 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526HHxR4d.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526HHxR4d.png" >}} + 如此,若服务端未对输入数据进行过滤而只是简单拼接则可输入一个恶意脚本,继而窃取数据。 ### 攻击原理 {#攻击原理} 有了对漏洞的基本认识,我们首先进行尝试,以确定服务端是否存在过滤,输入 `` -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526ajsV4z.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526ajsV4z.png" >}} + 可见插入的恶意代码的确被浏览器解析了,查看此时的网页源码 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/05260JBaMA.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/05260JBaMA.png" >}} + 可见插入的恶意代码没有任何处理直接渲染到了html中,导致浏览器将我们的输入当做脚本执行。确定攻击方式可行后,构造恶意脚本将用户的cookie发送至目标地址。 ```js @@ -59,7 +67,8 @@ CSRF (Cross-Site Request Forgery CSRF) 是指跨站点请求伪造漏洞,目 ``` 查看最近被偷取的cookie可见 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526EjpFaE.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526EjpFaE.png" >}} ## Attack 2 {#attack-2} @@ -68,10 +77,13 @@ CSRF (Cross-Site Request Forgery CSRF) 是指跨站点请求伪造漏洞,目 ### 漏洞分析 {#漏洞分析} 该网站在用户登录成功时会给用户返回一个表示会话的cookie,用户在访问其他页面时在请求头中放入这个cookie即可表示用户身份,如当用attacker登录后,访问其他页面时,请求头中cookie为 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526wE79Fd.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526wE79Fd.png" >}} + 这样只需要在访问页面发送请求时将cookie修改为user1的cookie即可伪装成user1。 cookie的生成过程可以在网络中查到,整体流程为 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529Ben1G1.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529Ben1G1.png" >}} 1. Cookie Serializer @@ -128,7 +140,8 @@ session = Marshal.load(raw_session) #反序列化 puts session #打印cookie ``` -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529hPBSuf.png) +{{< 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 的前半部分: @@ -138,7 +151,9 @@ cookie_value = Base64.encode64(Marshal.dump(session)).split.join #伪造前半 ``` cookie 的后半部分是使用 HMAC-SHA1 的签名,我们还需要伪造签名,可以在本地源代码得到 签名秘钥,在 /bitbar/config/initializers/secret_token.rb 中 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529PZNwNa.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529PZNwNa.png" >}} + 接下来生成签名 ```ruby @@ -154,13 +169,20 @@ puts "document.cookie=’#{cookie_full}’;" #打印完整的cookie ``` 运行完整的程序,得到 user1 的 cookie 如下 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529eMXh6p.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529eMXh6p.png" >}} + 接下来,在浏览器的 web 控制台使用前面脚本程序生成的 cookie 进行登录在使用attacker身份登录系统后,利用js修改浏览器中缓存的cookie,更改为user1的cookie即可伪装成user1。使用attacker登录系统 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526Q6TpTN.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526Q6TpTN.png" >}} + 设置cookie伪装成user1 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529QTHJTx.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529QTHJTx.png" >}} + 此时点击Home,访问Home页面,可见用户已变为user1 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/05261nSu5R.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/05261nSu5R.png" >}} ## Attack 3 {#attack-3} @@ -174,7 +196,8 @@ puts "document.cookie=’#{cookie_full}’;" #打印完整的cookie ### 攻击原理 {#攻击原理} 制作的html只需要使用js完成分析过程中需要的操作,最终将网址重定向到百度即可,表单数据可以通过使用attacker进行一次转账并抓包获得,如下 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526SMHwXl.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526SMHwXl.png" >}} ```html @@ -188,7 +211,8 @@ puts "document.cookie=’#{cookie_full}’;" #打印完整的cookie http.setRequestHeader("Content-type","application/x-www-form-urlencoded"); http.withCredentials = true; http.send("destination_username=attacker&quantity=10"); - window.location.replace("https://www.baidu.com"); + window.location.replace(" +https://www.baidu.com"); @@ -197,11 +221,16 @@ puts "document.cookie=’#{cookie_full}’;" #打印完整的cookie ``` 构造过程中要注意将GET请求url中的html标签转义,否则不能正常渲染。验证过程,首先查看当前各个用户的bitbar -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526aYAqvL.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526aYAqvL.png" >}} + 在登录user1账户的情况下,打开b.html页面,再查看各个用户的bitbar。 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526pwycGV.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526pwycGV.png" >}} + 此处还有一个非常有趣的漏洞,即如果将转账金额设置为-10,则会给自己的账户加10bitbar而给对方账户减10bitbar。效果如下 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526NcKqxT.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0526NcKqxT.png" >}} ## Attack 4 {#attack-4} @@ -215,7 +244,9 @@ puts "document.cookie=’#{cookie_full}’;" #打印完整的cookie ### 攻击原理 {#攻击原理} 构造一个表单,提示用户输入super secret token,用户点击提交按钮后我们读取用户的输入,并利用和Attack 3中攻击方法类似的构造方法,只需要在提交POST请求时将token数据放入即可,我们使用attacker账户尝试转账并抓包可得需要构造的POST请求数据为 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528zPHsMP.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528zPHsMP.png" >}} + 构造数据的部分为 ```html @@ -234,12 +265,18 @@ puts "document.cookie=’#{cookie_full}’;" #打印完整的cookie 其余部分见answer中的bp.html 打开后展示的页面如下 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528770hem.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528770hem.png" >}} + 此时账户的金额为 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528veOZk9.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528veOZk9.png" >}} + user1输入token后点击提交,再次查看账户金额 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528FhddNR.png) -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528U5vHLA.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528FhddNR.png" >}} + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528U5vHLA.png" >}} ## Attack 5 {#attack-5} @@ -248,9 +285,13 @@ user1输入token后点击提交,再次查看账户金额 ### 漏洞分析 {#漏洞分析} 在实验一中,可以发现,我们输入的用户名会被原封不动的处理输出到页面上,故由此可以猜测服务端在处理数据的过程中使用sql语句查询用户名相关信息时并没有对用户名字符串作任何过滤。由此我们可以尝试创建一些恶意用户名来确认是否存在注入点。如我们创建一个用户用户名为 `test'--` 。 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528PhIiBy.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528PhIiBy.png" >}} + 然后尝试删除这个用户,但会产生错误,错误页面如下 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528NaF0Js.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528NaF0Js.png" >}} + 由这个错误页面可以得知在删除用户时,sql查询语句直接使用输入的用户名,没有做任何变换和过滤。 @@ -258,9 +299,13 @@ user1输入token后点击提交,再次查看账户金额 既然已经知道在删除用户时存在sql注入问题,我们可以构造用户名注册新的用户,该用户名中包含可以删除 user3 的语句,这样在删除该用户名的同时也可以删 除掉 user3。根据删除过程中要执行的sql查询语句, `SELECT "users".* FROM "users" WHERE (username = '我们注册的用户名')` 。则可以构造出能删除user3和当前用户的sql语句为 `SELECT "users".* FROM "users" WHERE (username = 'user3' or username like '%aaaaaaaaaaa%')` 。此处后面只要保证补充了username like语句即可,因为后面的部分一定能匹配自身。与正常的sql查询语句比对,可以得到我们应该注册的用户名为 `user3' or username like '%aaaaaaaaaaa%` 我们注册这个新用户,并查看系统中当前的用户列表,如下 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528OBmtrP.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528OBmtrP.png" >}} + 接着我们关闭这个新用户的账户,即删除新用户,再次查看用户列表,得到 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528pn1hNx.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528pn1hNx.png" >}} + 可见user3和当前用户都已经被删除 @@ -270,15 +315,20 @@ user1输入token后点击提交,再次查看账户金额 ### 漏洞分析 {#漏洞分析} 登录至attacker用户,点击Profile,查看user1的profile,查看页面源码。可以在获取bitbar部分发现如下代码 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528EBQsGh.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528EBQsGh.png" >}} + 可见bitbar_count中的class属性的值会被当成代码执行。因此我们可以想办法将转账和修改profile的js代码嵌入一个标签内并将标签内容传入class属性。这样当其他人查看该用户的profile时会自动进行转账及修改profile的操作。 ### 攻击原理 {#攻击原理} 修改attacker的profile,抓包,可以得到修改profile时的post地址和参数 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529qoJGU1.png) -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528SmfZMw.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529qoJGU1.png" >}} + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528SmfZMw.png" >}} + 有了地址和参数,就可以套用前面攻击时使用的js代码模板。在漏洞分析时我们得知id为bitbar_count的span标签内class的内容会被当做代码执行,因此我们构造一个span标签id为bitbar_count,并使用DOM树的接口document读取一个标签块中的js代码,传递给class,这些代码就会被执行。构造的代码如下 ```html @@ -309,11 +359,19 @@ class="eval(document['getElementById']('myattack')['innerHTML'])"> ``` 将代码复制进profile内,更新profile,查看此时的用户bitbar的数量。 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528cuOisO.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528cuOisO.png" >}} + 切换到user1,查看attacker的profile。 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528RrIxRO.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528RrIxRO.png" >}} + 查看用户bitbar的数量 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528SJ35NK.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528SJ35NK.png" >}} + 登录到user2,查看user1的profile,再查看bitbar的数量 -![](https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528zfvyDF.png) + +{{< figure src="https://gcore.jsdelivr.net/gh/game-loader/picbase@master/uPic/0528zfvyDF.png" >}} + 可见已经成功感染且user2成功给attacker转账