真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么利用升級(jí)系統(tǒng)一鍵GetShell

這篇文章給大家分享的是有關(guān)怎么利用升級(jí)系統(tǒng)一鍵GetShell的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來(lái)看看吧。

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括威縣網(wǎng)站建設(shè)、威縣網(wǎng)站制作、威縣網(wǎng)頁(yè)制作以及威縣網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,威縣網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到威縣省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

0x01 程序安裝到復(fù)現(xiàn)

1.第一步安裝系統(tǒng)

怎么利用升級(jí)系統(tǒng)一鍵GetShell

2.第二步這里要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù),不然他不會(huì)自動(dòng)創(chuàng)建。

怎么利用升級(jí)系統(tǒng)一鍵GetShell

3.第三步完成安裝,然后我們點(diǎn)擊進(jìn)入后臺(tái)。

怎么利用升級(jí)系統(tǒng)一鍵GetShell

4.第四步進(jìn)入后臺(tái)-》程序升級(jí)-》升級(jí)配置

怎么利用升級(jí)系統(tǒng)一鍵GetShell

5.第五步,服務(wù)端構(gòu)建代碼,創(chuàng)建`index.php`放在網(wǎng)頁(yè)根目錄


怎么利用升級(jí)系統(tǒng)一鍵GetShell

6.第六步,后臺(tái)-》程序升級(jí)-》在線升級(jí),我這里改下1999-09-09 09:09:09代表是我服務(wù)器的升級(jí)軟件

怎么利用升級(jí)系統(tǒng)一鍵GetShell

7.第七步,我們點(diǎn)擊升級(jí),在用D盾監(jiān)聽下目錄是否上傳成功木馬文件。

怎么利用升級(jí)系統(tǒng)一鍵GetShell

8.第八步,訪問木馬文件,看看是否能訪問成功

怎么利用升級(jí)系統(tǒng)一鍵GetShell

0x02 代碼審計(jì)

漏洞所在文件:\framework\admin\update_control.php(在后臺(tái)程序升級(jí))

漏洞文件代碼:(只貼上相關(guān)代碼)


怎么利用升級(jí)系統(tǒng)一鍵GetShell

首先我們看第369行,$file = $this->get('file','int');,這里我們看到他這里是接收GET變量中的file值,那么int就是把接收的值轉(zhuǎn)換成int類型。

第370行,if(!$file)判斷$file變量是否有賦值,如果沒有復(fù)制那么就提示一個(gè)JSON數(shù)據(jù)。

第373行,$urlext = 'file='.rawurlencode($file);,rawurlencode函數(shù)代表空格轉(zhuǎn)換成%20。

第374行,$rs = $this->service(5,$urlext);,這里可以看到調(diào)用本身文件中的service方法,那我們進(jìn)入這個(gè)方法看看,在文章的第465行。


怎么利用升級(jí)系統(tǒng)一鍵GetShell

第465行,if(!file_exists($this->dir_root.'data/update.php')),file_exists函數(shù)代表檢查文件或目錄是否存在。

第470行,$uconfig = array();,申明一個(gè)空數(shù)組。

第471行,include($this->dir_root.'data/update.php');include函數(shù)代表引入一個(gè)文件,如果沒有找到這個(gè)文件只會(huì)提示個(gè)警告不會(huì)終止錯(cuò)誤。

第478行,if(file_exists($this->dir_root.'data/update.xml'))file_exists函數(shù)代表檢查文件或目錄是否存在。

第486行,if(substr($url,-1) != '/'),substr函數(shù)代表字符串切割,并且判斷不等于/那么就進(jìn)入487行區(qū)間。

第489行,$url .= 'index.php?version='.rawurlencode(trim($info['version'])).'&time='.$this->time.'&type='.$type;,URL地址拼接,rawurlencode函數(shù)代表空格轉(zhuǎn)換成%20,trim函數(shù)代表移除字符串兩側(cè)的空白字符。

第493行,if($type == 1 || $type == 4),判斷外部傳入的$type是否等于1或者等于4。

第494行,$onlyid = $uconfig['onlyid'] ? $uconfig['onlyid'] : $this->_onlyid();,這里使用了3元運(yùn)算符。

第495行,$domain = $this->lib('server')->domain($this->config['get_domain_method']);,這里代表是獲取當(dāng)前訪問的網(wǎng)址。

第496行,$client_ip = $this->lib('common')->ip();,獲取客戶端Ip

第497行,$url .= "&domain=".rawurlencode($domain)."&ip=".rawurlencode($client_ip);,URL地址拼接,rawurlencode函數(shù)代表空格轉(zhuǎn)換成%20。

