Skip to content

Commit

Permalink
Change argument format of call action
Browse files Browse the repository at this point in the history
  • Loading branch information
qtc-de committed May 6, 2024
1 parent d3aeb35 commit a653e63
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 32 deletions.
4 changes: 2 additions & 2 deletions src/eu/tneitzel/rmg/internal/ArgumentHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ public Object[] getCallArguments()
{
try
{
String argumentString = (String) RMGOption.CALL_ARGUMENTS.require();
return PluginSystem.getArgumentArray(argumentString);
String[] args = (String[])RMGOption.CALL_ARGUMENTS.require();
return PluginSystem.getArgumentArray(args);
}

catch (RequirementException e)
Expand Down
1 change: 1 addition & 0 deletions src/eu/tneitzel/rmg/internal/RMGOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ public enum RMGOption implements IOption
RMGOptionGroup.NONE,
new IArgumentModifier[] {
new MetaVar("args"),
new NArgs("*")
}),

/** ObjID string to parse */
Expand Down
88 changes: 66 additions & 22 deletions src/eu/tneitzel/rmg/plugin/DefaultProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
*
* @author Tobias Neitzel (@qtc_de)
*/
public class DefaultProvider implements IArgumentProvider, IPayloadProvider, ISocketFactoryProvider {

public class DefaultProvider implements IArgumentProvider, IPayloadProvider, ISocketFactoryProvider
{
/**
* Return an RMIServerImpl object as used by JMX endpoints when invoked from the bind, rebind or unbind
* actions. In this case, name is expected to be 'jmx' or args is expected to be null. When the name is
Expand All @@ -51,21 +51,26 @@ public class DefaultProvider implements IArgumentProvider, IPayloadProvider, ISo
@Override
public Object getPayloadObject(Operation action, String name, String args)
{
switch(action) {

switch(action)
{
case BIND:
case REBIND:
case UNBIND:

if(name.equalsIgnoreCase("jmx")) {
if (name.equalsIgnoreCase("jmx"))
{
String[] split = RMGUtils.splitListener(args);
return RegistryClient.prepareRMIServerImpl(split[0], Integer.valueOf(split[1]));
}

} else if(args == null) {
else if (args == null)
{
String[] split = RMGUtils.splitListener(name);
return RegistryClient.prepareRMIServerImpl(split[0], Integer.valueOf(split[1]));
}

} else {
else
{
Logger.eprintlnMixedYellow("The specified gadget", name, "is not supported for this action.");
RMGUtils.exit();
}
Expand All @@ -74,7 +79,8 @@ public Object getPayloadObject(Operation action, String name, String args)

default:

if(args == null) {
if (args == null)
{
Logger.eprintlnMixedBlue("Specifying a", "gadget argument", "is required for this action.");
RMGUtils.exit();
}
Expand All @@ -86,40 +92,50 @@ public Object getPayloadObject(Operation action, String name, String args)
}

/**
* This function performs basically an eval operation on the user specified argumentString. The argument string is
* inserted into the following expression: return new Object[] { " + argumentString + "};
* This function performs basically an eval operation on the user specified arguments. The argument string is
* inserted into the following expression: return new Object[] { arg1, arg2, arg3, ... };
* This expression is evaluated and the resulting Object array is returned by this function. For this to work it is
* important that all arguments within the argumentString are valid Java Object definitions. E.g. one has to use
* new Integer(5) instead of a plain 5.
*/
@Override
public Object[] getArgumentArray(String argumentString)
public Object[] getArgumentArray(String[] args)
{
Object[] result = null;
ClassPool pool = ClassPool.getDefault();

try {
String argumentString = prepareArgumentString(args);
StringBuilder evalFunction = new StringBuilder();

evalFunction.append("public static Object[] eval() { return new Object[] {");
evalFunction.append(argumentString);
evalFunction.append("};}");

try
{
CtClass evaluator = pool.makeClass("eu.tneitzel.rmg.plugin.DefaultProviderEval");
String evalFunction = "public static Object[] eval() {"
+ " return new Object[] { " + argumentString + "};"
+ "}";

CtMethod me = CtNewMethod.make(evalFunction, evaluator);

CtMethod me = CtNewMethod.make(evalFunction.toString(), evaluator);
evaluator.addMethod(me);
Class<?> evalClass = evaluator.toClass();

Method m = evalClass.getDeclaredMethods()[0];
result = (Object[]) m.invoke(evalClass, (Object[])null);
}

} catch(VerifyError | CannotCompileException e) {
catch(VerifyError | CannotCompileException e)
{
Logger.eprintlnMixedYellow("Specified argument string", argumentString, "is invalid.");
Logger.eprintlnMixedBlue("Argument string has to be a valid Java expression like:", "'\"id\", new Integer(4)'.");
Logger.eprintMixedYellow("Make sure that each argument is an", "Object", "not a ");
Logger.printlnPlainYellow("Primitive.");
ExceptionHandler.showStackTrace(e);
RMGUtils.exit();
}

} catch (Exception e) {
catch (Exception e)
{
ExceptionHandler.unexpectedException(e, "argument array", "generation", true);
}

Expand All @@ -132,17 +148,24 @@ public Object[] getArgumentArray(String argumentString)
@Override
public RMIClientSocketFactory getClientSocketFactory(String host, int port)
{
if( RMGOption.SSRF.getBool() ) {
if (RMGOption.SSRF.getBool())
{
return new SSRFSocketFactory();
}

} else if( RMGOption.SSRFRESPONSE.notNull() ) {
else if (RMGOption.SSRFRESPONSE.notNull())
{
byte[] content = RMGUtils.hexToBytes(RMGOption.SSRFRESPONSE.getValue());
return new SSRFResponseSocketFactory(content);
}

} else if( RMGOption.CONN_SSL.getBool() ) {
else if (RMGOption.CONN_SSL.getBool())
{
return new TrustAllSocketFactory();
}

} else {
else
{
return RMISocketFactory.getDefaultSocketFactory();
}
}
Expand Down Expand Up @@ -200,4 +223,25 @@ public String getDefaultSSLSocketFactory(String host, int port)

return "eu.tneitzel.rmg.networking.LoopbackSslSocketFactory";
}

/**
* Transforms an array of string arguments to a representation that can be used within new Object[] {}.
*
* @param args user specified arguments
* @return prepared argument string
*/
private static String prepareArgumentString(String[] args)
{
StringBuilder argString = new StringBuilder();

for (String arg : args)
{
argString.append(arg);
argString.append(",");
}

argString.setLength(argString.length() - 1);

return argString.toString();
}
}
8 changes: 4 additions & 4 deletions src/eu/tneitzel/rmg/plugin/IArgumentProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

/**
* The IArgumentProvider interface is used during rmg's 'call' action to obtain the argument array that should be
* used for the call. plugins can implement this class to obtain custom argument arrays that they want to use during
* the 'call' operation. The getArgumentArray method is called with the user specified argument string and is expected
* used for the call. plugins can implement this class to provide custom argument arrays that they want to use during
* the 'call' operation. The getArgumentArray method is called with the user specified arguments and is expected
* to return the Object array that should be used for the call.
*
* This interface is implemented by rmg's DefaultProvider class by default.
Expand All @@ -16,8 +16,8 @@ public interface IArgumentProvider
/**
* Provide an argument array for remote method calls.
*
* @param argumentString the argument string specified on the command line
* @param args the arguments specified on the command line
* @return argument array for a remote method call
*/
Object[] getArgumentArray(String argumentString);
Object[] getArgumentArray(String[] args);
}
7 changes: 3 additions & 4 deletions src/eu/tneitzel/rmg/plugin/PluginSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import eu.tneitzel.argparse4j.inf.Subparsers;
import eu.tneitzel.rmg.exceptions.MalformedPluginException;
import eu.tneitzel.rmg.internal.ExceptionHandler;
import eu.tneitzel.rmg.internal.RMGOption;
import eu.tneitzel.rmg.io.Logger;
import eu.tneitzel.rmg.operations.Operation;
import eu.tneitzel.rmg.utils.RMGUtils;
Expand Down Expand Up @@ -198,12 +197,12 @@ public static Object getPayloadObject(Operation action, String name, String args
* Is called during rmg's 'call' action to obtain the Object argument array. Just forwards the call to the corresponding
* plugin.
*
* @param argumentString as specified on the command line
* @param args as specified on the command line
* @return Object array to use for the call
*/
public static Object[] getArgumentArray(String argumentString)
public static Object[] getArgumentArray(String[] args)
{
return argumentProvider.getArgumentArray(argumentString);
return argumentProvider.getArgumentArray(args);
}

/**
Expand Down

0 comments on commit a653e63

Please sign in to comment.