【Web安全】Web安全Java代码审计总结

《网络安全Java代码审计实战》笔记。

一、SQL注入

1.1 常见的sql注入场景

1.预编译错误编程方式

String username = "";
String id = "2";
String sql = "SELECT * FROM user where id = ?";
if(!CommonUtils.isEmptyStr(username))
sql += "and username like '%" + username + "%'";
PreparedStatement pst = conn.prepareStatment(sql);
pst.setString(1,id);
rs = pst.executeQuery();

2.order by 注入

order by 子句后面需要加字段名或者字段位置,而字段名是不能带引号的,否则就会被认为是一个字符串而不是字段名。PrepareStatement是使用占位符传入参数的,传递的字符都会有单引号包裹,这样会使order by子句失效。

所以order by后面的字段只能通过入参校验的方式来防御sql注入。

3.%和_模糊查询

在java预编译查询中不会对%和_进行转义处理,而%和_是like查询的通配符,如果没有做好相关的过滤,就有可能导致恶意模糊查询,占用服务器性能,甚至可能耗尽资源,造成服务器宕机。

4.mybatis中的sql注入

【SQL注入】Mybatis框架下的sql注入白盒审计_l1b2090的博客-CSDN博客

5.二次注入

有一个sql查询语句select * from users where username = ${username},该语句未采用预编译,但是走读代码发现该参数并非由请求参数传入,而是在用户成功登录后,从session中取出。因此想要利用这个sql注入漏洞,我们需要创建一个用户名为恶意sql语句的用户,并成功登录应用,才能达到sql注入的目的。这种sql注入称为二次注入。

1.2 常规注入代码审计

1.代码扫码关键字:

常规的:Statement、createStatement、PrepareStatement、select、update、insert

Mybatis框架:

1)like'%$、in(${};

2)如果是使用xml文件映射,则直接在xml中搜索$即可;

3)使用SQL类构建sql语句的情况,可以搜索SQL关键字(区分大小写搜),有的项目也可能自己重写SQL类。另外这种方式构建sql语句,java文件的命名都有特征,比如xxxSQLProvider;

4)使用注解方式写sql时,java文件命名一般是xxxMapper.java。

1.3 SQL注入漏洞防护

1.预编译;

2.严格的参数校验;

3.入参是int就用int。

一、任意文件上传

任意文件上传漏洞的本质是在进行文件上传操作时未对文件类型进行检测或检测功能不规范导致被绕过,从而使攻击者上传的可执行脚本(WebShell)被上传至服务器并成功解析。

1.1 文件上传的方式

1.通过文件流的方式上传

2.通过ServletFileUpload方式上传

3.通过MultipartFile方式上传

另外还有一些专门用于文件上传下载的第三方服务,这类服务对文件上传下载漏洞做了很好的防护,这种情况可以看看服务的安全配置是否配置得当,比如文件上传下载的目录权限是否过大、是否有提供web管理页面、是否存在未授权访问等漏洞。

1.2 文件上传漏洞审计

1.代码搜索关键字:

org.apache.commons.fileupload

java.io.File

MultipartFile

RequestMethod

MultipartHttpServletRequest

CommonsMultipartResolver

2.定位到文件上传的代码段后,观察上传路径的获取、文件名的黑白名单。

比如通过黑名单过滤.jsp、.sh文件的代码如下,则可以通过构造形如payload.txt.jsp文件名的文件绕过校验。

String suffix = fileName.substring(fileName.indexOf("."));
string picBlack[] = {".jsp",".sh"}
for (String blackSuffix:picBlack){
    if(suffix.toLowerCase().equals(blackSuffix)){
        BlackFlag = true;
        break;
    }
}

遇到indexOf()、endsWith()、startsWith()等部分匹配的方法时要格外注意,使用这种方式判断往往存在漏洞。

使用请求头中的Content-Type字段校验也不安全,应该该字段可通过burpsuite等工具拦截请求随意更改。

1.3 文件上传漏洞防护

采取白名单策略限制运行上传的类型;对文件名字进行重命名;去除文件名中的特殊字符;上传图片时,通过图片库检测上传文件是否为图片。

比如上文漏洞,可以改用fileName.lastIndexOf(".")来获取文件的真实路径。

文件重命名可以防止文件在被上传到服务器后被调用,另外这里也需要注意重命名的方式要足够随机,避免被猜解。

三、XSS

1.1 常见触发位置

