栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java安全(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java安全(一)

命令执行

从上往下依次是:
单独的进程中执行指定的字符串命令
单独的进程中执行指定的命令并传入变量
在指定环境的独立进程执行命令和传入变量
在指定环境和工作目录的独立进程执行中执行命令
在指定环境和工作目录的独立进程执行中执行命令和传入变量

有回显的命令

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

public class Exec {
    public static void main(String[] args) throws IOException {
        BufferedReader br = null;
        try{
            Process p = Runtime.getRuntime().exec("ping 127.0.0.1");
            br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while((line= br.readLine())!=null){
                sb.append(line+"n");
            }
            System.out.println(sb.toString());
        
    }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(br != null){
                try{
                    br.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        }
}

进一步地,命令执行在不同系统下做一个判断
windows

 String [] cmd = {"cmd","/c","calc.exe"};
Process ps = Runtime.getRuntime().exec(cmd);

linux

String [] cmd = {"/bin/sh","-c","ls"};
Process ps = Runtime.getRuntime().exec(cmd);

判断方法可以使用getProperty获取系统变量
查看getproperties描述可以看到可以获取很多系统变量的键值对
判断系统

if(property.contains(‘linux’))
if (properties.contains(“windows”)||properties.contains(“Windows”))

具有回显的命令,使用IO流读出来输出

Process p = Runtime.getRuntime().exec("");
InputStream io = p.getInputStream();//获得命令结果
InputStreamReader reader = new InputStreamReader(io);//读取结果
BufferedReader BuffRead = new BufferReader(reader);//创建缓冲器
StringBuilder sb = new StringBuilder();
String line = null;
while((line = BuffRead.readline())!=null){
	sb.append(line);
	System.out.println(line);
	}
	关闭流....
反射

类加载器
java虚拟机加载类的时候,ClassLoader根据类名加载类,类名是类的完整路径,比如java.lang.Runtime

反射里面的几个重要方法

forName 获取类的方法
newInstance 获取实例化类对象的方法
getMethod 获取函数的方法
invoke 执行函数的方法
Java.lang.reflect.Constructor;
Java.lang.reflect.Field;
Java.lang.reflect.Method;
Java.lang.reflect.Modifier;

在获取类还有几种方式:

    如果上下文存在某个类的实例a,可以通过**a.getClass()**获取加载了某个类,获取它的java.lang.Class对象,访问它的属性class即可(不属于反射)知道某个类的名字,获取这个类就可以使用forName来获取

其中forName有两个函数重载
Class.forName(className)
Class.forName(className, true, currentLoader)

构造器
写payload的时候,newInstance()不成功原因有其一:1. 该类没有无参构造函数 2. 该类的构造函数时私有的

**getDeclaredConstructor()**获得构造方法,Runtime的构造方法是private,利用反射修改其访问权限
**getConstructor()**无论是否设置setAccessible(),都不可获取到类的私有构造器.

Constructor ct = a.getDeclaredConstructor();
ct.setAccessible(true);//修改访问权限 setAccessible

Object类是所有类的父类

实例化对象
在刚刚获得的构造器进行实例化一个对象

Object instance = ct.newInstance();
//等价于
Runtime rt = new Runtime();

获取方法

Method runMethod = a.getMethod("exec",String Class);

//获取当前类的所有成员方法
Method[] methods = class.getDeclaredMethod() ;
//获取指定类成员方法
Method method = class.getDeclaredMethod("func");
Method method = class.getDeclaredMethod("func",int,double,...)//详见重载

执行方法

Process ps = (Process) runMethod.invoke(instance,"clac")

method.invoke(instance,var1,var2…)

获取成员变量

Field var1 = class.getDeclaredField();
Field var2 = class.getDeclaredField("apple");//指定变量

Object obj = field.get(instance);//获取变量值
field.set(instance,setValue);//修改变量值

序列化

    类要实现java.io.Serlalizable接口所类的属性必须是可序列化,static,transient 修饰的变量不可被序列化

ObjectOutputStream类->writeObject():对参数指定的Obj文件序列化后写入一个ser文件

反序列化
ObjectInputStream类->readObject():从文件输入流读入,序列化成对象返回

当readObject()可控时,恶意构造后可以命令执行

一道简单的反序列化题
Recaf工具导入war包(java字节码,直接解压看不到源码)


上传的地方和读取的地方一致,考察文件上传木马了


Recaf将tools包导入进idea后,创建一个用来伪造cinfo的Test.java


成功进入,上传一句话木马

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/710810.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号