偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

從Java源碼來(lái)看Native命令執(zhí)行方法

開(kāi)發(fā) 前端
在Java中盛行的反序列化漏洞中,如果將RCE的功能簡(jiǎn)單的通過(guò)Runtime.getRuntime().exec(cmds)這種結(jié)構(gòu)來(lái)進(jìn)行實(shí)現(xiàn)可能大概率也不能達(dá)到我們的目的,所以探索一下Runtime的底層實(shí)現(xiàn),使用更加底層且復(fù)雜的調(diào)用來(lái)進(jìn)行RCE功能的實(shí)現(xiàn)相對(duì)來(lái)說(shuō)更加的可行

概述

在RASP等安全產(chǎn)品防護(hù)嚴(yán)密的現(xiàn)在,普通的尋找Runtime.getRuntime().exec(cmds)的調(diào)用已經(jīng)成為了一件不現(xiàn)實(shí)的事情。

同樣的,在Java中盛行的反序列化漏洞中,如果將RCE的功能簡(jiǎn)單的通過(guò)Runtime.getRuntime().exec(cmds)這種結(jié)構(gòu)來(lái)進(jìn)行實(shí)現(xiàn)可能大概率也不能達(dá)到我們的目的,所以探索一下Runtime的底層實(shí)現(xiàn),使用更加底層且復(fù)雜的調(diào)用來(lái)進(jìn)行RCE功能的實(shí)現(xiàn)相對(duì)來(lái)說(shuō)更加的可行。

這里主要是對(duì)Java中多種命令執(zhí)行的方式跟蹤源碼進(jìn)行原理分析、構(gòu)造利用代碼、集成自研工具。

前置

首先需要對(duì)Java中的反射機(jī)制有著基本的掌握

通過(guò)反射的方式,我們可以獲取到任何類的構(gòu)造方法,類方法,成員變量,且能夠獲取對(duì)應(yīng)類對(duì)象進(jìn)行對(duì)應(yīng)方法的調(diào)用等等目的

  • 獲取Class類對(duì)象對(duì)于類對(duì)象的獲取,主要可以通過(guò)Class.forName / loadClass的方式來(lái)獲取,值得注意的是,在調(diào)用Class.forName進(jìn)行類的加載的時(shí)候,將會(huì)調(diào)用static方法
Class.forName("java.lang.Runtime")

image-20230418202156861.png

  • 獲取對(duì)應(yīng)類的構(gòu)造方法對(duì)于獲取類的構(gòu)造方法,主要可以通過(guò)getConstructor或者getDeclaredConstructor這兩種方法來(lái)進(jìn)行實(shí)現(xiàn)

image-20230418202554295.png

兩者的區(qū)別主要是前者不能夠反射獲取private修飾的構(gòu)造方法,而后者能夠獲取。

所以通常使用后者進(jìn)行構(gòu)造函數(shù)的獲取,傳入的參數(shù)就是對(duì)應(yīng)構(gòu)造方法的參數(shù)類。

clazz.getDeclaredConstructor(type.class)
clazz.getConstructor(type.class)
  • 反射獲取成員變量和構(gòu)造方法類似的,存在有g(shù)etField和getDeclaredField兩個(gè)不同的獲取方法,區(qū)別和構(gòu)造函數(shù)類似。
clazz.getField(name)
clazz.getDeclaredField(name)
  1. 反射獲取類方法同樣具有g(shù)etMethod和getDeclaredMethod兩種。
  2. ...............

一個(gè)普通的命令執(zhí)行是

Runtime.getRuntime().exec("calc");

如果使用反射機(jī)制可以是

Class.forName("java.lang.Runtime").getMethod("exec", String.class).invoke(runtime, "calc");

或者是其他的一些使用反射機(jī)制的變形。

command

跟蹤Runtime

首先我們跟蹤Runtime執(zhí)行命令的過(guò)程。

image-20230418203905152.png

在這里接收一個(gè)String類型的參數(shù),調(diào)用exec的另一個(gè)重在方法對(duì)參數(shù)進(jìn)行處理,將其通過(guò)分隔符,將其封裝成了數(shù)組對(duì)象(這里就是一個(gè)字符串)。

image-20230418204046203.png

之后通過(guò)參數(shù)是String[]類型的另一個(gè)重載方法,通過(guò)調(diào)用ProcessBuilder類的方法進(jìn)行執(zhí)行。

image-20230418204233337.png