XSS漏洞产生后必然会有相关的输入/输出,因此我们只需快速找到这些输入/输出点,即可快速地进行跟踪发现漏洞。输入在java中通常使用request.getParameter()或${param}获取用户的输入信息。输出主要表现为前端的渲染,我们可以通过定位前端一些常见的标识来找到它们,然后根据后端逻辑来判断漏洞是否存在。

1.JSP表达式

<%=%>用于将已声明的变量或表达式输出到网页中。

//形式一
<%=msg%>
<%out.println(msg);%>

//形式二
<% String msg = request.getParameter('msg';)%>
<%=msg%>

2.EL(Expression Language,表达式语言)  //这部分内容挺多的,以后单独学习

为了使JSP写起来更加简单,例如

<% =request.getParameter('username';)%>

等价于${parame.username}.

JSP标准库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。例如:

1)<c:out>标签

<c:out>标签用来显示一个表达式的结果,与<%=%>作用相似,它们的区别是,<c: out>标签可以直接通过'.'操作符来访问属性,如下:

<c:out value = "${user.getUsername}"

2)<c:if>标签

<c:if>标签用来判断表达式的值,如果表达式的值为true,则执行其主体内容:

<c:if test="${user.salary>2000}"
<p>我的工资为:value="${user.salary}"</[>

3.ModelAndView类的使用

ModelAndView类用来存储处理完成后的结果数据,以及显示该数据的视图,其前端JSP页面可以使用${参数}的方法来获取值。

比如在SpringMVC中就经常用到。

4.ModelMap类的使用

Spring也提供了ModelMap类,这是java.util.Map实现的,可以根据模型属性的具体类型自动生成模型属性的名称:

Public String testmethod(String param,ModelMap mode){
    //省略方法处理逻辑
    //将数据放置到ModelMap类的model对象中,第二个参数可以是任何Java类型
    Model.addAttribute("key",param);
    retuen "success";
}

5.Model类的使用

Model类是一个接口类,通过attribute()添加数据,存储的数据域范围是requestScope:

Public String index(Model model){
    Model.addAttribute("result","后台返回");
    return "result";
}

通过这些常见语法的总结我们可以归纳出一些关键字,通过这些关键字可以快速定位到具有前后端交互功能的代码片段:

<%=>

${

<c:out

<c:if

<c:forEach

ModelAndView

ModelMap

Model

request.getParameter

request.setAttribute

response.getrWriter().print()

response.getWriter().writer()

感觉搜这些关键字的话,搜索结果会很多啊

对于xss漏洞,我个人更偏向于黑盒测试,白盒的话,如果使用了类似thymeleaf的模板引擎,可以搜一下html文件中哪些数据没有进行输出编码,这样工作量也会小很多。

1.2 XSS漏洞修复

1.输入校验:编写全局过滤器实现拦截(网上有很多)

2.输出编码:对所有字符采用HTML实体编码

四、目录穿越漏洞

目录穿越漏洞在Web程序中也是一种较为常见的漏洞,其往往出现在需要用户提供路径或文件名时,如文件下载。在访问者提供需要下载的文件后,Web应用程序没有去校验文件名中是否存在 ../ 等特殊字符,没有对访问的文件进行限制,导致目录穿越,读取到本不应该取到的内容。

目录穿越漏洞产生的本质是路径可控,一旦涉及文件的读取问题便会涉及java.io.File类,因此在审计这类漏洞时可以优先查找java.io.File引用,并根据经验来判断Paths、path、System.getPropert([user.dir])等各类可能会用来构造路径的关键字。

若项目采用SpringMVC这类框架也可以先查看一下路由,判断是否存在如path之类的路由。

1.1 目录穿越漏洞审计

这类漏洞可以先操作一遍web页面的功能,找到文件下载点(所有需要访问系统文件的地方),使用burpsuite拦截请求观察请求中是否有文件路径等信息,再定位到对应的后端代码,判断路径校验是否严谨。

1.2 目录穿越漏洞修复

1.对文件名进行过滤,防止出现 ./ 等特殊字符;

2.采用ID索引的方法来下载文件,文不是直接通过文件名;

3.对目录进行限制、合理分配后台文件权限。(特别是使用的第三方服务的情况,第三方文件服务权限一定要做合理的限制)

五、URL跳转漏洞

一个常见的URL跳转实现方式:

response.sendRedirect(request.getParameter("url"));

该代码从请求参数中获取需要跳转到的url,然后跳转到参数所指向的url,若服务端对接受URL跳转的参数没有进行过滤和限制,攻击者就有可能构造一个恶意的URL地址,诱导其它用户访问恶意的网站。

一般来讲,对于URL跳转漏洞在黑盒测试主要的关注点为:注意URL中是否带有return、redirect、url、jump、goto、target、link等参数值,并注意观察后跟的URL地址的具体格式,再构造相应的payload尝试跳转。在白盒审计中我们则会重点关注可以进行URL跳转的相关方法。

1.1 URL重定向

Spring MVC中使用重定向的场景很多,一般有以下几种方法:

1.通过ModelAndView方式

public ModelAndView testForward(HttpServletRequest request, HttpServletResponse response){
    String url = request.getParameter("url");
    url = "redirect:" + url;
    return new ModelAndView(url);
}

URL跳转使用方式:http://www.test.com?url=http://www.xxx.com

2.通过返回String方式

public String redirect(@RequestParam("url") String url){
    return "redirect:" + url;
}

URL跳转使用方式:http://www.test.com?url=http://www.xxx.com

3.使用sendRedirect方式

public static void sendRedirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String url = request.getParameter("url");
    response.sendRedirect(url);
}

URL跳转使用方式:http://www.test.com?url=http://www.xxx.com

4.使用RedirectAttributes方式

对于一般的URL跳转,使用redirect即可满足要求。如果需要进行参数拼接,则一般使用RedirectAttributes。

@RequestMapping("/RedirectAttributes")
public String test(RedirectAttributes redirectAttributes){
    redirectAttributes.addAttribute("id", "2");
    return "redirect:/test/index";
} 

URL跳转使用方式:http://www.test.com/RedirectAttributes

跳转后的url:/test/index?id=2

5.通过Header来进行跳转

public static void serHeader(HttpServletRequest request, HttpServletResponse response){
    String url = request.getParameter("url");
    //HttpServletResponse.SC_MOVED_TEMPORARILY) 设置返回的状态码302
    //301永久重定向、302临时重定向
    response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
    response.setHeader("Location",url);
}

URL跳转使用方式:http://www.test.com?url=http://www.xxx.com

通过上述这些方法可以总结出URL跳转漏洞一些常见的关键字如下:

redirect、sendRedirect、Location等

1.2 URL跳转漏洞修复

1.校验需要跳转的域名,尽可能的使用白名单;

2.使用服务器转发,forward。

六、命令执行漏洞

命令执行漏洞是指应用需要调用一些执行系统命令的函数,如果系统命令代码未对用户可控参数做过滤,则当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击。

Java中执行系统命令的函数有:

Runtime.getRuntime.exec、ProcessBuilder.start

1.1 ProcessBuilder命令执行漏洞

1)ProcessBuilder命令执行方法

