Strict Security Manager
A lot needs to be done but this blocks most of the security manager escapes
This commit is contained in:
parent
74c88d3933
commit
c2d2f6627d
4 changed files with 90 additions and 10 deletions
|
@ -131,7 +131,7 @@ public class BytecodeViewer
|
||||||
public static List<Process> createdProcesses = new ArrayList<>();
|
public static List<Process> createdProcesses = new ArrayList<>();
|
||||||
|
|
||||||
//Security Manager for dynamic analysis debugging
|
//Security Manager for dynamic analysis debugging
|
||||||
public static SecurityMan sm = new SecurityMan(); //might be insecure due to assholes targeting BCV
|
public static SecurityMan sm = new SecurityMan();
|
||||||
|
|
||||||
//Refactorer
|
//Refactorer
|
||||||
public static Refactorer refactorer = new Refactorer();
|
public static Refactorer refactorer = new Refactorer();
|
||||||
|
|
|
@ -35,6 +35,7 @@ public class Constants
|
||||||
public static final String pluginsName = getBCVDirectory() + fs + "recentplugins.json";
|
public static final String pluginsName = getBCVDirectory() + fs + "recentplugins.json";
|
||||||
public static final String settingsName = getBCVDirectory() + fs + "settings.bcv";
|
public static final String settingsName = getBCVDirectory() + fs + "settings.bcv";
|
||||||
public static final String tempDirectory = getBCVDirectory() + fs + "bcv_temp" + fs;
|
public static final String tempDirectory = getBCVDirectory() + fs + "bcv_temp" + fs;
|
||||||
|
public static final String systemTempDirectory = System.getProperty("java.io.tmpdir");
|
||||||
public static final String libsDirectory = getBCVDirectory() + fs + "libs" + fs;
|
public static final String libsDirectory = getBCVDirectory() + fs + "libs" + fs;
|
||||||
public static String krakatauWorkingDirectory = getBCVDirectory() + fs + "krakatau_" + krakatauVersion;
|
public static String krakatauWorkingDirectory = getBCVDirectory() + fs + "krakatau_" + krakatauVersion;
|
||||||
public static String enjarifyWorkingDirectory = getBCVDirectory() + fs + "enjarify_" + enjarifyVersion;
|
public static String enjarifyWorkingDirectory = getBCVDirectory() + fs + "enjarify_" + enjarifyVersion;
|
||||||
|
|
|
@ -49,7 +49,7 @@ import static the.bytecode.club.bytecodeviewer.Constants.*;
|
||||||
*/
|
*/
|
||||||
public class BCV
|
public class BCV
|
||||||
{
|
{
|
||||||
private static ClassNodeLoader loader = new ClassNodeLoader(); //might be insecure due to assholes targeting BCV
|
private static ClassNodeLoader loader = new ClassNodeLoader();
|
||||||
private static URLClassLoader cl;
|
private static URLClassLoader cl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,7 +8,9 @@ import the.bytecode.club.bytecodeviewer.compilers.impl.KrakatauAssembler;
|
||||||
import the.bytecode.club.bytecodeviewer.decompilers.impl.*;
|
import the.bytecode.club.bytecodeviewer.decompilers.impl.*;
|
||||||
import the.bytecode.club.bytecodeviewer.resources.ExternalResources;
|
import the.bytecode.club.bytecodeviewer.resources.ExternalResources;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.security.Permission;
|
import java.security.Permission;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
@ -39,7 +41,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class SecurityMan extends SecurityManager
|
public class SecurityMan extends SecurityManager
|
||||||
{
|
{
|
||||||
private AtomicInteger silentExec = new AtomicInteger(1);
|
private final AtomicInteger silentExec = new AtomicInteger(1);
|
||||||
private boolean printing = false;
|
private boolean printing = false;
|
||||||
private boolean printingPackage = false;
|
private boolean printingPackage = false;
|
||||||
|
|
||||||
|
@ -57,10 +59,21 @@ public class SecurityMan extends SecurityManager
|
||||||
this.printingPackage = printingPackage;
|
this.printingPackage = printingPackage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Rewritten on 07/19/2021
|
||||||
|
*
|
||||||
|
* @author Konloch
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void checkExec(String cmd)
|
public void checkExec(String cmd)
|
||||||
{
|
{
|
||||||
String[] whitelist =
|
//incoming command must contain the following or it will be automatically denied
|
||||||
|
String[] execWhitelist =
|
||||||
{
|
{
|
||||||
"attrib",
|
"attrib",
|
||||||
"python",
|
"python",
|
||||||
|
@ -68,16 +81,57 @@ public class SecurityMan extends SecurityManager
|
||||||
"java",
|
"java",
|
||||||
"brut_util",
|
"brut_util",
|
||||||
};
|
};
|
||||||
boolean allow = false;
|
|
||||||
|
|
||||||
String lowerCaseCMD = cmd.toLowerCase();
|
//the goal is to make this true
|
||||||
for (String s : whitelist)
|
boolean allow = false;
|
||||||
if (lowerCaseCMD.contains(s))
|
//while keeping this false
|
||||||
|
boolean blocked = false;
|
||||||
|
|
||||||
|
//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))
|
||||||
{
|
{
|
||||||
allow = true;
|
allow = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//filter class whitelist
|
||||||
boolean validClassCall = false;
|
boolean validClassCall = false;
|
||||||
if(canClassExecute(Thread.currentThread().getStackTrace()[3].getClassName()))
|
if(canClassExecute(Thread.currentThread().getStackTrace()[3].getClassName()))
|
||||||
validClassCall = true;
|
validClassCall = true;
|
||||||
|
@ -92,16 +146,17 @@ public class SecurityMan extends SecurityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allow && validClassCall)
|
//log exec if allowed
|
||||||
|
if (allow && validClassCall && !blocked)
|
||||||
{
|
{
|
||||||
if(silentExec.get() >= 1)
|
if(silentExec.get() >= 1)
|
||||||
System.err.println("Allowing exec: " + cmd);
|
System.err.println("Allowing exec: " + cmd);
|
||||||
}
|
} //throw exception stopping execution
|
||||||
else throw new SecurityException("BCV is awesome! Blocking exec: " + cmd);
|
else throw new SecurityException("BCV is awesome! Blocking exec: " + cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute Whitelist goes here
|
* Class Whitelist goes here
|
||||||
*/
|
*/
|
||||||
private boolean canClassExecute(String fullyQualifiedClassName)
|
private boolean canClassExecute(String fullyQualifiedClassName)
|
||||||
{
|
{
|
||||||
|
@ -250,5 +305,29 @@ public class SecurityMan extends SecurityManager
|
||||||
public void checkWrite(String file) {
|
public void checkWrite(String file) {
|
||||||
if(printing)
|
if(printing)
|
||||||
System.out.println("Writing: " + file);
|
System.out.println("Writing: " + file);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SecurityException("BCV is awesome, blocking write(" + file + ");");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue