root/framework3/trunk/msfencode

Revision 5689, 4.6 kB (checked in by hdm, 1 week ago)

Switches the executable template to something a little nicer and adds exe output to msfencode

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/env ruby
2
3 msfbase = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
4 $:.unshift(File.join(File.dirname(msfbase), 'lib'))
5 $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
6
7 require 'rex'
8 require 'msf/ui'
9 require 'msf/base'
10
11 OutStatus = "[*] "
12 OutError  = "[-] "
13
14 $args = Rex::Parser::Arguments.new(
15         "-i" => [ true, "Encode the contents of the supplied file path"                      ],
16         "-m" => [ true, "Specifies an additional module search path"                         ],
17         "-a" => [ true, "The architecture to encode as"                                      ],
18         "-t" => [ true, "The format to display the encoded buffer with (raw, ruby, perl, c)" ],
19         "-b" => [ true, "The list of characters to avoid: '\\x00\\xff'"                      ],
20         "-s" => [ true, "The maximum size of the encoded data"                               ],
21         "-e" => [ true, "The encoder to use"                                                 ],
22         "-o" => [ true, "The output file"                                                    ],
23         "-n" => [ false, "Dump encoder information"                                          ],
24         "-h" => [ false, "Help banner"                                                       ],
25         "-l" => [ false, "List available encoders"                                           ])
26
27 #
28 # Dump the list of encoders
29 #
30 def dump_encoders(arch = nil)
31         tbl = Rex::Ui::Text::Table.new(
32                 'Indent'  => 4,
33                 'Header'  => "Framework Encoders" + ((arch) ? " (architectures: #{arch})" : ""),
34                 'Columns' =>
35                         [
36                                 "Name",
37                                 "Rank",
38                                 "Description"
39                         ])
40         cnt = 0
41
42         $framework.encoders.each_module(
43                 'Arch' => arch ? arch.split(',') : nil) { |name, mod|
44                 tbl << [ name, mod.rank_to_s, mod.new.name ]
45
46                 cnt += 1
47         }
48
49         (cnt > 0) ? "\n" + tbl.to_s + "\n" : "\nNo compatible encoders found.\n\n"
50 end
51
52 #
53 # Returns the list of encoders to try
54 #
55 def get_encoders(arch, encoder)
56         encoders = []
57
58         if (encoder)
59                 encoders << $framework.encoders.create(encoder)
60         else
61                 $framework.encoders.each_module_ranked(
62                         'Arch' => arch ? arch.split(',') : nil) { |name, mod|
63                         encoders << mod.new
64                 }
65         end
66
67         encoders
68 end
69
70 #
71 # Nuff said.
72 #
73 def usage
74         $stderr.puts("\n" + "    Usage: #{$0} <options>\n" + $args.usage)
75         exit
76 end
77
78 # Initialize the simplified framework instance.
79 $framework = Msf::Simple::Framework.create
80
81 # Defaults
82 cmd      = "encode"
83 arch     = nil
84 badchars = ''
85 space    = nil
86 encoder  = nil
87 fmt      = "c"
88 input    = $stdin
89 options  = ''
90 delim    = '_|_'
91 output   = nil
92
93 # Parse the argument and rock that shit.
94 $args.parse(ARGV) { |opt, idx, val|
95         case opt
96                 when "-i"
97                         begin
98                                 input = File.new(val)
99                         rescue
100                                 $stderr.puts(OutError + "Failed to open file #{val}: #{$!}")
101                                 exit
102                         end
103                 when "-m"
104                         $framework.modules.add_module_path(val)
105                 when "-l"
106                         cmd = "list"
107                 when "-n"
108                         cmd = "dump"
109                 when "-a"
110                         arch = val
111                 when "-b"
112                         badchars = Rex::Text.hex_to_raw(val)
113                 when "-s"
114                         space = val.to_i
115                 when "-t"
116                         if (val =~ /^(perl|ruby|raw|c|exe)$/)
117                                 fmt = val
118                         else
119                                 $stderr.puts(OutError + "Invalid format: #{val}")
120                                 exit
121                         end
122                 when "-o"
123                         output = val
124                 when "-e"
125                         encoder = val
126                 when "-h"
127                         usage
128                 else
129                         if (val =~ /=/)
130                                 options += ((options.length > 0) ? delim : "") + "#{val}"
131                         end
132         end     
133 }
134
135 # Get the list of encoders to try
136 encoders = get_encoders(arch, encoder)
137
138 # Process the actual command
139 case cmd
140         when "list"
141                 $stderr.puts(dump_encoders(arch))
142         when "dump"
143                 enc = encoder ? $framework.encoders.create(encoder) : nil
144
145                 if (enc)
146                         $stderr.puts(Msf::Serializer::ReadableText.dump_module(enc))
147                 else
148                         $stderr.puts(OutError + "Invalid encoder specified.")
149                 end
150         when "encode"
151                 buf = input.read
152                
153                 encoders.each { |enc|
154                         next if not enc
155                         begin
156                                 # Imports options
157                                 enc.datastore.import_options_from_s(options, delim)
158
159                                 # Encode it up
160                                 raw = enc.encode(buf, badchars)
161
162                                 # Is it too big?
163                                 if (space and space > 0 and raw.length > space)
164                                         $stderr.puts(OutError + "#{enc.refname} created buffer that is too big (#{raw.length})")
165                                         next
166                                 end
167
168                                 # Print it out
169                                 $stderr.puts(OutStatus + "#{enc.refname} succeeded, final size #{raw.length}\n\n")
170                                
171                                 if(fmt != "exe")
172                                         if(not output)
173                                                 $stdout.print(Msf::Simple::Buffer.transform(raw, fmt))
174                                         else
175                                                 File.open(output, "wb") do |fd|
176                                                         fd.write(Msf::Simple::Buffer.transform(raw, fmt))
177                                                 end                                     
178                                         end
179                                 else
180                                         exe = Rex::Text.to_win32pe(buf, "")
181                                         if(not output)
182                                                 $stdout.write(exe)
183                                         else
184                                                 File.open(output, "wb") do |fd|
185                                                         fd.write(exe)
186                                                 end
187                                         end
188                                 end
189                                
190                                 exit
191
192                         rescue
193                                 $stderr.puts(OutError + "#{enc.refname} failed: #{$!}")
194                         end
195                 }
196
197                 $stderr.puts(OutError + "No encoders succeeded.")
198 end
Note: See TracBrowser for help on using the browser.