Java.lang.ProcessBuilder类用于创建操作系统进程,每个ProcessBuilder实例管理一个进程属性集。start()方法利用这些属性创建一个新的Process实例,可以利用ProcessBuilder执行命令。

public class Test {
    public static void main(String[] args) throws IOException {
        // 执行系统命令
        ProcessBuilder processBuilder = new ProcessBuilder("ipconfig");
        Process process = processBuilder.start();
        // 获取执行完成命令后的结果并输出
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
        while ((line = reader.readLine())!=null){
            System.out.println(line);
        }
        reader.close();
    }
}

1)ProcessBuilder命令执行漏洞利用

在上述代码中,如果new ProcessBuilder("ipconfig")中的参数ipconfig外部可控,则可能存在命令注入漏洞。

我们可以使用linux中的管道符,执行多条命令,造成命令注入。

这里也要注意,就算代码中对命令做了白名单校验且对管道命令做了过滤,也可能存在问题,我们可以查阅白名单中的命令,看是否存在一些危险参数。

1.2 Runtime exec命令执行漏洞

java.lang.Runtime公共类中的exec()方法也可以执行系统命令,exec()方法的使用方式有以下6种:

        // 在单独的进程中指定指定的字符串命令
        public Process exec(String cmd)
        // 在单独的进程中执行指定的命令和参数
        public Process exec(String[] cmdarray)
        // 在具有指定环境的单独进程中执行指定的命令和参数
        public Process exec(String[] cmdarray, String[] envp)
        // 在具有指定环境和工作目录的单独进程中执行指定的命令和参数
        public Process exec(String[] cmdarray, String[] envp, File dir)
        // 在具有指定环境的单独进程中执行指定的字符串命令
        public Process exec(String cmd, String[] envp)
        // 在具有指定环境和工作目录的单独进程中执行指定的字符串命令
        public Process exec(String cmd, String[] envp, File dir)