第498行,$url .= "&onlyid=".$onlyid."&phpversion=".PHP_VERSION;,也是URL地址拼接。

第499行,if(function_exists('php_uname')),function_exists函數(shù)代表判斷是否有某函數(shù)。

第502行,$soft = $_SERVER['SERVER_SOFTWARE'];,獲取服務(wù)器PHP版本。

第506行,$MySQLversion = $this->db->version('server');,獲取服務(wù)端mysql版本號(hào)。

第511行,$this->lib('html')->setting('timeout',900);,這里是設(shè)置CURL請(qǐng)求的超時(shí)時(shí)間。

第513行,$this->lib('html')->ip($uconfig['ip']);,設(shè)置請(qǐng)求IP。

第515行,$info = $this->lib('html')->get_content($url);,請(qǐng)求URL地址,返回XML內(nèi)容。

下面就是返回XML數(shù)據(jù),那么我們回到第一張圖片。

怎么利用升級(jí)系統(tǒng)一鍵GetShell

第375行,$rs = $this->lib('json')->decode($rs);,這里代表是把接收到的XML內(nèi)容轉(zhuǎn)換成JSON數(shù)據(jù)。

第376行,if($rs['status'] != 'ok'),判斷$rs['status']不等于ok。

第379行,if(!$rs['content']),判斷是否為空。

第382行,$info = base64_decode($rs['content']);,把接收到的$rs['content']值,從base64轉(zhuǎn)換成實(shí)體。

第383行,file_put_contents($this->dir_root.'data/tmp.zip',$info);,寫入當(dāng)前文件,第一個(gè)參數(shù)代表路徑,第二個(gè)參數(shù)代表內(nèi)容。

第384行,$this->lib('phpzip')->unzip($this->dir_root.'data/tmp.zip','data/update/');,我們看到這里的意思就是解壓文件到某個(gè)目錄。

第386行,$this->lib('file')->rm($this->dir_root.'data/tmp.zip');,刪除寫入的文件。

第386行,$verinfo = substr($file,0,1).".".substr($file,1,1).".".substr($file,2);,這里是字符串切割。

第387行,$info = $this->update_load($verinfo);,這里調(diào)用自定義方法,也是在本文章第152行。

怎么利用升級(jí)系統(tǒng)一鍵GetShell

第154行,$list = array();,定義一個(gè)空數(shù)組。

第155行,$this->lib('file')->deep_ls($this->dir_root.'data/update/',$list);,這里大概意思是遍歷當(dāng)前文件所有文件名,這里我就不去找代碼,就把代碼直接復(fù)制出來(lái)。

那么代碼路徑在framework\libs\file.php中第297-313行

    /**
     * 獲取文件夾及子文件夾等多層文件列表(無(wú)限級(jí),長(zhǎng)度受系統(tǒng)限制)
     * @參數(shù) $folder 文件夾
     * @參數(shù) $list 引用變量
    **/    public function deep_ls($folder,&$list)    {
            $this->read_count++;
            $tmplist = $this->_dir_list($folder);
            foreach($tmplist AS $key=>$value){
                    if(is_dir($value)){
                            $this->deep_ls($value,$list);
                    }else{
                            $list[] = $value;
                    }
            }
    }

第156行,if(!$list || count($list) < 1),判斷$list是否為空,并且判斷他的數(shù)據(jù)是不是小于1。

第159行,$strlen = strlen($this->dir_root."data/update/");strlen代表統(tǒng)計(jì)字符串長(zhǎng)度。

第162行,foreach($list as $key=>$value)foreach循環(huán)遍歷數(shù)組。

第163行,$value = trim($value);,trim代表移除字符串兩側(cè)的字符。

第165行,continue;,這里代表跳出循環(huán)。

第167行,$tmp = substr($value,$strlen);substr代表字符串切割。

第168行,if($tmp == 'version.txt'),這里判斷$tmp是否等于version.txt。

第169行,$verinfo = trim(file_get_contents($value));trim代表移除字符串兩側(cè)的字符,file_get_contents代表寫入文件。

第183行,if(substr($tmp,0,10) == 'framework/'),substr代表字符串切割,從0到10切割判斷等于framework/

第185行,if(is_file($value))is_file代表判斷文件是否存在。

第187行,$this->lib('file')->mv($value,$this->dir_phpok.$tmp1);,剪切文件到某個(gè)目錄。

第189行,if(is_dir($value) && !is_dir($this->dir_phpok.$tmp1)),is_dir代表判斷目錄是否存在,并且判斷臨時(shí)文件是否不存在。

