Remote CMD to Java App

10 篇文章 0 订阅
5 篇文章 0 订阅

package org.test.remotecmd;

public class JavaClassExecuter {

	public static String execute(byte[] classByte) {
		HackSystem.clearBuffer();
		ClassModifier cm = new ClassModifier(classByte);
		byte[] modiBytes = cm.modifyUTF8Constant("java/lang/System",
				"org/test/remotecmd/HackSystem");
		HotSwapClassloader loader = new HotSwapClassloader();
		Class<?> clazz = loader.loadByte(modiBytes);

		try {
			Method method = clazz.getMethod("main",
					new Class[] { String.class });
			method.invoke(null, (Object[]) new String[] { null });
		} catch (Throwable e) {
			e.printStackTrace(HackSystem.out);
		}
		return HackSystem.getBufferString();

	}
}

public class HotSwapClassloader extends ClassLoader {

	public HotSwapClassloader() {
		super(HotSwapClassloader.class.getClassLoader());
	}

	public Class<?> loadByte(byte[] classByte) {
		return defineClass(null, classByte, 0, classByte.length);
	}
}

public class HackSystem {

	public final static InputStream in = System.in;

	private static ByteArrayOutputStream buffer = new ByteArrayOutputStream();

	public final static PrintStream out = new PrintStream(buffer);

	public final static PrintStream err = out;

	public static String getBufferString() {
		return buffer.toString();
	}

	public static void clearBuffer() {
		buffer.reset();
	}

	public static void setSecurityManager(final SecurityManager s) {
		System.setSecurityManager(s);
	}

	public static SecurityManager getSecurityManager() {
		return System.getSecurityManager();
	}

	public static long currentTimeMillis() {
		return System.currentTimeMillis();
	}

	public static void arraycopy(Object src, int srcPos, Object dest,
			int destPos, int len) {
		System.arraycopy(src, srcPos, dest, destPos, len);
	}

	public static int indentityHashCode(Object x) {
		return System.identityHashCode(x);
	}

	// 下面所有的方法都与java.lang.System的名称一样,因版面原因,省略了其他方法
}

public class ByteUtils {

	public static int bytes2Int(byte[] b, int start, int len) {
		int sum = 0;
		int end = start + len;
		for (int i = start; i < end; i++) {
			int n = ((int) b[i]) & 0xff;
			n <<= (--len) * 8;
			sum = n + sum;
		}
		return sum;
	}

	public static byte[] int2Bytes(int value, int len) {
		byte[] b = new byte[len];
		for (int i = 0; i < len; i++) {
			b[len - i - 1] = (byte) ((value >> 8 * i) & 0xff);
		}
		return b;
	}

	public static String bytes2String(byte[] b, int start, int len) {
		return new String(b, start, len);
	}

	public static byte[] string2Bytes(String str) {
		return str.getBytes();
	}

	public static byte[] bytesReplace(byte[] origBytes, int offset, int len,
			byte[] replaceBytes) {
		byte[] newBytes = new byte[origBytes.length
				+ (replaceBytes.length - len)];
		System.arraycopy(origBytes, 0, newBytes, 0, offset);
		System.arraycopy(replaceBytes, 0, newBytes, offset, replaceBytes.length);
		System.arraycopy(origBytes, offset + len, newBytes, offset
				+ replaceBytes.length, origBytes.length - offset - len);

		return newBytes;
	}
}

public class ClassModifier {

	/**
	 * Class文件中常量池的起始偏移
	 */
	private static final int CONSTANT_POOL_INDEX = 8;

	/**
	 * CONSTANT_Utf8_info常量的tag标志
	 */
	private static final int CONSTANT_Utf8_info = 1;

	/**
	 * 常量池中11种常量所占的长度,CONSTANT_Utf8_info型常量除外,因为它不是定长的
	 */
	private static final int[] CONSTANT_ITEM_LEN = { -1, -1, 5, -1, 5, 9, 9, 3,
			3, 5, 5, 5, 5 };

	private static final int u1 = 1;
	private static final int u2 = 2;

	private byte[] classByte;

	public ClassModifier(byte[] classByte) {
		this.classByte = classByte;
	}

	public byte[] modifyUTF8Constant(String oldStr, String newStr) {
		int cpc = getConstantPoolCount();
		int offset = CONSTANT_POOL_INDEX + u2;
		for (int i = 0; i < cpc; i++) {
			int tag = ByteUtils.bytes2Int(classByte, offset, u1);
			if (tag == CONSTANT_Utf8_info) {
				int len = ByteUtils.bytes2Int(classByte, offset + u1, u2);
				offset += (u1 + u2);
				String str = ByteUtils.bytes2String(classByte, offset, len);
				if (str.equalsIgnoreCase(oldStr)) {
					byte[] strBytes = ByteUtils.string2Bytes(newStr);
					byte[] strLen = ByteUtils.int2Bytes(newStr.length(), u2);
					classByte = ByteUtils.bytesReplace(classByte, offset - u2,
							u2, strLen);
					classByte = ByteUtils.bytesReplace(classByte, offset, len,
							strBytes);
					return classByte;
				} else {
					offset += len;
				}
			} else {
				offset += CONSTANT_ITEM_LEN[tag];
			}
		}
		return classByte;
	}

	public int getConstantPoolCount() {
		return ByteUtils.bytes2Int(classByte, CONSTANT_POOL_INDEX, u2);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值