librex 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +4 -0
- data/lib/rex.rb +101 -0
- data/lib/rex.rb.ts.rb +70 -0
- data/lib/rex/LICENSE +29 -0
- data/lib/rex/arch.rb +103 -0
- data/lib/rex/arch/sparc.rb +75 -0
- data/lib/rex/arch/sparc.rb.ut.rb +18 -0
- data/lib/rex/arch/x86.rb +513 -0
- data/lib/rex/arch/x86.rb.ut.rb +93 -0
- data/lib/rex/assembly/nasm.rb +100 -0
- data/lib/rex/assembly/nasm.rb.ut.rb +22 -0
- data/lib/rex/codepage.map +104 -0
- data/lib/rex/compat.rb +281 -0
- data/lib/rex/constants.rb +113 -0
- data/lib/rex/elfparsey.rb +11 -0
- data/lib/rex/elfparsey/elf.rb +123 -0
- data/lib/rex/elfparsey/elfbase.rb +260 -0
- data/lib/rex/elfparsey/exceptions.rb +27 -0
- data/lib/rex/elfscan.rb +12 -0
- data/lib/rex/elfscan/scanner.rb +207 -0
- data/lib/rex/elfscan/search.rb +46 -0
- data/lib/rex/encoder/alpha2.rb +31 -0
- data/lib/rex/encoder/alpha2/alpha_mixed.rb +68 -0
- data/lib/rex/encoder/alpha2/alpha_upper.rb +79 -0
- data/lib/rex/encoder/alpha2/generic.rb +113 -0
- data/lib/rex/encoder/alpha2/unicode_mixed.rb +117 -0
- data/lib/rex/encoder/alpha2/unicode_upper.rb +129 -0
- data/lib/rex/encoder/ndr.rb +89 -0
- data/lib/rex/encoder/ndr.rb.ut.rb +44 -0
- data/lib/rex/encoder/nonalpha.rb +61 -0
- data/lib/rex/encoder/nonupper.rb +64 -0
- data/lib/rex/encoder/xdr.rb +106 -0
- data/lib/rex/encoder/xdr.rb.ut.rb +29 -0
- data/lib/rex/encoder/xor.rb +69 -0
- data/lib/rex/encoder/xor/dword.rb +13 -0
- data/lib/rex/encoder/xor/dword_additive.rb +13 -0
- data/lib/rex/encoders/xor_dword.rb +35 -0
- data/lib/rex/encoders/xor_dword_additive.rb +53 -0
- data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +12 -0
- data/lib/rex/encoding/xor.rb +20 -0
- data/lib/rex/encoding/xor.rb.ts.rb +14 -0
- data/lib/rex/encoding/xor/byte.rb +15 -0
- data/lib/rex/encoding/xor/byte.rb.ut.rb +21 -0
- data/lib/rex/encoding/xor/dword.rb +21 -0
- data/lib/rex/encoding/xor/dword.rb.ut.rb +15 -0
- data/lib/rex/encoding/xor/dword_additive.rb +92 -0
- data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +15 -0
- data/lib/rex/encoding/xor/exceptions.rb +17 -0
- data/lib/rex/encoding/xor/generic.rb +146 -0
- data/lib/rex/encoding/xor/generic.rb.ut.rb +120 -0
- data/lib/rex/encoding/xor/qword.rb +15 -0
- data/lib/rex/encoding/xor/word.rb +21 -0
- data/lib/rex/encoding/xor/word.rb.ut.rb +13 -0
- data/lib/rex/exceptions.rb +275 -0
- data/lib/rex/exceptions.rb.ut.rb +44 -0
- data/lib/rex/exploitation/cmdstager.rb +133 -0
- data/lib/rex/exploitation/egghunter.rb +143 -0
- data/lib/rex/exploitation/egghunter.rb.ut.rb +25 -0
- data/lib/rex/exploitation/encryptjs.rb +77 -0
- data/lib/rex/exploitation/heaplib.js.b64 +331 -0
- data/lib/rex/exploitation/heaplib.rb +94 -0
- data/lib/rex/exploitation/javascriptosdetect.rb +735 -0
- data/lib/rex/exploitation/obfuscatejs.rb +335 -0
- data/lib/rex/exploitation/opcodedb.rb +818 -0
- data/lib/rex/exploitation/opcodedb.rb.ut.rb +279 -0
- data/lib/rex/exploitation/seh.rb +92 -0
- data/lib/rex/exploitation/seh.rb.ut.rb +19 -0
- data/lib/rex/file.rb +84 -0
- data/lib/rex/file.rb.ut.rb +16 -0
- data/lib/rex/image_source.rb +12 -0
- data/lib/rex/image_source/disk.rb +60 -0
- data/lib/rex/image_source/image_source.rb +46 -0
- data/lib/rex/image_source/memory.rb +37 -0
- data/lib/rex/io/bidirectional_pipe.rb +157 -0
- data/lib/rex/io/datagram_abstraction.rb +35 -0
- data/lib/rex/io/stream.rb +313 -0
- data/lib/rex/io/stream_abstraction.rb +186 -0
- data/lib/rex/io/stream_server.rb +211 -0
- data/lib/rex/job_container.rb +202 -0
- data/lib/rex/logging.rb +4 -0
- data/lib/rex/logging/log_dispatcher.rb +179 -0
- data/lib/rex/logging/log_sink.rb +42 -0
- data/lib/rex/logging/sinks/flatfile.rb +55 -0
- data/lib/rex/logging/sinks/stderr.rb +43 -0
- data/lib/rex/machparsey.rb +9 -0
- data/lib/rex/machparsey/exceptions.rb +34 -0
- data/lib/rex/machparsey/mach.rb +209 -0
- data/lib/rex/machparsey/machbase.rb +408 -0
- data/lib/rex/machscan.rb +9 -0
- data/lib/rex/machscan/scanner.rb +217 -0
- data/lib/rex/mime.rb +9 -0
- data/lib/rex/mime/header.rb +75 -0
- data/lib/rex/mime/message.rb +112 -0
- data/lib/rex/mime/part.rb +20 -0
- data/lib/rex/nop/opty2.rb +108 -0
- data/lib/rex/nop/opty2.rb.ut.rb +23 -0
- data/lib/rex/nop/opty2_tables.rb +300 -0
- data/lib/rex/ole.rb +128 -0
- data/lib/rex/ole/clsid.rb +47 -0
- data/lib/rex/ole/difat.rb +141 -0
- data/lib/rex/ole/directory.rb +230 -0
- data/lib/rex/ole/direntry.rb +240 -0
- data/lib/rex/ole/fat.rb +99 -0
- data/lib/rex/ole/header.rb +204 -0
- data/lib/rex/ole/minifat.rb +77 -0
- data/lib/rex/ole/samples/create_ole.rb +27 -0
- data/lib/rex/ole/samples/dir.rb +35 -0
- data/lib/rex/ole/samples/dump_stream.rb +34 -0
- data/lib/rex/ole/samples/ole_info.rb +23 -0
- data/lib/rex/ole/storage.rb +395 -0
- data/lib/rex/ole/stream.rb +53 -0
- data/lib/rex/ole/substorage.rb +49 -0
- data/lib/rex/ole/util.rb +157 -0
- data/lib/rex/parser/arguments.rb +97 -0
- data/lib/rex/parser/arguments.rb.ut.rb +67 -0
- data/lib/rex/parser/ini.rb +185 -0
- data/lib/rex/parser/ini.rb.ut.rb +29 -0
- data/lib/rex/parser/nmap_xml.rb +111 -0
- data/lib/rex/payloads.rb +1 -0
- data/lib/rex/payloads/win32.rb +2 -0
- data/lib/rex/payloads/win32/common.rb +26 -0
- data/lib/rex/payloads/win32/kernel.rb +53 -0
- data/lib/rex/payloads/win32/kernel/common.rb +54 -0
- data/lib/rex/payloads/win32/kernel/migration.rb +12 -0
- data/lib/rex/payloads/win32/kernel/recovery.rb +50 -0
- data/lib/rex/payloads/win32/kernel/stager.rb +171 -0
- data/lib/rex/peparsey.rb +12 -0
- data/lib/rex/peparsey/exceptions.rb +32 -0
- data/lib/rex/peparsey/pe.rb +188 -0
- data/lib/rex/peparsey/pe_memdump.rb +63 -0
- data/lib/rex/peparsey/pebase.rb +1655 -0
- data/lib/rex/peparsey/section.rb +136 -0
- data/lib/rex/pescan.rb +13 -0
- data/lib/rex/pescan/analyze.rb +309 -0
- data/lib/rex/pescan/scanner.rb +206 -0
- data/lib/rex/pescan/search.rb +56 -0
- data/lib/rex/platforms.rb +1 -0
- data/lib/rex/platforms/windows.rb +51 -0
- data/lib/rex/poly.rb +132 -0
- data/lib/rex/poly/block.rb +468 -0
- data/lib/rex/poly/register.rb +100 -0
- data/lib/rex/poly/register/x86.rb +40 -0
- data/lib/rex/post.rb +8 -0
- data/lib/rex/post/dir.rb +51 -0
- data/lib/rex/post/file.rb +172 -0
- data/lib/rex/post/file_stat.rb +220 -0
- data/lib/rex/post/gen.pl +13 -0
- data/lib/rex/post/io.rb +182 -0
- data/lib/rex/post/meterpreter.rb +4 -0
- data/lib/rex/post/meterpreter/channel.rb +438 -0
- data/lib/rex/post/meterpreter/channel_container.rb +54 -0
- data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
- data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
- data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
- data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
- data/lib/rex/post/meterpreter/client.rb +335 -0
- data/lib/rex/post/meterpreter/client_core.rb +274 -0
- data/lib/rex/post/meterpreter/dependencies.rb +3 -0
- data/lib/rex/post/meterpreter/extension.rb +32 -0
- data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
- data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +16 -0
- data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
- data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +21 -0
- data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
- data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +104 -0
- data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +28 -0
- data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +100 -0
- data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +24 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +333 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +273 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +235 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +103 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +144 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +73 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +56 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +137 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +167 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +167 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +192 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +139 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +97 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +184 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +61 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +361 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +279 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +182 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +174 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +185 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +227 -0
- data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
- data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
- data/lib/rex/post/meterpreter/packet.rb +596 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +409 -0
- data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
- data/lib/rex/post/meterpreter/ui/console.rb +135 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +62 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +595 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +108 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +241 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +61 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +98 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +51 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +132 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +187 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +63 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +376 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +270 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +484 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +315 -0
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +95 -0
- data/lib/rex/post/permission.rb +26 -0
- data/lib/rex/post/process.rb +57 -0
- data/lib/rex/post/thread.rb +57 -0
- data/lib/rex/post/ui.rb +52 -0
- data/lib/rex/proto.rb +12 -0
- data/lib/rex/proto.rb.ts.rb +8 -0
- data/lib/rex/proto/dcerpc.rb +6 -0
- data/lib/rex/proto/dcerpc.rb.ts.rb +9 -0
- data/lib/rex/proto/dcerpc/client.rb +358 -0
- data/lib/rex/proto/dcerpc/client.rb.ut.rb +491 -0
- data/lib/rex/proto/dcerpc/exceptions.rb +150 -0
- data/lib/rex/proto/dcerpc/handle.rb +47 -0
- data/lib/rex/proto/dcerpc/handle.rb.ut.rb +85 -0
- data/lib/rex/proto/dcerpc/ndr.rb +72 -0
- data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +41 -0
- data/lib/rex/proto/dcerpc/packet.rb +253 -0
- data/lib/rex/proto/dcerpc/packet.rb.ut.rb +56 -0
- data/lib/rex/proto/dcerpc/response.rb +186 -0
- data/lib/rex/proto/dcerpc/response.rb.ut.rb +15 -0
- data/lib/rex/proto/dcerpc/uuid.rb +84 -0
- data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +46 -0
- data/lib/rex/proto/drda.rb +5 -0
- data/lib/rex/proto/drda.rb.ts.rb +17 -0
- data/lib/rex/proto/drda/constants.rb +49 -0
- data/lib/rex/proto/drda/constants.rb.ut.rb +23 -0
- data/lib/rex/proto/drda/packet.rb +252 -0
- data/lib/rex/proto/drda/packet.rb.ut.rb +109 -0
- data/lib/rex/proto/drda/utils.rb +123 -0
- data/lib/rex/proto/drda/utils.rb.ut.rb +84 -0
- data/lib/rex/proto/http.rb +5 -0
- data/lib/rex/proto/http.rb.ts.rb +12 -0
- data/lib/rex/proto/http/client.rb +817 -0
- data/lib/rex/proto/http/client.rb.ut.rb +93 -0
- data/lib/rex/proto/http/handler.rb +46 -0
- data/lib/rex/proto/http/handler/erb.rb +128 -0
- data/lib/rex/proto/http/handler/erb.rb.ut.rb +21 -0
- data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +1 -0
- data/lib/rex/proto/http/handler/proc.rb +54 -0
- data/lib/rex/proto/http/handler/proc.rb.ut.rb +24 -0
- data/lib/rex/proto/http/header.rb +161 -0
- data/lib/rex/proto/http/header.rb.ut.rb +46 -0
- data/lib/rex/proto/http/packet.rb +394 -0
- data/lib/rex/proto/http/packet.rb.ut.rb +165 -0
- data/lib/rex/proto/http/request.rb +356 -0
- data/lib/rex/proto/http/request.rb.ut.rb +214 -0
- data/lib/rex/proto/http/response.rb +85 -0
- data/lib/rex/proto/http/response.rb.ut.rb +149 -0
- data/lib/rex/proto/http/server.rb +367 -0
- data/lib/rex/proto/http/server.rb.ut.rb +79 -0
- data/lib/rex/proto/smb.rb +7 -0
- data/lib/rex/proto/smb.rb.ts.rb +8 -0
- data/lib/rex/proto/smb/client.rb +1733 -0
- data/lib/rex/proto/smb/client.rb.ut.rb +223 -0
- data/lib/rex/proto/smb/constants.rb +1062 -0
- data/lib/rex/proto/smb/constants.rb.ut.rb +18 -0
- data/lib/rex/proto/smb/crypt.rb +95 -0
- data/lib/rex/proto/smb/crypt.rb.ut.rb +20 -0
- data/lib/rex/proto/smb/evasions.rb +65 -0
- data/lib/rex/proto/smb/exceptions.rb +846 -0
- data/lib/rex/proto/smb/simpleclient.rb +292 -0
- data/lib/rex/proto/smb/simpleclient.rb.ut.rb +128 -0
- data/lib/rex/proto/smb/utils.rb +514 -0
- data/lib/rex/proto/smb/utils.rb.ut.rb +20 -0
- data/lib/rex/proto/sunrpc.rb +1 -0
- data/lib/rex/proto/sunrpc/client.rb +195 -0
- data/lib/rex/script.rb +42 -0
- data/lib/rex/script/base.rb +59 -0
- data/lib/rex/script/meterpreter.rb +9 -0
- data/lib/rex/script/shell.rb +9 -0
- data/lib/rex/service.rb +48 -0
- data/lib/rex/service_manager.rb +141 -0
- data/lib/rex/service_manager.rb.ut.rb +32 -0
- data/lib/rex/services/local_relay.rb +423 -0
- data/lib/rex/socket.rb +586 -0
- data/lib/rex/socket.rb.ut.rb +86 -0
- data/lib/rex/socket/comm.rb +119 -0
- data/lib/rex/socket/comm/local.rb +409 -0
- data/lib/rex/socket/comm/local.rb.ut.rb +75 -0
- data/lib/rex/socket/ip.rb +129 -0
- data/lib/rex/socket/parameters.rb +345 -0
- data/lib/rex/socket/parameters.rb.ut.rb +51 -0
- data/lib/rex/socket/range_walker.rb +295 -0
- data/lib/rex/socket/range_walker.rb.ut.rb +55 -0
- data/lib/rex/socket/ssl_tcp.rb +184 -0
- data/lib/rex/socket/ssl_tcp.rb.ut.rb +39 -0
- data/lib/rex/socket/ssl_tcp_server.rb +122 -0
- data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +51 -0
- data/lib/rex/socket/subnet_walker.rb +75 -0
- data/lib/rex/socket/subnet_walker.rb.ut.rb +28 -0
- data/lib/rex/socket/switch_board.rb +272 -0
- data/lib/rex/socket/switch_board.rb.ut.rb +52 -0
- data/lib/rex/socket/tcp.rb +76 -0
- data/lib/rex/socket/tcp.rb.ut.rb +64 -0
- data/lib/rex/socket/tcp_server.rb +67 -0
- data/lib/rex/socket/tcp_server.rb.ut.rb +44 -0
- data/lib/rex/socket/udp.rb +157 -0
- data/lib/rex/socket/udp.rb.ut.rb +44 -0
- data/lib/rex/struct2.rb +5 -0
- data/lib/rex/struct2/c_struct.rb +181 -0
- data/lib/rex/struct2/c_struct_template.rb +39 -0
- data/lib/rex/struct2/constant.rb +26 -0
- data/lib/rex/struct2/element.rb +44 -0
- data/lib/rex/struct2/generic.rb +73 -0
- data/lib/rex/struct2/restraint.rb +54 -0
- data/lib/rex/struct2/s_string.rb +72 -0
- data/lib/rex/struct2/s_struct.rb +111 -0
- data/lib/rex/sync.rb +6 -0
- data/lib/rex/sync/event.rb +94 -0
- data/lib/rex/sync/read_write_lock.rb +176 -0
- data/lib/rex/sync/ref.rb +57 -0
- data/lib/rex/sync/thread_safe.rb +82 -0
- data/lib/rex/test.rb +35 -0
- data/lib/rex/text.rb +1029 -0
- data/lib/rex/text.rb.ut.rb +168 -0
- data/lib/rex/time.rb +65 -0
- data/lib/rex/transformer.rb +115 -0
- data/lib/rex/transformer.rb.ut.rb +38 -0
- data/lib/rex/ui.rb +21 -0
- data/lib/rex/ui/interactive.rb +252 -0
- data/lib/rex/ui/output.rb +80 -0
- data/lib/rex/ui/output/none.rb +18 -0
- data/lib/rex/ui/progress_tracker.rb +96 -0
- data/lib/rex/ui/subscriber.rb +149 -0
- data/lib/rex/ui/text/color.rb +97 -0
- data/lib/rex/ui/text/color.rb.ut.rb +18 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +382 -0
- data/lib/rex/ui/text/input.rb +117 -0
- data/lib/rex/ui/text/input/buffer.rb +75 -0
- data/lib/rex/ui/text/input/readline.rb +129 -0
- data/lib/rex/ui/text/input/socket.rb +95 -0
- data/lib/rex/ui/text/input/stdio.rb +45 -0
- data/lib/rex/ui/text/irb_shell.rb +55 -0
- data/lib/rex/ui/text/output.rb +80 -0
- data/lib/rex/ui/text/output/buffer.rb +65 -0
- data/lib/rex/ui/text/output/file.rb +37 -0
- data/lib/rex/ui/text/output/socket.rb +43 -0
- data/lib/rex/ui/text/output/stdio.rb +40 -0
- data/lib/rex/ui/text/progress_tracker.rb +56 -0
- data/lib/rex/ui/text/progress_tracker.rb.ut.rb +34 -0
- data/lib/rex/ui/text/shell.rb +321 -0
- data/lib/rex/ui/text/table.rb +254 -0
- data/lib/rex/ui/text/table.rb.ut.rb +55 -0
- data/lib/rex/zip.rb +93 -0
- data/lib/rex/zip/archive.rb +91 -0
- data/lib/rex/zip/blocks.rb +182 -0
- data/lib/rex/zip/entry.rb +95 -0
- data/lib/rex/zip/samples/comment.rb +32 -0
- data/lib/rex/zip/samples/mkwar.rb +138 -0
- data/lib/rex/zip/samples/mkzip.rb +19 -0
- data/lib/rex/zip/samples/recursive.rb +58 -0
- metadata +435 -0
data/lib/rex/sync/ref.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'thread'
|
|
2
|
+
|
|
3
|
+
module Rex
|
|
4
|
+
|
|
5
|
+
###
|
|
6
|
+
#
|
|
7
|
+
# This module provides a uniform reference counted interface for classes to
|
|
8
|
+
# use.
|
|
9
|
+
#
|
|
10
|
+
###
|
|
11
|
+
module Ref
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# Initializes the reference count to one.
|
|
15
|
+
#
|
|
16
|
+
def refinit
|
|
17
|
+
@_references = 1
|
|
18
|
+
@_references_mutex = Mutex.new
|
|
19
|
+
|
|
20
|
+
self
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Increments the total number of references.
|
|
25
|
+
#
|
|
26
|
+
def ref
|
|
27
|
+
@_references_mutex.synchronize {
|
|
28
|
+
@_references += 1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Decrements the total number of references. If the reference count
|
|
36
|
+
# reaches zero, true is returned. Otherwise, false is returned.
|
|
37
|
+
#
|
|
38
|
+
def deref
|
|
39
|
+
@_references_mutex.synchronize {
|
|
40
|
+
if ((@_references -= 1) == 0)
|
|
41
|
+
cleanup
|
|
42
|
+
|
|
43
|
+
true
|
|
44
|
+
else
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# Called to clean up resources once the ref count drops to zero.
|
|
52
|
+
#
|
|
53
|
+
def cleanup
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'timeout'
|
|
2
|
+
|
|
3
|
+
module Rex
|
|
4
|
+
|
|
5
|
+
###
|
|
6
|
+
#
|
|
7
|
+
# This module provides a set of methods for performing various blocking
|
|
8
|
+
# operations in a manner that is compatible with ruby style threads.
|
|
9
|
+
#
|
|
10
|
+
###
|
|
11
|
+
module ThreadSafe
|
|
12
|
+
|
|
13
|
+
DefaultCycle = 0.2
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Wraps calls to select with a lower timeout period and does the
|
|
17
|
+
# calculations to walk down to zero timeout. This has a little room for
|
|
18
|
+
# improvement in that it should probably check how much time actually
|
|
19
|
+
# elapsed during the select call considering ruby threading wont be exactly
|
|
20
|
+
# accurate perhaps.
|
|
21
|
+
#
|
|
22
|
+
def self.select(rfd = nil, wfd = nil, efd = nil, t = nil)
|
|
23
|
+
left = t
|
|
24
|
+
|
|
25
|
+
# Immediately raise a StreamClosedError if the socket was closed. This
|
|
26
|
+
# prevents a bad fd from being passed downstream and solves an issue
|
|
27
|
+
# with Ruby on Windows.
|
|
28
|
+
rfd.each { |fd| raise StreamClosedError.new(fd) if (fd.closed?) } if rfd
|
|
29
|
+
|
|
30
|
+
begin
|
|
31
|
+
orig_size = rfd.length if (rfd)
|
|
32
|
+
|
|
33
|
+
# Poll the set supplied to us at least once.
|
|
34
|
+
begin
|
|
35
|
+
rv = ::IO.select(rfd, wfd, efd, DefaultCycle)
|
|
36
|
+
rescue ::IOError, ::Errno::EBADF, ::Errno::ENOTSOCK
|
|
37
|
+
# If a stream was detected as being closed, re-raise the error as
|
|
38
|
+
# a StreamClosedError with the specific file descriptor that was
|
|
39
|
+
# detected as being closed. This is to better handle the case of
|
|
40
|
+
# a closed socket being detected so that it can be cleaned up and
|
|
41
|
+
# removed.
|
|
42
|
+
rfd.each { |fd| raise StreamClosedError.new(fd) if (fd.closed?) } if rfd
|
|
43
|
+
|
|
44
|
+
# If the original rfd length is not the same as the current
|
|
45
|
+
# length, then the list may have been altered and as such may not
|
|
46
|
+
# contain the socket that caused the IOError. This is a bad way
|
|
47
|
+
# to do this since it's possible that the array length could be
|
|
48
|
+
# back to the size that it was originally and yet have had the
|
|
49
|
+
# socket that caused the IOError to be removed.
|
|
50
|
+
return nil if (rfd and rfd.length != orig_size)
|
|
51
|
+
|
|
52
|
+
# Re-raise the exception since we didn't handle it here.
|
|
53
|
+
raise $!
|
|
54
|
+
# rescue ::Exception => e
|
|
55
|
+
# $stderr.puts "SELECT(#{t}) #{[rfd,wfd,efd].inspect} #{e.class} #{e} #{e.backtrace}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
return rv if (rv)
|
|
59
|
+
|
|
60
|
+
# Decrement the amount of time left by the polling cycle
|
|
61
|
+
left -= DefaultCycle if (left)
|
|
62
|
+
|
|
63
|
+
# Keep chugging until we run out of time, if time was supplied.
|
|
64
|
+
end while ((left == nil) or (left > 0))
|
|
65
|
+
|
|
66
|
+
# Nothin.
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Simulates a sleep operation by selecting on nil until a timeout period
|
|
72
|
+
# expires.
|
|
73
|
+
#
|
|
74
|
+
def self.sleep(seconds)
|
|
75
|
+
self.select(nil, nil, nil, seconds)
|
|
76
|
+
|
|
77
|
+
seconds
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
data/lib/rex/test.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
|
|
3
|
+
# DEFAULTS
|
|
4
|
+
module Rex
|
|
5
|
+
class Test
|
|
6
|
+
|
|
7
|
+
$_REX_TEST_NO_MOCK = nil
|
|
8
|
+
$_REX_TEST_TIMEOUT = 30
|
|
9
|
+
$_REX_TEST_SMB_HOST = '10.4.10.58'
|
|
10
|
+
$_REX_TEXT_SMB_USER = 'SMBTest'
|
|
11
|
+
$_REX_TEXT_SMB_PASS = 'SMBTest'
|
|
12
|
+
|
|
13
|
+
# overwrite test defaults with rex/test-config.rb
|
|
14
|
+
def self.load()
|
|
15
|
+
file = File.join( ENV.fetch('HOME'), '.msf3', 'test')
|
|
16
|
+
begin
|
|
17
|
+
if File.stat(file + '.rb')
|
|
18
|
+
require file
|
|
19
|
+
end
|
|
20
|
+
rescue
|
|
21
|
+
# just ignore the errors
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.cantmock()
|
|
27
|
+
if (!$_REX_TEST_NO_MOCK)
|
|
28
|
+
raise RuntimeError, "*** $_REX_TEST_NO_MOCK must not be set for this test ***", caller
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Rex::Test.load()
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/rex/text.rb
ADDED
|
@@ -0,0 +1,1029 @@
|
|
|
1
|
+
require 'digest/md5'
|
|
2
|
+
require 'stringio'
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'iconv'
|
|
6
|
+
require 'zlib'
|
|
7
|
+
rescue LoadError
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module Rex
|
|
11
|
+
|
|
12
|
+
###
|
|
13
|
+
#
|
|
14
|
+
# This class formats text in various fashions and also provides
|
|
15
|
+
# a mechanism for wrapping text at a given column.
|
|
16
|
+
#
|
|
17
|
+
###
|
|
18
|
+
module Text
|
|
19
|
+
@@codepage_map_cache = nil
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
#
|
|
23
|
+
# Constants
|
|
24
|
+
#
|
|
25
|
+
##
|
|
26
|
+
|
|
27
|
+
States = ["AK", "AL", "AR", "AZ", "CA", "CO", "CT", "DE", "FL", "GA", "HI",
|
|
28
|
+
"IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN",
|
|
29
|
+
"MO", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH",
|
|
30
|
+
"OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VT", "WA",
|
|
31
|
+
"WI", "WV", "WY"]
|
|
32
|
+
UpperAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
33
|
+
LowerAlpha = "abcdefghijklmnopqrstuvwxyz"
|
|
34
|
+
Numerals = "0123456789"
|
|
35
|
+
Alpha = UpperAlpha + LowerAlpha
|
|
36
|
+
AlphaNumeric = Alpha + Numerals
|
|
37
|
+
HighAscii = [*(0x80 .. 0xff)].pack("C*")
|
|
38
|
+
DefaultWrap = 60
|
|
39
|
+
AllChars = [*(0x00 .. 0xff)].pack("C*")
|
|
40
|
+
|
|
41
|
+
DefaultPatternSets = [ Rex::Text::UpperAlpha, Rex::Text::LowerAlpha, Rex::Text::Numerals ]
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
#
|
|
45
|
+
# Serialization
|
|
46
|
+
#
|
|
47
|
+
##
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Converts a raw string into a ruby buffer
|
|
51
|
+
#
|
|
52
|
+
def self.to_ruby(str, wrap = DefaultWrap, name = "buf")
|
|
53
|
+
return hexify(str, wrap, '"', '" +', "#{name} = \n", '"')
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#
|
|
57
|
+
# Creates a ruby-style comment
|
|
58
|
+
#
|
|
59
|
+
def self.to_ruby_comment(str, wrap = DefaultWrap)
|
|
60
|
+
return wordwrap(str, 0, wrap, '', '# ')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#
|
|
64
|
+
# Converts a raw string into a C buffer
|
|
65
|
+
#
|
|
66
|
+
def self.to_c(str, wrap = DefaultWrap, name = "buf")
|
|
67
|
+
return hexify(str, wrap, '"', '"', "unsigned char #{name}[] = \n", '";')
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Creates a c-style comment
|
|
72
|
+
#
|
|
73
|
+
def self.to_c_comment(str, wrap = DefaultWrap)
|
|
74
|
+
return "/*\n" + wordwrap(str, 0, wrap, '', ' * ') + " */\n"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Creates a javascript-style comment
|
|
79
|
+
#
|
|
80
|
+
def self.to_js_comment(str, wrap = DefaultWrap)
|
|
81
|
+
return wordwrap(str, 0, wrap, '', '// ')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Converts a raw string into a perl buffer
|
|
86
|
+
#
|
|
87
|
+
def self.to_perl(str, wrap = DefaultWrap, name = "buf")
|
|
88
|
+
return hexify(str, wrap, '"', '" .', "my $#{name} = \n", '";')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
#
|
|
92
|
+
# Converts a raw string into a java byte array
|
|
93
|
+
#
|
|
94
|
+
def self.to_java(str, name = "shell")
|
|
95
|
+
buff = "byte #{name}[] = new byte[]\n{\n"
|
|
96
|
+
cnt = 0
|
|
97
|
+
max = 0
|
|
98
|
+
str.unpack('C*').each do |c|
|
|
99
|
+
buff << ", " if max > 0
|
|
100
|
+
buff << "\t" if max == 0
|
|
101
|
+
buff << sprintf('(byte) 0x%.2x', c)
|
|
102
|
+
max +=1
|
|
103
|
+
cnt +=1
|
|
104
|
+
|
|
105
|
+
if (max > 7)
|
|
106
|
+
buff << ",\n" if cnt != str.length
|
|
107
|
+
max = 0
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
buff << "\n};\n"
|
|
111
|
+
return buff
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
#
|
|
115
|
+
# Creates a perl-style comment
|
|
116
|
+
#
|
|
117
|
+
def self.to_perl_comment(str, wrap = DefaultWrap)
|
|
118
|
+
return wordwrap(str, 0, wrap, '', '# ')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
#
|
|
122
|
+
# Returns the raw string
|
|
123
|
+
#
|
|
124
|
+
def self.to_raw(str)
|
|
125
|
+
return str
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
#
|
|
129
|
+
# Converts ISO-8859-1 to UTF-8
|
|
130
|
+
#
|
|
131
|
+
def self.to_utf8(str)
|
|
132
|
+
begin
|
|
133
|
+
Iconv.iconv("utf-8","iso-8859-1", str).join(" ")
|
|
134
|
+
rescue
|
|
135
|
+
raise ::RuntimeError, "Your installation does not support iconv (needed for utf8 conversion)"
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
#
|
|
140
|
+
# Converts ASCII to EBCDIC
|
|
141
|
+
#
|
|
142
|
+
def self.to_ebcdic(str)
|
|
143
|
+
begin
|
|
144
|
+
Iconv.iconv("EBCDIC-US", "ASCII", str).first
|
|
145
|
+
rescue ::Iconv::IllegalSequence => e
|
|
146
|
+
raise e
|
|
147
|
+
rescue
|
|
148
|
+
raise ::RuntimeError, "Your installation does not support iconv (needed for EBCDIC conversion)"
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
#
|
|
153
|
+
# Converts EBCIDC to ASCII
|
|
154
|
+
#
|
|
155
|
+
def self.from_ebcdic(str)
|
|
156
|
+
begin
|
|
157
|
+
Iconv.iconv("ASCII", "EBCDIC-US", str).first
|
|
158
|
+
rescue ::Iconv::IllegalSequence => e
|
|
159
|
+
raise e
|
|
160
|
+
rescue
|
|
161
|
+
raise ::RuntimeError, "Your installation does not support iconv (needed for EBCDIC conversion)"
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#
|
|
166
|
+
# Returns a unicode escaped string for Javascript
|
|
167
|
+
#
|
|
168
|
+
def self.to_unescape(data, endian=ENDIAN_LITTLE)
|
|
169
|
+
data << "\x41" if (data.length % 2 != 0)
|
|
170
|
+
dptr = 0
|
|
171
|
+
buff = ''
|
|
172
|
+
while (dptr < data.length)
|
|
173
|
+
c1 = data[dptr,1].unpack("C*")[0]
|
|
174
|
+
dptr += 1
|
|
175
|
+
c2 = data[dptr,1].unpack("C*")[0]
|
|
176
|
+
dptr += 1
|
|
177
|
+
|
|
178
|
+
if (endian == ENDIAN_LITTLE)
|
|
179
|
+
buff << sprintf('%%u%.2x%.2x', c2, c1)
|
|
180
|
+
else
|
|
181
|
+
buff << sprintf('%%u%.2x%.2x', c1, c2)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
return buff
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
#
|
|
188
|
+
# Returns the hex version of the supplied string
|
|
189
|
+
#
|
|
190
|
+
def self.to_hex(str, prefix = "\\x", count = 1)
|
|
191
|
+
raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)
|
|
192
|
+
|
|
193
|
+
# XXX: Regexp.new is used here since using /.{#{count}}/o would compile
|
|
194
|
+
# the regex the first time it is used and never check again. Since we
|
|
195
|
+
# want to know how many to capture on every instance, we do it this
|
|
196
|
+
# way.
|
|
197
|
+
return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s| prefix + s }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
#
|
|
201
|
+
# Converts standard ASCII text to a unicode string.
|
|
202
|
+
#
|
|
203
|
+
# Supported unicode types include: utf-16le, utf16-be, utf32-le, utf32-be, utf-7, and utf-8
|
|
204
|
+
#
|
|
205
|
+
# Providing 'mode' provides hints to the actual encoder as to how it should encode the string. Only UTF-7 and UTF-8 use "mode".
|
|
206
|
+
#
|
|
207
|
+
# utf-7 by default does not encode alphanumeric and a few other characters. By specifying the mode of "all", then all of the characters are encoded, not just the non-alphanumeric set.
|
|
208
|
+
# to_unicode(str, 'utf-7', 'all')
|
|
209
|
+
#
|
|
210
|
+
# utf-8 specifies that alphanumeric characters are used directly, eg "a" is just "a". However, there exist 6 different overlong encodings of "a" that are technically not valid, but parse just fine in most utf-8 parsers. (0xC1A1, 0xE081A1, 0xF08081A1, 0xF8808081A1, 0xFC80808081A1, 0xFE8080808081A1). How many bytes to use for the overlong enocding is specified providing 'size'.
|
|
211
|
+
# to_unicode(str, 'utf-8', 'overlong', 2)
|
|
212
|
+
#
|
|
213
|
+
# Many utf-8 parsers also allow invalid overlong encodings, where bits that are unused when encoding a single byte are modified. Many parsers will ignore these bits, rendering simple string matching to be ineffective for dealing with UTF-8 strings. There are many more invalid overlong encodings possible for "a". For example, three encodings are available for an invalid 2 byte encoding of "a". (0xC1E1 0xC161 0xC121). By specifying "invalid", a random invalid encoding is chosen for the given byte size.
|
|
214
|
+
# to_unicode(str, 'utf-8', 'invalid', 2)
|
|
215
|
+
#
|
|
216
|
+
# utf-7 defaults to 'normal' utf-7 encoding
|
|
217
|
+
# utf-8 defaults to 2 byte 'normal' encoding
|
|
218
|
+
#
|
|
219
|
+
def self.to_unicode(str='', type = 'utf-16le', mode = '', size = '')
|
|
220
|
+
return '' if not str
|
|
221
|
+
case type
|
|
222
|
+
when 'utf-16le'
|
|
223
|
+
return str.unpack('C*').pack('v*')
|
|
224
|
+
when 'utf-16be'
|
|
225
|
+
return str.unpack('C*').pack('n*')
|
|
226
|
+
when 'utf-32le'
|
|
227
|
+
return str.unpack('C*').pack('V*')
|
|
228
|
+
when 'utf-32be'
|
|
229
|
+
return str.unpack('C*').pack('N*')
|
|
230
|
+
when 'utf-7'
|
|
231
|
+
case mode
|
|
232
|
+
when 'all'
|
|
233
|
+
return str.gsub(/./){ |a|
|
|
234
|
+
out = ''
|
|
235
|
+
if 'a' != '+'
|
|
236
|
+
out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '')
|
|
237
|
+
end
|
|
238
|
+
'+' + out + '-'
|
|
239
|
+
}
|
|
240
|
+
else
|
|
241
|
+
return str.gsub(/[^\n\r\t\ A-Za-z0-9\'\(\),-.\/\:\?]/){ |a|
|
|
242
|
+
out = ''
|
|
243
|
+
if a != '+'
|
|
244
|
+
out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '')
|
|
245
|
+
end
|
|
246
|
+
'+' + out + '-'
|
|
247
|
+
}
|
|
248
|
+
end
|
|
249
|
+
when 'utf-8'
|
|
250
|
+
if size == ''
|
|
251
|
+
size = 2
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
if size >= 2 and size <= 7
|
|
255
|
+
string = ''
|
|
256
|
+
str.each_byte { |a|
|
|
257
|
+
if (a < 21 || a > 0x7f) || mode != ''
|
|
258
|
+
# ugh. turn a single byte into the binary representation of it, in array form
|
|
259
|
+
bin = [a].pack('C').unpack('B8')[0].split(//)
|
|
260
|
+
|
|
261
|
+
# even more ugh.
|
|
262
|
+
bin.collect!{|a_| a_.to_i}
|
|
263
|
+
|
|
264
|
+
out = Array.new(8 * size, 0)
|
|
265
|
+
|
|
266
|
+
0.upto(size - 1) { |i|
|
|
267
|
+
out[i] = 1
|
|
268
|
+
out[i * 8] = 1
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
i = 0
|
|
272
|
+
byte = 0
|
|
273
|
+
bin.reverse.each { |bit|
|
|
274
|
+
if i < 6
|
|
275
|
+
mod = (((size * 8) - 1) - byte * 8) - i
|
|
276
|
+
out[mod] = bit
|
|
277
|
+
else
|
|
278
|
+
byte = byte + 1
|
|
279
|
+
i = 0
|
|
280
|
+
redo
|
|
281
|
+
end
|
|
282
|
+
i = i + 1
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if mode != ''
|
|
286
|
+
case mode
|
|
287
|
+
when 'overlong'
|
|
288
|
+
# do nothing, since we already handle this as above...
|
|
289
|
+
when 'invalid'
|
|
290
|
+
done = 0
|
|
291
|
+
while done == 0
|
|
292
|
+
# the ghetto...
|
|
293
|
+
bits = [7, 8, 15, 16, 23, 24, 31, 32, 41]
|
|
294
|
+
bits.each { |bit|
|
|
295
|
+
bit = (size * 8) - bit
|
|
296
|
+
if bit > 1
|
|
297
|
+
set = rand(2)
|
|
298
|
+
if out[bit] != set
|
|
299
|
+
out[bit] = set
|
|
300
|
+
done = 1
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
}
|
|
304
|
+
end
|
|
305
|
+
else
|
|
306
|
+
raise TypeError, 'Invalid mode. Only "overlong" and "invalid" are acceptable modes for utf-8'
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
string << [out.join('')].pack('B*')
|
|
310
|
+
else
|
|
311
|
+
string << [a].pack('C')
|
|
312
|
+
end
|
|
313
|
+
}
|
|
314
|
+
return string
|
|
315
|
+
else
|
|
316
|
+
raise TypeError, 'invalid utf-8 size'
|
|
317
|
+
end
|
|
318
|
+
when 'uhwtfms' # suggested name from HD :P
|
|
319
|
+
load_codepage()
|
|
320
|
+
|
|
321
|
+
string = ''
|
|
322
|
+
# overloading mode as codepage
|
|
323
|
+
if mode == ''
|
|
324
|
+
mode = 1252 # ANSI - Latan 1, default for US installs of MS products
|
|
325
|
+
else
|
|
326
|
+
mode = mode.to_i
|
|
327
|
+
end
|
|
328
|
+
if @@codepage_map_cache[mode].nil?
|
|
329
|
+
raise TypeError, "Invalid codepage #{mode}"
|
|
330
|
+
end
|
|
331
|
+
str.each_byte {|byte|
|
|
332
|
+
char = [byte].pack('C*')
|
|
333
|
+
possible = @@codepage_map_cache[mode]['data'][char]
|
|
334
|
+
if possible.nil?
|
|
335
|
+
raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}"
|
|
336
|
+
end
|
|
337
|
+
string << possible[ rand(possible.length) ]
|
|
338
|
+
}
|
|
339
|
+
return string
|
|
340
|
+
when 'uhwtfms-half' # suggested name from HD :P
|
|
341
|
+
load_codepage()
|
|
342
|
+
string = ''
|
|
343
|
+
# overloading mode as codepage
|
|
344
|
+
if mode == ''
|
|
345
|
+
mode = 1252 # ANSI - Latan 1, default for US installs of MS products
|
|
346
|
+
else
|
|
347
|
+
mode = mode.to_i
|
|
348
|
+
end
|
|
349
|
+
if mode != 1252
|
|
350
|
+
raise TypeError, "Invalid codepage #{mode}, only 1252 supported for uhwtfms_half"
|
|
351
|
+
end
|
|
352
|
+
str.each_byte {|byte|
|
|
353
|
+
if ((byte >= 33 && byte <= 63) || (byte >= 96 && byte <= 126))
|
|
354
|
+
string << "\xFF" + [byte ^ 32].pack('C')
|
|
355
|
+
elsif (byte >= 64 && byte <= 95)
|
|
356
|
+
string << "\xFF" + [byte ^ 96].pack('C')
|
|
357
|
+
else
|
|
358
|
+
char = [byte].pack('C')
|
|
359
|
+
possible = @@codepage_map_cache[mode]['data'][char]
|
|
360
|
+
if possible.nil?
|
|
361
|
+
raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}"
|
|
362
|
+
end
|
|
363
|
+
string << possible[ rand(possible.length) ]
|
|
364
|
+
end
|
|
365
|
+
}
|
|
366
|
+
return string
|
|
367
|
+
else
|
|
368
|
+
raise TypeError, 'invalid utf type'
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
#
|
|
373
|
+
# Encode a string in a manor useful for HTTP URIs and URI Parameters.
|
|
374
|
+
#
|
|
375
|
+
def self.uri_encode(str, mode = 'hex-normal')
|
|
376
|
+
return "" if str == nil
|
|
377
|
+
|
|
378
|
+
return str if mode == 'none' # fast track no encoding
|
|
379
|
+
|
|
380
|
+
all = /[^\/\\]+/
|
|
381
|
+
normal = /[^a-zA-Z0-9\/\\\.\-]+/
|
|
382
|
+
normal_na = /[a-zA-Z0-9\/\\\.\-]/
|
|
383
|
+
|
|
384
|
+
case mode
|
|
385
|
+
when 'hex-normal'
|
|
386
|
+
return str.gsub(normal) { |s| Rex::Text.to_hex(s, '%') }
|
|
387
|
+
when 'hex-all'
|
|
388
|
+
return str.gsub(all) { |s| Rex::Text.to_hex(s, '%') }
|
|
389
|
+
when 'hex-random'
|
|
390
|
+
res = ''
|
|
391
|
+
str.each_byte do |c|
|
|
392
|
+
b = c.chr
|
|
393
|
+
res << ((rand(2) == 0) ?
|
|
394
|
+
b.gsub(all) { |s| Rex::Text.to_hex(s, '%') } :
|
|
395
|
+
b.gsub(normal){ |s| Rex::Text.to_hex(s, '%') } )
|
|
396
|
+
end
|
|
397
|
+
return res
|
|
398
|
+
when 'u-normal'
|
|
399
|
+
return str.gsub(normal) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
|
|
400
|
+
when 'u-all'
|
|
401
|
+
return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
|
|
402
|
+
when 'u-random'
|
|
403
|
+
res = ''
|
|
404
|
+
str.each_byte do |c|
|
|
405
|
+
b = c.chr
|
|
406
|
+
res << ((rand(2) == 0) ?
|
|
407
|
+
b.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) } :
|
|
408
|
+
b.gsub(normal){ |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) } )
|
|
409
|
+
end
|
|
410
|
+
return res
|
|
411
|
+
when 'u-half'
|
|
412
|
+
return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms-half'), '%u', 2) }
|
|
413
|
+
else
|
|
414
|
+
raise TypeError, 'invalid mode'
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
#
|
|
419
|
+
# Encode a string in a manner useful for HTTP URIs and URI Parameters.
|
|
420
|
+
#
|
|
421
|
+
def self.html_encode(str, mode = 'hex')
|
|
422
|
+
case mode
|
|
423
|
+
when 'hex'
|
|
424
|
+
return str.unpack('C*').collect{ |i| "&#x" + ("%.2x" % i) + ";"}.join
|
|
425
|
+
when 'int'
|
|
426
|
+
return str.unpack('C*').collect{ |i| "&#" + i.to_s + ";"}.join
|
|
427
|
+
when 'int-wide'
|
|
428
|
+
return str.unpack('C*').collect{ |i| "&#" + ("0" * (7 - i.to_s.length)) + i.to_s + ";" }.join
|
|
429
|
+
else
|
|
430
|
+
raise TypeError, 'invalid mode'
|
|
431
|
+
end
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
#
|
|
435
|
+
# Decode a URI encoded string
|
|
436
|
+
#
|
|
437
|
+
def self.uri_decode(str)
|
|
438
|
+
str.gsub(/(%[a-z0-9]{2})/i){ |c| [c[1,2]].pack("H*") }
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
#
|
|
442
|
+
# Converts a string to random case
|
|
443
|
+
#
|
|
444
|
+
def self.to_rand_case(str)
|
|
445
|
+
buf = str.dup
|
|
446
|
+
0.upto(str.length) do |i|
|
|
447
|
+
buf[i,1] = rand(2) == 0 ? str[i,1].upcase : str[i,1].downcase
|
|
448
|
+
end
|
|
449
|
+
return buf
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
#
|
|
453
|
+
# Takes a string, and returns an array of all mixed case versions.
|
|
454
|
+
#
|
|
455
|
+
# Example:
|
|
456
|
+
#
|
|
457
|
+
# >> Rex::Text.to_mixed_case_array "abc1"
|
|
458
|
+
# => ["abc1", "abC1", "aBc1", "aBC1", "Abc1", "AbC1", "ABc1", "ABC1"]
|
|
459
|
+
#
|
|
460
|
+
def self.to_mixed_case_array(str)
|
|
461
|
+
letters = []
|
|
462
|
+
str.scan(/./).each { |l| letters << [l.downcase, l.upcase] }
|
|
463
|
+
coords = []
|
|
464
|
+
(1 << str.size).times { |i| coords << ("%0#{str.size}b" % i) }
|
|
465
|
+
mixed = []
|
|
466
|
+
coords.each do |coord|
|
|
467
|
+
c = coord.scan(/./).map {|x| x.to_i}
|
|
468
|
+
this_str = ""
|
|
469
|
+
c.each_with_index { |d,i| this_str << letters[i][d] }
|
|
470
|
+
mixed << this_str
|
|
471
|
+
end
|
|
472
|
+
return mixed.uniq
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
#
|
|
476
|
+
# Converts a string a nicely formatted hex dump
|
|
477
|
+
#
|
|
478
|
+
def self.to_hex_dump(str, width=16)
|
|
479
|
+
buf = ''
|
|
480
|
+
idx = 0
|
|
481
|
+
cnt = 0
|
|
482
|
+
snl = false
|
|
483
|
+
lst = 0
|
|
484
|
+
|
|
485
|
+
while (idx < str.length)
|
|
486
|
+
|
|
487
|
+
chunk = str[idx, width]
|
|
488
|
+
line = chunk.unpack("H*")[0].scan(/../).join(" ")
|
|
489
|
+
buf << line
|
|
490
|
+
|
|
491
|
+
if (lst == 0)
|
|
492
|
+
lst = line.length
|
|
493
|
+
buf << " " * 4
|
|
494
|
+
else
|
|
495
|
+
buf << " " * ((lst - line.length) + 4).abs
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
chunk.unpack("C*").each do |c|
|
|
499
|
+
if (c > 0x1f and c < 0x7f)
|
|
500
|
+
buf << c.chr
|
|
501
|
+
else
|
|
502
|
+
buf << "."
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
buf << "\n"
|
|
507
|
+
|
|
508
|
+
idx += width
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
buf << "\n"
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
#
|
|
515
|
+
# Converts a hex string to a raw string
|
|
516
|
+
#
|
|
517
|
+
def self.hex_to_raw(str)
|
|
518
|
+
[ str.downcase.gsub(/'/,'').gsub(/\\?x([a-f0-9][a-f0-9])/, '\1') ].pack("H*")
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
#
|
|
522
|
+
# Wraps text at a given column using a supplied indention
|
|
523
|
+
#
|
|
524
|
+
def self.wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '')
|
|
525
|
+
return str.gsub(/.{1,#{col - indent}}(?:\s|\Z)/){
|
|
526
|
+
( (" " * indent) + prepend + $& + append + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
#
|
|
530
|
+
# Converts a string to a hex version with wrapping support
|
|
531
|
+
#
|
|
532
|
+
def self.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '')
|
|
533
|
+
output = buf_start
|
|
534
|
+
cur = 0
|
|
535
|
+
count = 0
|
|
536
|
+
new_line = true
|
|
537
|
+
|
|
538
|
+
# Go through each byte in the string
|
|
539
|
+
str.each_byte { |byte|
|
|
540
|
+
count += 1
|
|
541
|
+
append = ''
|
|
542
|
+
|
|
543
|
+
# If this is a new line, prepend with the
|
|
544
|
+
# line start text
|
|
545
|
+
if (new_line == true)
|
|
546
|
+
append << line_start
|
|
547
|
+
new_line = false
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
# Append the hexified version of the byte
|
|
551
|
+
append << sprintf("\\x%.2x", byte)
|
|
552
|
+
cur += append.length
|
|
553
|
+
|
|
554
|
+
# If we're about to hit the column or have gone past it,
|
|
555
|
+
# time to finish up this line
|
|
556
|
+
if ((cur + line_end.length >= col) or (cur + buf_end.length >= col))
|
|
557
|
+
new_line = true
|
|
558
|
+
cur = 0
|
|
559
|
+
|
|
560
|
+
# If this is the last byte, use the buf_end instead of
|
|
561
|
+
# line_end
|
|
562
|
+
if (count == str.length)
|
|
563
|
+
append << buf_end + "\n"
|
|
564
|
+
else
|
|
565
|
+
append << line_end + "\n"
|
|
566
|
+
end
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
output << append
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
# If we were in the middle of a line, finish the buffer at this point
|
|
573
|
+
if (new_line == false)
|
|
574
|
+
output << buf_end + "\n"
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
return output
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
##
|
|
581
|
+
#
|
|
582
|
+
# Transforms
|
|
583
|
+
#
|
|
584
|
+
##
|
|
585
|
+
|
|
586
|
+
#
|
|
587
|
+
# Base64 encoder
|
|
588
|
+
#
|
|
589
|
+
def self.encode_base64(str, delim='')
|
|
590
|
+
[str].pack("m").gsub(/\s+/, delim)
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
#
|
|
594
|
+
# Base64 decoder
|
|
595
|
+
#
|
|
596
|
+
def self.decode_base64(str)
|
|
597
|
+
str.unpack("m")[0]
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
#
|
|
601
|
+
# Raw MD5 digest of the supplied string
|
|
602
|
+
#
|
|
603
|
+
def self.md5_raw(str)
|
|
604
|
+
Digest::MD5.digest(str)
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
#
|
|
608
|
+
# Hexidecimal MD5 digest of the supplied string
|
|
609
|
+
#
|
|
610
|
+
def self.md5(str)
|
|
611
|
+
Digest::MD5.hexdigest(str)
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
##
|
|
616
|
+
#
|
|
617
|
+
# Generators
|
|
618
|
+
#
|
|
619
|
+
##
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
# Generates a random character.
|
|
623
|
+
def self.rand_char(bad, chars = AllChars)
|
|
624
|
+
rand_text(1, bad, chars)
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
# Base text generator method
|
|
628
|
+
def self.rand_base(len, bad, *foo)
|
|
629
|
+
# Remove restricted characters
|
|
630
|
+
(bad || '').split('').each { |c| foo.delete(c) }
|
|
631
|
+
|
|
632
|
+
# Return nil if all bytes are restricted
|
|
633
|
+
return nil if foo.length == 0
|
|
634
|
+
|
|
635
|
+
buff = ""
|
|
636
|
+
|
|
637
|
+
# Generate a buffer from the remaining bytes
|
|
638
|
+
if foo.length >= 256
|
|
639
|
+
len.times { buff << Kernel.rand(256) }
|
|
640
|
+
else
|
|
641
|
+
len.times { buff << foo[ rand(foo.length) ] }
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
return buff
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
# Generate random bytes of data
|
|
648
|
+
def self.rand_text(len, bad='', chars = AllChars)
|
|
649
|
+
foo = chars.split('')
|
|
650
|
+
rand_base(len, bad, *foo)
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
# Generate random bytes of alpha data
|
|
654
|
+
def self.rand_text_alpha(len, bad='')
|
|
655
|
+
foo = []
|
|
656
|
+
foo += ('A' .. 'Z').to_a
|
|
657
|
+
foo += ('a' .. 'z').to_a
|
|
658
|
+
rand_base(len, bad, *foo )
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
# Generate random bytes of lowercase alpha data
|
|
662
|
+
def self.rand_text_alpha_lower(len, bad='')
|
|
663
|
+
rand_base(len, bad, *('a' .. 'z').to_a)
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
# Generate random bytes of uppercase alpha data
|
|
667
|
+
def self.rand_text_alpha_upper(len, bad='')
|
|
668
|
+
rand_base(len, bad, *('A' .. 'Z').to_a)
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
# Generate random bytes of alphanumeric data
|
|
672
|
+
def self.rand_text_alphanumeric(len, bad='')
|
|
673
|
+
foo = []
|
|
674
|
+
foo += ('A' .. 'Z').to_a
|
|
675
|
+
foo += ('a' .. 'z').to_a
|
|
676
|
+
foo += ('0' .. '9').to_a
|
|
677
|
+
rand_base(len, bad, *foo )
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
# Generate random bytes of alphanumeric hex.
|
|
681
|
+
def self.rand_text_hex(len, bad='')
|
|
682
|
+
foo = []
|
|
683
|
+
foo += ('0' .. '9').to_a
|
|
684
|
+
foo += ('a' .. 'f').to_a
|
|
685
|
+
rand_base(len, bad, *foo)
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
# Generate random bytes of numeric data
|
|
689
|
+
def self.rand_text_numeric(len, bad='')
|
|
690
|
+
foo = ('0' .. '9').to_a
|
|
691
|
+
rand_base(len, bad, *foo )
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
# Generate random bytes of english-like data
|
|
695
|
+
def self.rand_text_english(len, bad='')
|
|
696
|
+
foo = []
|
|
697
|
+
foo += (0x21 .. 0x7e).map{ |c| c.chr }
|
|
698
|
+
rand_base(len, bad, *foo )
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
# Generate random bytes of high ascii data
|
|
702
|
+
def self.rand_text_highascii(len, bad='')
|
|
703
|
+
foo = []
|
|
704
|
+
foo += (0x80 .. 0xff).map{ |c| c.chr }
|
|
705
|
+
rand_base(len, bad, *foo )
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
#
|
|
709
|
+
# Creates a pattern that can be used for offset calculation purposes. This
|
|
710
|
+
# routine is capable of generating patterns using a supplied set and a
|
|
711
|
+
# supplied number of identifiable characters (slots). The supplied sets
|
|
712
|
+
# should not contain any duplicate characters or the logic will fail.
|
|
713
|
+
#
|
|
714
|
+
def self.pattern_create(length, sets = [ UpperAlpha, LowerAlpha, Numerals ])
|
|
715
|
+
buf = ''
|
|
716
|
+
idx = 0
|
|
717
|
+
offsets = []
|
|
718
|
+
|
|
719
|
+
sets.length.times { offsets << 0 }
|
|
720
|
+
|
|
721
|
+
until buf.length >= length
|
|
722
|
+
begin
|
|
723
|
+
buf << converge_sets(sets, 0, offsets, length)
|
|
724
|
+
rescue RuntimeError
|
|
725
|
+
break
|
|
726
|
+
end
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
# Maximum permutations reached, but we need more data
|
|
730
|
+
if (buf.length < length)
|
|
731
|
+
buf = buf * (length / buf.length.to_f).ceil
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
buf[0,length]
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
#
|
|
738
|
+
# Calculate the offset to a pattern
|
|
739
|
+
#
|
|
740
|
+
def self.pattern_offset(pattern, value, start=0)
|
|
741
|
+
if (value.kind_of?(String))
|
|
742
|
+
pattern.index(value, start)
|
|
743
|
+
elsif (value.kind_of?(Fixnum) or value.kind_of?(Bignum))
|
|
744
|
+
pattern.index([ value ].pack('V'), start)
|
|
745
|
+
else
|
|
746
|
+
raise ::ArgumentError, "Invalid class for value: #{value.class}"
|
|
747
|
+
end
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
#
|
|
751
|
+
# Compresses a string, eliminating all superfluous whitespace before and
|
|
752
|
+
# after lines and eliminating all lines.
|
|
753
|
+
#
|
|
754
|
+
def self.compress(str)
|
|
755
|
+
str.gsub(/\n/m, ' ').gsub(/\s+/, ' ').gsub(/^\s+/, '').gsub(/\s+$/, '')
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
#
|
|
759
|
+
# Randomize the whitespace in a string
|
|
760
|
+
#
|
|
761
|
+
def self.randomize_space(str)
|
|
762
|
+
str.gsub(/\s+/) { |s|
|
|
763
|
+
len = rand(50)+2
|
|
764
|
+
set = "\x09\x20\x0d\x0a"
|
|
765
|
+
buf = ''
|
|
766
|
+
while (buf.length < len)
|
|
767
|
+
buf << set[rand(set.length),1]
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
buf
|
|
771
|
+
}
|
|
772
|
+
end
|
|
773
|
+
|
|
774
|
+
# Returns true if zlib can be used.
|
|
775
|
+
def self.zlib_present?
|
|
776
|
+
begin
|
|
777
|
+
temp = Zlib
|
|
778
|
+
return true
|
|
779
|
+
rescue
|
|
780
|
+
return false
|
|
781
|
+
end
|
|
782
|
+
end
|
|
783
|
+
|
|
784
|
+
# backwards compat for just a bit...
|
|
785
|
+
def self.gzip_present?
|
|
786
|
+
self.zlib_present?
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
#
|
|
790
|
+
# Compresses a string using zlib
|
|
791
|
+
#
|
|
792
|
+
def self.zlib_deflate(str, level = Zlib::BEST_COMPRESSION)
|
|
793
|
+
if self.zlib_present?
|
|
794
|
+
z = Zlib::Deflate.new(level)
|
|
795
|
+
dst = z.deflate(str, Zlib::FINISH)
|
|
796
|
+
z.close
|
|
797
|
+
return dst
|
|
798
|
+
else
|
|
799
|
+
raise RuntimeError, "Gzip support is not present."
|
|
800
|
+
end
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
#
|
|
804
|
+
# Uncompresses a string using zlib
|
|
805
|
+
#
|
|
806
|
+
def self.zlib_inflate(str)
|
|
807
|
+
if(self.zlib_present?)
|
|
808
|
+
zstream = Zlib::Inflate.new
|
|
809
|
+
buf = zstream.inflate(str)
|
|
810
|
+
zstream.finish
|
|
811
|
+
zstream.close
|
|
812
|
+
return buf
|
|
813
|
+
else
|
|
814
|
+
raise RuntimeError, "Gzip support is not present."
|
|
815
|
+
end
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
#
|
|
819
|
+
# Compresses a string using gzip
|
|
820
|
+
#
|
|
821
|
+
def self.gzip(str, level = 9)
|
|
822
|
+
raise RuntimeError, "Gzip support is not present." if (!zlib_present?)
|
|
823
|
+
raise RuntimeError, "Invalid gzip compression level" if (level < 1 or level > 9)
|
|
824
|
+
|
|
825
|
+
s = ""
|
|
826
|
+
gz = Zlib::GzipWriter.new(StringIO.new(s), level)
|
|
827
|
+
gz << str
|
|
828
|
+
gz.close
|
|
829
|
+
return s
|
|
830
|
+
end
|
|
831
|
+
|
|
832
|
+
#
|
|
833
|
+
# Uncompresses a string using gzip
|
|
834
|
+
#
|
|
835
|
+
def self.ungzip(str)
|
|
836
|
+
raise RuntimeError, "Gzip support is not present." if (!zlib_present?)
|
|
837
|
+
|
|
838
|
+
s = ""
|
|
839
|
+
gz = Zlib::GzipReader.new(StringIO.new(str))
|
|
840
|
+
s << gz.read
|
|
841
|
+
gz.close
|
|
842
|
+
return s
|
|
843
|
+
end
|
|
844
|
+
|
|
845
|
+
#
|
|
846
|
+
# Return the index of the first badchar in data, otherwise return
|
|
847
|
+
# nil if there wasn't any badchar occurences.
|
|
848
|
+
#
|
|
849
|
+
def self.badchar_index(data, badchars = '')
|
|
850
|
+
badchars.unpack("C*").each { |badchar|
|
|
851
|
+
pos = data.index(badchar.chr)
|
|
852
|
+
return pos if pos
|
|
853
|
+
}
|
|
854
|
+
return nil
|
|
855
|
+
end
|
|
856
|
+
|
|
857
|
+
#
|
|
858
|
+
# This method removes bad characters from a string.
|
|
859
|
+
#
|
|
860
|
+
def self.remove_badchars(data, badchars = '')
|
|
861
|
+
data.delete(badchars)
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
#
|
|
865
|
+
# This method returns all chars but the supplied set
|
|
866
|
+
#
|
|
867
|
+
def self.charset_exclude(keepers)
|
|
868
|
+
[*(0..255)].pack('C*').delete(keepers)
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
#
|
|
872
|
+
# Shuffles a byte stream
|
|
873
|
+
#
|
|
874
|
+
def self.shuffle_s(str)
|
|
875
|
+
shuffle_a(str.unpack("C*")).pack("C*")
|
|
876
|
+
end
|
|
877
|
+
|
|
878
|
+
#
|
|
879
|
+
# Performs a Fisher-Yates shuffle on an array
|
|
880
|
+
#
|
|
881
|
+
def self.shuffle_a(arr)
|
|
882
|
+
len = arr.length
|
|
883
|
+
max = len - 1
|
|
884
|
+
cyc = [* (0..max) ]
|
|
885
|
+
for d in cyc
|
|
886
|
+
e = rand(d+1)
|
|
887
|
+
next if e == d
|
|
888
|
+
f = arr[d];
|
|
889
|
+
g = arr[e];
|
|
890
|
+
arr[d] = g;
|
|
891
|
+
arr[e] = f;
|
|
892
|
+
end
|
|
893
|
+
return arr
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
# Permute the case of a word
|
|
897
|
+
def self.permute_case(word, idx=0)
|
|
898
|
+
res = []
|
|
899
|
+
|
|
900
|
+
if( (UpperAlpha+LowerAlpha).index(word[idx,1]))
|
|
901
|
+
|
|
902
|
+
word_ucase = word.dup
|
|
903
|
+
word_ucase[idx, 1] = word[idx, 1].upcase
|
|
904
|
+
|
|
905
|
+
word_lcase = word.dup
|
|
906
|
+
word_lcase[idx, 1] = word[idx, 1].downcase
|
|
907
|
+
|
|
908
|
+
if (idx == word.length)
|
|
909
|
+
return [word]
|
|
910
|
+
else
|
|
911
|
+
res << permute_case(word_ucase, idx+1)
|
|
912
|
+
res << permute_case(word_lcase, idx+1)
|
|
913
|
+
end
|
|
914
|
+
else
|
|
915
|
+
res << permute_case(word, idx+1)
|
|
916
|
+
end
|
|
917
|
+
|
|
918
|
+
res.flatten
|
|
919
|
+
end
|
|
920
|
+
|
|
921
|
+
# Generate a random hostname
|
|
922
|
+
def self.rand_hostname
|
|
923
|
+
host = []
|
|
924
|
+
(rand(5) + 1).times {
|
|
925
|
+
host.push(Rex::Text.rand_text_alphanumeric(rand(10) + 1))
|
|
926
|
+
}
|
|
927
|
+
d = ['com', 'net', 'org', 'gov']
|
|
928
|
+
host.push(d[rand(d.size)])
|
|
929
|
+
host.join('.').downcase
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
# Generate a state
|
|
933
|
+
def self.rand_state()
|
|
934
|
+
States[rand(States.size)]
|
|
935
|
+
end
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
#
|
|
939
|
+
# Calculate the ROR13 hash of a given string
|
|
940
|
+
#
|
|
941
|
+
def self.ror13_hash(name)
|
|
942
|
+
hash = 0
|
|
943
|
+
name.unpack("C*").each {|c| hash = ror(hash, 13); hash += c }
|
|
944
|
+
hash
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
#
|
|
948
|
+
# Rotate a 32-bit value to the right by cnt bits
|
|
949
|
+
#
|
|
950
|
+
def self.ror(val, cnt)
|
|
951
|
+
bits = [val].pack("N").unpack("B32")[0].split(//)
|
|
952
|
+
1.upto(cnt) do |c|
|
|
953
|
+
bits.unshift( bits.pop )
|
|
954
|
+
end
|
|
955
|
+
[bits.join].pack("B32").unpack("N")[0]
|
|
956
|
+
end
|
|
957
|
+
|
|
958
|
+
#
|
|
959
|
+
# Rotate a 32-bit value to the left by cnt bits
|
|
960
|
+
#
|
|
961
|
+
def self.rol(val, cnt)
|
|
962
|
+
bits = [val].pack("N").unpack("B32")[0].split(//)
|
|
963
|
+
1.upto(cnt) do |c|
|
|
964
|
+
bits.push( bits.shift )
|
|
965
|
+
end
|
|
966
|
+
[bits.join].pack("B32").unpack("N")[0]
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
protected
|
|
971
|
+
|
|
972
|
+
def self.converge_sets(sets, idx, offsets, length) # :nodoc:
|
|
973
|
+
buf = sets[idx][offsets[idx]].chr
|
|
974
|
+
|
|
975
|
+
# If there are more sets after use, converage with them.
|
|
976
|
+
if (sets[idx + 1])
|
|
977
|
+
buf << converge_sets(sets, idx + 1, offsets, length)
|
|
978
|
+
else
|
|
979
|
+
# Increment the current set offset as well as previous ones if we
|
|
980
|
+
# wrap back to zero.
|
|
981
|
+
while (idx >= 0 and ((offsets[idx] = (offsets[idx] + 1) % sets[idx].length)) == 0)
|
|
982
|
+
idx -= 1
|
|
983
|
+
end
|
|
984
|
+
|
|
985
|
+
# If we reached the point where the idx fell below zero, then that
|
|
986
|
+
# means we've reached the maximum threshold for permutations.
|
|
987
|
+
if (idx < 0)
|
|
988
|
+
raise RuntimeError, "Maximum permutations reached"
|
|
989
|
+
end
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
buf
|
|
993
|
+
end
|
|
994
|
+
|
|
995
|
+
def self.load_codepage()
|
|
996
|
+
return if (!@@codepage_map_cache.nil?)
|
|
997
|
+
file = File.join(File.dirname(__FILE__),'codepage.map')
|
|
998
|
+
page = ''
|
|
999
|
+
name = ''
|
|
1000
|
+
map = {}
|
|
1001
|
+
File.open(file).each { |line|
|
|
1002
|
+
next if line =~ /^#/
|
|
1003
|
+
next if line =~ /^\s*$/
|
|
1004
|
+
data = line.split
|
|
1005
|
+
if data[1] =~ /^\(/
|
|
1006
|
+
page = data.shift.to_i
|
|
1007
|
+
name = data.join(' ').sub(/^\(/,'').sub(/\)$/,'')
|
|
1008
|
+
map[page] = {}
|
|
1009
|
+
map[page]['name'] = name
|
|
1010
|
+
map[page]['data'] = {}
|
|
1011
|
+
else
|
|
1012
|
+
data.each { |entry|
|
|
1013
|
+
wide, char = entry.split(':')
|
|
1014
|
+
char = [char].pack('H*')
|
|
1015
|
+
wide = [wide].pack('H*')
|
|
1016
|
+
if map[page]['data'][char].nil?
|
|
1017
|
+
map[page]['data'][char] = [wide]
|
|
1018
|
+
else
|
|
1019
|
+
map[page]['data'][char].push(wide)
|
|
1020
|
+
end
|
|
1021
|
+
}
|
|
1022
|
+
end
|
|
1023
|
+
}
|
|
1024
|
+
@@codepage_map_cache = map
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
end
|
|
1028
|
+
end
|
|
1029
|
+
|