专栏首页漏斗社区Java代码审计| Spring框架知识篇

Java代码审计| Spring框架知识篇

在上期的Java代码审计Spring框架思路篇中,斗哥为大家讲述了如何得到Spring审计的Demo,审计源码,根据Spring框架审计思路初步判定是否存在漏洞,剩下就是构造POC,动态调试分析修改POC。本期Java代码审计Spring框架知识篇将讲述Spring构造POC要必备的知识。

0X01 传统Java代码命令执行

1.知识说明

由于业务需求,程序有可能要执行系统命令的功能,但如果执行的命令用户可控,业务上有没有做好限制,就可能出现命令执行漏洞。 但Spring框架漏洞则是某组件可能存在解析执行系统命令代码的方法并根据命令执行方法(Runtime.getRuntime().exec(cmd))构造执行系统命令的POC,如果命令执行成功,造成Spring远程命令执行漏洞。

2.例子

此处以getRuntime为例,Runtime.getRuntime().exec(cmd)执行系统命令并弹出计算器。 示例代码如下:

import java.io.IOException;

public class Cmd {//在linux系统下运行计算器
    public static void main(String[] args){
        String cmd = "gnome-calculator";//gnome-calculator计算器进程名
        try {
            Process ps = Runtime.getRuntime().exec(cmd);//执行命令
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

系统命令的执行结果:

此方法将产生一个本地的进程,并返回一个Process子类的实例(注意:Runtime.getRuntime().exec(cmd)返回的是 一个Process类的实例)该实例可用于控制进程或取得进程的相关信息。

由于调用 Runtime.exec()方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过 Process.getOutputStream() 输入流 Process.getInputStream() 输出流 Process.getErrorStream() 错误流 等方法重定向给它的父进程了。 用户需要用这些Stream来向子进程输入数据或获取子进程的输出,使用getInputStream()去读取命令执行结果:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Cmd {
    public static void main(String[] args){
        String cmd = "ifconfig";
        try {
            Process run = Runtime.getRuntime().exec(cmd);//执行
            InputStream is = run.getInputStream();//取得执行结果输出流
            InputStreamReader isr =new InputStreamReader(is);//读输出流读取
            BufferedReader br=new BufferedReader(isr);//缓冲器读取
            String line=null;
            while((line=br.readLine())!=null)
            {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

执行结果:

3.补充

例如要执行带参数的命令等,exec有下列的方法重载:

public Process exec(String var1) throws IOException {
    return this.exec((String)var1, (String[])null, (File)null);
}

public Process exec(String var1, String[] var2) throws IOException {
    return this.exec((String)var1, var2, (File)null);
}

public Process exec(String var1, String[] var2, File var3) throws IOException {
    if (var1.length() == 0) {
        throw new IllegalArgumentException("Empty command");
    } else {
        StringTokenizer var4 = new StringTokenizer(var1);
        String[] var5 = new String[var4.countTokens()];

        for(int var6 = 0; var4.hasMoreTokens(); ++var6) {
            var5[var6] = var4.nextToken();
        }

        return this.exec(var5, var2, var3);
    }
}

public Process exec(String[] var1) throws IOException {
    return this.exec((String[])var1, (String[])null, (File)null);
}

public Process exec(String[] var1, String[] var2) throws IOException {
    return this.exec((String[])var1, var2, (File)null);
}

public Process exec(String[] var1, String[] var2, File var3) throws IOException {
    return (new ProcessBuilder(var1)).environment(var2).directory(var3).start();
}

sdfd

sdfd

0X02 SpEL表达式

1.知识说明

在Spring框架漏洞中大多数的远程命令执行漏洞,都不是直接解析执行系统命令代码,而是解析SpEL表达式。这时要构造的就是包含执行系统命令代码的SpEL表达式。

2.SpEL表达式介绍

Spring表达式语言全称Spring Expression Language是一种表达式语言,是一种可以与一个基于Spring的应用程序中的运行时对象交互。SpEL表达式是一种简化开发的表达式,通过使用表达式来简化开发,减少一些逻辑、配置的编写。SpEL是单独模块,只依赖于core模块,不依赖于其他模块,可以单独使用。

3.功能特性

SpEL支持以下的一些特性: 字符表达式 布尔和关系操作符 正则表达式 类表达式 访问properties,arrays,lists,maps等集合 方法调用 关系操作符 赋值 调用构造器 Bean对象引用 创建数组 三元操作符 变量 用户自定义函数 集合选择

4.SpEL基础表达式用法

用来计算String类型的字面值:

#{'HELLO'}

为了在SpEL中表达使用Java的Runtime类,可以调用T()运算符所得到类型的静态方法。

T(java.lang.Runtime).getRuntime()

计算正则表达式:

#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9._%+-]+\\.com'}

sdfd

0X03 SpEL表达式与命令执行组合

此处以SpEL表达式与getRuntime组合为例,T(java.lang.Runtime).getRuntime().exec('gnome-calculator')SpEL表达式中包含 执行系统命令并由parseExpression解析弹出计算器 示例代码如下:

import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

public class Sdemo {
        public static void main(String[] args){
          ExpressionParser parser = new SpelExpressionParser();
          String expression = "T(java.lang.Runtime).getRuntime().exec('gnome-calculator')";//构造好的SpEL表达式
          String result = parser.parseExpression(expression).getValue().toString();//解析SpEL

        }
}

系统命令的执行结果:

0X04 小总结

此篇讲述Spring框架构造POC必备的知识,如java命令执行函数,SpEL表达式使用、两者的配合使用构造Spring框架的POC。下期斗哥将带来Java代码审计Spring框架实例篇将以Spring框架漏洞中的某个远程命令执行漏洞的Demo。根据审计思路来分析,深入学习Spring框架的代码审计。

本文分享自微信公众号 - 漏斗社区(newdooneSec)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-07-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CTF流量分析之wireshark使用

    在CTF比赛中,对于流量包的分析取证是一种十分重要的题型。通常这类题目都是会提供一个包含流量数据的pcap文件,参赛选手通过该文件筛选和过滤其中无关的流量信息,...

    漏斗社区
  • 专属| 勒索软件 Virobot 肆虐

    根据趋势实验室披露的安全报告,一种全新的僵尸网络勒索软件Virobot正通过微软Outlook进行大肆传播。报告中指出该恶意软件同时兼具僵尸网络和勒索软件的特征...

    漏斗社区
  • 啥是佩奇?PWN解题技能全配齐!

    CTF的PWN题想必是很多小伙伴心里的痛,大多小伙伴不知道PWN该如何入门,不知道该如何系统性学习,本期开始,斗哥将输出PWN的一系列文章,手把手带小伙伴们入坑...

    漏斗社区
  • 【JAVA代码审计】——1、Spring框架知识篇

    本期Java代码审计Spring框架知识篇将讲述Spring构造POC要必备的知识。

    用户7886150
  • 数据字典 加载到 web 项目的 application 全局

    北漂的我
  • Android NDK编程(四)--- C/C++调用Java中的方法

    上一篇我们介绍了《Android NDK编程(三)--- Android调用C的函数》,主要是介绍了在Android中怎么调用C/C++中的方法,在我们开发nd...

    Vaccae
  • Android开发笔记(四)字符串格式化

    博主原来是搞C的,C里面有sprintf来格式化字符串,后来转到java变傻了,拼接String只会用n个“+”,要么就是用StringBuilder的ap...

    用户4464237
  • 微信支付宝一码付

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    逝兮诚
  • Flink 如何使用ProcessFunction

    ProcessFunction 函数是低阶流处理算子,可以访问流应用程序所有(非循环)基本构建块:

    smartsi
  • String类详解(基础篇八)

    String有很多重载的构造方法,这些方法支持很多类型的对象,例如:String、char[]、byte[]

    故里

扫码关注云+社区

领取腾讯云代金券