BishopFox / rmiscout

RMIScout uses wordlist and bruteforce strategies to enumerate Java RMI functions and exploit RMI parameter unmarshalling vulnerabilities
https://labs.bishopfox.com/tech-blog/rmiscout
MIT License
422 stars 60 forks source link

Dockerfile does not work #15

Open cosad3s opened 3 years ago

cosad3s commented 3 years ago

Description of Bug

The Docker build operation does not work as expected.

What should the expected behavior be

Docker build successful.

Platform Affected

N/A

Steps to Reproduce

docker build . -t rmiscout
Sending build context to Docker daemon  13.04MB
Step 1/6 : FROM openjdk:8
8: Pulling from library/openjdk
df5590a8898b: Pull complete 
705bb4cb554e: Pull complete 
519df5fceacd: Pull complete 
ccc287cbeddc: Pull complete 
39a2961e8351: Pull complete 
a12df774715e: Pull complete 
08f28107b8b3: Pull complete 
Digest: sha256:29790ba47d15339629a8e6c2ae971b5ec417e2b99b24a4f2506d29439bd5bcb4
Status: Downloaded newer image for openjdk:8
 ---> c6a23ae24020
Step 2/6 : COPY . /rmiscout
 ---> 5713a7b8f3d9
Step 3/6 : WORKDIR /rmiscout
 ---> Running in ee04b6a6efa3
Removing intermediate container ee04b6a6efa3
 ---> 6c98d19414ac
Step 4/6 : RUN ./gradlew shadowJar
 ---> Running in 6d720f86e604
Downloading https://services.gradle.org/distributions/gradle-4.10.3-bin.zip
..........................................................................

Welcome to Gradle 4.10.3!

Here are the highlights of this release:
 - Incremental Java compilation by default
 - Periodic Gradle caches cleanup
 - Gradle Kotlin DSL 1.0-RC6
 - Nested included builds
 - SNAPSHOT plugin versions in the `plugins {}` block

For more details see https://docs.gradle.org/4.10.3/release-notes.html

Starting a Gradle Daemon (subsequent builds will be faster)
> Task :compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> A problem occurred starting process 'command '/usr/lib/jvm/jdk1.8.0_301/bin/javac''

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.3/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 34s
1 actionable task: 1 executed
The command '/bin/sh -c ./gradlew shadowJar' returned a non-zero code: 1
ilatypov commented 2 years ago

