2021-06-21 09:45:31 +00:00
|
|
|
package the.bytecode.club.bytecodeviewer.util;
|
|
|
|
|
2021-07-19 17:46:35 +00:00
|
|
|
import java.io.File;
|
2015-11-11 04:16:45 +00:00
|
|
|
import java.io.FileDescriptor;
|
2021-07-19 17:46:35 +00:00
|
|
|
import java.io.IOException;
|
2015-11-11 04:16:45 +00:00
|
|
|
import java.net.InetAddress;
|
|
|
|
import java.security.Permission;
|
2021-07-19 13:23:30 +00:00
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
2021-08-26 21:59:07 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|
|
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
|
|
|
import the.bytecode.club.bytecodeviewer.Constants;
|
|
|
|
import the.bytecode.club.bytecodeviewer.compilers.impl.JavaCompiler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.compilers.impl.KrakatauAssembler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.decompilers.impl.CFRDecompiler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.decompilers.impl.FernFlowerDecompiler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.decompilers.impl.JDGUIDecompiler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.decompilers.impl.KrakatauDecompiler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.decompilers.impl.KrakatauDisassembler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.decompilers.impl.ProcyonDecompiler;
|
|
|
|
import the.bytecode.club.bytecodeviewer.resources.ExternalResources;
|
2015-11-11 04:16:45 +00:00
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
|
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
|
|
|
* *
|
|
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An awesome security manager.
|
|
|
|
*
|
2018-01-31 15:41:24 +00:00
|
|
|
* @author Konloch
|
2015-11-11 04:16:45 +00:00
|
|
|
*/
|
|
|
|
|
2021-07-07 04:21:06 +00:00
|
|
|
public class SecurityMan extends SecurityManager
|
|
|
|
{
|
2021-07-19 17:46:35 +00:00
|
|
|
private final AtomicInteger silentExec = new AtomicInteger(1);
|
2021-07-07 04:21:06 +00:00
|
|
|
private boolean printing = false;
|
|
|
|
private boolean printingPackage = false;
|
|
|
|
|
2021-07-12 12:50:23 +00:00
|
|
|
public void silenceExec(boolean b) {
|
2021-07-19 13:23:30 +00:00
|
|
|
silentExec.addAndGet(b ? 1 : -1);
|
2021-07-12 12:50:23 +00:00
|
|
|
}
|
|
|
|
|
2021-07-07 04:21:06 +00:00
|
|
|
public void setPrinting(boolean printing)
|
|
|
|
{
|
|
|
|
this.printing = printing;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPrintingPackage(boolean printingPackage)
|
|
|
|
{
|
|
|
|
this.printingPackage = printingPackage;
|
|
|
|
}
|
|
|
|
|
2021-07-19 17:46:35 +00:00
|
|
|
/**
|
|
|
|
* Attempts to secure untrusted code
|
|
|
|
*
|
|
|
|
* When paired with checkWrite it should prevent most escapes
|
|
|
|
* JNI is still possible so make sure to block checkLink as well //TODO for BCV
|
2021-07-19 18:28:47 +00:00
|
|
|
*
|
2021-07-19 17:46:35 +00:00
|
|
|
* Rewritten on 07/19/2021
|
|
|
|
*
|
|
|
|
* @author Konloch
|
|
|
|
*/
|
2018-01-31 15:41:24 +00:00
|
|
|
@Override
|
2021-07-19 15:39:59 +00:00
|
|
|
public void checkExec(String cmd)
|
|
|
|
{
|
2021-07-19 17:46:35 +00:00
|
|
|
//incoming command must contain the following or it will be automatically denied
|
|
|
|
String[] execWhitelist =
|
2021-07-19 15:39:59 +00:00
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
"attrib",
|
|
|
|
"python",
|
|
|
|
"pypy",
|
2019-06-01 01:04:07 +00:00
|
|
|
"java",
|
|
|
|
"brut_util",
|
2018-01-31 15:41:24 +00:00
|
|
|
};
|
2021-07-19 17:46:35 +00:00
|
|
|
|
|
|
|
//the goal is to make this true
|
2018-01-31 15:41:24 +00:00
|
|
|
boolean allow = false;
|
2021-07-19 17:46:35 +00:00
|
|
|
//while keeping this false
|
|
|
|
boolean blocked = false;
|
2018-01-31 15:41:24 +00:00
|
|
|
|
2021-07-19 17:46:35 +00:00
|
|
|
//normalize all command paths
|
|
|
|
final String normalizedPath;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
normalizedPath = new File(cmd.toLowerCase()).getCanonicalPath();
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
throw new SecurityException(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
//don't trust .jar file extensions being executed
|
|
|
|
if(normalizedPath.endsWith(".jar"))
|
|
|
|
blocked = true;
|
|
|
|
|
|
|
|
//don't trust .js file extensions being executed
|
|
|
|
else if(normalizedPath.endsWith(".js"))
|
|
|
|
blocked = true;
|
|
|
|
|
|
|
|
//block anything executing in system temp
|
|
|
|
else if(normalizedPath.startsWith(Constants.systemTempDirectory.toLowerCase()))
|
|
|
|
blocked = true;
|
|
|
|
|
|
|
|
//can only write into BCV dir, so anything executing from here has probably been dropped
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if(normalizedPath.startsWith(Constants.BCVDir.getCanonicalPath().toLowerCase()))
|
|
|
|
blocked = true;
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
throw new SecurityException(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
//filter exec whitelist
|
|
|
|
for (String whiteList : execWhitelist)
|
|
|
|
{
|
|
|
|
if (normalizedPath.contains(whiteList))
|
2021-07-19 15:39:59 +00:00
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
allow = true;
|
2021-04-12 22:31:22 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-07-19 17:46:35 +00:00
|
|
|
}
|
2021-07-12 11:18:52 +00:00
|
|
|
|
2021-07-19 17:46:35 +00:00
|
|
|
//filter class whitelist
|
2021-07-19 15:39:59 +00:00
|
|
|
boolean validClassCall = false;
|
2021-07-21 12:00:28 +00:00
|
|
|
//JDK-8
|
2021-07-19 15:39:59 +00:00
|
|
|
if(canClassExecute(Thread.currentThread().getStackTrace()[3].getClassName()))
|
|
|
|
validClassCall = true;
|
2021-07-21 12:00:28 +00:00
|
|
|
//JDK-15
|
|
|
|
else if(canClassExecute(Thread.currentThread().getStackTrace()[4].getClassName()))
|
|
|
|
validClassCall = true;
|
|
|
|
//JDK-8
|
2021-07-19 15:39:59 +00:00
|
|
|
else if(canClassExecute(Thread.currentThread().getStackTrace()[6].getClassName()))
|
|
|
|
validClassCall = true;
|
2021-07-21 12:00:28 +00:00
|
|
|
//JDK-15
|
|
|
|
else if(canClassExecute(Thread.currentThread().getStackTrace()[7].getClassName()))
|
|
|
|
validClassCall = true;
|
2021-07-19 15:39:59 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int index = 0;
|
|
|
|
for (StackTraceElement stackTraceElements : Thread.currentThread().getStackTrace())
|
|
|
|
{
|
|
|
|
System.out.println(index++ + ":" + stackTraceElements.getClassName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-19 17:46:35 +00:00
|
|
|
//log exec if allowed
|
|
|
|
if (allow && validClassCall && !blocked)
|
2021-07-12 12:50:23 +00:00
|
|
|
{
|
2021-07-19 13:23:30 +00:00
|
|
|
if(silentExec.get() >= 1)
|
|
|
|
System.err.println("Allowing exec: " + cmd);
|
2021-07-19 17:46:35 +00:00
|
|
|
} //throw exception stopping execution
|
2021-07-19 15:39:59 +00:00
|
|
|
else throw new SecurityException("BCV is awesome! Blocking exec: " + cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-07-19 17:46:35 +00:00
|
|
|
* Class Whitelist goes here
|
2021-07-19 15:39:59 +00:00
|
|
|
*/
|
|
|
|
private boolean canClassExecute(String fullyQualifiedClassName)
|
|
|
|
{
|
|
|
|
return fullyQualifiedClassName.equals(KrakatauDecompiler.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(KrakatauDisassembler.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(CFRDecompiler.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(ProcyonDecompiler.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(FernFlowerDecompiler.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(JDGUIDecompiler.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(KrakatauAssembler.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(ExternalResources.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(Enjarify.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(APKTool.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(BytecodeViewer.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(Constants.class.getCanonicalName()) ||
|
|
|
|
fullyQualifiedClassName.equals(JavaCompiler.class.getCanonicalName());
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2015-11-11 04:16:45 +00:00
|
|
|
public void checkListen(int port) {
|
2018-01-31 15:41:24 +00:00
|
|
|
throw new SecurityException("BCV is awesome, blocking port " + port + " from listening");
|
2015-11-11 04:16:45 +00:00
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
@Override
|
2015-11-11 04:16:45 +00:00
|
|
|
public void checkPermission(Permission perm) { //expand eventually
|
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
|
|
|
|
@Override
|
2015-11-11 04:16:45 +00:00
|
|
|
public void checkPermission(Permission perm, Object context) {//expand eventually
|
|
|
|
}
|
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
@Override
|
|
|
|
public void checkAccess(Thread t) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkAccept(String host, int port) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkAccess(ThreadGroup g) {
|
|
|
|
}
|
2021-06-21 23:37:55 +00:00
|
|
|
|
|
|
|
@SuppressWarnings("deprecation")
|
2018-01-31 15:41:24 +00:00
|
|
|
public void checkAwtEventQueueAccess() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkConnect(String host, int port) {
|
2021-07-07 04:21:06 +00:00
|
|
|
if(printing)
|
|
|
|
System.out.println("Connecting to: " + host + ":" + port);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkConnect(String host, int port, Object context) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkCreateClassLoader() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkDelete(String file) {
|
2021-07-07 04:21:06 +00:00
|
|
|
if(printing)
|
|
|
|
System.out.println("Deleting: " + file);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkExit(int status) {
|
2021-06-21 11:13:11 +00:00
|
|
|
if (!Configuration.canExit) {
|
2021-04-12 20:19:12 +00:00
|
|
|
throw new SecurityException("BCV is awesome, blocking System.exit(" + status + ");");
|
2019-04-25 21:27:35 +00:00
|
|
|
}
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkLink(String lib) {
|
2021-07-07 04:21:06 +00:00
|
|
|
if(printing)
|
|
|
|
System.out.println("Linking: " + lib);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2021-06-21 23:37:55 +00:00
|
|
|
|
|
|
|
@SuppressWarnings("deprecation")
|
2018-01-31 15:41:24 +00:00
|
|
|
public void checkMemberAccess(Class<?> clazz, int which) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkMulticast(InetAddress maddr) {
|
|
|
|
}
|
2021-06-21 23:37:55 +00:00
|
|
|
|
|
|
|
@SuppressWarnings("deprecation")
|
2018-01-31 15:41:24 +00:00
|
|
|
public void checkMulticast(InetAddress maddr, byte ttl) {
|
|
|
|
}
|
2021-08-09 17:37:52 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
public void checkPackageAccess(String pkg) {
|
2021-07-07 04:21:06 +00:00
|
|
|
if(printingPackage)
|
|
|
|
System.out.println("Accessing: " + pkg);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkPackageDefinition(String pkg) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkPrintJobAccess() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkPropertiesAccess() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkPropertyAccess(String key) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkRead(FileDescriptor fd) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkRead(String file) {
|
2021-07-07 04:21:06 +00:00
|
|
|
if(printing)
|
|
|
|
System.out.println("Reading: " + file);
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkRead(String file, Object context) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkSecurityAccess(String target) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkSetFactory() {
|
|
|
|
}
|
2021-06-21 23:37:55 +00:00
|
|
|
|
|
|
|
@SuppressWarnings("deprecation")
|
2018-01-31 15:41:24 +00:00
|
|
|
public void checkSystemClipboardAccess() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkWrite(FileDescriptor fd) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void checkWrite(String file) {
|
2021-07-07 04:21:06 +00:00
|
|
|
if(printing)
|
|
|
|
System.out.println("Writing: " + file);
|
2021-07-19 17:46:35 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
//can only export as the following extensions
|
|
|
|
if(file.endsWith(".zip") || file.endsWith(".jar") || file.endsWith(".apk")
|
|
|
|
|| file.endsWith(".dex") || file.endsWith(".class") || file.endsWith("js")
|
|
|
|
|| file.endsWith(".java") || file.endsWith(".gy") || file.endsWith(".bcv")
|
|
|
|
|| file.endsWith(".json") || file.endsWith(".txt") || file.endsWith(".log"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
//can only write into BCV dir
|
|
|
|
if(file.startsWith(Constants.BCVDir.getCanonicalPath()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
//can only write into system temp
|
|
|
|
if(file.startsWith(Constants.systemTempDirectory))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
throw new SecurityException(e);
|
|
|
|
}
|
2021-08-09 17:37:52 +00:00
|
|
|
|
|
|
|
throw new SecurityException("BCV is awesome, blocking write(" + file + ");");
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
2015-11-11 04:16:45 +00:00
|
|
|
}
|