Module: Rex::Payloads::Meterpreter::UriChecksum
- Included in:
- Msf::Handler::ReverseHttp, Msf::Payload::UUID::Options, Rex::Post::Meterpreter::ClientCore
- Defined in:
- lib/rex/payloads/meterpreter/uri_checksum.rb
Constant Summary collapse
- URI_CHECKSUM_INITW =
Define 8-bit checksums for matching URLs These are based on charset frequency
92
- URI_CHECKSUM_INITN =
Windows
92
- URI_CHECKSUM_INITP =
Native (same as Windows)
80
- URI_CHECKSUM_INITJ =
Python
88
- URI_CHECKSUM_CONN =
Java
98
- URI_CHECKSUM_INIT_CONN =
Existing session
95
- URI_CHECKSUM_MODES =
Mapping between checksums and modes
Hash[ URI_CHECKSUM_INITN, :init_native, URI_CHECKSUM_INITP, :init_python, URI_CHECKSUM_INITJ, :init_java, URI_CHECKSUM_INIT_CONN, :init_connect, URI_CHECKSUM_CONN, :connect ]
- URI_CHECKSUM_MIN_LEN =
5
- URI_CHECKSUM_CONN_MAX_LEN =
Limit how long :connect URLs are to stay within 256 bytes when including the hostname, colon, port, and leading slash
128
- URI_CHECKSUM_UUID_MIN_LEN =
URI_CHECKSUM_MIN_LEN + Msf::Payload::UUID::UriLength
Instance Method Summary collapse
-
#generate_uri_checksum(sum, len = 5, prefix = "") ⇒ String
Create an arbitrary length URI that matches a given checksum.
-
#generate_uri_uuid(sum, uuid, len = nil) ⇒ String
Create a URI that matches the specified checksum and payload uuid.
-
#process_uri_resource(uri) ⇒ Hash
Map “random” URIs to static strings, allowing us to randomize the URI sent in the first request.
-
#uri_checksum_lookup(mode) ⇒ Integer
Return the numerical checksum for a given mode symbol.
Instance Method Details
#generate_uri_checksum(sum, len = 5, prefix = "") ⇒ String
Create an arbitrary length URI that matches a given checksum
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/rex/payloads/meterpreter/uri_checksum.rb', line 90 def generate_uri_checksum(sum, len=5, prefix="") # Lengths shorter than 4 bytes are unable to match all possible checksums # Lengths of exactly 4 are relatively slow to find for high checksum values # Lengths of 5 or more bytes find a matching checksum fairly quickly (~80ms) if len < URI_CHECKSUM_MIN_LEN raise ArgumentError, "Length must be #{URI_CHECKSUM_MIN_LEN} bytes or greater" end gen_len = len-prefix.length if gen_len < URI_CHECKSUM_MIN_LEN raise ArgumentError, "Prefix must be at least {URI_CHECKSUM_MIN_LEN} bytes smaller than total length" end # Brute force a matching checksum for shorter URIs if gen_len < 40 loop do uri = prefix + Rex::Text.rand_text_base64url(gen_len) return uri if Rex::Text.checksum8(uri) == sum end end # The rand_text_base64url() method becomes a bottleneck at around 40 bytes # Calculating a static prefix flattens out the average runtime for longer URIs prefix << Rex::Text.rand_text_base64url(gen_len-20) loop do uri = prefix + Rex::Text.rand_text_base64url(20) return uri if Rex::Text.checksum8(uri) == sum end end |
#generate_uri_uuid(sum, uuid, len = nil) ⇒ String
Create a URI that matches the specified checksum and payload uuid
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/rex/payloads/meterpreter/uri_checksum.rb', line 67 def generate_uri_uuid(sum, uuid, len=nil) curl_uri_len = URI_CHECKSUM_UUID_MIN_LEN + rand(URI_CHECKSUM_CONN_MAX_LEN - URI_CHECKSUM_UUID_MIN_LEN) curl_prefix = uuid.to_uri if len # Subtract a byte to take into account the leading / curl_uri_len = len - 1 end if curl_uri_len < URI_CHECKSUM_UUID_MIN_LEN raise ArgumentError, "Length must be #{URI_CHECKSUM_UUID_MIN_LEN+1} bytes or greater" end # Pad out the URI and make the checksum match the specified sum "/" + generate_uri_checksum(sum, curl_uri_len, curl_prefix) end |
#process_uri_resource(uri) ⇒ Hash
Map “random” URIs to static strings, allowing us to randomize the URI sent in the first request.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/rex/payloads/meterpreter/uri_checksum.rb', line 41 def process_uri_resource(uri) # Ignore non-base64url characters in the URL = uri.gsub(/[^a-zA-Z0-9_\-]/, '') # Figure out the mode based on the checksum uri_csum = Rex::Text.checksum8() # Extract the UUID if the URI is long enough uri_uuid = nil if .length >= URI_CHECKSUM_UUID_MIN_LEN uri_uuid = Msf::Payload::UUID.new(uri: ) end uri_mode = URI_CHECKSUM_MODES[uri_csum] # Return a hash of URI attributes { uri: , sum: uri_csum, uuid: uri_uuid, mode: uri_mode } end |
#uri_checksum_lookup(mode) ⇒ Integer
Return the numerical checksum for a given mode symbol
125 126 127 128 129 130 131 |
# File 'lib/rex/payloads/meterpreter/uri_checksum.rb', line 125 def uri_checksum_lookup(mode) sum = URI_CHECKSUM_MODES.keys.select{|ksum| URI_CHECKSUM_MODES[ksum] == mode}.first unless sum raise ArgumentError, "Unknown checksum mode: #{mode}" end sum end |