第190行,$this->lib('file')->make($this->dir_phpok.$tmp1,'folder');,創(chuàng)建目錄。

第194行,if(is_file($value) && $tmp != 'table.sql'),is_file代表判斷文件是否存在,并且判斷$tmp不等于table.sql文件的進(jìn)入?yún)^(qū)間。

第194行-第210行都是一樣,剪切和創(chuàng)建目錄。

第205行,$dlist = file($delfile);,file代表整個(gè)文件讀入一個(gè)數(shù)組中。

第209行,foreach($dlist AS $key=>$value),foreach代表數(shù)組循環(huán)。

第213行,$value = trim($value);trim代表移除字符串兩側(cè)的字符。

第214行,if($value && is_file($this->dir_root.$value)),判斷$value是否有值,并且判斷文件是否存在。

第215行,$this->lib('file')->rm($this->dir_root.$value);,代表刪除文件。

第218行,if($value && is_dir($this->dir_root.$value)),判斷$value是否有值,并且判斷目錄是否存在。

第225行,$this->update_table();這里又看到調(diào)用自己的方法。

為何還有那么多代碼要分析。

我們接下來(lái)繼續(xù)往下分析,這里的話我就把代碼Copy出來(lái),代碼太多截圖不好看。

我這里挑重要的函數(shù)講解下,這里都是sql執(zhí)行語(yǔ)句,沒有什么可以分析的。

函數(shù):

file_exists,代表檢查文件或目錄是否存在。

file_get_contents,代表讀取文件,如果攜帶2個(gè)參數(shù)那么就是寫入。

str_replace,代表字符串替換。

strlen,代表查看字符串長(zhǎng)度。

substr,代表字符串切割。

unset,代表變量刪除。

explode,代表把字符串切割成數(shù)組。

trim,代表移除字符串兩側(cè)的字符。

    private function update_table()    {
            if(!file_exists($this->dir_root.'data/update/table.sql')){
                    return false;
            }
            //創(chuàng)建新表臨時(shí)            $prefix = 'tmp_'.$this->db->prefix;
            $sqlcontent = file_get_contents($this->dir_root.'data/update/table.sql');
            $sqlcontent = str_replace('qinggan_',$prefix,$sqlcontent);
            $this->sql_run($sqlcontent);
            //比較新表結(jié)果            $list = $this->db->list_tables();
            $tblist = array();
            $nlength = strlen($prefix);
            $olength = strlen($this->db->prefix);
            foreach($list as $key=>$value){
                    //跳過擴(kuò)展表                    $continue_1 = substr($value,0,strlen($prefix.'list_'));
                    $continue_2 = substr($value,0,strlen($this->db->prefix.'list_'));
                    if($continue_1== $prefix.'list_' ||  $continue_2 == $this->db->prefix."list_"){
                            continue;
                    }
                    if(substr($value,0,$nlength) == $prefix){
                            $tblid = substr($value,$nlength);
                            $tblist[$tblid]['new'] = $value;
                    }
                    if(substr($value,0,$olength) == $this->db->prefix){
                            $tblid = substr($value,strlen($this->db->prefix));
                            $tblist[$tblid]['old'] = $value;
                    }
            }
            foreach($tblist as $key=>$value){
                    if(!$value['new']){
                            continue;
                    }
                    if(!$value['old']){
                            $sql = "SHOW CREATE TABLE ".$value['new'];
                            $rs = $this->db->get_one($sql);
                            if(!$rs['Create Table']){
                                    continue;
                            }
                            $rs['Create Table'] = str_replace($prefix,$this->db->prefix,$rs['Create Table']);
                            $this->db->query($rs['Create Table']);
                            continue;
                    }
                    //比較新表                    $nlist = $this->db->list_fields_more($value['new']);
                    $olist = $this->db->list_fields_more($value['old']);
                    foreach($nlist as $k=>$v){
                            if($olist[$k] && $olist[$k]['type'] == $v['type']){
                                    continue;
                            }
                            if(!$olist[$k]){
                                    $sql = "ALTER TABLE ".$value['old']." ADD `".$k."` ".$v['type']." ";
                            }else{
                                    $sql = "ALTER TABLE `".$value['old']."` CHANGE `".$k."` `".$k."` ".$v['type']." ";
                            }
                            if($v['null'] == 'NO'){
                                    $sql .= " NOT NULL ";
                                    if($v['default'] != ''){
                                            $sql .= " DEFAULT ".$v['default']." ";
                                    }
                            }else{
                                    $sql .= " DEFAULT ".($v['default'] != '' ? $v['default'] : ' NULL ')." ";
                            }
                            if($value['extra']){
                                    $sql .= " ".$v['extra']." ";
                            }
                            if($v['comment']){
                                    $sql .= " COMMENT '".$v['comment']."'";
                            }
                            $this->db->query($sql);
                    }
                    unset($nlist,$olist);
            }
            //刪除臨時(shí)表操作            foreach($list as $key=>$value){
                    if(substr($value,0,$nlength) == $prefix){
                            $sql = "DROP TABLE ".$value;
                            $this->db->query($sql);
                    }
            }
            unset($list,$tbllist);
            return true;
    }

    private function sql_run($sql='')    {
            $sql = str_replace("\r","\n",$sql);
            $ret = array();
            $num = 0;
            foreach(explode(";\n", trim($sql)) as $query){
                    $queries = explode("\n", trim($query));
                    foreach($queries as $query){
                            $ret[$num] .= $query[0] == '#' || $query[0].$query[1] == '--' ? '' : $query;
                    }
                    $num++;
            }
            foreach($ret as $query){
                    $query = trim($query);
                    if($query){
                            $this->db->query($query);
                    }
            }
            return true;
    }