在ProcessBuilder#start方法中,將命令傳遞給了ProcessImpl#start方法進(jìn)行處理

image-20230418204613461.png

windows

在windows中主要是在ProcessImpl的構(gòu)造方法中調(diào)用了create方法。

image-20230418210009655.png

。這個(gè)create方法是通過(guò)win32的方式創(chuàng)建了一個(gè)進(jìn)程。

image-20230418210027743.png

linux

在linux下,在ProcessImpl#start的調(diào)用中將會(huì)創(chuàng)建一個(gè)UNIXProcess對(duì)象并返回

image-20230418213534618.png

image-20230418213547533.png

在UNIXProcess類的構(gòu)造方法中,調(diào)用了forkAndExec這個(gè)native方法

image-20230418213735497.png

創(chuàng)建了一個(gè)一個(gè)進(jìn)程,并返回了對(duì)應(yīng)進(jìn)程的pid

構(gòu)造命令執(zhí)行

ProcessBuilder#start

在上面的流程分析中,知道了在Runtime.getRuntime().exec()方法調(diào)用的下一層就是使用ProcessBuilder#start方法。

如果hook掉了我們可以通過(guò)使用ProcessBuilder類來(lái)進(jìn)行命令執(zhí)行的構(gòu)造。

new ProcessBuilder("calc").start();

或者使用反射的思路構(gòu)造

//method_1
        Class pro = Class.forName("java.lang.ProcessBuilder");
        ((ProcessBuilder) pro.getConstructor(List.class).newInstance(Arrays.asList("calc.exe"))).start();

        //method_2
        Class pro = Class.forName("java.lang.ProcessBuilder");
        pro.getMethod("start").invoke(pro.getConstructor(List.class).newInstance(Arrays.asList("calc.exe")));

        //method_3
        Class pro = Class.forName("java.lang.ProcessBuilder");
        ((ProcessBuilder) pro.getConstructor(String[].class).newInstance(new String[][]{{"calc.exe"}})).start();

        //method_4
        Class pro = Class.forName("java.lang.ProcessBuilder");
        pro.getMethod("start").invoke(pro.getConstructor(String[].class).newInstance(new String[][]{{"calc.exe"}}));

ProcessImpl

從上面的分析可以知道,在windows環(huán)境下的JDK。

ProcessImpl類的構(gòu)造方法將會(huì)調(diào)用create方法執(zhí)行native方法進(jìn)行命令執(zhí)行。

image-20230418215221068.png

所以我們只需要反射獲取ProcessImpl類的構(gòu)造方法并實(shí)例化就會(huì)執(zhí)行我們的惡意邏輯。

UNIXProcess

上面是針對(duì)windows的方式

針對(duì)linux,在前面的分析中知道主要是在其start方法中調(diào)用了UNIXProcess類的構(gòu)造方法。

image-20230419094058481.png

執(zhí)行forkAndExec這個(gè)native方法進(jìn)行命令執(zhí)行。

other

甚至于,我們知道最后主要是在create方法(windows)、forkAndExec方法(linux)中執(zhí)行命令,我們同樣可以通過(guò)反射這兩個(gè)方法進(jìn)行命令執(zhí)行。

本文作者:superLeeH, 轉(zhuǎn)載請(qǐng)注明來(lái)自

責(zé)任編輯:武曉燕 來(lái)源: FreeBuf.COM
相關(guān)推薦

2023-07-10 07:40:14

2022-12-30 09:08:29

JDK源碼工具

2020-06-15 08:07:30

命令Linux字符

2014-09-26 15:41:51

2020-05-07 19:46:18

LinuxMySQLMariaDB

2010-04-20 14:15:49

負(fù)載均衡產(chǎn)品

2009-09-04 09:36:17

Java調(diào)用

2011-06-07 14:47:19

JAVA

2012-07-04 13:28:51

2024-06-12 13:36:24

2022-09-27 10:07:01

要使用 source

2023-12-25 16:10:34

Linuxdconfig命令

2023-04-04 13:40:36

2021-07-14 09:48:15

Linux源碼Epoll

2010-08-31 14:01:00

DB2SQL腳本

2015-04-08 09:34:13

2016-01-26 14:36:06

混合云混合云成本混合云安全

2019-07-22 15:59:21

2021-04-22 07:29:46

數(shù)據(jù)展現(xiàn)方式

2021-04-15 08:15:27

Vue.js源碼方法
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)