Skip to content

Fixes the script for updating cached payload sizes#20911

Open
msutovsky-r7 wants to merge 9 commits intorapid7:masterfrom
msutovsky-r7:fix/script/update_payload_cached_sizes
Open

Fixes the script for updating cached payload sizes#20911
msutovsky-r7 wants to merge 9 commits intorapid7:masterfrom
msutovsky-r7:fix/script/update_payload_cached_sizes

Conversation

@msutovsky-r7
Copy link
Contributor

Fixes #20864

This PR addresses issue with update_payload_cached_sizes script. There has been some issues and inconsistencies with the script, leading to behavior when developers had to manually update cached sizes of payload, when CI failed. This PR tries to address the issue by unifying the way framework instance is created in CI and in the script. Furthermore, it takes into account the dynamic cached sizes and tries to forbid overwriting cached sizes by multiple payloads (i.e. staggers). As a bonus, it fixes a bug in PHP exec payload.

This is work in progress, the initial fix seems to be working, further tests are necessary.

  • Run the script with multiple modified payloads, the script should updates cached_sizes accordingly
  • Run the script in latest commit, the script should not update any cached sizes
  • Make sure dynamic payloads stay dynamic

@msutovsky-r7 msutovsky-r7 added bug rn-fix release notes fix labels Jan 29, 2026
@msutovsky-r7 msutovsky-r7 marked this pull request as draft January 29, 2026 09:33
@msutovsky-r7 msutovsky-r7 moved this from Todo to In Progress in Metasploit Kanban Jan 29, 2026
# @return [Boolean]
def self.is_cached_size_accurate?(mod)
return true if mod.dynamic_size? && is_dynamic?(mod)
return true if mod.dynamic_size? || is_dynamic?(mod)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remind me the reason to this logic switch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, because this was effectively turning some :dynamic payloads into fixed length payload. That's because is_dynamic? returns true, if payload generates x times output with different length using same datastore options. This function fails to detect two types of dynamic payloads: if payload is unique each time but with fixed size or if the payload should be dynamic due to other datastore option. This fix tries to address it by basically declaring that :dynamic payload should stay :dynamic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative method is to change is_dynamic? - some payloads are and should be marked as dynamic, due to changing output. So another option is to change the logic to use hash instead of size length.

# Initialize the simplified framework instance.
framework = Msf::Simple::Framework.create('DisableDatabase' => true)
exceptions = []
framework = Msf::Simple::Framework.create({'DeferModuleLoads' => true})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this one the change we discussed to avoid having DATASTORE saved with save being fetched by the script?

Comment on lines 129 to 130
#return true if mod.dynamic_size?
#return true if mod.dynamic_size? || is_dynamic?(mod)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#return true if mod.dynamic_size?
#return true if mod.dynamic_size? || is_dynamic?(mod)

# @return [Boolean]
def self.is_cached_size_accurate?(mod)
return true if mod.dynamic_size? && is_dynamic?(mod)
return true if mod.dynamic_size? || is_dynamic?(mod)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative method is to change is_dynamic? - some payloads are and should be marked as dynamic, due to changing output. So another option is to change the logic to use hash instead of size length.

@smcintyre-r7
Copy link
Contributor

So I know this is drafted right now but I gave it a quick test.

After running it on the main branch, I see that it's flipped some modules from dynamic to sized and the top one seems to still have the problem from the original issues where the CachedSize is changed from 7497 to 7506. I'm pretty sure that would result in a failure because it's generating to a larger size locally.

diff --git a/modules/payloads/singles/java/shell_reverse_tcp.rb b/modules/payloads/singles/java/shell_reverse_tcp.rb
index 97b9e2cac9..14afb33541 100644
--- a/modules/payloads/singles/java/shell_reverse_tcp.rb
+++ b/modules/payloads/singles/java/shell_reverse_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = 7497
+
+  CachedSize = 7506
 
   include Msf::Payload::Single
   include Msf::Payload::Java
diff --git a/modules/payloads/singles/python/shell_bind_tcp.rb b/modules/payloads/singles/python/shell_bind_tcp.rb
index 55b0c1fa93..511a816b7a 100644
--- a/modules/payloads/singles/python/shell_bind_tcp.rb
+++ b/modules/payloads/singles/python/shell_bind_tcp.rb
@@ -1,5 +1,6 @@
 module MetasploitModule
-  CachedSize = :dynamic
+
+  CachedSize = 420
 
   include Msf::Payload::Single
   include Msf::Payload::Python
diff --git a/modules/payloads/singles/python/shell_reverse_sctp.rb b/modules/payloads/singles/python/shell_reverse_sctp.rb
index eff88b0110..7abeb44a0f 100644
--- a/modules/payloads/singles/python/shell_reverse_sctp.rb
+++ b/modules/payloads/singles/python/shell_reverse_sctp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = :dynamic
+
+  CachedSize = 464
 
   include Msf::Payload::Single
   include Msf::Payload::Python
diff --git a/modules/payloads/singles/python/shell_reverse_tcp.rb b/modules/payloads/singles/python/shell_reverse_tcp.rb
index 42eee0c623..1b8b18d8b2 100644
--- a/modules/payloads/singles/python/shell_reverse_tcp.rb
+++ b/modules/payloads/singles/python/shell_reverse_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = :dynamic
+
+  CachedSize = 408
 
   include Msf::Payload::Single
   include Msf::Payload::Python
diff --git a/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb b/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb
index 00e66b7fc4..b20b1b2795 100644
--- a/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb
+++ b/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = :dynamic
+
+  CachedSize = 432
 
   include Msf::Payload::Single
   include Msf::Payload::Python
diff --git a/modules/payloads/singles/python/shell_reverse_udp.rb b/modules/payloads/singles/python/shell_reverse_udp.rb
index 2c4c25e1e0..d2a91fc2e2 100644
--- a/modules/payloads/singles/python/shell_reverse_udp.rb
+++ b/modules/payloads/singles/python/shell_reverse_udp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = :dynamic
+
+  CachedSize = 404
 
   include Msf::Payload::Single
   include Msf::Payload::Python
diff --git a/modules/payloads/stagers/java/bind_tcp.rb b/modules/payloads/stagers/java/bind_tcp.rb
index d118991612..5455117467 100644
--- a/modules/payloads/stagers/java/bind_tcp.rb
+++ b/modules/payloads/stagers/java/bind_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = 5256
+
+  CachedSize = 5265
 
   include Msf::Payload::Stager
   include Msf::Payload::Java
diff --git a/modules/payloads/stagers/java/reverse_tcp.rb b/modules/payloads/stagers/java/reverse_tcp.rb
index 72b3d6b475..08c0fb8d82 100644
--- a/modules/payloads/stagers/java/reverse_tcp.rb
+++ b/modules/payloads/stagers/java/reverse_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = 5256
+
+  CachedSize = 5265
 
   include Msf::Payload::Stager
   include Msf::Payload::Java
diff --git a/modules/payloads/stagers/python/bind_tcp.rb b/modules/payloads/stagers/python/bind_tcp.rb
index 6a6aea06ee..5a478f0ace 100644
--- a/modules/payloads/stagers/python/bind_tcp.rb
+++ b/modules/payloads/stagers/python/bind_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = :dynamic
+
+  CachedSize = 388
 
   include Msf::Payload::Stager
   include Msf::Payload::Python
diff --git a/modules/payloads/stagers/python/reverse_tcp.rb b/modules/payloads/stagers/python/reverse_tcp.rb
index cd69d7c8f2..24d7607101 100644
--- a/modules/payloads/stagers/python/reverse_tcp.rb
+++ b/modules/payloads/stagers/python/reverse_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = :dynamic
+
+  CachedSize = 428
 
   include Msf::Payload::Stager
   include Msf::Payload::Python::ReverseTcp
diff --git a/modules/payloads/stagers/python/reverse_tcp_ssl.rb b/modules/payloads/stagers/python/reverse_tcp_ssl.rb
index 1480fb6d07..e8fea648f6 100644
--- a/modules/payloads/stagers/python/reverse_tcp_ssl.rb
+++ b/modules/payloads/stagers/python/reverse_tcp_ssl.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = :dynamic
+
+  CachedSize = 424
 
   include Msf::Payload::Stager
   include Msf::Payload::Python::ReverseTcpSsl

@msutovsky-r7 msutovsky-r7 changed the title WIP: fixes the script for updating cached payload sizes Fixes the script for updating cached payload sizes Feb 6, 2026
@msutovsky-r7 msutovsky-r7 marked this pull request as ready for review February 10, 2026 10:56
@msutovsky-r7 msutovsky-r7 moved this from In Progress to Waiting on Review in Metasploit Kanban Feb 10, 2026
@smcintyre-r7
Copy link
Contributor

On testing this, it still seems like it's updating the sizes for payloads that shouldn't have their sizes updated

diff --git a/modules/payloads/singles/java/shell_reverse_tcp.rb b/modules/payloads/singles/java/shell_reverse_tcp.rb
index 97b9e2cac9..14afb33541 100644
--- a/modules/payloads/singles/java/shell_reverse_tcp.rb
+++ b/modules/payloads/singles/java/shell_reverse_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = 7497
+
+  CachedSize = 7506
 
   include Msf::Payload::Single
   include Msf::Payload::Java
diff --git a/modules/payloads/stagers/java/bind_tcp.rb b/modules/payloads/stagers/java/bind_tcp.rb
index d118991612..5455117467 100644
--- a/modules/payloads/stagers/java/bind_tcp.rb
+++ b/modules/payloads/stagers/java/bind_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = 5256
+
+  CachedSize = 5265
 
   include Msf::Payload::Stager
   include Msf::Payload::Java
diff --git a/modules/payloads/stagers/java/reverse_tcp.rb b/modules/payloads/stagers/java/reverse_tcp.rb
index 72b3d6b475..08c0fb8d82 100644
--- a/modules/payloads/stagers/java/reverse_tcp.rb
+++ b/modules/payloads/stagers/java/reverse_tcp.rb
@@ -4,7 +4,8 @@
 ##
 
 module MetasploitModule
-  CachedSize = 5256
+
+  CachedSize = 5265
 
   include Msf::Payload::Stager
   include Msf::Payload::Java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug rn-fix release notes fix

Projects

Status: Waiting on Review

Development

Successfully merging this pull request may close these issues.

Payload Cache Size Update Script is Broken

3 participants