<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/papers/1957

                    0x00 前言


                    話說一個人的快樂,兩個人分享就成為兩份快樂,這個我看未必吧,倘若分享與被分享的兩者之間是情敵關系,而分享者快樂的原因恰好是… 哈哈,不說了,都懂的;

                    BUT, 倘若一個技巧被分享出來,那么受益的人我堅信肯定遠遠不只兩個,所以我們更應該學會的是--分享!

                    Today,簡單說說漏洞挖掘中由邏輯缺陷造成的文件上傳漏洞。

                    Tips:傳統的MIME驗證、客戶端js驗證、黑名單驗證、解析漏洞等這些都比較簡單,不在我們討論的范圍內。

                    0x01 程序員對某些常用函數的錯誤認識


                    這些函數有:empty()、isset()、strpos()、rename()等,如下面的代碼(摘自用友ICC軟件):

                    #!php
                    if($operateId == 1){
                        $date = date("Ymd");
                        $dest = $CONFIG->basePath."data/files/".$date."/";
                        $COMMON->createDir($dest);
                        //if (!is_dir($dest))   mkdir($dest, 0777);
                        $nameExt = strtolower($COMMON->getFileExtName($_FILES['Filedata']['name']));
                        $allowedType = array('jpg', 'gif', 'bmp', 'png', 'jpeg');
                        if(!in_array($nameExt, $allowedType)){
                            $msg = 0;
                        }
                        if(empty($msg)){
                            $filename = getmicrotime().'.'.$nameExt;
                            $file_url = urlencode($CONFIG->baseUrl.'data/files/'.$date."/".$filename);
                            $filename = $dest.$filename;
                            if(empty($_FILES['Filedata']['error'])){
                                move_uploaded_file($_FILES['Filedata']['tmp_name'],$filename);
                            }
                            if (file_exists($filename)){
                                //$msg = 1;
                                $msg = $file_url;
                                @chmod($filename, 0444);
                            }else{
                                $msg = 0;
                            }
                        }
                        $outMsg = "fileUrl=".$msg;
                        $_SESSION["eoutmsg"] = $outMsg;
                        exit;
                    }
                    

                    我們來看上面的這段代碼,要想文件成功的上傳, if(empty($msg)) 必須為True才能進入if的分支,接下來我們來看empty函數何時返回True,看看PHP Manual怎么說,如圖

                    enter image description here

                    很明顯,""、0、"0"、NULL、FALSE、array()、var $var; 以及沒有任何屬性的對象都將被認為是空的,如果var為空,則返回True。 非常好,接下來我們往回看,有這樣的幾行代碼

                    #!php
                    $allowedType = array('jpg', 'gif', 'bmp', 'png', 'jpeg');
                    if(!in_array($nameExt, $allowedType)){
                        $msg = 0;
                    }
                    

                    看見沒有,即使我們上傳類似shell.php的文件,雖然程序的安全檢查把$msg賦值為0,經empty($msg)后,仍然返回True,于是我們利用這個邏輯缺陷即可成功的上傳shell.php。

                    具體詳見漏洞案例:

                    WooYun: 用友ICC網站客服系統遠程代碼執行漏洞

                    0x02 程序員對某些常用函數的錯誤使用


                    這些函數有iconv()、copy()等,如下面的這段代碼(摘自SiteStar)

                    #!php
                    public function img_create(){
                         $file_info =& ParamHolder::get('img_name', array(), PS_FILES);
                         if($file_info['error'] > 0){
                             Notice::set('mod_marquee/msg', __('Invalid post file data!'));
                             Content::redirect(Html::uriquery('mod_tool', 'upload_img'));
                         }
                         if(!preg_match('/\.('.PIC_ALLOW_EXT.')$/i', $file_info["name"])){
                             Notice::set('mod_marquee/msg', __('File type error!'));
                             Content::redirect(Html::uriquery('mod_marquee', 'upload_img'));
                         }
                         if(file_exists(ROOT.'/upload/image/'.$file_info["name"])){
                             $file_info["name"] = Toolkit::randomStr(8).strrchr($file_info["name"],".");
                         }
                         if(!$this->_savelinkimg($file_info)){
                             Notice::set('mod_marquee/msg', __('Link image upload failed!'));
                             Content::redirect(Html::uriquery('mod_marquee', 'upload_img'));
                          }
                          //...
                     }
                    private function _savelinkimg($struct_file){
                        $struct_file['name'] = iconv("UTF-8", "gb2312", $struct_file['name']);
                        move_uploaded_file($struct_file['tmp_name'], ROOT.'/upload/image/'.$struct_file['name']);
                        return ParamParser::fire_virus(ROOT.'/upload/image/'.$struct_file['name']);
                    }
                    

                    我們再來看看這段代碼, img_create()函數的邏輯非常嚴密,安全檢查做的很到位。然而問題出在了_savelinkimg()函數,即在保存文件的前面程序員錯誤的使用了iconv()函數,并且文件名經過了此函數,為什么是錯用了呢?因為啊 iconv函數在轉碼過程中,可能存在字符串截斷的問題:

                    在iconv轉碼的過程中,utf->gb2312(其他部分編碼之間轉換同樣存在這個問題)會導致字符串被截斷,如:$filename="shell.php(hex).jpg";(hex為0x80-0x99),經過iconv轉碼后會變成$filename="shell.php ";

                    所以,經過iconv 后$struct_file['name'])為shell.php,于是我們利用這個邏輯缺陷可以成功的上傳shell.php(前提是上傳的文件名為shell.php{%80-%99}.jpg)。

                    具體詳見漏洞案例:

                    WooYun: 建站之星模糊測試實戰之任意文件上傳漏洞

                    0x03 歷史經典漏洞再次爆發


                    條件競爭漏洞,這類歷史經典漏洞在逐漸淡出人們視線的時候,再次爆發..

                    接著看下面這段代碼(摘自某VPN系統)

                    #!php
                    <?
                    if($_POST['realfile']){
                        copy($_POST['realfile'],$_POST['path']);
                    }
                    $file = mb_convert_encoding($_POST[file],"GBK","UTF-8");
                    header("Pragma:");
                    header("Cache-Control:");
                    header("Content-type:application/octet-stream");
                    header("Content-Length:".filesize($_POST[path]));
                    header("Content-Disposition:attachment;filename=\"$file\"");
                    readfile($_POST[path]);
                    if($_POST['realfile']){
                        unlink($_POST["path"]);
                    }
                    ?>
                    

                    上述代碼的邏輯表面上看起來是這樣的(對于攻擊者來說):

                    利用copy函數,將realfile生成shell.php-→刪除掉shell.php

                    這樣初看起來沒辦法利用,但是仔細一想, 這段代碼其實是存在邏輯問題的,所以我們可以利用這個邏輯缺陷達到GetShell的目的。

                    具體利用方法:

                    copy成temp.php-->不斷訪問temp.php->temp.php生成shell.php->刪除temp.php

                    具體詳見漏洞案例:

                    WooYun: 國內外多家vpn設備廠商批量漏洞(續集一)

                    WooYun: PHPCMS前臺設計缺陷導致任意代碼執行

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频