Perhaps this was a bad Java 8 docker image (its versioning scheme indicates that it's a rolling tag).

I used a different image but saw lots of IllegalArgumentExceptions and javaassist.NotFoundExceptions. Not sure if my suppressing those was a good idea. I did not see a guessed signature yet.

diff --git a/Dockerfile b/Dockerfile
index 500b582..8d86236 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,4 @@
-FROM openjdk:8
-COPY . /rmiscout
-WORKDIR /rmiscout
-RUN ./gradlew shadowJar
-ENTRYPOINT ["./rmiscout.sh"]
-CMD ["-h"]
+FROM gradle:7.4-jdk8
+USER gradle
+ENV GRADLE_USER_HOME="/home/gradle/.gradle"
+
diff --git a/build.gradle b/build.gradle
index 0cdb6c7..1c73f0d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,12 @@
+buildscript {
+    dependencies {
+        classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4'
+    }
+}
+
 plugins {
     id 'java'
     id 'application'
-    id 'com.github.johnrengelman.shadow' version '2.0.4'
 }

 sourceCompatibility = 1.8
@@ -27,10 +32,13 @@ repositories {
 }

 dependencies {
-    testCompile group: 'junit', name: 'junit', version: '4.12'
-    compile group: 'org.javassist', name: 'javassist', version: '3.27.0-GA'
-    compile group: 'net.sourceforge.argparse4j', name: 'argparse4j', version: '0.8.1'
+    testImplementation group: 'junit', name: 'junit', version: '4.12'
+    implementation group: 'org.javassist', name: 'javassist', version: '3.28.0-GA'
+    implementation group: 'net.sourceforge.argparse4j', name: 'argparse4j', version: '0.8.1'

     implementation 'com.github.frohoff:ysoserial:master-SNAPSHOT'
     implementation 'com.github.BishopFox:GadgetProbe:master-SNAPSHOT'
 }
+
+apply plugin: 'com.github.johnrengelman.shadow'
+
diff --git a/rmiscout.sh b/rmiscout.sh
index 39eb628..c913ad7 100755
--- a/rmiscout.sh
+++ b/rmiscout.sh
@@ -1,6 +1,6 @@
 #!/bin/bash

-if [[ ! -f build/libs/rmiscout-1.4-SNAPSHOT-all.jar ]]; then
-    ./gradlew shadowJar
+if [[ ! -f build/libs/rmiscout-1.4-SNAPSHOT.jar ]]; then
+    gradle --info clean shadowJar
 fi
-java -jar build/libs/rmiscout-1.4-SNAPSHOT-all.jar "$@"
+java -jar build/libs/rmiscout-1.4-SNAPSHOT.jar "$@" 2> /dev/null
diff --git a/src/main/java/com/bishopfox/rmiscout/RMIConnector.java b/src/main/java/com/bishopfox/rmiscout/RMIConnector.java
index 5b4cb0c..f9724de 100644
--- a/src/main/java/com/bishopfox/rmiscout/RMIConnector.java
+++ b/src/main/java/com/bishopfox/rmiscout/RMIConnector.java
@@ -359,7 +359,11 @@ public class RMIConnector implements Connector {
                         isActivationServer = true;
                         Field f = RemoteObject.class.getDeclaredField("ref");
                         f.setAccessible(true);
+                        try {
                             ref = (RemoteRef) f.get(stub);
+                        } catch (IllegalArgumentException e) {
+                            System.err.println("Illegal argument: " + interfaceName);
+                        }
                     } else {
                         Field f = Proxy.class.getDeclaredField("h");
                         f.setAccessible(true);
@@ -412,6 +416,7 @@ public class RMIConnector implements Connector {
                     // at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:222)
                     Thread.sleep(10);

+                    if (ref != null) {
                         // Invoke remote method
                         Object response = ref.invoke(stub, me, params, methodHash);

@@ -419,6 +424,9 @@ public class RMIConnector implements Connector {
                         System.out.println(Utilities.Colors.YELLOW + "Executed: " + methodSignature + Utilities.Colors.ENDC);
                         System.out.println("\tResponse [" + response.getClass() + "] = " + response.toString());
                         return true;
+                    } else {
+                        System.err.println("ref: null for method " + methodSignature);
+                    }
                 } catch (IllegalArgumentException e) {
                     if (e.getMessage().contains("argument type") || e.getMessage().contains("ClassCast")) {
                         System.out.println(Utilities.Colors.GREEN + "Found: " + methodSignature + Utilities.Colors.ENDC);
@@ -470,7 +478,8 @@ public class RMIConnector implements Connector {
                     defaultClassPool.getCtClass(pair.getValue().getClass().getName()).detach();
                 }
             } catch (NotFoundException e) {
-                e.printStackTrace();
+                System.err.println("Not found: " + interfaceName);
+                // e.printStackTrace();
             }
         }

My run.sh,

#! /bin/bash

set -x

rm -rf tmp
mkdir -p tmp
docker build -t rmiscout -f Dockerfile tmp
rm -rf tmp
# docker ps -aq | xargs docker rm
# docker volume ls -q | xargs docker volume rm
docker run -it --read-only --rm \
    --tmpfs /tmp:exec \
    -v buildrequisites:/home/gradle/.gradle \
    -v "${PWD}:/home/gradle/rmiscout" \
    -w /home/gradle/rmiscout \
    --entrypoint ./rmiscout.sh \
    rmiscout "$@"