Skip to content

Commit

Permalink
Merge pull request #23 from qtc-de/develop
Browse files Browse the repository at this point in the history
Prepare v4.1.0 Release
  • Loading branch information
qtc-de authored Dec 23, 2021
2 parents 7d26261 + 7669062 commit 7f87697
Show file tree
Hide file tree
Showing 24 changed files with 222 additions and 42 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [4.1.0] - Dec 23, 2021

### Added

* Add *TLS* enumeration during ``enum`` action.

### Changed

* Error messages are now printed to stderr.
* Bugfix: Error messages not being shown when using ``--raw``
* Bugfix: Uncaught ``UnknownHostException``
* Bugfix: Uncaught exception during ``call`` action when used with wrong argument count
* Bugfix: Uncaught exception during ``call`` action when no signature was specified
* Bugfix: Uncaught exception when the specified port number is out of range

### Docker

* The *SSRF* server now logs in hexdump format
* Bugfix: Indentation issue within the *SSRF* server


## [4.0.0] - Dec 05, 2021

### Added
Expand Down
2 changes: 1 addition & 1 deletion docker/example-server/resources/server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.qtc.rmg.server.ExampleServer</groupId>
<artifactId>rmg-example-server</artifactId>
<version>2.0.0</version>
<version>3.1.0</version>
<name>rmg-example-server</name>
<description>RMG Example Server</description>

Expand Down
2 changes: 1 addition & 1 deletion docker/ssrf-server/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ version: '3.7'

services:
rmg:
image: ghcr.io/qtc-de/remote-method-guesser/rmg-ssrf-server:1.1
image: ghcr.io/qtc-de/remote-method-guesser/rmg-ssrf-server:1.2
build: .
2 changes: 1 addition & 1 deletion docker/ssrf-server/resources/server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>de.qtc.rmg.server.ssrf</groupId>
<artifactId>rmg-ssrf-server</artifactId>
<version>1.0.0</version>
<version>1.2.0</version>
<name>rmg-ssrf-server</name>
<description>RMG SSRF Server</description>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package de.qtc.rmg.server.ssrf.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

import de.qtc.rmg.server.ssrf.utils.Logger;

import org.apache.commons.io.HexDump;
import org.apache.commons.io.IOUtils;

/**
Expand Down Expand Up @@ -49,33 +52,47 @@ public void handle(HttpExchange t) throws IOException

} else {

byte[] output = null;
int length = urlParam.length() > 50 ? 50 : urlParam.length();
ByteArrayOutputStream bos = new ByteArrayOutputStream();

int length = urlParam.length() > 57 ? 57 : urlParam.length();
Logger.printlnMixedYellow("url parameter:", urlParam.substring(0, length) + "[...]");
Process p = Runtime.getRuntime().exec(new String[] {"curl", urlParam});

Process p = Runtime.getRuntime().exec(new String[] {"curl", urlParam});
int exitStatus = p.waitFor();

Logger.printlnMixedBlue("curl exit status:", String.valueOf(exitStatus));
InputStream stream;

if( exitStatus != 0 ) {
output = IOUtils.toByteArray(p.getErrorStream());

Logger.printlnMixedYellow("Stderr:", new String(output));
Logger.printlnMixedBlue("Sending", "500 Internal Server Error", "response.");
t.sendResponseHeaders(500, output.length);
if( exitStatus == 0 ) {
stream = p.getInputStream();
Logger.println("Stdout:");

} else {
output = IOUtils.toByteArray(p.getInputStream());
length = output.length > 50 ? 50 : output.length;
stream = p.getErrorStream();
Logger.println("Stderr:");
}

byte[] output = IOUtils.toByteArray(stream);
HexDump.dump(output, 0, bos, 0);
String[] hexDump = new String(bos.toByteArray()).split("\n");

Logger.increaseIndent();

Logger.printlnMixedYellow("Stdout:", new String(output).substring(0, length));
for(String line : hexDump)
Logger.printlnBlue(line);

Logger.decreaseIndent();

if( exitStatus == 0 ) {
Logger.printlnMixedBlue("Sending", "200 OK", "response.");
t.sendResponseHeaders(200, output.length);

} else {
Logger.printlnMixedBlue("Sending", "500 Internal Server Error", "response.");
t.sendResponseHeaders(500, output.length);
}

response.write(output);
Logger.decreaseIndent();
}

} catch( IOException | InterruptedException e ){
Expand All @@ -90,6 +107,7 @@ public void handle(HttpExchange t) throws IOException
}

response.close();
Logger.decreaseIndent();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<artifactId>remote-method-guesser</artifactId>
<name>remote-method-guesser</name>
<packaging>jar</packaging>
<version>4.0.0</version>
<version>4.1.0</version>
<description>Identify common misconfigurations on Java RMI endpoints</description>

<properties>
Expand Down
21 changes: 20 additions & 1 deletion src/de/qtc/rmg/internal/ArgumentHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,30 @@ private void initialize()
Logger.disableColor();

if( RMGOption.SSRF_RAW.getBool() )
Logger.disable();
Logger.disableStdout();

checkPortRange();

PluginSystem.init(RMGOption.GLOBAL_PLUGIN.getValue());
}

/**
* If the current action uses the TARGET_PORT argument, this function validates that the specified
* port number is not out of range.
*/
private void checkPortRange()
{
if( RMGOption.TARGET_PORT.isNull() )
return;

int port = RMGOption.TARGET_PORT.getValue();

if( port < 1 || port > 65535 ) {
Logger.eprintlnMixedYellow("The specified port number", String.valueOf(port), "is out of range.");
RMGUtils.exit();
}
}

