前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【JAVA代码审计】——1、Spring框架知识篇

【JAVA代码审计】——1、Spring框架知识篇

作者头像
用户7886150
修改2020-12-11 14:24:08
5730
修改2020-12-11 14:24:08
举报
文章被收录于专栏:bit哲学院

参考链接: Java中StringTokenizer类的示例| 1(构造函数)

本期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();

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'}

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框架的代码审计。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
代码审计
代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档