1)Runtime exec执行字符串参数和数组参数

exec()方法在执行命令时,当传入的参数为字符串参数和数组参数时会有不同的返回结果。

原因:

    public StringTokenizer(String str) {
        this(str, " \t\n\r\f", false);
    }

当exec()执行字符串参数时,会经过StringTokenizer类的拆分,因此若命令为:

"/bin/sh -c \"ping -t 3 127.0.0.1;id\"";

会被拆分成:

{"/bin/sh","-c",""ping","-t","3","127.0.0.1;id","""}

改变了命令的语义,导致不能正常执行。

如果传入的参数为数组,则不会经过StringTokenizer的拆分,而是直接调用ProcessBUilder执行命令。

因此若代码里Runtime.exec()方法接收的参数为String类型时,我们需要使用一些字符来替代空格,如${IFS}、$IFS$9等。不过URL中不能出现{},所以需要将payload进行url编码。

1.3 命令执行漏洞修复

入参校验,尽可能使用白名单。

七、XXE漏洞

XXE为XML外部实体注入。当应用程序在解析XML输入时,在没有禁止外部实体的加载而导致加载了外部文件及代码时,就会造成XXE漏洞。XXE漏洞可以通过file协议或是FTP协议来读取文件源码,当然也可以通过XXE漏洞来对内网进行探测或者攻击。如下图。

 漏洞危害有:任意文件读取、内网探测、攻击内网站点、命令指定、DOS攻击等。

1.1 XML的常见接口  //这个后面有空再具体学习

在Java中一般用以下几种常见的接口来解析XML:

1.XMLReader

XMLReader接口是一种通过回调读取XML文档的接口,其存在于公共域中。XMLReader接口是XML解析器实现SAX2驱动程序所必需的接口,其允许应用程序设置和查询解析器中的功能和属性、注册文档处理的事件处理程序,以及开始文档解析。当XMLReader使用默认的解析方法并且未对XML进行过滤时,会出现XXE漏洞。

使用XmlReader读Xml_玉开的博客-CSDN博客_xmlreader

2.SAXBuilder

SAXBuilder是一个JDOM解析器,其能够将路径中的XML文件解析为Document对象。SAXBuilder使用第三方SAX解析器来处理解析任务,并使用SAXHandler的实例侦听SAX事件。当SAXBuilder使用默认的解析方法并且未对XML进行过滤时,会出现XXE漏洞。

3.SAXReader

DOM4J是dom4j.org出品的一个开源XML解析包,使用起来非常简单,只要了解基本的XML-DOM模型,就能使用。DOM4J读/写XML文档主要依赖于org.dom4j包,它有DOMReader和SAXReader两种方式。因为使用了同一接口,所以这两种方式的调用方法是完全一致的。同样的,在使用默认解析方法并且未对XML进行过滤时,也会出现XXE漏洞。

4.SAXParseractory

SAXParseractory使应用程序能够配置和获取基于SAX的解析器以解析XML文档。其受保护的构造方法,可以强制使用newinstance()。使用默认的解析方法并且未对XML进行过滤时,会出现XXE漏洞。

5.Digester

Digester类用来将XML映射成Java类,以简化XML的处理。它是Apache commons库中的一个jar包:common-digester包。使用默认的解析方法并且未对XML进行过滤时,会出现XXE漏洞。其触发的XXE漏洞是没有回显的,我们一般需要通过Blind XXE的方法来利用。

6.DocumentBuilderFactory

java.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器对象,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance()方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。

1.2 XXE漏洞审计

搜索上面提到的类名,查看是否有解析XML的代码,进一步查看XML是否可控。

GitHub上有个开源的XXE靶场:XXE-Lab

代码搜索到关键字DocumentBuilderFactory.newInstance()

例如如下代码段:

documentBuilder.parse()的参数为请求中传入的一个XML文件

后续直接对传入的XML文件进行解析,拿到username节点的值进行后续的处理,并且会将结果返回到页面中。

DocumentBuilderFactory documentBuilderFactory =  DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder;
documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(request.getInputStream);
String username = getValueByTagName(doc,"username");

因此,我们可以构造一个恶意的XML,替换username节点中的内容,就能够返回服务器中/passwd文件的内容,比如:

