惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Help Net Security
Help Net Security
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
爱范儿
爱范儿
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
阮一峰的网络日志
阮一峰的网络日志
C
CERT Recently Published Vulnerability Notes
月光博客
月光博客
Cisco Talos Blog
Cisco Talos Blog
Google DeepMind News
Google DeepMind News
T
Tor Project blog
T
Tenable Blog
Forbes - Security
Forbes - Security
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
NISL@THU
NISL@THU
人人都是产品经理
人人都是产品经理
博客园 - 司徒正美
F
Full Disclosure
雷峰网
雷峰网
N
News and Events Feed by Topic
T
Threatpost
TaoSecurity Blog
TaoSecurity Blog
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog
Hacker News: Ask HN
Hacker News: Ask HN
S
Secure Thoughts
S
Security @ Cisco Blogs
The Hacker News
The Hacker News
P
Palo Alto Networks Blog
P
Privacy International News Feed
H
Heimdal Security Blog
博客园_首页
MongoDB | Blog
MongoDB | Blog
V
Visual Studio Blog
C
Check Point Blog
Stack Overflow Blog
Stack Overflow Blog
B
Blog RSS Feed
有赞技术团队
有赞技术团队
B
Blog
Microsoft Security Blog
Microsoft Security Blog
S
Schneier on Security
T
Tailwind CSS Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Project Zero
Project Zero
T
The Exploit Database - CXSecurity.com
U
Unit 42
Jina AI
Jina AI

SumSec's Blog

