Module: Rex::Powershell::Output
Instance Method Summary collapse
-
#compress_code(eof = nil, gzip = true) ⇒ String
Compresses script contents with gzip (default) or deflate.
-
#decode_code ⇒ String
Return ASCII powershell code from base64/unicode.
-
#decompress_code ⇒ String
Reverse the compression process Try gzip, inflate if that fails.
-
#deflate_code(eof = nil) ⇒ String
Return a zlib compressed powershell code wrapped in decode stub.
-
#encode_code(eof = nil) ⇒ String
Return Base64 encoded powershell code.
-
#gzip_code(eof = nil) ⇒ String
Return a gzip compressed powershell code wrapped in decoder stub.
-
#size ⇒ Integer
Returns code size.
-
#to_s ⇒ String
To String.
-
#to_s_lineno ⇒ String
Return code with numbered lines.
Instance Method Details
#compress_code(eof = nil, gzip = true) ⇒ String
Compresses script contents with gzip (default) or deflate
133 134 135 |
# File 'lib/rex/powershell/output.rb', line 133 def compress_code(eof = nil, gzip = true) @code = gzip ? gzip_code(eof) : deflate_code(eof) end |
#decode_code ⇒ String
Return ASCII powershell code from base64/unicode
87 88 89 |
# File 'lib/rex/powershell/output.rb', line 87 def decode_code @code = Rex::Text.to_ascii(Rex::Text.decode_base64(code)) end |
#decompress_code ⇒ String
Reverse the compression process Try gzip, inflate if that fails
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/rex/powershell/output.rb', line 142 def decompress_code # Extract substring with payload4 if @code =~ /FromBase64String\('([a-zA-z0-9\+\/=]*)'\)/ encoded_stream = Regexp.last_match(1) elsif @code =~ /FromBase64String(\((?>[^)(]+|\g<1>)*\))/ encoded_stream = Obfu.descate_string_literal(Regexp.last_match(1)) else raise Exceptions::PowershellError, 'Failed to identify the base64 data' end # Decode and decompress the string unencoded = Rex::Text.decode_base64(encoded_stream) begin @code = Rex::Text.ungzip(unencoded) || Rex::Text.zlib_inflate(unencoded) rescue Zlib::GzipFile::Error begin @code = Rex::Text.zlib_inflate(unencoded) rescue Zlib::DataError => e raise Exceptions::PowershellError, 'Invalid compression' end end @code end |
#deflate_code(eof = nil) ⇒ String
Return a zlib compressed powershell code wrapped in decode stub
decompression stub
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rex/powershell/output.rb', line 45 def deflate_code(eof = nil) # Compress using the Deflate algorithm compressed_stream = ::Zlib::Deflate.deflate(code, ::Zlib::BEST_COMPRESSION) # Base64 encode the compressed file contents encoded_stream = Rex::Text.encode_base64(compressed_stream) # Build the powershell expression # Decode base64 encoded command and create a stream object psh_expression = "$s=New-Object System.IO.MemoryStream(," psh_expression << "[System.Convert]::FromBase64String(#{Obfu.scate_string_literal(encoded_stream, threshold: 0.01)}));" # Read & delete the first two bytes due to incompatibility with MS psh_expression << '$s.ReadByte();' psh_expression << '$s.ReadByte();' # Uncompress and invoke the expression (execute) psh_expression << 'IEX (New-Object System.IO.StreamReader(' psh_expression << 'New-Object System.IO.Compression.DeflateStream(' psh_expression << '$s,' psh_expression << '[System.IO.Compression.CompressionMode]::Decompress)' psh_expression << ')).ReadToEnd();' # If eof is set, add a marker to signify end of code output # if (eof && eof.length == 8) then psh_expression += "'#{eof}'" end psh_expression << "echo '#{eof}';" if eof @code = psh_expression end |
#encode_code(eof = nil) ⇒ String
Return Base64 encoded powershell code
79 80 81 |
# File 'lib/rex/powershell/output.rb', line 79 def encode_code(eof = nil) @code = Rex::Text.encode_base64(Rex::Text.to_unicode(code)) end |
#gzip_code(eof = nil) ⇒ String
Return a gzip compressed powershell code wrapped in decoder stub
decompression stub
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/rex/powershell/output.rb', line 98 def gzip_code(eof = nil) # Compress using the Gzip algorithm compressed_stream = Rex::Text.gzip(code) # Base64 encode the compressed file contents encoded_stream = Rex::Text.encode_base64(compressed_stream) # Build the powershell expression # Create and execute script lock fed by the IO.StreamReader psh_expression = '&([scriptblock]::create((New-Object System.IO.StreamReader(' # Feed StreamREader from a GzipStream psh_expression << 'New-Object System.IO.Compression.GzipStream(' # GzipStream operates on the Memory Stream psh_expression << '(New-Object System.IO.MemoryStream(,' # MemoryStream consists of base64 encoded compressed data psh_expression << "[System.Convert]::FromBase64String(#{Obfu.scate_string_literal(encoded_stream, threshold: 0.01)})))" # Set the GzipStream to decompress its MemoryStream contents psh_expression << ',[System.IO.Compression.CompressionMode]::Decompress)' # Read the decoded, decompressed result into scriptblock contents psh_expression << ')).ReadToEnd()))' # If eof is set, add a marker to signify end of code output # if (eof && eof.length == 8) then psh_expression += "'#{eof}'" end psh_expression << "echo '#{eof}';" if eof @code = psh_expression end |
#size ⇒ Integer
Returns code size
21 22 23 |
# File 'lib/rex/powershell/output.rb', line 21 def size code.size end |
#to_s ⇒ String
To String
13 14 15 |
# File 'lib/rex/powershell/output.rb', line 13 def to_s code end |
#to_s_lineno ⇒ String
Return code with numbered lines
29 30 31 32 33 34 35 36 |
# File 'lib/rex/powershell/output.rb', line 29 def to_s_lineno numbered = '' code.split(/\r\n|\n/).each_with_index do |line, idx| numbered << "#{idx}: #{line}" end numbered end |