<!DOCTYPE replace [<!ENTITY file SYSTEM "file:///etc/passwd">]>
<user><username>&file;</username></user>

1.3 XXE漏洞修复

在使用XML解析器时设置其属性,禁用DTD或者禁止使用外部实体,使用不同的解析库设置的属性也略有不同。

八、SSRF漏洞

SSRF(Server-Side Request Forge),服务器端请求伪造。Web应用程序往往会提供一些能够从远程获取图片或是文件的接口,在这些接口上用户使用指定的URL便能完成远程获取图片、下载文件等操作。攻击者可以通过使用file协议来读取服务器本地/etc/passwd和/proc/self/cmdline等敏感文件,同时攻击者也可以利用被攻击的服务器绕过防火墙直接对处于内网的机器发起进一步的攻击,如图所示:

 SSRF漏洞的主要危害:1)获取内网主机、端口和banner信息;2)对内网的应用程序进行攻击,例如Redis、jboss;3)利用file协议读取文件;4)可以攻击内网程序造成溢出。

在Java中,SSRF仅支持sun.net.www.protocol下所有的协议:http、https、file、ftp、mailto、netdoc。

在Java中可以通过利用file协议或netdoc协议进行列目录操作,以读取到更多的敏感信息。如图。对于无回显的文件读取可以利用FTP协议进行带外攻击,但值得注意的是:部分版本的Java,即使使用FTP协议也无法读取多行文件。

1.1 SSRF漏洞常见接口

SSRF漏洞通常出现在社交分享、远程图片加载或下载、图片或文章收藏、转码、通过网址在线翻译、网站采集、从远程服务器请求资源等功能点处。

SSRF漏洞URL中常出现url、f、file、page等参数。SSRF会使用HTTP请求远程地址,因此代码审计时我们要特别留意能够发起HTTP请求的类及函数,如:

HttpURLconnection.getInputStream

URLConnection.getInputStream

HttpClient.execute

OkHttpClient.newCall.execute

Request.Get.execute

Request.Post.execute

URL.openStream

ImageIO.read

值得注意的是,虽然上面提到的方法都可以发起HTTP请求,导致SSRF漏洞,但若是想支持sun.net.www.protocol中的所有协议,则只能使用以下方法:

URLConnection

URL

若发起网络请求的是带HTTP的,那么其将只支持HTTP、HTTPS协议。

HttpURLConnection

HttpClient

OkHttpClient.newCall.execute

下面是几种常见的可以发起网络请求,并且会导致SSRF漏洞的错误写法:

1.URLConnection

URLConnection是一个抽象类,表示指向URL指定资源的活动链接,它有两个直接子类,分别是HttpURLConnection和JarURLConnection。在默认情况下,URLConnection的参数没有有效控制时会引起SSRF漏洞。如下代码段:

        String url = request.getParameter("url");
        URL u = new URL(url);
        URLConnection urlConnection = u.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
        String inputLine;
        StringBuffer html = new StringBuffer();
        while ((inputLine = in.readLine())!=null){
            html.append(inputLine);
        }
        in.close();
        return html.toString();

2.HttpURLConnection

HttpURLConnection是Java的标准类,它继承自URLConnection,可用于向指定网站发送GET请求与POST请求。

        String url = request.getParameter("url");
        URL u = new URL(url);
        URLConnection urlConnection = u.openConnection();
        HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
        BufferedReader in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
        String inputLine;
        StringBuffer html = new StringBuffer();
        while ((inputLine = in.readLine())!=null){
            html.append(inputLine);
        }
        in.close();
        return html.toString();

3.Request

Request与Python中的request对象类似,其主要用来发送HTTP请求。

        String url = request.getParameter("url");
        return Request.GET(url).execute().returnContext().toString();

4.openStream

通过URL对象的openStream()方法,能够得到指定资源的输入流。

5.HttpClient

HttpClient是Apache Jakarta Common下的一个子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。

1.2 SSRF漏洞审计

根据上面提到的接口,在代码中搜索关键字。

漏洞验证:

通过file协议进行任意文件读取,比如传入参数 file:///etc/passed

或者使用http进行内网探测:比如传入参数 http://127.0.0.1:81

1.3 SSRF漏洞修复

(1)正确处理302跳转(对跳转的地址重新进行检查);

(2)限制协议只能为HTTP/HTTPS,防止跨协议;

(3)设置内网IP黑名单;

(4)在内网防火墙在设置常见的Web端口白名单(防止端口扫描,则可能业务受限比较大)。

