Skip to content

Instantly share code, notes, and snippets.

@beargiles
Last active January 3, 2016 23:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beargiles/0bc3c741b51c295d67a9 to your computer and use it in GitHub Desktop.
Save beargiles/0bc3c741b51c295d67a9 to your computer and use it in GitHub Desktop.
SecurityManager example
package com.invariantproperties.sandbox.securityManager;
import java.net.InetSocketAddress;
import java.net.SocketPermission;
import java.security.Permission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Security manager that blocks DNS queries. This will block certain
* types of data exfiltration.
*
* @author bgiles
*/
public class DnsBlockingSecurityManager extends SecurityManager {
private final SecurityManager parent;
private final List<String> whitelist = new ArrayList<>();
public DnsBlockingSecurityManager() {
this(null);
}
public DnsBlockingSecurityManager(SecurityManager parent) {
this.parent = parent;
// we can read a configuration file to get a list of
// acceptable DNS servers.
}
@Override
public void checkPermission(Permission perm) {
if (parent != null) {
parent.checkPermission(perm);
}
if (perm instanceof SocketPermission) {
SocketPermission sp = (SocketPermission) perm;
List<String> actions = Arrays.asList(sp.getActions().split(","));
if (actions.contains("connect")) {
String name = sp.getName();
if (!name.matches("[a-zA-Z0-9_\\.]+:[0-9]+")) {
throw new SecurityException("unexpected socket addr format");
}
String[] elements = sp.getName().split(":");
InetSocketAddress addr = new InetSocketAddress(elements[0], Integer.valueOf(elements[1]));
if (addr.getPort() == 53 && !whitelist.contains(addr.getHostName())) {
throw new SecurityException("DNS connections are not allowed to this host");
}
}
}
}
}
package com.invariantproperties.sandbox.securityManager;
import java.io.PrintStream;
import java.security.Permission;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Simple SecurityManager that does nothing but log requests.
*
* @author bgiles
*/
public class LoggingSecurityManager extends SecurityManager {
private final Set<String> permissions = new HashSet<>();
/**
* List permissions required since last time. Reset set of permissions.
*
* @param ps
*/
public void listPermissions(PrintStream ps) {
List<String> list = new ArrayList<String>(permissions);
Collections.sort(list);
for (String entry : list) {
ps.println(entry);
}
permissions.clear();
}
public void checkPermission(Permission perm) {
permissions.add(perm.toString());
}
public void checkPermission(Permission perm, Object obj) {
permissions.add(perm.toString() + ": " + obj);
}
}
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/i386/libnet.so" "read")
("java.lang.RuntimePermission" "loadLibrary.net")
("java.net.SocketPermission" "8.8.8.8:53" "accept,resolve")
("java.net.SocketPermission" "8.8.8.8:53" "connect,resolve")
("java.net.SocketPermission" "localhost:0" "listen,resolve")
("java.util.PropertyPermission" "impl.prefix" "read")
("java.util.PropertyPermission" "os.name" "read")
("java.util.PropertyPermission" "sun.net.maxDatagramSockets" "read")
("java.io.FilePermission" "/dev/random" "read")
("java.io.FilePermission" "/dev/urandom" "read")
("java.io.FilePermission" "/etc/java-8-openjdk/net.properties" "read")
("java.io.FilePermission" "/tmp/nothing-1388226371259550611.html" "delete")
("java.io.FilePermission" "/tmp/nothing-1388226371259550611.html" "write")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/classes" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/charsets.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/ext/i386/libsunec.so" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/ext/libsunec.so" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/ext/sunec.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/ext/sunjce_provider.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/i386/libnet.so" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/i386/libnio.so" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/i386/libsunec.so" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/jce.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/jfr.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/jsse.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/meta-index" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/resources.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/rt.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/security/US_export_policy.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/security/blacklisted.certs" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/security/cacerts" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/security/jssecacerts" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/security/local_policy.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/lib/sunrsasign.jar" "read")
("java.io.FilePermission" "/usr/lib/jvm/java-8-openjdk-i386/jre/meta-index" "read")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.action")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.ec")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.internal.interfaces")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.internal.spec")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.pkcs")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.provider")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.rsa")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.util")
("java.lang.RuntimePermission" "accessClassInPackage.sun.security.x509")
("java.lang.RuntimePermission" "createClassLoader")
("java.lang.RuntimePermission" "createSecurityManager")
("java.lang.RuntimePermission" "fileSystemProvider")
("java.lang.RuntimePermission" "getProtectionDomain")
("java.lang.RuntimePermission" "loadLibrary.net")
("java.lang.RuntimePermission" "loadLibrary.nio")
("java.lang.RuntimePermission" "loadLibrary.sunec")
("java.lang.RuntimePermission" "modifyThread")
("java.lang.RuntimePermission" "modifyThreadGroup")
("java.lang.RuntimePermission" "readFileDescriptor")
("java.lang.RuntimePermission" "setContextClassLoader")
("java.lang.RuntimePermission" "writeFileDescriptor")
("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
("java.net.NetPermission" "getCookieHandler")
("java.net.NetPermission" "getProxySelector")
("java.net.NetPermission" "getResponseCache")
("java.net.NetPermission" "specifyStreamHandler")
("java.net.SocketPermission" "52.34.60.105:443" "connect,resolve")
("java.net.SocketPermission" "invariantproperties.com" "resolve")
("java.net.SocketPermission" "invariantproperties.com:443" "connect,resolve")
("java.net.URLPermission" "https://invariantproperties.com" "GET:")
("java.security.SecurityPermission" "getProperty.jdk.certpath.disabledAlgorithms")
("java.security.SecurityPermission" "getProperty.jdk.tls.disabledAlgorithms")
("java.security.SecurityPermission" "getProperty.keystore.type")
("java.security.SecurityPermission" "getProperty.keystore.type.compat")
("java.security.SecurityPermission" "getProperty.networkaddress.cache.negative.ttl")
("java.security.SecurityPermission" "getProperty.networkaddress.cache.ttl")
("java.security.SecurityPermission" "getProperty.securerandom.source")
("java.security.SecurityPermission" "getProperty.security.provider.1")
("java.security.SecurityPermission" "getProperty.security.provider.10")
("java.security.SecurityPermission" "getProperty.security.provider.2")
("java.security.SecurityPermission" "getProperty.security.provider.3")
("java.security.SecurityPermission" "getProperty.security.provider.4")
("java.security.SecurityPermission" "getProperty.security.provider.5")
("java.security.SecurityPermission" "getProperty.security.provider.6")
("java.security.SecurityPermission" "getProperty.security.provider.7")
("java.security.SecurityPermission" "getProperty.security.provider.8")
("java.security.SecurityPermission" "getProperty.security.provider.9")
("java.security.SecurityPermission" "getProperty.ssl.KeyManagerFactory.algorithm")
("java.security.SecurityPermission" "getProperty.ssl.SocketFactory.provider")
("java.security.SecurityPermission" "getProperty.ssl.TrustManagerFactory.algorithm")
("java.security.SecurityPermission" "putProviderProperty.SUN")
("java.security.SecurityPermission" "putProviderProperty.SunEC")
("java.security.SecurityPermission" "putProviderProperty.SunJCE")
("java.security.SecurityPermission" "putProviderProperty.SunJSSE")
("java.security.SecurityPermission" "putProviderProperty.SunRsaSign")
("java.util.PropertyPermission" "com.sun.net.ssl.checkRevocation" "read")
("java.util.PropertyPermission" "com.sun.net.ssl.enableECC" "read")
("java.util.PropertyPermission" "com.sun.net.ssl.requireCloseNotify" "read")
("java.util.PropertyPermission" "com.sun.sdp.conf" "read")
("java.util.PropertyPermission" "com.sun.security.preserveOldDCEncoding" "read")
("java.util.PropertyPermission" "file.encoding" "read")
("java.util.PropertyPermission" "http.agent" "read")
("java.util.PropertyPermission" "http.auth.digest.validateProxy" "read")
("java.util.PropertyPermission" "http.auth.digest.validateServer" "read")
("java.util.PropertyPermission" "http.auth.serializeRequests" "read")
("java.util.PropertyPermission" "http.keepAlive" "read")
("java.util.PropertyPermission" "http.maxConnections" "read")
("java.util.PropertyPermission" "http.maxRedirects" "read")
("java.util.PropertyPermission" "https.cipherSuites" "read")
("java.util.PropertyPermission" "https.protocols" "read")
("java.util.PropertyPermission" "https.proxyHost" "read")
("java.util.PropertyPermission" "impl.prefix" "read")
("java.util.PropertyPermission" "java.home" "read")
("java.util.PropertyPermission" "java.io.tmpdir" "read")
("java.util.PropertyPermission" "java.net.preferIPv4Stack" "read")
("java.util.PropertyPermission" "java.net.preferIPv6Addresses" "read")
("java.util.PropertyPermission" "java.net.useSystemProxies" "read")
("java.util.PropertyPermission" "java.nio.file.spi.DefaultFileSystemProvider" "read")
("java.util.PropertyPermission" "java.protocol.handler.pkgs" "read")
("java.util.PropertyPermission" "java.security.egd" "read")
("java.util.PropertyPermission" "java.util.logging.SimpleFormatter.format" "read")
("java.util.PropertyPermission" "java.util.logging.config.class" "read")
("java.util.PropertyPermission" "java.util.logging.config.file" "read")
("java.util.PropertyPermission" "java.version" "read")
("java.util.PropertyPermission" "javax.net.debug" "read")
("java.util.PropertyPermission" "javax.net.ssl.keyStore" "read")
("java.util.PropertyPermission" "javax.net.ssl.keyStorePassword" "read")
("java.util.PropertyPermission" "javax.net.ssl.keyStoreProvider" "read")
("java.util.PropertyPermission" "javax.net.ssl.keyStoreType" "read")
("java.util.PropertyPermission" "javax.net.ssl.sessionCacheSize" "read")
("java.util.PropertyPermission" "javax.net.ssl.trustStore" "read")
("java.util.PropertyPermission" "javax.net.ssl.trustStorePassword" "read")
("java.util.PropertyPermission" "javax.net.ssl.trustStoreProvider" "read")
("java.util.PropertyPermission" "javax.net.ssl.trustStoreType" "read")
("java.util.PropertyPermission" "jdk.internal.lambda.dumpProxyClasses" "read")
("java.util.PropertyPermission" "jdk.tls.allowUnsafeServerCertChange" "read")
("java.util.PropertyPermission" "jdk.tls.client.protocols" "read")
("java.util.PropertyPermission" "jdk.tls.rejectClientInitiatedRenegotiation" "read")
("java.util.PropertyPermission" "jdk.tls.trustNameService" "read")
("java.util.PropertyPermission" "jsse.SSLEngine.acceptLargeFragments" "read")
("java.util.PropertyPermission" "jsse.enableSNIExtension" "read")
("java.util.PropertyPermission" "line.separator" "read")
("java.util.PropertyPermission" "os.arch" "read")
("java.util.PropertyPermission" "os.name" "read")
("java.util.PropertyPermission" "proxyHost" "read")
("java.util.PropertyPermission" "socksProxyHost" "read")
("java.util.PropertyPermission" "sun.jnu.encoding" "read")
("java.util.PropertyPermission" "sun.net.client.defaultConnectTimeout" "read")
("java.util.PropertyPermission" "sun.net.client.defaultReadTimeout" "read")
("java.util.PropertyPermission" "sun.net.http.allowRestrictedHeaders" "read")
("java.util.PropertyPermission" "sun.net.http.errorstream.bufferSize" "read")
("java.util.PropertyPermission" "sun.net.http.errorstream.enableBuffering" "read")
("java.util.PropertyPermission" "sun.net.http.errorstream.timeout" "read")
("java.util.PropertyPermission" "sun.net.http.retryPost" "read")
("java.util.PropertyPermission" "sun.net.inetaddr.ttl" "read")
("java.util.PropertyPermission" "sun.net.spi.nameservice.provider.1" "read")
("java.util.PropertyPermission" "sun.nio.fs.chdirAllowed" "read")
("java.util.PropertyPermission" "sun.security.rsa.restrictRSAExponent" "read")
("java.util.PropertyPermission" "sun.security.ssl.allowLegacyHelloMessages" "read")
("java.util.PropertyPermission" "sun.security.ssl.allowUnsafeRenegotiation" "read")
("java.util.PropertyPermission" "user.dir" "read")
("java.io.FilePermission" "/home/bgiles/Documents/src/security-manager/target/classes/com/invariantproperties/sandbox/securityManager/DnsBlockingSecurityManager.class" "read")
("java.io.FilePermission" "/home/bgiles/Documents/src/security-manager/target/classes/com/invariantproperties/sandbox/securityManager/Nothing.class" "read")
("java.lang.RuntimePermission" "modifyThread")
("java.lang.RuntimePermission" "modifyThreadGroup")
("java.util.PropertyPermission" "java.class.path" "read")
("java.util.PropertyPermission" "java.endorsed.dirs" "read")
("java.util.PropertyPermission" "java.ext.dirs" "read")
("java.util.PropertyPermission" "java.home" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.COMPILE_THRESHOLD" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.DEBUG_NAMES" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.DUMP_CLASS_FILES" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.PROFILE_GWT" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.PROFILE_LEVEL" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.TRACE_INTERPRETER" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE" "read")
("java.util.PropertyPermission" "java.lang.invoke.MethodHandleImpl.MAX_ARITY" "read")
("java.util.PropertyPermission" "java.library.path" "read")
("java.util.PropertyPermission" "java.system.class.loader" "read")
("java.util.PropertyPermission" "java.version" "read")
("java.util.PropertyPermission" "java.vm.info" "read")
("java.util.PropertyPermission" "java.vm.name" "read")
("java.util.PropertyPermission" "java.vm.specification.name" "read")
("java.util.PropertyPermission" "java.vm.specification.vendor" "read")
("java.util.PropertyPermission" "java.vm.specification.version" "read")
("java.util.PropertyPermission" "java.vm.vendor" "read")
("java.util.PropertyPermission" "java.vm.version" "read")
("java.util.PropertyPermission" "sun.boot.class.path" "read")
("java.util.PropertyPermission" "sun.boot.library.path" "read")
("java.util.PropertyPermission" "sun.jnu.encoding" "read")
package com.invariantproperties.sandbox.securityManager;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
/**
* Simple application that does one simple thing (download a page from a
* website) and one malicious thing (exfiltrating sensitive information via a
* DNS query). We want to use the SecurityManager to allow the former while
* denying the latter.
*
* @author bgiles
*/
public class SimpleApp {
/**
* This method contains a bit of useful code that we might want to do.
*
* @throws Exception
*/
public static void doSomethingUseful() throws Exception {
URL url = new URL("https://invariantproperties.com");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.connect();
try (OutputStream os = conn.getOutputStream(); InputStream is = conn.getInputStream()) {
os.write("GET /\r\n".getBytes("UTF-8"));
os.flush();
File file = File.createTempFile("nothing-", ".html");
Files.copy(is, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
/**
* This method contains a bit of evil code that we do not want to do.
*
* On the surface we perform a DNS query. This is a common query, esp. if
* the loggers perform a reverse lookup of the caller's IP address.
*
* In fact we're calling our own DNS server and lookup hostnames that look
* like
*
* filename.data.offset.length.example.com
*
* where the values are encrypted to obscure their nature in case the
* security administrator is scanning all packets for sensitive information.
* E.g., it might scan for any packet containing NNN-NN-NNNN since that
* might contain an unencrypted SSN number or NNNN-NNNN-NNNN-NNNN since that
* might contain an uncrypted credit card number. With a bit of care it's
* possible to encrypt and encode the payload so it looks like a valid DNS
* request.
*
* The "correct" way to handle this is set up an internal DNS server and
* block all DNS traffic going anywhere but this server. That server, alone,
* can query white-listed DNS servers on the outside.
*
* Our security manager sandbox is "defense in depth" and mostly acts as a
* monitoring tool since any security exception thrown by it indicates
* something is very wrong.
*
* @throws Exception
*/
public static void doSomethingEvil() throws Exception {
InetSocketAddress google = new InetSocketAddress("8.8.8.8", 53);
try (DatagramSocket dns = new DatagramSocket()) {
dns.connect(google);
byte[] buffer = new byte[2048];
// populate DNS query
// doEvilThing
DatagramPacket query = new DatagramPacket(buffer, buffer.length, google);
// dns.send(data);
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
// dns.receive(response);
dns.disconnect();
}
}
/**
* Main method.
*/
public static void main(String[] args) throws Exception {
// important: launch app with
// "-Djava.security.manager=com.invariantproperties.LoggingSecurityManager
LoggingSecurityManager sm = (LoggingSecurityManager) System.getSecurityManager();
System.out.println("before main...");
sm.listPermissions(System.out);
System.out.println();
// do something useful
doSomethingUseful();
System.out.println("after something useful...");
sm.listPermissions(System.out);
System.out.println();
// do something useful
doSomethingEvil();
System.out.println("after something evil...");
sm.listPermissions(System.out);
System.out.println()
// try it again
System.setSecurityManager(new DnsBlockingSecurityManager(sm));
try {
System.out.println("trying it again after installing security manager...");
doSomethingEvil();
} catch (SecurityException e) {
e.printStackTrace(System.err);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment