Runtime.getRuntime().exec()命令注入问题

1.原代码

    public void execCommand(String command){
        List<String> inputStreamList=new LinkedList<>();
        List<String> errorStreamList=new LinkedList<>();

        try {
            // 执行脚本
            Process process = Runtime.getRuntime().exec(command);
            process.waitFor();

            // 获取正常输出的输入流:the input stream connected to the normal output of the subprocess
            inputStreamList=readInputStream(process.getInputStream());
            log.info("命令执行结果(正常输出)为:"+"\n"+inputStreamList);

            // 获取错误输出的输入流:the input stream connected to the error output of the subprocess
            errorStreamList=readInputStream(process.getErrorStream());
            log.info("命令执行结果(错误输出)为:"+"\n"+errorStreamResult);
        } catch (Exception e) {
            log.error("命令执行失败!",e);
        }
    }


    public List<String> readInputStream(InputStream inputStream) throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        List<String> list=new LinkedList<>();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            list.add(line);
            //log.info(line);
        }
        inputStreamReader.close();
        bufferedReader.close();
        return list;
    }

 

2.代码扫描

上述代码进行代码扫描时,会有命令注入的漏洞,属于高危漏洞。

 

3.修改后的代码,重新扫描后没有命令注入的漏洞

3.1.引入依赖

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-exec</artifactId>
            <version>1.3</version>
        </dependency>

3.2.代码

    public void exeCommand(String command) throws IOException {
        HashMap<String,String> resultHashMap=new HashMap<>();
        //接收正常结果流
        ByteArrayOutputStream successStream = new ByteArrayOutputStream();
        //接收异常结果流
        ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
        CommandLine commandLine = CommandLine.parse(command);
        PumpStreamHandler pumpStreamHandler= new PumpStreamHandler(successStream, errorStream);
        // 设置超时时间,10s
        ExecuteWatchdog watchdog = new ExecuteWatchdog(10000);
        DefaultExecutor executor = new DefaultExecutor();
        executor.setStreamHandler(pumpStreamHandler);
        executor.setWatchdog(watchdog);
        
        //注意,命令执行失败会直接抛出异常(不在执行后面的代码),不会输出命令为什么执行失败,如果要得知命令执行失败原因,要先catch异常,再得到命令执行的输出
        //executor.execute(commandLine);
        
        try {
            executor.execute(commandLine);
        }catch (Exception e){
            //这样commons-exec遇到命令执行错误,就会输出错误信息,不会直接抛出异常
            log.info("正常输出为:"+successStream.toString());
            log.info("错误输出为:"+errorStream.toString());
        }
        
        log.info("正常输出为:"+successStream.toString());
        log.info("错误输出为:"+errorStream.toString());

    }

 

posted @ 2023-08-31 10:01  wdgde  阅读(1095)  评论(0)    收藏  举报