九、SpEL表达式注入漏洞

Spring表达式语言(Spring Expression Language,SpEL)是一种功能强大的表达式语言,用于在运动时查询和操作对象图,语法上类似于Unified EL,但提供了更多的特性,特别是方法调用和基本字符串模版函数。

1.1 SpEL表达式语法

1)使用量表达式

在SpEL表达式中,我们可以直接使用量表达式:

"#{'Hello World'}"

2)使用java代码new/instance of

在SpEL表达式中,我们可以直接使用Java代码new/instance of:

Expression exp = parser.parseExpression("new Spring('Hello World')");

3)使用T(Type)

在SpEL表达式中,可以使用T(Type)来表示java.lang.Class实例,常用于引用常量和静态方法:

parser.parseExpression("T(Integer).MAX_VALUE");

在SpEL中可以使用#bean_id来获取容器内的变量。同时,还存在两个特殊的变量#this和#root,分别用来表示使用当前的上下文和引用容器的root对象:

String result = parser.parseExpression("#root").getValue(ctx,String.class);
String s = new String("abcdef");
ctx.setVariable("abc",s);
parser.parseExpression("#abc.substring(0,1)").getValue(ctx,String.class);

SpEL中可以使用T()操作符声明特定的Java类型,一般用来访问Java类型中的静态属性或静态方法。括号中需要包含类名的全限定名。唯一的例外是,SpEL内置了java.lang包下的类的生声明,所以java.lang.Sring可以通过T(String)访问。

我们通过T()调用一个类的静态方法,它将返回一个Class Object,然后再调用相应的方法或属性。同样的,SpEL也可以对类进行实例化,使用new可以直接在SpEL中创建实例,创建实例的类要通过全限定名进行访问:

ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("new java.util.Date()");
Date value = (Date)exp.getValue();
System.out.println(value);

产生SpEL表达式注入漏洞的大前提是存在SpEL的相关库,因此我们在审计时可以针对这些库进行搜索,并跟踪参数是否可控。根据常用的库,可以总结出以下常见关键字。

org.springframework.expression.spel.standard

SpelExpressionParser

parseExpression

expression.getValue()

expression.setValue()

56%(这部分先放放)

十、Java反序列化漏洞

Java序列化就是把对象转换成字节序列用于存储跟传输,反序列化则是把字节序列还原成对象的过程。比如服务器存储session、RMI的底层实现等应用场景。

在Java中反序列漏洞之所以比较严重的原因之一是:Java存在大量的公用库,例如Apache commons Collections。而这其中实现的一些类可以被反序列化用来实现任意代码执行。WebLogic、WebSphere、JBoss、Jenkins、OpenNMS这些应用的反序列化漏洞能够得以利用,便是依靠了Apache commons Collections。当然反序列化漏洞的根源并不在于公用库,而是在于Java程序没有对反序列化生成的对象的类型做限制。Java反序列化漏洞一般有以下几种危害:任意代码执行、获取Shell、对服务器进行破坏。

【Java反序列化】URLDNS_l1b2090的博客-CSDN博客

1.1 Java反序列化漏洞审计

关键字:

ObjectInputStream.readObject

ObjectInputStream.readUnshared

XMLDecoder.readObject

Yaml.load

XStream.fromXML

ObjectMapper.readValue

JSON.parseObject

当我们通过搜索关键函数或库,找到存在反序列化操作的文件时,便可开始考虑参数是否可控,以及应用的Class Path中是否包含Apache Commons Collections等危险库(ysoserial所支持的其它库亦可)。同时满足了这些条件后,就可以直接通过ysoserial生成所需的命令执行的反序列化语句。 

当然,不支持Apache Commons Collections等危险库不代表不能进一步利用。对于这种情况,我们可以通过查找其他代码中设计的执行命令或代码的区域。通过构造利用链来达到任意代码执行的目的。

1.2 Java反序列化漏洞修复

在使用readObject()反序列化时,首先会调用resolveClass方法读取反序列化的类名,所以我们可以通过重写ObjectInputStream对象的resolveClass方法来实现对反序列化类的校验。

十一、模版引擎注入(先放放)

十二、整数溢出漏洞(不看了)

十三、硬编码密码漏洞

没啥说的,任何口令都不能直接写死在代码中

十四、不安全的随机数生成器

在密码学场景,使用安全的随机数生成器:java.Security.SecureRandom

学习结束(暂时)。撒花!

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值