/**
* Returns the user specified remote-method-guesser action.
*
Expand Down
11 changes: 9 additions & 2 deletions src/de/qtc/rmg/internal/ExceptionHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public static void noJRMPServer(Exception e, String during1, String during2)
{
Logger.eprintlnMixedYellow("Caught unexpected", "ConnectIOException", "during " + during1 + " " + during2 + ".");
Logger.eprintMixedBlue("Remote endpoint is either", "no RMI endpoint", "or uses an");
Logger.printlnPlainBlue(" SSL socket.");
Logger.eprintlnPlainBlue(" SSL socket.");

ExceptionHandler.sslOption();

Expand Down Expand Up @@ -444,6 +444,13 @@ public static void invalidObjectId(String objID)
RMGUtils.exit();
}

public static void wrongArgumentCount(int expected, int is)
{
Logger.eprintlnMixedYellow("The specified method signature expects", String.valueOf(expected), "arguments,");
Logger.eprintlnMixedBlue("but", String.valueOf(is), "arguments have been specified.");
RMGUtils.exit();
}

public static void unrecognizedMethodHash(Exception e, String action, String signature)
{
Logger.eprintlnMixedYellow("Caught", "UnmarshalException (unrecognized method hash)", "during " + action + " action.");
Expand Down Expand Up @@ -492,7 +499,7 @@ public static void connectionReset(Exception e, String during1, String during2)
{
Logger.eprintlnMixedYellow("Caught", "Connection Reset", "during " + during1 + " " + during2 + ".");
Logger.eprintMixedBlue("The specified port is probably", "not an RMI service ");
Logger.printlnPlainMixedBlue("or you used a wrong", "TLS", "setting.");
Logger.eprintlnPlainMixedBlue("or you used a wrong", "TLS", "setting.");

ExceptionHandler.sslOption();
ExceptionHandler.showStackTrace(e);
Expand Down
17 changes: 15 additions & 2 deletions src/de/qtc/rmg/internal/MethodCandidate.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class MethodCandidate {
private String signature;

private boolean isVoid;
private int argumentCount;
private int primitiveSize;

/**
Expand Down Expand Up @@ -94,10 +95,12 @@ public MethodCandidate(CtMethod method) throws NotFoundException
*/
private void initialize(CtMethod method) throws NotFoundException
{
this.hash = getCtMethodHash(method);
CtClass[] types = method.getParameterTypes();

if( types.length == 0 ) {
this.argumentCount = types.length;
this.hash = getCtMethodHash(method);

if( argumentCount == 0 ) {

this.isVoid = true;
this.primitiveSize = -99;
Expand Down Expand Up @@ -212,6 +215,16 @@ public String getName() throws CannotCompileException, NotFoundException
return "method";
}

/**
* Returns the expected argument count of the method candidate.
*
* @return expected argument count as int
*/
public int getArgumentCount()
{
return argumentCount;
}

/**
* Searches the current MethodCandidate for non primitive arguments (yes, the name is misleading).
* Non primitive arguments are required for deserialization attacks. If a non primitive argument is
Expand Down
17 changes: 16 additions & 1 deletion src/de/qtc/rmg/io/Formatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,21 @@ private void printLiveRef(RemoteObjectWrapper ref)

Logger.print(" ");
Logger.printPlainMixedBlue("Endpoint:", ref.getTarget());
Logger.printlnPlainMixedBlue(" ObjID:", ref.objID.toString());

switch( ref.isTLSProtected() ) {

case 1:
Logger.printPlainMixedGreen(" TLS:", "yes");
break;

case -1:
Logger.printPlainMixedRed(" TLS:", "no");
break;

default:
Logger.printPlainMixedPurple(" TLS:", "unknown");
}

Logger.printlnPlainMixedBlue(" ObjID:", ref.objID.toString());
}
}
59 changes: 52 additions & 7 deletions src/de/qtc/rmg/io/Logger.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,20 @@ public class Logger {

public static int indent = 0;
public static int printCount = 0;
public static boolean enabled = true;
public static boolean stdout = true;
public static boolean stderr = true;

public static void disable() {
Logger.enabled = false;
Logger.stdout = false;
Logger.stderr = false;
}

public static void disableStdout() {
Logger.stdout = false;
}

public static void disableStderr() {
Logger.stderr = false;
}

public static void disableIfNotVerbose() {
Expand All @@ -34,7 +44,16 @@ public static void disableIfNotVerbose() {
}

public static void enable() {
Logger.enabled = true;
Logger.stdout = true;
Logger.stderr = true;
}

public static void enableStdout() {
Logger.stdout = true;
}

public static void enableStderr() {
Logger.stderr = true;
}

public static String blue(String msg)
Expand Down Expand Up @@ -81,7 +100,7 @@ private static void log(String msg)

private static void log(String msg, boolean newline)
{
if( Logger.enabled ) {
if( Logger.stdout ) {

if( newline )
System.out.println(msg);
Expand All @@ -97,12 +116,12 @@ private static void elog(String msg)

private static void elog(String msg, boolean newline)
{
if( Logger.enabled ) {
if( Logger.stderr ) {

if( newline )
System.out.println(msg);
System.err.println(msg);
else
System.out.print(msg);
System.err.print(msg);
}
}

Expand Down Expand Up @@ -220,6 +239,11 @@ public static void printlnPlainMixedRed(String first, String second)
log(first + " " + red(second));
}

public static void printPlainMixedRed(String first, String second)
{
log(first + " " + red(second), false);
}

public static void printlnMixedGreen(String first, String second)
{
log(prefix() + first + " " + green(second));
Expand All @@ -230,6 +254,11 @@ public static void printlnPlainMixedGreen(String first, String second)
log(first + " " + green(second));
}

public static void printPlainMixedGreen(String first, String second)
{
log(first + " " + green(second), false);
}

public static void printlnMixedPurple(String first, String second)
{
log(prefix() + first + " " + purple(second));
Expand All @@ -240,6 +269,11 @@ public static void printlnPlainMixedPurple(String first, String second)
log(first + " " + purple(second));
}

public static void printPlainMixedPurple(String first, String second)
{
log(first + " " + purple(second), false);
}

public static void printlnMixedBlue(String first, String second)
{
log(prefix() + first + " " + blue(second));
Expand Down Expand Up @@ -289,11 +323,22 @@ public static void printlnPlainMixedBlue(String first, String second)
log(first + " " + blue(second));
}

public static void eprintlnPlainMixedBlue(String first, String second)
{
elog(first + " " + blue(second));
}

public static void printlnPlainMixedBlue(String first, String second, String third)
{
log(first + " " + blue(second) + " " + third);
}

public static void eprintlnPlainMixedBlue(String first, String second, String third)
{
elog(first + " " + blue(second) + " " + third);
}


public static void printPlainMixedBlue(String first, String second)
{
log(first + " " + blue(second), false);
Expand Down
Loading

0 comments on commit 7f87697

Please sign in to comment.