AI Agent 工程的必然演进:CLI、Skills、Harne… 从安全角度谈Java反射机制--终章 · SUMSEC 逆向学习fastjson反序列化始 · SUMSEC 2020年研究回顾总结 · SUMSEC Abstract syntax tree classes for … Analyzing data flow in Java · SUM… Annotations in Java · SUMSEC Basic query for Java code · SUMSEC BypassSuper使用介绍说明 · SUMSEC CodeQL Create OpenJdk/Jdk8 Databa… CodeQL library for Java · SUMSEC Navigating the call graph · SUMSEC Overflow-prone comparisons in Jav… Types in Java · SUMSEC Working with source locations · S… Aliases · SUMSEC Expression · SUMSEC Formulas · SUMSEC Javadoc · SUMSEC Modules · SUMSEC Predicates · SUMSEC Queries · SUMSEC Type · SUMSEC Variables · SUMSEC 一道shiro反序列化题目引发的思考 · SUMSEC 修改ysoserial使其支持任意代码执行 · SUMSEC 自定义 ClassLoader 隔离运行不同版本jar包的方式 ·… 2020网鼎杯---Java文件上传wp · SUMSEC CNVD-2020-10487(CVE-2020-1938)tom… JDSRC安全课笔记 · SUMSEC Java反序列化链回显解决方案 · SUMSEC Skipped breakpoint because it hap… Windows Terminal 配置文件 · SUMSEC bypass 学习笔记之绕安全狗bypass safedog · … 一次意外的代码审计----JfinalCMS审计 · SUMSEC 一篇文章读懂Java代码审计之XXE · SUMSEC 从安全角度谈Java反射机制--序章 · SUMSEC 小楼昨夜又春风,你知ysoserial-Gadget-URLDNS… 春眠不觉晓,RCE知多少? · SUMSEC 漫谈Commons-Collections反序列化 · SUMSEC 漫谈Java反序列化 · SUMSEC 白头搔更短,SSTI惹人心! · SUMSEC 记一次面试题 · SUMSEC About Me 关于我 · SUMSEC Apache Flink任意Jar包上传导致远程代码执行 · SU… CVE-2019-1388 UAC提权复现 · SUMSEC CVE-2019-16097 || Harbor任意管理员注册漏洞… Python加密shellcode免杀 · SUMSEC Telegram机器人作为渗透测试框架 · SUMSEC VM虚拟机无法安装vmtools解决|本程序需要您将此虚拟机上安装… 谁能想到,电视遥控器竟成了 Vibe Coding 神器 · SU… 从手改 Skill 到自动进化:评测结果和执行轨迹如何让 Agen… 模型人人都能用,什么才是你能带走的?我的答案是一个可进化的SKIL… 模型人人都能用,什么才是你能带走的?我的答案是一个可进化的Skil… AI 时代 ShiroAttack2 5.x:修改了什么 · SU… 在 AGI 降临前,先给 AI 开一条”脑内弹幕”通道 · SUM… 一篇博文,三种时间:网页幻灯与 Remotion 动效的交付逻辑 … 🔍 别让大模型”想太多”:SKILL开发中的语义陷阱与抗幻觉设计 … 2022 年年度总结 · SUMSEC Java Swing To RCE 漏洞分析 · SUMSEC SpringBoot GatewayEL表达式漏洞分析 · SUM… Sensitive keys in codebases · SUM… 论如何优雅注入 Java 内存马 · SUMSEC SUMSEC 知识点 · SUMSEC VMWare Workspace ONE Access Auth … Spring Framework RCE CVE-2022-229… 相似度算法调研 · SUMSEC CVE-2022-33891 Apache Spark shell… 正则匹配配置不当 · SUMSEC Spring Data MongoDB SpEL CVE-2022… CodeQl Usage Tricks · SUMSEC Spring Boot RCE到内存马探索 · SUMSEC Shiro后渗透拓展面 · SUMSEC shiro反序列化漏洞攻击拓展面–修改key · SUMSEC GitHub Java CodeQL CTF · SUMSEC Hack-Tools 转化成Web · SUMSEC CodeQL与Shiro550碰撞 · SUMSEC CodeQL初见Shiro550 · SUMSEC CodeQL与AST之间联系 · SUMSEC Java加载动态链接库 · SUMSEC Log4j2 漏洞分析 · SUMSEC Interprocedural-Analysis 过程间分析 · … Data Analysis Foundation 数据分析基础 ·… Data Flow Analysis · SUMSEC Intermediate Representation 中间代表(… PII泄露–用CodeQL识别日志中的PII数据 · SUMSEC CodeQL workshop for Java: Unsafe … 前言 · SUMSEC 漏洞环境的搭建 · SUMSEC Fastjson回显 · SUMSEC Tomcat通用回显学习笔记 · SUMSEC 从Java反序列化漏洞题看CodeQL数据流 · SUMSEC 概述 · SUMSEC 记一次Log4j失败的Gadget挖掘记录 · SUMSEC Ysoserial改造记录 · SUMSEC JNDI注入 · SUMSEC shiro JRMP gadget · SUMSEC Fastjson MySQL gadget复现 · SUMSEC 2021年度总结 · SUMSEC
从安全角度谈Java反射机制--前章 · SUMSEC
2026-07-17 · via SumSec's Blog

从安全角度谈Java反射机制–前章

前言

首发:https://www.sec-in.com/article/307
   欢迎回来,上回说到Java反射机制基础知识,并用简单代码做了一个简单的Demo。
  笔者从执行命令的角度来展开话题,看这篇文章大部分都是网络安全的从业者亦或者是安全规范的学习者,众所周知执行命令获取权限是安全人员追求,也是黑客最终追求。所以从执行命令的角度来展开,无疑是激发你们读者最大阅读兴趣。

ps: 本文实验代码都上传JavaLearnVulnerability项目,为了让更多人知道,麻烦动动小手star一下。


知识补充

   这里稍微补充一点小知识,对于一些0基础的读者的一些知识补充,老司机可以忽视。Java执行命令常见的有两个类java.lang.Runtimejava.lang.ProcessBuilder,通常情况下使用java.lang.Runtime类,个人觉得Runtime类是比ProcessBuilder好使用些。

windows下执行命令的几种方式

  1. Windows下调用程序

    Process proc =Runtime.getRuntime().exec(“exefile”);

    1. Windows下调用系统命令
      String [] cmd={“cmd”,”/C”,”copy exe1 exe2”};
      Process proc =Runtime.getRuntime().exec(cmd);
    2. Windows下调用系统命令并弹出命令行窗口
      String [] cmd={“cmd”,”/C”,”start copy exe1 exe2”};
      Process proc =Runtime.getRuntime().exec(cmd);

    Linux下执行命令的几种方式

    1. Linux下调用程序

      Process proc =Runtime.getRuntime().exec(“./exefile”);

    2. Linux下调用系统命令

      String [] cmd={“/bin/sh”,”-c”,”ln -s exe1 exe2”};
      Process proc =Runtime.getRuntime().exec(cmd);

    3. Linux下调用系统命令并弹出命令行窗口

      String [] cmd={“/bin/sh”,”-c”,”xterm -e ln -s exe1 exe2”};
      Process proc =Runtime.getRuntime().exec(cmd);


反射之Runtime

在这里插入图片描述

方法一

Object ob = cls.getMethod(“getRuntime”,null).invoke(null,null);
返回的是一个Runtime类对象
前文说过,invoke第一个参数是一个Object类对象
你可能好奇为什么我不直接使用newInstance()呢?
因为Runtime类中的无参构造方法是private权限,无法访问。ps:其实是有办法的,下文会说道。
getRuntime方法返回的是Runtime类对象,这就是为什么有些payload会使用此方法了,而不是直接newInstanc()

在这里插入图片描述

public static void Method1(){
        try {
            //获取对象
            Class cls = Class.forName("java.lang.Runtime");
            //实例化对象
            Object ob = cls.getMethod("getRuntime",null).invoke(null,null);
            // 反射调用执行命令
            cls.getMethod("exec", String.class).invoke(ob,"calc");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

方法二

前文说过java.lang.Runtime类无参构造方法是private权限无法直接调用
setAccessible通过反射修改方法的访问权限,强制可以访问
Constructor constructor = cls.getDeclaredConstructor();是获取类构造器方法的方法

public static void Method2(){
       try {
           // 获取对象
           Class cls = Class.forName("java.lang.Runtime");
           // 获取构造方法
           Constructor constructor = cls.getDeclaredConstructor();
           
           constructor.setAccessible(true);
           // 实例化对象
           Object ob = constructor.newInstance();
           Method mt = cls.getMethod("exec", String.class);

           mt.invoke(ob,"calc");

       } catch (ClassNotFoundException | NoSuchMethodException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       } catch (InstantiationException e) {
           e.printStackTrace();
       } catch (InvocationTargetException e) {
           e.printStackTrace();
       }
   }

反射之ProcessBuilder

在这里插入图片描述

通过看JDK文档,ProcessBuilder类有两个构造方法。
在这里插入图片描述
如果分别使用反射构造方法获取实例化语句如下:

  • Class.forName("java.lang.ProcessBuilder").getDeclaredConstructor(List.class).newInstance(Arrays.asList("calc")))
  • Class.forName("java.lang.ProcessBuilder").getDeclaredConstructor(String.class).newInstance("calc"))

方法一

   方法一笔者在此就提一点,newInstance()实例化时把所需要执行命令参数直接一并进行了。

public static void Method1(){
        try {
            // 获取对象
            Class cls = Class.forName("java.lang.ProcessBuilder");
            // 实例化对象
            Object ob = cls.getDeclaredConstructor(List.class
            ).newInstance(Arrays.asList("calc"));
            // 执行命令
            cls.getMethod("start").invoke(ob,null);

        } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

方法二

   方法二使用第二种构造方法,可变长参数(String...表示参数长度不确定)。那么对于反射来说,如果要获取目标函数里包含的可变长参数,可直接视为数组。因此只需要将String [].class传给构造方法即可,但在调用newInstance()实例化方法时,不能直接传一个一维数组String[]{“calc"},而是应该传入一个二维数组String[][]calc。因为newInstance()函数本身接收的是一个可变长参数,我们传给ProcessBuilder的也是一个可变长参数,二者叠加由一维数组变成了二维数组。

public static void Method2(){
        try {
            // 获取对象
            Class cls = Class.forName("java.lang.ProcessBuilder");
            // 实例化对象
            
            String[][] cls2 = new String[][]{{"calc"}};
            Object ob = cls.getConstructor(String[].class).newInstance(cls2);
            //执行命令
            cls.getMethod("start").invoke(ob,null);

        } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

参考

https://xz.aliyun.com/t/7029#toc-3
https://javasec.org/javase/Reflection/Reflection.html
JDK文档
Java安全漫谈-反射篇 –P牛著。