好了 我們回到上上張圖片。

怎么利用升級(jí)系統(tǒng)一鍵GetShell

第231行,$info = trim(file_get_contents($value));,trim代表移除字符串兩側(cè)的字符,file_get_contents代表寫入文件。

第233行,$info = str_replace('qinggan_',$this->db->prefix,$info);,str_replace代表字符串替換。

第240行,if(file_exists($this->dir_root."data/update/run.php"))file_exists代表檢查文件或目錄是否存在。

第241行,include($this->dir_root.'data/update/run.php');,include引入一個(gè)文件。

第243行,$this->lib('file')->rm($this->dir_root.'data/update/');,代表刪除文件。

第244行,$list = $this->lib('file')->ls($this->dir_root.'data/update/');,代表把目錄結(jié)構(gòu)挪列出來(lái)。

第245行,if($list && count($list)>0),判斷$list值是否存在,并且判斷他的數(shù)量是否小于0。

第247行,$this->lib('file')->rm($value,'folder');,這里代表循環(huán)刪除某個(gè)文件。

第251行,$this->success_version($verinfo);這里又進(jìn)入一個(gè)自定義方法區(qū)間。

老樣子,Copy代碼,代碼量不多我就Copy出來(lái)。

    //更新成功后,修改記錄    private function success_version($version='')    {
            if(!$version){
                    return false;
            }
            //寫入到最新版本            $html = ''."\n";
            $html.= ''."\n";
            $html.= "\t".''.trim($version).''."\n";
            $html.= "\t".''."\n";
            $html.= '';
            file_put_contents($this->dir_root.'data/update.xml',$html);
            if(is_writeable($this->dir_root.'version.php') && file_exists($this->dir_data.'version.tpl')){
                    $info = file_get_contents($this->dir_data.'version.tpl');
                    $info = str_replace('{version}',trim($version),$info);
                    $info = str_replace('{updatetime}',date("Y年m月d日 H時(shí)i分s秒",$this->time),$info);
                    file_put_contents($this->dir_root.'version.php',$info);
            }
            $this->lib('file')->rm($this->dir_root.'data/tpl_admin/');
            $this->lib('file')->rm($this->dir_root.'data/tpl_www/');
            $this->lib('file')->rm($this->dir_cache);
            return true;
    }

那么我們還是做簡(jiǎn)單的介紹下重要函數(shù)。

trim,代表移除字符串兩側(cè)的字符。

is_writeable,判斷文件是否可寫。

file_exists,代表檢查文件或目錄是否存在。

str_replace,字符串替換。

file_put_contents,寫入文件或讀取文件。

這里已經(jīng)介紹完畢了,整個(gè)審計(jì)分析邏輯在上面。

0x03 漏洞修復(fù)

路徑:\framework\admin\update_control.php

第152行,方法里面的foreach循環(huán)加上這段代碼去過濾。

$verinfo = str_replace(['eval','assert','system','phpinfo'], ['eval','assert','system','phpinfo'], strtolower(trim(file_get_contents($value))));,這里我只寫了比較有危害的關(guān)鍵字。


怎么利用升級(jí)系統(tǒng)一鍵GetShell

感謝各位的閱讀!關(guān)于“怎么利用升級(jí)系統(tǒng)一鍵GetShell”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!


分享標(biāo)題:怎么利用升級(jí)系統(tǒng)一鍵GetShell
當(dāng)前地址:http://weahome.cn/article/ipsjji.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部