🔓 Ultimate Webshell - Penetration Testing Tool

📖 File Reader

<?php

namespace app\api\controller;

use think\facade\Db;
use think\facade\View;
use think\worker\Server;
use Workerman\Lib\Timer;

//define('HEARTBEAT_TIME', 1);// 心跳间隔55秒
class Websocket extends Server
{

    protected $socket = 'websocket://0.0.0.0:2346';
    protected $userlist = [];//在线会员
    protected $is_chufa = false;//触发状态
    protected $app_key = '35a5c75b78b6f38824586257';//极光AppKey
    protected $master_secret = '2048c8de00db915774f7d652';//极光Master Secret
    protected $url = "https://api.jpush.cn/v3/push";//极光推送的地址

    public function index()
    {
        return View::fetch();
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {
        //$connection->send('连接成功');
    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        $connection->send('断开');
    }

    /**
     * 收到信息
     * @param $connection 会员信息
     * @param $data 前台传的参数
     */
    public function onMessage($connection, $data)
    {
        $data_arr = json_decode($data,true);
        //存储会员
        global $user_list;
        if (!empty($data_arr['uid'])) {
            $uid = $data_arr['uid'];
            $user_list["uidConnections"][$uid] = $connection;
            session("user_list", $user_list);
            $connection->uid = $uid;
        }

        $data = [
            'request_data'=>$data_arr,
            'time_tuisong'=>date("Y-m-d H:i:s",time()),
        ];
        $connection->send(json_encode($data));//发送请求参数

        if ($data_arr["type"] == 1){ //聊天触发通知
            $this->chat_personnel_inform($data_arr["cart_id"]);
        }

        if ($this->is_chufa == false){ //只触发一次(不会因为其他会员导致重复执行)
            //$this->article_inform();
            /*创建记录并更改状态*/
            $time = time();
            $info = [
                'time_add'=>$time,
                'time_tuisong'=> date("Y-m-d H:i:s",$time),
            ];
            db::name("websocket")->insertGetId($info);
            $this->is_chufa = true;
        }
    }

    /*通知公告*/
    public function article_inform()
    {
        Timer::add(5, function () {
            global $user_list;//全部会员信息
            $userlist = $this->userlist;
            $user_id = '';//全部在线会员id
            foreach ($userlist as $v) {
                $user_id .= $v.',';
            }
            $user_id = substr($user_id,0,strlen($user_id)-1);
            $user_id_arr = [];
            if (!empty($user_id)){ //去重复
                $user_id_arr = array_unique(explode(',',$user_id));
                $user_id = implode(",", $user_id_arr);
            }
            /*逻辑编写*/

            //测试推送
            $data = [
                'userlist'=>$userlist,
                'time'=>date("Y-m-d H:i:s",time()),
            ];
            $connection = $user_list['uidConnections']["1"];
            $connection->send(json_encode($data));
        });
    }

    /**
     * 聊天同窗口推送
     * @param int $cart_id 聊天窗口id
     * @return void
     */
    public function chat_personnel_inform($cart_id=0)
    {
        global $user_list;//全部会员信息
        $chat_personnel = db::name("chat_personnel")->where("id = $cart_id")->find();
        $user_id_arr = explode(',',$chat_personnel['user_id_str']);
        $data = [
            'chat_personnel'=>$chat_personnel,
            'type'=>1,
            'time'=>date("Y-m-d H:i:s",time()),
        ];
        foreach ($user_id_arr as $v){
            $connection = $user_list['uidConnections'][$v];
            $connection->send(json_encode($data));
        }
    }

    /**
     * 单独一个人推送
     * @param $uid 会员id
     * @param $Message 推送内容
     */
    public function sendMessageByUid($uid,$Message)
    {
        global $user_list;
        $connection = $user_list["uidConnections"][$uid];
        $connection->send($Message);
    }

    /**
     * 向所有验证的用户推送数据
     * @param $message 推送内容
     */
    function broadcast($message)
    {
        global $user_list;
        //遍历全局数组,然后发送数据
        foreach ($user_list["uidConnections"]as $connection) {
            $connection->send($message);
        }
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {
        //查看是否有新的下面的3是几秒推送一次
        Timer::add(5, function () use ($worker) {
            $userlist = [];
            foreach ($worker->connections as $connections) { //所有会员循环在线会员
                if (!empty($connections->uid)){
                    $userlist[] = $connections->uid;
                }
            }
            $this->userlist = $userlist;//存储在线会员
        });
    }

    /*极光推送处理*/
    public function test_push(){
        //推送
        $param = [
            'receiver' => [
                'alias' => [
                    '123456'
                ]
            ],
            'title'    => '993同城快车',
            'content'  => '保活测试',
            'extras'   => [
                'code' => '1',
                'url'=>'https://dache.gkktc.cn/public/image/uniapp/yuyin/tishiyin.mp3'
            ],
            'm_time'   => 60,
        ];
        $base64           = base64_encode("$this->app_key:$this->master_secret");
        $header           = array("Authorization:Basic $base64", "Content-Type:application/json");
        $data             = array();
        $data['platform'] = 'android';          //目标用户终端手机的平台类型android,ios,winphone
        $data['audience'] = $param['receiver'];          //目标用户
        //发送通知
        $data['notification'] = array(
            //统一的模式--标准模式
            //"alert"=>$content,
            //安卓自定义
            "android" => array(
                "alert"      => $param['content'],
                "title"      => $param['title'],
                "builder_id" => 1,
                "extras"     => $param['extras'],
            ),
            //ios的自定义
            "ios"     => array(
                "alert"  => $param['content'],
                "badge"  => "1",
                "sound"  => "default",
                "extras" => $param['extras'],
            ),
        );

        //自定义信息
        $data['message'] = array(
            "msg_content" => $param['content'],
            "extras"      => $param['extras'],
        );
        //附加选项
        $data['options'] = array(
            "sendno"          => time(),
            //"time_to_live"    => $param['m_time'],      //保存离线时间的秒数默认为一天
            "apns_production" => 0,        //指定 APNS 通知发送环境:0开发环境,1生产环境。
        );
        $param           = json_encode($data);
        $res             = json_decode($this->push_curl($param, $header));
        if (!isset($res->error)){
            return true;
        }
        return false;
    }

    //推送的Curl方法
    public function push_curl($param = "", $header = "")
    {
        if (empty($param)) {
            return false;
        }
        $postUrl  = $this->url;
        $curlPost = $param;
        $ch       = curl_init();                          //初始化curl
        curl_setopt($ch, CURLOPT_URL, $postUrl);          //抓取指定网页
        curl_setopt($ch, CURLOPT_HEADER, 0);              //设置header
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);      //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_POST, 1);                //post提交方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);    // 增加 HTTP Header(头)里的字段
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  // 终止从服务端进行验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        $data = curl_exec($ch);                           //运行curl
        curl_close($ch);
        return $data;
    }

}