刷題Phuck2--data協議差異

m1xian發表於2024-07-04

刷題Phuck2

使用arjun掃出hl引數,獲取到原始碼

image-20240704231439-teiap68

原始碼:

<?php
    stream_wrapper_unregister('php');
    if(isset($_GET['hl'])) highlight_file(__FILE__);

    $mkdir = function($dir) {
        system('mkdir -- '.escapeshellarg($dir));
    };
    $randFolder = bin2hex(random_bytes(16));
    $mkdir('users/'.$randFolder);
    chdir('users/'.$randFolder);

    $userFolder = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
    $userFolder = basename(str_replace(['.','-'],['',''],$userFolder));

    $mkdir($userFolder);
    chdir($userFolder);
    file_put_contents('profile',print_r($_SERVER,true));
    chdir('..');
    $_GET['page']=str_replace('.','',$_GET['page']);
    if(!stripos(file_get_contents($_GET['page']),'<?') && !stripos(file_get_contents($_GET['page']),'php')) {
        include($_GET['page']);
    }

    chdir(__DIR__);
    system('rm -rf users/'.$randFolder);

?>

這裡學到的知識:

  1. stream_wrapper_unregister('php');禁用php流(php開頭的偽協議)
  2. allow_url_include=Off時,include函式不支援 include data URI 的,也就是說:file_get_contents在處理data:,xxx時會直接取xxx ,而include會包含檔名為data:,xxx****的檔案

本題就是在頭部進行RCE,頭部資訊會寫進profile檔案,我們再利用include包含profile檔案

但是需要繞過對profile檔案內容的檢測

    if(!stripos(file_get_contents($_GET['page']),'<?') && !stripos(file_get_contents($_GET['page']),'php')) {
        include($_GET['page']);

這裡的話就是data協議處理差異

當allow_url_include=Off時,include不支援data偽協議。
file_get_contents是讀取而include是包含
這兩者還是有區別的。所以我們傳file_get_contents('data://text/plain,aa/profile')​時會得到aa/profile​字串
而include因為不包含data偽協議。就會把data://text/plain,aa​當作一個目錄,去包含下面的profile檔案

但是這裡出現一個問題,我們名字裡有斜槓,是不合法的,其實直接使用data:,aa或者時data:aa就行
我們可以傳值XFF為data:aa
就會建立data:aa​這個資料夾。然後包含data:aa/profile

image-20240704215616-3cgceg3

相關文章