dstruct 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.
- checksums.yaml +15 -0
- data/README.markdown +23 -0
- data/examples/smb_example.rb +35 -0
- data/lib/rex.rb +108 -0
- data/lib/rex/LICENSE +29 -0
- data/lib/rex/arch.rb +104 -0
- data/lib/rex/arch/sparc.rb +75 -0
- data/lib/rex/arch/x86.rb +524 -0
- data/lib/rex/assembly/nasm.rb +104 -0
- data/lib/rex/codepage.map +104 -0
- data/lib/rex/compat.rb +389 -0
- data/lib/rex/constants.rb +124 -0
- data/lib/rex/elfparsey.rb +9 -0
- data/lib/rex/elfparsey/elf.rb +121 -0
- data/lib/rex/elfparsey/elfbase.rb +256 -0
- data/lib/rex/elfparsey/exceptions.rb +25 -0
- data/lib/rex/elfscan.rb +10 -0
- data/lib/rex/elfscan/scanner.rb +226 -0
- data/lib/rex/elfscan/search.rb +44 -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 +90 -0
- data/lib/rex/encoder/alpha2/unicode_mixed.rb +116 -0
- data/lib/rex/encoder/alpha2/unicode_upper.rb +123 -0
- data/lib/rex/encoder/bloxor/bloxor.rb +327 -0
- data/lib/rex/encoder/ndr.rb +90 -0
- data/lib/rex/encoder/nonalpha.rb +61 -0
- data/lib/rex/encoder/nonupper.rb +64 -0
- data/lib/rex/encoder/xdr.rb +107 -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/encoding/xor.rb +20 -0
- data/lib/rex/encoding/xor/byte.rb +15 -0
- data/lib/rex/encoding/xor/dword.rb +21 -0
- data/lib/rex/encoding/xor/dword_additive.rb +92 -0
- data/lib/rex/encoding/xor/exceptions.rb +17 -0
- data/lib/rex/encoding/xor/generic.rb +146 -0
- data/lib/rex/encoding/xor/qword.rb +15 -0
- data/lib/rex/encoding/xor/word.rb +21 -0
- data/lib/rex/exceptions.rb +275 -0
- data/lib/rex/exploitation/cmdstager.rb +10 -0
- data/lib/rex/exploitation/cmdstager/base.rb +190 -0
- data/lib/rex/exploitation/cmdstager/bourne.rb +105 -0
- data/lib/rex/exploitation/cmdstager/debug_asm.rb +140 -0
- data/lib/rex/exploitation/cmdstager/debug_write.rb +134 -0
- data/lib/rex/exploitation/cmdstager/echo.rb +164 -0
- data/lib/rex/exploitation/cmdstager/printf.rb +122 -0
- data/lib/rex/exploitation/cmdstager/tftp.rb +71 -0
- data/lib/rex/exploitation/cmdstager/vbs.rb +126 -0
- data/lib/rex/exploitation/egghunter.rb +425 -0
- data/lib/rex/exploitation/encryptjs.rb +78 -0
- data/lib/rex/exploitation/heaplib.js.b64 +331 -0
- data/lib/rex/exploitation/heaplib.rb +107 -0
- data/lib/rex/exploitation/js.rb +6 -0
- data/lib/rex/exploitation/js/detect.rb +69 -0
- data/lib/rex/exploitation/js/memory.rb +81 -0
- data/lib/rex/exploitation/js/network.rb +84 -0
- data/lib/rex/exploitation/js/utils.rb +33 -0
- data/lib/rex/exploitation/jsobfu.rb +513 -0
- data/lib/rex/exploitation/obfuscatejs.rb +336 -0
- data/lib/rex/exploitation/omelet.rb +321 -0
- data/lib/rex/exploitation/opcodedb.rb +819 -0
- data/lib/rex/exploitation/powershell.rb +62 -0
- data/lib/rex/exploitation/powershell/function.rb +63 -0
- data/lib/rex/exploitation/powershell/obfu.rb +98 -0
- data/lib/rex/exploitation/powershell/output.rb +151 -0
- data/lib/rex/exploitation/powershell/param.rb +23 -0
- data/lib/rex/exploitation/powershell/parser.rb +183 -0
- data/lib/rex/exploitation/powershell/psh_methods.rb +70 -0
- data/lib/rex/exploitation/powershell/script.rb +99 -0
- data/lib/rex/exploitation/ropdb.rb +190 -0
- data/lib/rex/exploitation/seh.rb +93 -0
- data/lib/rex/file.rb +160 -0
- data/lib/rex/image_source.rb +10 -0
- data/lib/rex/image_source/disk.rb +58 -0
- data/lib/rex/image_source/image_source.rb +44 -0
- data/lib/rex/image_source/memory.rb +35 -0
- data/lib/rex/io/bidirectional_pipe.rb +161 -0
- data/lib/rex/io/datagram_abstraction.rb +35 -0
- data/lib/rex/io/ring_buffer.rb +369 -0
- data/lib/rex/io/stream.rb +312 -0
- data/lib/rex/io/stream_abstraction.rb +209 -0
- data/lib/rex/io/stream_server.rb +221 -0
- data/lib/rex/job_container.rb +200 -0
- data/lib/rex/logging.rb +4 -0
- data/lib/rex/logging/log_dispatcher.rb +180 -0
- data/lib/rex/logging/log_sink.rb +43 -0
- data/lib/rex/logging/sinks/flatfile.rb +56 -0
- data/lib/rex/logging/sinks/stderr.rb +44 -0
- data/lib/rex/mac_oui.rb +16581 -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 +10 -0
- data/lib/rex/mime/encoding.rb +17 -0
- data/lib/rex/mime/header.rb +78 -0
- data/lib/rex/mime/message.rb +150 -0
- data/lib/rex/mime/part.rb +50 -0
- data/lib/rex/nop/opty2.rb +109 -0
- data/lib/rex/nop/opty2_tables.rb +301 -0
- data/lib/rex/ole.rb +202 -0
- data/lib/rex/ole/clsid.rb +44 -0
- data/lib/rex/ole/difat.rb +138 -0
- data/lib/rex/ole/directory.rb +228 -0
- data/lib/rex/ole/direntry.rb +237 -0
- data/lib/rex/ole/docs/dependencies.txt +8 -0
- data/lib/rex/ole/docs/references.txt +1 -0
- data/lib/rex/ole/fat.rb +96 -0
- data/lib/rex/ole/header.rb +201 -0
- data/lib/rex/ole/minifat.rb +74 -0
- data/lib/rex/ole/propset.rb +141 -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 +392 -0
- data/lib/rex/ole/stream.rb +50 -0
- data/lib/rex/ole/substorage.rb +46 -0
- data/lib/rex/ole/util.rb +154 -0
- data/lib/rex/parser/acunetix_nokogiri.rb +406 -0
- data/lib/rex/parser/apple_backup_manifestdb.rb +132 -0
- data/lib/rex/parser/appscan_nokogiri.rb +367 -0
- data/lib/rex/parser/arguments.rb +108 -0
- data/lib/rex/parser/burp_session_nokogiri.rb +291 -0
- data/lib/rex/parser/ci_nokogiri.rb +193 -0
- data/lib/rex/parser/foundstone_nokogiri.rb +342 -0
- data/lib/rex/parser/fusionvm_nokogiri.rb +109 -0
- data/lib/rex/parser/group_policy_preferences.rb +185 -0
- data/lib/rex/parser/ini.rb +186 -0
- data/lib/rex/parser/ip360_aspl_xml.rb +103 -0
- data/lib/rex/parser/ip360_xml.rb +98 -0
- data/lib/rex/parser/mbsa_nokogiri.rb +256 -0
- data/lib/rex/parser/nessus_xml.rb +121 -0
- data/lib/rex/parser/netsparker_xml.rb +109 -0
- data/lib/rex/parser/nexpose_raw_nokogiri.rb +686 -0
- data/lib/rex/parser/nexpose_simple_nokogiri.rb +330 -0
- data/lib/rex/parser/nexpose_xml.rb +172 -0
- data/lib/rex/parser/nmap_nokogiri.rb +394 -0
- data/lib/rex/parser/nmap_xml.rb +166 -0
- data/lib/rex/parser/nokogiri_doc_mixin.rb +233 -0
- data/lib/rex/parser/openvas_nokogiri.rb +172 -0
- data/lib/rex/parser/outpost24_nokogiri.rb +240 -0
- data/lib/rex/parser/retina_xml.rb +110 -0
- data/lib/rex/parser/unattend.rb +171 -0
- data/lib/rex/parser/wapiti_nokogiri.rb +105 -0
- data/lib/rex/payloads.rb +2 -0
- data/lib/rex/payloads/win32.rb +3 -0
- data/lib/rex/payloads/win32/common.rb +27 -0
- data/lib/rex/payloads/win32/kernel.rb +54 -0
- data/lib/rex/payloads/win32/kernel/common.rb +55 -0
- data/lib/rex/payloads/win32/kernel/migration.rb +13 -0
- data/lib/rex/payloads/win32/kernel/recovery.rb +51 -0
- data/lib/rex/payloads/win32/kernel/stager.rb +195 -0
- data/lib/rex/peparsey.rb +10 -0
- data/lib/rex/peparsey/exceptions.rb +30 -0
- data/lib/rex/peparsey/pe.rb +210 -0
- data/lib/rex/peparsey/pe_memdump.rb +61 -0
- data/lib/rex/peparsey/pebase.rb +1662 -0
- data/lib/rex/peparsey/section.rb +128 -0
- data/lib/rex/pescan.rb +11 -0
- data/lib/rex/pescan/analyze.rb +366 -0
- data/lib/rex/pescan/scanner.rb +230 -0
- data/lib/rex/pescan/search.rb +68 -0
- data/lib/rex/platforms.rb +2 -0
- data/lib/rex/platforms/windows.rb +52 -0
- data/lib/rex/poly.rb +134 -0
- data/lib/rex/poly/block.rb +480 -0
- data/lib/rex/poly/machine.rb +13 -0
- data/lib/rex/poly/machine/machine.rb +830 -0
- data/lib/rex/poly/machine/x86.rb +509 -0
- data/lib/rex/poly/register.rb +101 -0
- data/lib/rex/poly/register/x86.rb +41 -0
- data/lib/rex/post.rb +7 -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 +5 -0
- data/lib/rex/post/meterpreter/channel.rb +446 -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 +483 -0
- data/lib/rex/post/meterpreter/client_core.rb +352 -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/android/android.rb +128 -0
- data/lib/rex/post/meterpreter/extensions/android/tlv.rb +40 -0
- data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
- data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +17 -0
- data/lib/rex/post/meterpreter/extensions/extapi/adsi/adsi.rb +71 -0
- data/lib/rex/post/meterpreter/extensions/extapi/clipboard/clipboard.rb +169 -0
- data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +45 -0
- data/lib/rex/post/meterpreter/extensions/extapi/service/service.rb +104 -0
- data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +77 -0
- data/lib/rex/post/meterpreter/extensions/extapi/window/window.rb +56 -0
- data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +75 -0
- data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
- data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +22 -0
- data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +361 -0
- data/lib/rex/post/meterpreter/extensions/kiwi/tlv.rb +76 -0
- data/lib/rex/post/meterpreter/extensions/lanattacks/dhcp/dhcp.rb +78 -0
- data/lib/rex/post/meterpreter/extensions/lanattacks/lanattacks.rb +43 -0
- data/lib/rex/post/meterpreter/extensions/lanattacks/tftp/tftp.rb +49 -0
- data/lib/rex/post/meterpreter/extensions/lanattacks/tlv.rb +17 -0
- data/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +128 -0
- data/lib/rex/post/meterpreter/extensions/mimikatz/tlv.rb +16 -0
- data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +57 -0
- data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +16 -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 +109 -0
- data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +29 -0
- data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +117 -0
- data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +27 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +396 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +284 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +399 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +104 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/arp.rb +59 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +256 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +129 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/netstat.rb +97 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb +106 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +67 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +139 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +180 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +168 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +209 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38146 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +48 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +2102 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_crypt32.rb +32 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +97 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3852 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +100 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +168 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_psapi.rb +32 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +32 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3170 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_version.rb +41 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wlanapi.rb +87 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +128 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +613 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +388 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +111 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +149 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb +27 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/mock_magic.rb +515 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +319 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb +23 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +301 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +56 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb +106 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +676 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +96 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +151 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +128 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +192 -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 +60 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +408 -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 +328 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +193 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +188 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +180 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +236 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +259 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +201 -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 +709 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +543 -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 +142 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +86 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +383 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +939 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +109 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi.rb +65 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +198 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/clipboard.rb +444 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/service.rb +199 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/window.rb +118 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/wmi.rb +108 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +242 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +509 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks.rb +60 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +254 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/tftp.rb +159 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +182 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +232 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +62 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +97 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +52 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +133 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +204 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +66 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +527 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +448 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +906 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +318 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +343 -0
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +99 -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 +15 -0
- data/lib/rex/proto/addp.rb +218 -0
- data/lib/rex/proto/dcerpc.rb +7 -0
- data/lib/rex/proto/dcerpc/client.rb +362 -0
- data/lib/rex/proto/dcerpc/exceptions.rb +151 -0
- data/lib/rex/proto/dcerpc/handle.rb +48 -0
- data/lib/rex/proto/dcerpc/ndr.rb +73 -0
- data/lib/rex/proto/dcerpc/packet.rb +264 -0
- data/lib/rex/proto/dcerpc/response.rb +188 -0
- data/lib/rex/proto/dcerpc/uuid.rb +85 -0
- data/lib/rex/proto/dcerpc/wdscp.rb +3 -0
- data/lib/rex/proto/dcerpc/wdscp/constants.rb +89 -0
- data/lib/rex/proto/dcerpc/wdscp/packet.rb +94 -0
- data/lib/rex/proto/dhcp.rb +7 -0
- data/lib/rex/proto/dhcp/constants.rb +34 -0
- data/lib/rex/proto/dhcp/server.rb +334 -0
- data/lib/rex/proto/drda.rb +6 -0
- data/lib/rex/proto/drda/constants.rb +50 -0
- data/lib/rex/proto/drda/packet.rb +253 -0
- data/lib/rex/proto/drda/utils.rb +124 -0
- data/lib/rex/proto/http.rb +7 -0
- data/lib/rex/proto/http/client.rb +722 -0
- data/lib/rex/proto/http/client_request.rb +472 -0
- data/lib/rex/proto/http/handler.rb +47 -0
- data/lib/rex/proto/http/handler/erb.rb +129 -0
- data/lib/rex/proto/http/handler/proc.rb +61 -0
- data/lib/rex/proto/http/header.rb +173 -0
- data/lib/rex/proto/http/packet.rb +414 -0
- data/lib/rex/proto/http/request.rb +354 -0
- data/lib/rex/proto/http/response.rb +151 -0
- data/lib/rex/proto/http/server.rb +385 -0
- data/lib/rex/proto/iax2.rb +2 -0
- data/lib/rex/proto/iax2/call.rb +326 -0
- data/lib/rex/proto/iax2/client.rb +218 -0
- data/lib/rex/proto/iax2/codecs.rb +5 -0
- data/lib/rex/proto/iax2/codecs/alaw.rb +16 -0
- data/lib/rex/proto/iax2/codecs/g711.rb +2176 -0
- data/lib/rex/proto/iax2/codecs/mulaw.rb +17 -0
- data/lib/rex/proto/iax2/constants.rb +262 -0
- data/lib/rex/proto/ipmi.rb +57 -0
- data/lib/rex/proto/ipmi/channel_auth_reply.rb +89 -0
- data/lib/rex/proto/ipmi/open_session_reply.rb +36 -0
- data/lib/rex/proto/ipmi/rakp2.rb +36 -0
- data/lib/rex/proto/ipmi/utils.rb +125 -0
- data/lib/rex/proto/natpmp.rb +7 -0
- data/lib/rex/proto/natpmp/constants.rb +19 -0
- data/lib/rex/proto/natpmp/packet.rb +45 -0
- data/lib/rex/proto/ntlm.rb +8 -0
- data/lib/rex/proto/ntlm/base.rb +327 -0
- data/lib/rex/proto/ntlm/constants.rb +75 -0
- data/lib/rex/proto/ntlm/crypt.rb +412 -0
- data/lib/rex/proto/ntlm/exceptions.rb +17 -0
- data/lib/rex/proto/ntlm/message.rb +534 -0
- data/lib/rex/proto/ntlm/utils.rb +765 -0
- data/lib/rex/proto/ntp.rb +3 -0
- data/lib/rex/proto/ntp/constants.rb +12 -0
- data/lib/rex/proto/ntp/modes.rb +130 -0
- data/lib/rex/proto/pjl.rb +31 -0
- data/lib/rex/proto/pjl/client.rb +163 -0
- data/lib/rex/proto/proxy/socks4a.rb +441 -0
- data/lib/rex/proto/rfb.rb +13 -0
- data/lib/rex/proto/rfb/cipher.rb +82 -0
- data/lib/rex/proto/rfb/client.rb +205 -0
- data/lib/rex/proto/rfb/constants.rb +50 -0
- data/lib/rex/proto/sip.rb +4 -0
- data/lib/rex/proto/sip/response.rb +61 -0
- data/lib/rex/proto/smb.rb +8 -0
- data/lib/rex/proto/smb/client.rb +2064 -0
- data/lib/rex/proto/smb/constants.rb +1064 -0
- data/lib/rex/proto/smb/crypt.rb +37 -0
- data/lib/rex/proto/smb/evasions.rb +67 -0
- data/lib/rex/proto/smb/exceptions.rb +867 -0
- data/lib/rex/proto/smb/simpleclient.rb +173 -0
- data/lib/rex/proto/smb/simpleclient/open_file.rb +106 -0
- data/lib/rex/proto/smb/simpleclient/open_pipe.rb +57 -0
- data/lib/rex/proto/smb/utils.rb +104 -0
- data/lib/rex/proto/sunrpc.rb +2 -0
- data/lib/rex/proto/sunrpc/client.rb +196 -0
- data/lib/rex/proto/tftp.rb +13 -0
- data/lib/rex/proto/tftp/client.rb +344 -0
- data/lib/rex/proto/tftp/constants.rb +39 -0
- data/lib/rex/proto/tftp/server.rb +497 -0
- data/lib/rex/random_identifier_generator.rb +177 -0
- data/lib/rex/registry.rb +14 -0
- data/lib/rex/registry/hive.rb +132 -0
- data/lib/rex/registry/lfkey.rb +51 -0
- data/lib/rex/registry/nodekey.rb +54 -0
- data/lib/rex/registry/regf.rb +25 -0
- data/lib/rex/registry/valuekey.rb +67 -0
- data/lib/rex/registry/valuelist.rb +29 -0
- data/lib/rex/ropbuilder.rb +8 -0
- data/lib/rex/ropbuilder/rop.rb +271 -0
- data/lib/rex/script.rb +42 -0
- data/lib/rex/script/base.rb +61 -0
- data/lib/rex/script/meterpreter.rb +16 -0
- data/lib/rex/script/shell.rb +10 -0
- data/lib/rex/service.rb +49 -0
- data/lib/rex/service_manager.rb +154 -0
- data/lib/rex/services/local_relay.rb +424 -0
- data/lib/rex/socket.rb +788 -0
- data/lib/rex/socket/comm.rb +120 -0
- data/lib/rex/socket/comm/local.rb +526 -0
- data/lib/rex/socket/ip.rb +132 -0
- data/lib/rex/socket/parameters.rb +363 -0
- data/lib/rex/socket/range_walker.rb +470 -0
- data/lib/rex/socket/ssl_tcp.rb +345 -0
- data/lib/rex/socket/ssl_tcp_server.rb +188 -0
- data/lib/rex/socket/subnet_walker.rb +76 -0
- data/lib/rex/socket/switch_board.rb +289 -0
- data/lib/rex/socket/tcp.rb +79 -0
- data/lib/rex/socket/tcp_server.rb +67 -0
- data/lib/rex/socket/udp.rb +165 -0
- data/lib/rex/sslscan/result.rb +201 -0
- data/lib/rex/sslscan/scanner.rb +206 -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 +85 -0
- data/lib/rex/sync/read_write_lock.rb +177 -0
- data/lib/rex/sync/ref.rb +58 -0
- data/lib/rex/sync/thread_safe.rb +83 -0
- data/lib/rex/text.rb +1813 -0
- data/lib/rex/thread_factory.rb +43 -0
- data/lib/rex/time.rb +66 -0
- data/lib/rex/transformer.rb +116 -0
- data/lib/rex/ui.rb +22 -0
- data/lib/rex/ui/interactive.rb +304 -0
- data/lib/rex/ui/output.rb +85 -0
- data/lib/rex/ui/output/none.rb +19 -0
- data/lib/rex/ui/progress_tracker.rb +97 -0
- data/lib/rex/ui/subscriber.rb +160 -0
- data/lib/rex/ui/text/color.rb +98 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +538 -0
- data/lib/rex/ui/text/input.rb +119 -0
- data/lib/rex/ui/text/input/buffer.rb +79 -0
- data/lib/rex/ui/text/input/readline.rb +129 -0
- data/lib/rex/ui/text/input/socket.rb +96 -0
- data/lib/rex/ui/text/input/stdio.rb +46 -0
- data/lib/rex/ui/text/irb_shell.rb +62 -0
- data/lib/rex/ui/text/output.rb +86 -0
- data/lib/rex/ui/text/output/buffer.rb +62 -0
- data/lib/rex/ui/text/output/buffer/stdout.rb +26 -0
- data/lib/rex/ui/text/output/file.rb +44 -0
- data/lib/rex/ui/text/output/socket.rb +44 -0
- data/lib/rex/ui/text/output/stdio.rb +53 -0
- data/lib/rex/ui/text/output/tee.rb +56 -0
- data/lib/rex/ui/text/progress_tracker.rb +57 -0
- data/lib/rex/ui/text/shell.rb +403 -0
- data/lib/rex/ui/text/table.rb +346 -0
- data/lib/rex/zip.rb +96 -0
- data/lib/rex/zip/archive.rb +130 -0
- data/lib/rex/zip/blocks.rb +184 -0
- data/lib/rex/zip/entry.rb +122 -0
- data/lib/rex/zip/jar.rb +283 -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 +536 -0
data/lib/rex/text.rb
ADDED
|
@@ -0,0 +1,1813 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
require 'digest/md5'
|
|
3
|
+
require 'digest/sha1'
|
|
4
|
+
require 'stringio'
|
|
5
|
+
require 'cgi'
|
|
6
|
+
require 'rex/exploitation/powershell'
|
|
7
|
+
|
|
8
|
+
%W{ iconv zlib }.each do |libname|
|
|
9
|
+
begin
|
|
10
|
+
old_verbose = $VERBOSE
|
|
11
|
+
$VERBOSE = nil
|
|
12
|
+
require libname
|
|
13
|
+
rescue ::LoadError
|
|
14
|
+
ensure
|
|
15
|
+
$VERBOSE = old_verbose
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module Rex
|
|
20
|
+
|
|
21
|
+
###
|
|
22
|
+
#
|
|
23
|
+
# This class formats text in various fashions and also provides
|
|
24
|
+
# a mechanism for wrapping text at a given column.
|
|
25
|
+
#
|
|
26
|
+
###
|
|
27
|
+
module Text
|
|
28
|
+
@@codepage_map_cache = nil
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
#
|
|
32
|
+
# Constants
|
|
33
|
+
#
|
|
34
|
+
##
|
|
35
|
+
|
|
36
|
+
TLDs = ['com', 'net', 'org', 'gov', 'biz', 'edu']
|
|
37
|
+
States = ["AK", "AL", "AR", "AZ", "CA", "CO", "CT", "DE", "FL", "GA", "HI",
|
|
38
|
+
"IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN",
|
|
39
|
+
"MO", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH",
|
|
40
|
+
"OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VT", "WA",
|
|
41
|
+
"WI", "WV", "WY"]
|
|
42
|
+
UpperAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
43
|
+
LowerAlpha = "abcdefghijklmnopqrstuvwxyz"
|
|
44
|
+
Numerals = "0123456789"
|
|
45
|
+
Base32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
|
46
|
+
Alpha = UpperAlpha + LowerAlpha
|
|
47
|
+
AlphaNumeric = Alpha + Numerals
|
|
48
|
+
HighAscii = [*(0x80 .. 0xff)].pack("C*")
|
|
49
|
+
LowAscii = [*(0x00 .. 0x1f)].pack("C*")
|
|
50
|
+
DefaultWrap = 60
|
|
51
|
+
AllChars = [*(0x00 .. 0xff)].pack("C*")
|
|
52
|
+
Punctuation = ( [*(0x21 .. 0x2f)] + [*(0x3a .. 0x3F)] + [*(0x5b .. 0x60)] + [*(0x7b .. 0x7e)] ).flatten.pack("C*")
|
|
53
|
+
|
|
54
|
+
DefaultPatternSets = [ Rex::Text::UpperAlpha, Rex::Text::LowerAlpha, Rex::Text::Numerals ]
|
|
55
|
+
|
|
56
|
+
# In case Iconv isn't loaded
|
|
57
|
+
Iconv_EBCDIC = [
|
|
58
|
+
"\x00", "\x01", "\x02", "\x03", "7", "-", ".", "/", "\x16", "\x05",
|
|
59
|
+
"%", "\v", "\f", "\r", "\x0E", "\x0F", "\x10", "\x11", "\x12", "\x13",
|
|
60
|
+
"<", "=", "2", "&", "\x18", "\x19", "?", "'", "\x1C", "\x1D", "\x1E",
|
|
61
|
+
"\x1F", "@", "Z", "\x7F", "{", "[", "l", "P", "}", "M", "]", "\\",
|
|
62
|
+
"N", "k", "`", "K", "a", "\xF0", "\xF1", "\xF2", "\xF3", "\xF4",
|
|
63
|
+
"\xF5", "\xF6", "\xF7", "\xF8", "\xF9", "z", "^", "L", "~", "n", "o",
|
|
64
|
+
"|", "\xC1", "\xC2", "\xC3", "\xC4", "\xC5", "\xC6", "\xC7", "\xC8",
|
|
65
|
+
"\xC9", "\xD1", "\xD2", "\xD3", "\xD4", "\xD5", "\xD6", "\xD7",
|
|
66
|
+
"\xD8", "\xD9", "\xE2", "\xE3", "\xE4", "\xE5", "\xE6", "\xE7",
|
|
67
|
+
"\xE8", "\xE9", nil, "\xE0", nil, nil, "m", "y", "\x81", "\x82",
|
|
68
|
+
"\x83", "\x84", "\x85", "\x86", "\x87", "\x88", "\x89", "\x91",
|
|
69
|
+
"\x92", "\x93", "\x94", "\x95", "\x96", "\x97", "\x98", "\x99",
|
|
70
|
+
"\xA2", "\xA3", "\xA4", "\xA5", "\xA6", "\xA7", "\xA8", "\xA9",
|
|
71
|
+
"\xC0", "O", "\xD0", "\xA1", "\a", nil, nil, nil, nil, nil, nil,
|
|
72
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
73
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
74
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
75
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
76
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
77
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
78
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
79
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
80
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
81
|
+
nil, nil, nil, nil, nil
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
Iconv_ASCII = [
|
|
85
|
+
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\a", "\b",
|
|
86
|
+
"\t", "\n", "\v", "\f", "\r", "\x0E", "\x0F", "\x10", "\x11", "\x12",
|
|
87
|
+
"\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1A", "\e",
|
|
88
|
+
"\x1C", "\x1D", "\x1E", "\x1F", " ", "!", "\"", "#", "$", "%", "&",
|
|
89
|
+
"'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4",
|
|
90
|
+
"5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B",
|
|
91
|
+
"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
|
|
92
|
+
"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", nil, "\\", nil,
|
|
93
|
+
nil, "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
|
|
94
|
+
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
|
|
95
|
+
"z", "{", "|", "}", "~", "\x7F", nil, nil, nil, nil, nil, nil, nil,
|
|
96
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
97
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
98
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
99
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
100
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
101
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
102
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
103
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
|
104
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
# Most 100 common surnames, male/female names in the U.S. (http://names.mongabay.com/)
|
|
109
|
+
#
|
|
110
|
+
|
|
111
|
+
Surnames = [
|
|
112
|
+
"adams", "alexander", "allen", "anderson", "bailey", "baker", "barnes",
|
|
113
|
+
"bell", "bennett", "brooks", "brown", "bryant", "butler", "campbell",
|
|
114
|
+
"carter", "clark", "coleman", "collins", "cook", "cooper", "cox",
|
|
115
|
+
"davis", "diaz", "edwards", "evans", "flores", "foster", "garcia",
|
|
116
|
+
"gonzales", "gonzalez", "gray", "green", "griffin", "hall", "harris",
|
|
117
|
+
"hayes", "henderson", "hernandez", "hill", "howard", "hughes", "jackson",
|
|
118
|
+
"james", "jenkins", "johnson", "jones", "kelly", "king", "lee", "lewis",
|
|
119
|
+
"long", "lopez", "martin", "martinez", "miller", "mitchell", "moore",
|
|
120
|
+
"morgan", "morris", "murphy", "nelson", "parker", "patterson", "perez",
|
|
121
|
+
"perry", "peterson", "phillips", "powell", "price", "ramirez", "reed",
|
|
122
|
+
"richardson", "rivera", "roberts", "robinson", "rodriguez", "rogers",
|
|
123
|
+
"ross", "russell", "sanchez", "sanders", "scott", "simmons", "smith",
|
|
124
|
+
"stewart", "taylor", "thomas", "thompson", "torres", "turner", "walker",
|
|
125
|
+
"ward", "washington", "watson", "white", "williams", "wilson", "wood",
|
|
126
|
+
"wright", "young"
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
Names_Male = [
|
|
130
|
+
"aaron", "adam", "alan", "albert", "andrew", "anthony", "antonio",
|
|
131
|
+
"arthur", "benjamin", "billy", "bobby", "brandon", "brian", "bruce",
|
|
132
|
+
"carl", "carlos", "charles", "chris", "christopher", "clarence", "craig",
|
|
133
|
+
"daniel", "david", "dennis", "donald", "douglas", "earl", "edward",
|
|
134
|
+
"eric", "ernest", "eugene", "frank", "fred", "gary", "george", "gerald",
|
|
135
|
+
"gregory", "harold", "harry", "henry", "howard", "jack", "james", "jason",
|
|
136
|
+
"jeffrey", "jeremy", "jerry", "jesse", "jimmy", "joe", "john", "johnny",
|
|
137
|
+
"jonathan", "jose", "joseph", "joshua", "juan", "justin", "keith",
|
|
138
|
+
"kenneth", "kevin", "larry", "lawrence", "louis", "mark", "martin",
|
|
139
|
+
"matthew", "michael", "nicholas", "patrick", "paul", "peter", "philip",
|
|
140
|
+
"phillip", "ralph", "randy", "raymond", "richard", "robert", "roger",
|
|
141
|
+
"ronald", "roy", "russell", "ryan", "samuel", "scott", "sean", "shawn",
|
|
142
|
+
"stephen", "steve", "steven", "terry", "thomas", "timothy", "todd",
|
|
143
|
+
"victor", "walter", "wayne", "william", "willie"
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
Names_Female = [
|
|
147
|
+
"alice", "amanda", "amy", "andrea", "angela", "ann", "anna", "anne",
|
|
148
|
+
"annie", "ashley", "barbara", "betty", "beverly", "bonnie", "brenda",
|
|
149
|
+
"carol", "carolyn", "catherine", "cheryl", "christina", "christine",
|
|
150
|
+
"cynthia", "deborah", "debra", "denise", "diana", "diane", "donna",
|
|
151
|
+
"doris", "dorothy", "elizabeth", "emily", "evelyn", "frances", "gloria",
|
|
152
|
+
"heather", "helen", "irene", "jacqueline", "jane", "janet", "janice",
|
|
153
|
+
"jean", "jennifer", "jessica", "joan", "joyce", "judith", "judy", "julia",
|
|
154
|
+
"julie", "karen", "katherine", "kathleen", "kathryn", "kathy", "kelly",
|
|
155
|
+
"kimberly", "laura", "lillian", "linda", "lisa", "lois", "lori", "louise",
|
|
156
|
+
"margaret", "maria", "marie", "marilyn", "martha", "mary", "melissa",
|
|
157
|
+
"michelle", "mildred", "nancy", "nicole", "norma", "pamela", "patricia",
|
|
158
|
+
"paula", "phyllis", "rachel", "rebecca", "robin", "rose", "ruby", "ruth",
|
|
159
|
+
"sandra", "sara", "sarah", "sharon", "shirley", "stephanie", "susan",
|
|
160
|
+
"tammy", "teresa", "theresa", "tina", "virginia", "wanda"
|
|
161
|
+
]
|
|
162
|
+
|
|
163
|
+
##
|
|
164
|
+
#
|
|
165
|
+
# Serialization
|
|
166
|
+
#
|
|
167
|
+
##
|
|
168
|
+
|
|
169
|
+
#
|
|
170
|
+
# Converts a raw string into a ruby buffer
|
|
171
|
+
#
|
|
172
|
+
def self.to_ruby(str, wrap = DefaultWrap, name = "buf")
|
|
173
|
+
return hexify(str, wrap, '"', '" +', "#{name} = \n", '"')
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
#
|
|
177
|
+
# Creates a comma separated list of numbers
|
|
178
|
+
#
|
|
179
|
+
def self.to_num(str, wrap = DefaultWrap)
|
|
180
|
+
code = str.unpack('C*')
|
|
181
|
+
buff = ""
|
|
182
|
+
0.upto(code.length-1) do |byte|
|
|
183
|
+
if(byte % 15 == 0) and (buff.length > 0)
|
|
184
|
+
buff << "\r\n"
|
|
185
|
+
end
|
|
186
|
+
buff << sprintf('0x%.2x, ', code[byte])
|
|
187
|
+
end
|
|
188
|
+
# strip , at the end
|
|
189
|
+
buff = buff.chomp(', ')
|
|
190
|
+
buff << "\r\n"
|
|
191
|
+
return buff
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
#
|
|
195
|
+
# Creates a comma separated list of dwords
|
|
196
|
+
#
|
|
197
|
+
def self.to_dword(str, wrap = DefaultWrap)
|
|
198
|
+
code = str
|
|
199
|
+
alignnr = str.length % 4
|
|
200
|
+
if (alignnr > 0)
|
|
201
|
+
code << "\x00" * (4 - alignnr)
|
|
202
|
+
end
|
|
203
|
+
codevalues = Array.new
|
|
204
|
+
code.split("").each_slice(4) do |chars4|
|
|
205
|
+
chars4 = chars4.join("")
|
|
206
|
+
dwordvalue = chars4.unpack('*V')
|
|
207
|
+
codevalues.push(dwordvalue[0])
|
|
208
|
+
end
|
|
209
|
+
buff = ""
|
|
210
|
+
0.upto(codevalues.length-1) do |byte|
|
|
211
|
+
if(byte % 8 == 0) and (buff.length > 0)
|
|
212
|
+
buff << "\r\n"
|
|
213
|
+
end
|
|
214
|
+
buff << sprintf('0x%.8x, ', codevalues[byte])
|
|
215
|
+
end
|
|
216
|
+
# strip , at the end
|
|
217
|
+
buff = buff.chomp(', ')
|
|
218
|
+
buff << "\r\n"
|
|
219
|
+
return buff
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
#
|
|
223
|
+
# Creates a ruby-style comment
|
|
224
|
+
#
|
|
225
|
+
def self.to_ruby_comment(str, wrap = DefaultWrap)
|
|
226
|
+
return wordwrap(str, 0, wrap, '', '# ')
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
#
|
|
230
|
+
# Converts a raw string into a C buffer
|
|
231
|
+
#
|
|
232
|
+
def self.to_c(str, wrap = DefaultWrap, name = "buf")
|
|
233
|
+
return hexify(str, wrap, '"', '"', "unsigned char #{name}[] = \n", '";')
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def self.to_csharp(str, wrap = DefaultWrap, name = "buf")
|
|
237
|
+
ret = "byte[] #{name} = new byte[#{str.length}] {"
|
|
238
|
+
i = -1;
|
|
239
|
+
while (i += 1) < str.length
|
|
240
|
+
ret << "\n" if i%(wrap/4) == 0
|
|
241
|
+
ret << "0x" << str[i].unpack("H*")[0] << ","
|
|
242
|
+
end
|
|
243
|
+
ret = ret[0..ret.length-2] #cut off last comma
|
|
244
|
+
ret << " };\n"
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
#
|
|
248
|
+
# Creates a c-style comment
|
|
249
|
+
#
|
|
250
|
+
def self.to_c_comment(str, wrap = DefaultWrap)
|
|
251
|
+
return "/*\n" + wordwrap(str, 0, wrap, '', ' * ') + " */\n"
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
#
|
|
255
|
+
# Creates a javascript-style comment
|
|
256
|
+
#
|
|
257
|
+
def self.to_js_comment(str, wrap = DefaultWrap)
|
|
258
|
+
return wordwrap(str, 0, wrap, '', '// ')
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
#
|
|
262
|
+
# Converts a raw string into a perl buffer
|
|
263
|
+
#
|
|
264
|
+
def self.to_perl(str, wrap = DefaultWrap, name = "buf")
|
|
265
|
+
return hexify(str, wrap, '"', '" .', "my $#{name} = \n", '";')
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
#
|
|
269
|
+
# Converts a raw string into a python buffer
|
|
270
|
+
#
|
|
271
|
+
def self.to_python(str, wrap = DefaultWrap, name = "buf")
|
|
272
|
+
return hexify(str, wrap, "#{name} += \"", '"', "#{name} = \"\"\n", '"')
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
#
|
|
276
|
+
# Converts a raw string into a Bash buffer
|
|
277
|
+
#
|
|
278
|
+
def self.to_bash(str, wrap = DefaultWrap, name = "buf")
|
|
279
|
+
return hexify(str, wrap, '$\'', '\'\\', "export #{name}=\\\n", '\'')
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
#
|
|
283
|
+
# Converts a raw string into a java byte array
|
|
284
|
+
#
|
|
285
|
+
def self.to_java(str, name = "shell")
|
|
286
|
+
buff = "byte #{name}[] = new byte[]\n{\n"
|
|
287
|
+
cnt = 0
|
|
288
|
+
max = 0
|
|
289
|
+
str.unpack('C*').each do |c|
|
|
290
|
+
buff << ", " if max > 0
|
|
291
|
+
buff << "\t" if max == 0
|
|
292
|
+
buff << sprintf('(byte) 0x%.2x', c)
|
|
293
|
+
max +=1
|
|
294
|
+
cnt +=1
|
|
295
|
+
|
|
296
|
+
if (max > 7)
|
|
297
|
+
buff << ",\n" if cnt != str.length
|
|
298
|
+
max = 0
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
buff << "\n};\n"
|
|
302
|
+
return buff
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
#
|
|
306
|
+
# Converts a raw string to a powershell byte array
|
|
307
|
+
#
|
|
308
|
+
def self.to_powershell(str, name = "buf")
|
|
309
|
+
return Rex::Exploitation::Powershell::Script.to_byte_array(str, name)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
#
|
|
313
|
+
# Converts a raw string to a vbscript byte array
|
|
314
|
+
#
|
|
315
|
+
def self.to_vbscript(str, name = "buf")
|
|
316
|
+
return "#{name}" if str.nil? or str.empty?
|
|
317
|
+
|
|
318
|
+
code = str.unpack('C*')
|
|
319
|
+
buff = "#{name}=Chr(#{code[0]})"
|
|
320
|
+
1.upto(code.length-1) do |byte|
|
|
321
|
+
if(byte % 100 == 0)
|
|
322
|
+
buff << "\r\n#{name}=#{name}"
|
|
323
|
+
end
|
|
324
|
+
# exe is an Array of bytes, not a String, thanks to the unpack
|
|
325
|
+
# above, so the following line is not subject to the different
|
|
326
|
+
# treatments of String#[] between ruby 1.8 and 1.9
|
|
327
|
+
buff << "&Chr(#{code[byte]})"
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
return buff
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
#
|
|
334
|
+
# Converts a raw string into a vba buffer
|
|
335
|
+
#
|
|
336
|
+
def self.to_vbapplication(str, name = "buf")
|
|
337
|
+
return "#{name} = Array()" if str.nil? or str.empty?
|
|
338
|
+
|
|
339
|
+
code = str.unpack('C*')
|
|
340
|
+
buff = "#{name} = Array("
|
|
341
|
+
maxbytes = 20
|
|
342
|
+
|
|
343
|
+
1.upto(code.length) do |idx|
|
|
344
|
+
buff << code[idx].to_s
|
|
345
|
+
buff << "," if idx < code.length - 1
|
|
346
|
+
buff << " _\r\n" if (idx > 1 and (idx % maxbytes) == 0)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
buff << ")\r\n"
|
|
350
|
+
|
|
351
|
+
return buff
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
#
|
|
355
|
+
# Creates a perl-style comment
|
|
356
|
+
#
|
|
357
|
+
def self.to_perl_comment(str, wrap = DefaultWrap)
|
|
358
|
+
return wordwrap(str, 0, wrap, '', '# ')
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
#
|
|
362
|
+
# Creates a Bash-style comment
|
|
363
|
+
#
|
|
364
|
+
def self.to_bash_comment(str, wrap = DefaultWrap)
|
|
365
|
+
return wordwrap(str, 0, wrap, '', '# ')
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
#
|
|
369
|
+
# Returns the raw string
|
|
370
|
+
#
|
|
371
|
+
def self.to_raw(str)
|
|
372
|
+
return str
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
#
|
|
376
|
+
# Converts ISO-8859-1 to UTF-8
|
|
377
|
+
#
|
|
378
|
+
def self.to_utf8(str)
|
|
379
|
+
|
|
380
|
+
if str.respond_to?(:encode)
|
|
381
|
+
# Skip over any bytes that fail to convert to UTF-8
|
|
382
|
+
return str.encode('utf-8', { :invalid => :replace, :undef => :replace, :replace => '' })
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
begin
|
|
386
|
+
Iconv.iconv("utf-8","iso-8859-1", str).join(" ")
|
|
387
|
+
rescue
|
|
388
|
+
raise ::RuntimeError, "Your installation does not support iconv (needed for utf8 conversion)"
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
#
|
|
393
|
+
# Converts ASCII to EBCDIC
|
|
394
|
+
#
|
|
395
|
+
class IllegalSequence < ArgumentError; end
|
|
396
|
+
|
|
397
|
+
# A native implementation of the ASCII->EBCDIC table, used to fall back from using
|
|
398
|
+
# Iconv
|
|
399
|
+
def self.to_ebcdic_rex(str)
|
|
400
|
+
new_str = []
|
|
401
|
+
str.each_byte do |x|
|
|
402
|
+
if Iconv_ASCII.index(x.chr)
|
|
403
|
+
new_str << Iconv_EBCDIC[Iconv_ASCII.index(x.chr)]
|
|
404
|
+
else
|
|
405
|
+
raise Rex::Text::IllegalSequence, ("\\x%x" % x)
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
new_str.join
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# A native implementation of the EBCDIC->ASCII table, used to fall back from using
|
|
412
|
+
# Iconv
|
|
413
|
+
def self.from_ebcdic_rex(str)
|
|
414
|
+
new_str = []
|
|
415
|
+
str.each_byte do |x|
|
|
416
|
+
if Iconv_EBCDIC.index(x.chr)
|
|
417
|
+
new_str << Iconv_ASCII[Iconv_EBCDIC.index(x.chr)]
|
|
418
|
+
else
|
|
419
|
+
raise Rex::Text::IllegalSequence, ("\\x%x" % x)
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
new_str.join
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
def self.to_ebcdic(str)
|
|
426
|
+
begin
|
|
427
|
+
Iconv.iconv("EBCDIC-US", "ASCII", str).first
|
|
428
|
+
rescue ::Iconv::IllegalSequence => e
|
|
429
|
+
raise e
|
|
430
|
+
rescue
|
|
431
|
+
self.to_ebcdic_rex(str)
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
#
|
|
436
|
+
# Converts EBCIDC to ASCII
|
|
437
|
+
#
|
|
438
|
+
def self.from_ebcdic(str)
|
|
439
|
+
begin
|
|
440
|
+
Iconv.iconv("ASCII", "EBCDIC-US", str).first
|
|
441
|
+
rescue ::Iconv::IllegalSequence => e
|
|
442
|
+
raise e
|
|
443
|
+
rescue
|
|
444
|
+
self.from_ebcdic_rex(str)
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
#
|
|
449
|
+
# Returns the words in +str+ as an Array.
|
|
450
|
+
#
|
|
451
|
+
# strict - include *only* words, no boundary characters (like spaces, etc.)
|
|
452
|
+
#
|
|
453
|
+
def self.to_words( str, strict = false )
|
|
454
|
+
splits = str.split( /\b/ )
|
|
455
|
+
splits.reject! { |w| !(w =~ /\w/) } if strict
|
|
456
|
+
splits
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
#
|
|
460
|
+
# Removes noise from 2 Strings and return a refined String version.
|
|
461
|
+
#
|
|
462
|
+
def self.refine( str1, str2 )
|
|
463
|
+
return str1 if str1 == str2
|
|
464
|
+
|
|
465
|
+
# get the words of the first str in an array
|
|
466
|
+
s_words = to_words( str1 )
|
|
467
|
+
|
|
468
|
+
# get the words of the second str in an array
|
|
469
|
+
o_words = to_words( str2 )
|
|
470
|
+
|
|
471
|
+
# get what hasn't changed (the rdiff, so to speak) as a string
|
|
472
|
+
(s_words - (s_words - o_words)).join
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
#
|
|
476
|
+
# Returns a unicode escaped string for Javascript
|
|
477
|
+
#
|
|
478
|
+
def self.to_unescape(data, endian=ENDIAN_LITTLE, prefix='%%u')
|
|
479
|
+
data << "\x41" if (data.length % 2 != 0)
|
|
480
|
+
dptr = 0
|
|
481
|
+
buff = ''
|
|
482
|
+
while (dptr < data.length)
|
|
483
|
+
c1 = data[dptr,1].unpack("C*")[0]
|
|
484
|
+
dptr += 1
|
|
485
|
+
c2 = data[dptr,1].unpack("C*")[0]
|
|
486
|
+
dptr += 1
|
|
487
|
+
|
|
488
|
+
if (endian == ENDIAN_LITTLE)
|
|
489
|
+
buff << sprintf("#{prefix}%.2x%.2x", c2, c1)
|
|
490
|
+
else
|
|
491
|
+
buff << sprintf("#{prefix}%.2x%.2x", c1, c2)
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
return buff
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
#
|
|
498
|
+
# Returns the escaped octal version of the supplied string
|
|
499
|
+
#
|
|
500
|
+
# @example
|
|
501
|
+
# Rex::Text.to_octal("asdf") # => "\\141\\163\\144\\146"
|
|
502
|
+
#
|
|
503
|
+
# @param str [String] The string to be converted
|
|
504
|
+
# @param prefix [String]
|
|
505
|
+
# @return [String] The escaped octal version of +str+
|
|
506
|
+
def self.to_octal(str, prefix = "\\")
|
|
507
|
+
octal = ""
|
|
508
|
+
str.each_byte { |b|
|
|
509
|
+
octal << "#{prefix}#{b.to_s 8}"
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
return octal
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
#
|
|
516
|
+
# Returns the escaped hex version of the supplied string
|
|
517
|
+
#
|
|
518
|
+
# @example
|
|
519
|
+
# Rex::Text.to_hex("asdf") # => "\\x61\\x73\\x64\\x66"
|
|
520
|
+
#
|
|
521
|
+
# @param str (see to_octal)
|
|
522
|
+
# @param prefix (see to_octal)
|
|
523
|
+
# @param count [Fixnum] Number of bytes to put in each escape chunk
|
|
524
|
+
# @return [String] The escaped hex version of +str+
|
|
525
|
+
def self.to_hex(str, prefix = "\\x", count = 1)
|
|
526
|
+
raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)
|
|
527
|
+
|
|
528
|
+
# XXX: Regexp.new is used here since using /.{#{count}}/o would compile
|
|
529
|
+
# the regex the first time it is used and never check again. Since we
|
|
530
|
+
# want to know how many to capture on every instance, we do it this
|
|
531
|
+
# way.
|
|
532
|
+
return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s| prefix + s }
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
#
|
|
536
|
+
# Returns the string with nonprintable hex characters sanitized to ascii.
|
|
537
|
+
# Similiar to {.to_hex}, but regular ASCII is not translated if +count+ is 1.
|
|
538
|
+
#
|
|
539
|
+
# @example
|
|
540
|
+
# Rex::Text.to_hex_ascii("\x7fABC\0") # => "\\x7fABC\\x00"
|
|
541
|
+
#
|
|
542
|
+
# @param str (see to_hex)
|
|
543
|
+
# @param prefix (see to_hex)
|
|
544
|
+
# @param count (see to_hex)
|
|
545
|
+
# @param suffix [String,nil] A string to append to the converted bytes
|
|
546
|
+
# @return [String] The original string with non-printables converted to
|
|
547
|
+
# their escaped hex representation
|
|
548
|
+
def self.to_hex_ascii(str, prefix = "\\x", count = 1, suffix=nil)
|
|
549
|
+
raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)
|
|
550
|
+
return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s|
|
|
551
|
+
(0x20..0x7e) === s.to_i(16) ? s.to_i(16).chr : prefix + s + suffix.to_s
|
|
552
|
+
}
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
#
|
|
556
|
+
# Converts standard ASCII text to a unicode string.
|
|
557
|
+
#
|
|
558
|
+
# Supported unicode types include: utf-16le, utf16-be, utf32-le,
|
|
559
|
+
# utf32-be, utf-7, and utf-8
|
|
560
|
+
#
|
|
561
|
+
# Providing 'mode' provides hints to the actual encoder as to how it
|
|
562
|
+
# should encode the string.
|
|
563
|
+
#
|
|
564
|
+
# Only UTF-7 and UTF-8 use "mode".
|
|
565
|
+
#
|
|
566
|
+
# utf-7 by default does not encode alphanumeric and a few other
|
|
567
|
+
# characters. By specifying the mode of "all", then all of the
|
|
568
|
+
# characters are encoded, not just the non-alphanumeric set.
|
|
569
|
+
# to_unicode(str, 'utf-7', 'all')
|
|
570
|
+
#
|
|
571
|
+
# utf-8 specifies that alphanumeric characters are used directly, eg
|
|
572
|
+
# "a" is just "a". However, there exist 6 different overlong
|
|
573
|
+
# encodings of "a" that are technically not valid, but parse just fine
|
|
574
|
+
# in most utf-8 parsers. (0xC1A1, 0xE081A1, 0xF08081A1, 0xF8808081A1,
|
|
575
|
+
# 0xFC80808081A1, 0xFE8080808081A1). How many bytes to use for the
|
|
576
|
+
# overlong enocding is specified providing 'size'. to_unicode(str,
|
|
577
|
+
# 'utf-8', 'overlong', 2)
|
|
578
|
+
#
|
|
579
|
+
# Many utf-8 parsers also allow invalid overlong encodings, where bits
|
|
580
|
+
# that are unused when encoding a single byte are modified. Many
|
|
581
|
+
# parsers will ignore these bits, rendering simple string matching to
|
|
582
|
+
# be ineffective for dealing with UTF-8 strings. There are many more
|
|
583
|
+
# invalid overlong encodings possible for "a". For example, three
|
|
584
|
+
# encodings are available for an invalid 2 byte encoding of "a".
|
|
585
|
+
# (0xC1E1 0xC161 0xC121).
|
|
586
|
+
#
|
|
587
|
+
# By specifying "invalid", a random invalid encoding is chosen for the
|
|
588
|
+
# given byte size. to_unicode(str, 'utf-8', 'invalid', 2)
|
|
589
|
+
#
|
|
590
|
+
# utf-7 defaults to 'normal' utf-7 encoding utf-8 defaults to 2 byte
|
|
591
|
+
# 'normal' encoding
|
|
592
|
+
def self.to_unicode(str='', type = 'utf-16le', mode = '', size = '')
|
|
593
|
+
return '' if not str
|
|
594
|
+
case type
|
|
595
|
+
when 'utf-16le'
|
|
596
|
+
return str.unpack('C*').pack('v*')
|
|
597
|
+
when 'utf-16be'
|
|
598
|
+
return str.unpack('C*').pack('n*')
|
|
599
|
+
when 'utf-32le'
|
|
600
|
+
return str.unpack('C*').pack('V*')
|
|
601
|
+
when 'utf-32be'
|
|
602
|
+
return str.unpack('C*').pack('N*')
|
|
603
|
+
when 'utf-7'
|
|
604
|
+
case mode
|
|
605
|
+
when 'all'
|
|
606
|
+
return str.gsub(/./){ |a|
|
|
607
|
+
out = ''
|
|
608
|
+
if 'a' != '+'
|
|
609
|
+
out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '')
|
|
610
|
+
end
|
|
611
|
+
'+' + out + '-'
|
|
612
|
+
}
|
|
613
|
+
else
|
|
614
|
+
return str.gsub(/[^\n\r\t\ A-Za-z0-9\'\(\),-.\/\:\?]/){ |a|
|
|
615
|
+
out = ''
|
|
616
|
+
if a != '+'
|
|
617
|
+
out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '')
|
|
618
|
+
end
|
|
619
|
+
'+' + out + '-'
|
|
620
|
+
}
|
|
621
|
+
end
|
|
622
|
+
when 'utf-8'
|
|
623
|
+
if size == ''
|
|
624
|
+
size = 2
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
if size >= 2 and size <= 7
|
|
628
|
+
string = ''
|
|
629
|
+
str.each_byte { |a|
|
|
630
|
+
if (a < 21 || a > 0x7f) || mode != ''
|
|
631
|
+
# ugh. turn a single byte into the binary representation of it, in array form
|
|
632
|
+
bin = [a].pack('C').unpack('B8')[0].split(//)
|
|
633
|
+
|
|
634
|
+
# even more ugh.
|
|
635
|
+
bin.collect!{|a_| a_.to_i}
|
|
636
|
+
|
|
637
|
+
out = Array.new(8 * size, 0)
|
|
638
|
+
|
|
639
|
+
0.upto(size - 1) { |i|
|
|
640
|
+
out[i] = 1
|
|
641
|
+
out[i * 8] = 1
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
i = 0
|
|
645
|
+
byte = 0
|
|
646
|
+
bin.reverse.each { |bit|
|
|
647
|
+
if i < 6
|
|
648
|
+
mod = (((size * 8) - 1) - byte * 8) - i
|
|
649
|
+
out[mod] = bit
|
|
650
|
+
else
|
|
651
|
+
byte = byte + 1
|
|
652
|
+
i = 0
|
|
653
|
+
redo
|
|
654
|
+
end
|
|
655
|
+
i = i + 1
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
if mode != ''
|
|
659
|
+
case mode
|
|
660
|
+
when 'overlong'
|
|
661
|
+
# do nothing, since we already handle this as above...
|
|
662
|
+
when 'invalid'
|
|
663
|
+
done = 0
|
|
664
|
+
while done == 0
|
|
665
|
+
# the ghetto...
|
|
666
|
+
bits = [7, 8, 15, 16, 23, 24, 31, 32, 41]
|
|
667
|
+
bits.each { |bit|
|
|
668
|
+
bit = (size * 8) - bit
|
|
669
|
+
if bit > 1
|
|
670
|
+
set = rand(2)
|
|
671
|
+
if out[bit] != set
|
|
672
|
+
out[bit] = set
|
|
673
|
+
done = 1
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
}
|
|
677
|
+
end
|
|
678
|
+
else
|
|
679
|
+
raise TypeError, 'Invalid mode. Only "overlong" and "invalid" are acceptable modes for utf-8'
|
|
680
|
+
end
|
|
681
|
+
end
|
|
682
|
+
string << [out.join('')].pack('B*')
|
|
683
|
+
else
|
|
684
|
+
string << [a].pack('C')
|
|
685
|
+
end
|
|
686
|
+
}
|
|
687
|
+
return string
|
|
688
|
+
else
|
|
689
|
+
raise TypeError, 'invalid utf-8 size'
|
|
690
|
+
end
|
|
691
|
+
when 'uhwtfms' # suggested name from HD :P
|
|
692
|
+
load_codepage()
|
|
693
|
+
|
|
694
|
+
string = ''
|
|
695
|
+
# overloading mode as codepage
|
|
696
|
+
if mode == ''
|
|
697
|
+
mode = 1252 # ANSI - Latan 1, default for US installs of MS products
|
|
698
|
+
else
|
|
699
|
+
mode = mode.to_i
|
|
700
|
+
end
|
|
701
|
+
if @@codepage_map_cache[mode].nil?
|
|
702
|
+
raise TypeError, "Invalid codepage #{mode}"
|
|
703
|
+
end
|
|
704
|
+
str.each_byte {|byte|
|
|
705
|
+
char = [byte].pack('C*')
|
|
706
|
+
possible = @@codepage_map_cache[mode]['data'][char]
|
|
707
|
+
if possible.nil?
|
|
708
|
+
raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}"
|
|
709
|
+
end
|
|
710
|
+
string << possible[ rand(possible.length) ]
|
|
711
|
+
}
|
|
712
|
+
return string
|
|
713
|
+
when 'uhwtfms-half' # suggested name from HD :P
|
|
714
|
+
load_codepage()
|
|
715
|
+
string = ''
|
|
716
|
+
# overloading mode as codepage
|
|
717
|
+
if mode == ''
|
|
718
|
+
mode = 1252 # ANSI - Latan 1, default for US installs of MS products
|
|
719
|
+
else
|
|
720
|
+
mode = mode.to_i
|
|
721
|
+
end
|
|
722
|
+
if mode != 1252
|
|
723
|
+
raise TypeError, "Invalid codepage #{mode}, only 1252 supported for uhwtfms_half"
|
|
724
|
+
end
|
|
725
|
+
str.each_byte {|byte|
|
|
726
|
+
if ((byte >= 33 && byte <= 63) || (byte >= 96 && byte <= 126))
|
|
727
|
+
string << "\xFF" + [byte ^ 32].pack('C')
|
|
728
|
+
elsif (byte >= 64 && byte <= 95)
|
|
729
|
+
string << "\xFF" + [byte ^ 96].pack('C')
|
|
730
|
+
else
|
|
731
|
+
char = [byte].pack('C')
|
|
732
|
+
possible = @@codepage_map_cache[mode]['data'][char]
|
|
733
|
+
if possible.nil?
|
|
734
|
+
raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}"
|
|
735
|
+
end
|
|
736
|
+
string << possible[ rand(possible.length) ]
|
|
737
|
+
end
|
|
738
|
+
}
|
|
739
|
+
return string
|
|
740
|
+
else
|
|
741
|
+
raise TypeError, 'invalid utf type'
|
|
742
|
+
end
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
#
|
|
746
|
+
# Converts a unicode string to standard ASCII text.
|
|
747
|
+
#
|
|
748
|
+
def self.to_ascii(str='', type = 'utf-16le', mode = '', size = '')
|
|
749
|
+
return '' if not str
|
|
750
|
+
case type
|
|
751
|
+
when 'utf-16le'
|
|
752
|
+
return str.unpack('v*').pack('C*')
|
|
753
|
+
when 'utf-16be'
|
|
754
|
+
return str.unpack('n*').pack('C*')
|
|
755
|
+
when 'utf-32le'
|
|
756
|
+
return str.unpack('V*').pack('C*')
|
|
757
|
+
when 'utf-32be'
|
|
758
|
+
return str.unpack('N*').pack('C*')
|
|
759
|
+
when 'utf-7'
|
|
760
|
+
raise TypeError, 'invalid utf type, not yet implemented'
|
|
761
|
+
when 'utf-8'
|
|
762
|
+
raise TypeError, 'invalid utf type, not yet implemented'
|
|
763
|
+
when 'uhwtfms' # suggested name from HD :P
|
|
764
|
+
raise TypeError, 'invalid utf type, not yet implemented'
|
|
765
|
+
when 'uhwtfms-half' # suggested name from HD :P
|
|
766
|
+
raise TypeError, 'invalid utf type, not yet implemented'
|
|
767
|
+
else
|
|
768
|
+
raise TypeError, 'invalid utf type'
|
|
769
|
+
end
|
|
770
|
+
end
|
|
771
|
+
|
|
772
|
+
#
|
|
773
|
+
# Encode a string in a manor useful for HTTP URIs and URI Parameters.
|
|
774
|
+
#
|
|
775
|
+
def self.uri_encode(str, mode = 'hex-normal')
|
|
776
|
+
return "" if str == nil
|
|
777
|
+
|
|
778
|
+
return str if mode == 'none' # fast track no encoding
|
|
779
|
+
|
|
780
|
+
all = /./
|
|
781
|
+
noslashes = /[^\/\\]+/
|
|
782
|
+
# http://tools.ietf.org/html/rfc3986#section-2.3
|
|
783
|
+
normal = /[^a-zA-Z0-9\/\\\.\-_~]+/
|
|
784
|
+
|
|
785
|
+
case mode
|
|
786
|
+
when 'hex-all'
|
|
787
|
+
return str.gsub(all) { |s| Rex::Text.to_hex(s, '%') }
|
|
788
|
+
when 'hex-normal'
|
|
789
|
+
return str.gsub(normal) { |s| Rex::Text.to_hex(s, '%') }
|
|
790
|
+
when 'hex-noslashes'
|
|
791
|
+
return str.gsub(noslashes) { |s| Rex::Text.to_hex(s, '%') }
|
|
792
|
+
when 'hex-random'
|
|
793
|
+
res = ''
|
|
794
|
+
str.each_byte do |c|
|
|
795
|
+
b = c.chr
|
|
796
|
+
res << ((rand(2) == 0) ?
|
|
797
|
+
b.gsub(all) { |s| Rex::Text.to_hex(s, '%') } :
|
|
798
|
+
b.gsub(normal){ |s| Rex::Text.to_hex(s, '%') } )
|
|
799
|
+
end
|
|
800
|
+
return res
|
|
801
|
+
when 'u-all'
|
|
802
|
+
return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
|
|
803
|
+
when 'u-normal'
|
|
804
|
+
return str.gsub(normal) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
|
|
805
|
+
when 'u-noslashes'
|
|
806
|
+
return str.gsub(noslashes) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
|
|
807
|
+
when 'u-random'
|
|
808
|
+
res = ''
|
|
809
|
+
str.each_byte do |c|
|
|
810
|
+
b = c.chr
|
|
811
|
+
res << ((rand(2) == 0) ?
|
|
812
|
+
b.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) } :
|
|
813
|
+
b.gsub(normal){ |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) } )
|
|
814
|
+
end
|
|
815
|
+
return res
|
|
816
|
+
when 'u-half'
|
|
817
|
+
return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms-half'), '%u', 2) }
|
|
818
|
+
else
|
|
819
|
+
raise TypeError, "invalid mode #{mode.inspect}"
|
|
820
|
+
end
|
|
821
|
+
end
|
|
822
|
+
|
|
823
|
+
#
|
|
824
|
+
# Encode a string in a manner useful for HTTP URIs and URI Parameters.
|
|
825
|
+
#
|
|
826
|
+
# @param str [String] The string to be encoded
|
|
827
|
+
# @param mode ["hex","int","int-wide"]
|
|
828
|
+
# @return [String]
|
|
829
|
+
# @raise [TypeError] if +mode+ is not one of the three available modes
|
|
830
|
+
def self.html_encode(str, mode = 'hex')
|
|
831
|
+
case mode
|
|
832
|
+
when 'hex'
|
|
833
|
+
return str.unpack('C*').collect{ |i| "&#x" + ("%.2x" % i) + ";"}.join
|
|
834
|
+
when 'int'
|
|
835
|
+
return str.unpack('C*').collect{ |i| "&#" + i.to_s + ";"}.join
|
|
836
|
+
when 'int-wide'
|
|
837
|
+
return str.unpack('C*').collect{ |i| "&#" + ("0" * (7 - i.to_s.length)) + i.to_s + ";" }.join
|
|
838
|
+
else
|
|
839
|
+
raise TypeError, 'invalid mode'
|
|
840
|
+
end
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
#
|
|
844
|
+
# Decode a string that's html encoded
|
|
845
|
+
#
|
|
846
|
+
def self.html_decode(str)
|
|
847
|
+
decoded_str = CGI.unescapeHTML(str)
|
|
848
|
+
return decoded_str
|
|
849
|
+
end
|
|
850
|
+
|
|
851
|
+
#
|
|
852
|
+
# Encode an ASCII string so it's safe for XML. It's a wrapper for to_hex_ascii.
|
|
853
|
+
#
|
|
854
|
+
def self.xml_char_encode(str)
|
|
855
|
+
self.to_hex_ascii(str, "&#x", 1, ";")
|
|
856
|
+
end
|
|
857
|
+
|
|
858
|
+
#
|
|
859
|
+
# Decode a URI encoded string
|
|
860
|
+
#
|
|
861
|
+
def self.uri_decode(str)
|
|
862
|
+
str.gsub(/(%[a-z0-9]{2})/i){ |c| [c[1,2]].pack("H*") }
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
#
|
|
866
|
+
# Converts a string to random case
|
|
867
|
+
#
|
|
868
|
+
# @example
|
|
869
|
+
# Rex::Text.to_rand_case("asdf") # => "asDf"
|
|
870
|
+
#
|
|
871
|
+
# @param str [String] The string to randomize
|
|
872
|
+
# @return [String]
|
|
873
|
+
# @see permute_case
|
|
874
|
+
# @see to_mixed_case_array
|
|
875
|
+
def self.to_rand_case(str)
|
|
876
|
+
buf = str.dup
|
|
877
|
+
0.upto(str.length) do |i|
|
|
878
|
+
buf[i,1] = rand(2) == 0 ? str[i,1].upcase : str[i,1].downcase
|
|
879
|
+
end
|
|
880
|
+
return buf
|
|
881
|
+
end
|
|
882
|
+
|
|
883
|
+
#
|
|
884
|
+
# Takes a string, and returns an array of all mixed case versions.
|
|
885
|
+
#
|
|
886
|
+
# @example
|
|
887
|
+
# >> Rex::Text.to_mixed_case_array "abc1"
|
|
888
|
+
# => ["abc1", "abC1", "aBc1", "aBC1", "Abc1", "AbC1", "ABc1", "ABC1"]
|
|
889
|
+
#
|
|
890
|
+
# @param str [String] The string to randomize
|
|
891
|
+
# @return [Array<String>]
|
|
892
|
+
# @see permute_case
|
|
893
|
+
def self.to_mixed_case_array(str)
|
|
894
|
+
letters = []
|
|
895
|
+
str.scan(/./).each { |l| letters << [l.downcase, l.upcase] }
|
|
896
|
+
coords = []
|
|
897
|
+
(1 << str.size).times { |i| coords << ("%0#{str.size}b" % i) }
|
|
898
|
+
mixed = []
|
|
899
|
+
coords.each do |coord|
|
|
900
|
+
c = coord.scan(/./).map {|x| x.to_i}
|
|
901
|
+
this_str = ""
|
|
902
|
+
c.each_with_index { |d,i| this_str << letters[i][d] }
|
|
903
|
+
mixed << this_str
|
|
904
|
+
end
|
|
905
|
+
return mixed.uniq
|
|
906
|
+
end
|
|
907
|
+
|
|
908
|
+
#
|
|
909
|
+
# Converts a string to a nicely formatted hex dump
|
|
910
|
+
#
|
|
911
|
+
# @param str [String] The string to convert
|
|
912
|
+
# @param width [Fixnum] Number of bytes to convert before adding a newline
|
|
913
|
+
# @param base [Fixnum] The base address of the dump
|
|
914
|
+
def self.to_hex_dump(str, width=16, base=nil)
|
|
915
|
+
buf = ''
|
|
916
|
+
idx = 0
|
|
917
|
+
cnt = 0
|
|
918
|
+
snl = false
|
|
919
|
+
lst = 0
|
|
920
|
+
lft_col_len = (base.to_i+str.length).to_s(16).length
|
|
921
|
+
lft_col_len = 8 if lft_col_len < 8
|
|
922
|
+
|
|
923
|
+
while (idx < str.length)
|
|
924
|
+
chunk = str[idx, width]
|
|
925
|
+
addr = base ? "%0#{lft_col_len}x " %(base.to_i + idx) : ''
|
|
926
|
+
line = chunk.unpack("H*")[0].scan(/../).join(" ")
|
|
927
|
+
buf << addr + line
|
|
928
|
+
|
|
929
|
+
if (lst == 0)
|
|
930
|
+
lst = line.length
|
|
931
|
+
buf << " " * 4
|
|
932
|
+
else
|
|
933
|
+
buf << " " * ((lst - line.length) + 4).abs
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
buf << "|"
|
|
937
|
+
|
|
938
|
+
chunk.unpack("C*").each do |c|
|
|
939
|
+
if (c > 0x1f and c < 0x7f)
|
|
940
|
+
buf << c.chr
|
|
941
|
+
else
|
|
942
|
+
buf << "."
|
|
943
|
+
end
|
|
944
|
+
end
|
|
945
|
+
|
|
946
|
+
buf << "|\n"
|
|
947
|
+
|
|
948
|
+
idx += width
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
buf << "\n"
|
|
952
|
+
end
|
|
953
|
+
|
|
954
|
+
#
|
|
955
|
+
# Converts a hex string to a raw string
|
|
956
|
+
#
|
|
957
|
+
# @example
|
|
958
|
+
# Rex::Text.hex_to_raw("\\x41\\x7f\\x42") # => "A\x7fB"
|
|
959
|
+
#
|
|
960
|
+
def self.hex_to_raw(str)
|
|
961
|
+
[ str.downcase.gsub(/'/,'').gsub(/\\?x([a-f0-9][a-f0-9])/, '\1') ].pack("H*")
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
#
|
|
965
|
+
# Turn non-printable chars into hex representations, leaving others alone
|
|
966
|
+
#
|
|
967
|
+
# If +whitespace+ is true, converts whitespace (0x20, 0x09, etc) to hex as
|
|
968
|
+
# well.
|
|
969
|
+
#
|
|
970
|
+
# @see hexify
|
|
971
|
+
# @see to_hex Converts all the chars
|
|
972
|
+
#
|
|
973
|
+
def self.ascii_safe_hex(str, whitespace=false)
|
|
974
|
+
if whitespace
|
|
975
|
+
str.gsub(/([\x00-\x20\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] }
|
|
976
|
+
else
|
|
977
|
+
str.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0]}
|
|
978
|
+
end
|
|
979
|
+
end
|
|
980
|
+
|
|
981
|
+
#
|
|
982
|
+
# Wraps text at a given column using a supplied indention
|
|
983
|
+
#
|
|
984
|
+
def self.wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '')
|
|
985
|
+
return str.gsub(/.{1,#{col - indent}}(?:\s|\Z)/){
|
|
986
|
+
( (" " * indent) + prepend + $& + append + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
|
|
987
|
+
end
|
|
988
|
+
|
|
989
|
+
#
|
|
990
|
+
# Converts a string to a hex version with wrapping support
|
|
991
|
+
#
|
|
992
|
+
def self.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '')
|
|
993
|
+
output = buf_start
|
|
994
|
+
cur = 0
|
|
995
|
+
count = 0
|
|
996
|
+
new_line = true
|
|
997
|
+
|
|
998
|
+
# Go through each byte in the string
|
|
999
|
+
str.each_byte { |byte|
|
|
1000
|
+
count += 1
|
|
1001
|
+
append = ''
|
|
1002
|
+
|
|
1003
|
+
# If this is a new line, prepend with the
|
|
1004
|
+
# line start text
|
|
1005
|
+
if (new_line == true)
|
|
1006
|
+
append << line_start
|
|
1007
|
+
new_line = false
|
|
1008
|
+
end
|
|
1009
|
+
|
|
1010
|
+
# Append the hexified version of the byte
|
|
1011
|
+
append << sprintf("\\x%.2x", byte)
|
|
1012
|
+
cur += append.length
|
|
1013
|
+
|
|
1014
|
+
# If we're about to hit the column or have gone past it,
|
|
1015
|
+
# time to finish up this line
|
|
1016
|
+
if ((cur + line_end.length >= col) or (cur + buf_end.length >= col))
|
|
1017
|
+
new_line = true
|
|
1018
|
+
cur = 0
|
|
1019
|
+
|
|
1020
|
+
# If this is the last byte, use the buf_end instead of
|
|
1021
|
+
# line_end
|
|
1022
|
+
if (count == str.length)
|
|
1023
|
+
append << buf_end + "\n"
|
|
1024
|
+
else
|
|
1025
|
+
append << line_end + "\n"
|
|
1026
|
+
end
|
|
1027
|
+
end
|
|
1028
|
+
|
|
1029
|
+
output << append
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
# If we were in the middle of a line, finish the buffer at this point
|
|
1033
|
+
if (new_line == false)
|
|
1034
|
+
output << buf_end + "\n"
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
return output
|
|
1038
|
+
end
|
|
1039
|
+
|
|
1040
|
+
##
|
|
1041
|
+
#
|
|
1042
|
+
# Transforms
|
|
1043
|
+
#
|
|
1044
|
+
##
|
|
1045
|
+
|
|
1046
|
+
#
|
|
1047
|
+
# Base32 code
|
|
1048
|
+
#
|
|
1049
|
+
|
|
1050
|
+
# Based on --> https://github.com/stesla/base32
|
|
1051
|
+
|
|
1052
|
+
# Copyright (c) 2007-2011 Samuel Tesla
|
|
1053
|
+
|
|
1054
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1055
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
1056
|
+
# in the Software without restriction, including without limitation the rights
|
|
1057
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1058
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
1059
|
+
# furnished to do so, subject to the following conditions:
|
|
1060
|
+
|
|
1061
|
+
# The above copyright notice and this permission notice shall be included in
|
|
1062
|
+
# all copies or substantial portions of the Software.
|
|
1063
|
+
|
|
1064
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1065
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1066
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1067
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1068
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1069
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
1070
|
+
# THE SOFTWARE.
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
#
|
|
1074
|
+
# Base32 encoder
|
|
1075
|
+
#
|
|
1076
|
+
def self.b32encode(bytes_in)
|
|
1077
|
+
n = (bytes_in.length * 8.0 / 5.0).ceil
|
|
1078
|
+
p = n < 8 ? 5 - (bytes_in.length * 8) % 5 : 0
|
|
1079
|
+
c = bytes_in.inject(0) {|m,o| (m << 8) + o} << p
|
|
1080
|
+
[(0..n-1).to_a.reverse.collect {|i| Base32[(c >> i * 5) & 0x1f].chr},
|
|
1081
|
+
("=" * (8-n))]
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
def self.encode_base32(str)
|
|
1085
|
+
bytes = str.bytes
|
|
1086
|
+
result = ''
|
|
1087
|
+
size= 5
|
|
1088
|
+
while bytes.any? do
|
|
1089
|
+
bytes.each_slice(size) do |a|
|
|
1090
|
+
bytes_out = b32encode(a).flatten.join
|
|
1091
|
+
result << bytes_out
|
|
1092
|
+
bytes = bytes.drop(size)
|
|
1093
|
+
end
|
|
1094
|
+
end
|
|
1095
|
+
return result
|
|
1096
|
+
end
|
|
1097
|
+
|
|
1098
|
+
#
|
|
1099
|
+
# Base32 decoder
|
|
1100
|
+
#
|
|
1101
|
+
def self.b32decode(bytes_in)
|
|
1102
|
+
bytes = bytes_in.take_while {|c| c != 61} # strip padding
|
|
1103
|
+
n = (bytes.length * 5.0 / 8.0).floor
|
|
1104
|
+
p = bytes.length < 8 ? 5 - (n * 8) % 5 : 0
|
|
1105
|
+
c = bytes.inject(0) {|m,o| (m << 5) + Base32.index(o.chr)} >> p
|
|
1106
|
+
(0..n-1).to_a.reverse.collect {|i| ((c >> i * 8) & 0xff).chr}
|
|
1107
|
+
end
|
|
1108
|
+
|
|
1109
|
+
def self.decode_base32(str)
|
|
1110
|
+
bytes = str.bytes
|
|
1111
|
+
result = ''
|
|
1112
|
+
size= 8
|
|
1113
|
+
while bytes.any? do
|
|
1114
|
+
bytes.each_slice(size) do |a|
|
|
1115
|
+
bytes_out = b32decode(a).flatten.join
|
|
1116
|
+
result << bytes_out
|
|
1117
|
+
bytes = bytes.drop(size)
|
|
1118
|
+
end
|
|
1119
|
+
end
|
|
1120
|
+
return result
|
|
1121
|
+
end
|
|
1122
|
+
|
|
1123
|
+
#
|
|
1124
|
+
# Base64 encoder
|
|
1125
|
+
#
|
|
1126
|
+
def self.encode_base64(str, delim='')
|
|
1127
|
+
[str.to_s].pack("m").gsub(/\s+/, delim)
|
|
1128
|
+
end
|
|
1129
|
+
|
|
1130
|
+
#
|
|
1131
|
+
# Base64 decoder
|
|
1132
|
+
#
|
|
1133
|
+
def self.decode_base64(str)
|
|
1134
|
+
str.to_s.unpack("m")[0]
|
|
1135
|
+
end
|
|
1136
|
+
|
|
1137
|
+
#
|
|
1138
|
+
# Raw MD5 digest of the supplied string
|
|
1139
|
+
#
|
|
1140
|
+
def self.md5_raw(str)
|
|
1141
|
+
Digest::MD5.digest(str)
|
|
1142
|
+
end
|
|
1143
|
+
|
|
1144
|
+
#
|
|
1145
|
+
# Hexidecimal MD5 digest of the supplied string
|
|
1146
|
+
#
|
|
1147
|
+
def self.md5(str)
|
|
1148
|
+
Digest::MD5.hexdigest(str)
|
|
1149
|
+
end
|
|
1150
|
+
|
|
1151
|
+
#
|
|
1152
|
+
# Raw SHA1 digest of the supplied string
|
|
1153
|
+
#
|
|
1154
|
+
def self.sha1_raw(str)
|
|
1155
|
+
Digest::SHA1.digest(str)
|
|
1156
|
+
end
|
|
1157
|
+
|
|
1158
|
+
#
|
|
1159
|
+
# Hexidecimal SHA1 digest of the supplied string
|
|
1160
|
+
#
|
|
1161
|
+
def self.sha1(str)
|
|
1162
|
+
Digest::SHA1.hexdigest(str)
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
#
|
|
1166
|
+
# Convert hex-encoded characters to literals.
|
|
1167
|
+
#
|
|
1168
|
+
# @example
|
|
1169
|
+
# Rex::Text.dehex("AA\\x42CC") # => "AABCC"
|
|
1170
|
+
#
|
|
1171
|
+
# @see hex_to_raw
|
|
1172
|
+
# @param str [String]
|
|
1173
|
+
def self.dehex(str)
|
|
1174
|
+
return str unless str.respond_to? :match
|
|
1175
|
+
return str unless str.respond_to? :gsub
|
|
1176
|
+
regex = /\x5cx[0-9a-f]{2}/nmi
|
|
1177
|
+
if str.match(regex)
|
|
1178
|
+
str.gsub(regex) { |x| x[2,2].to_i(16).chr }
|
|
1179
|
+
else
|
|
1180
|
+
str
|
|
1181
|
+
end
|
|
1182
|
+
end
|
|
1183
|
+
|
|
1184
|
+
#
|
|
1185
|
+
# Convert and replace hex-encoded characters to literals.
|
|
1186
|
+
#
|
|
1187
|
+
# @param (see dehex)
|
|
1188
|
+
def self.dehex!(str)
|
|
1189
|
+
return str unless str.respond_to? :match
|
|
1190
|
+
return str unless str.respond_to? :gsub
|
|
1191
|
+
regex = /\x5cx[0-9a-f]{2}/nmi
|
|
1192
|
+
str.gsub!(regex) { |x| x[2,2].to_i(16).chr }
|
|
1193
|
+
end
|
|
1194
|
+
|
|
1195
|
+
##
|
|
1196
|
+
#
|
|
1197
|
+
# Generators
|
|
1198
|
+
#
|
|
1199
|
+
##
|
|
1200
|
+
|
|
1201
|
+
|
|
1202
|
+
# Generates a random character.
|
|
1203
|
+
def self.rand_char(bad, chars = AllChars)
|
|
1204
|
+
rand_text(1, bad, chars)
|
|
1205
|
+
end
|
|
1206
|
+
|
|
1207
|
+
# Base text generator method
|
|
1208
|
+
def self.rand_base(len, bad, *foo)
|
|
1209
|
+
cset = (foo.join.unpack("C*") - bad.to_s.unpack("C*")).uniq
|
|
1210
|
+
return "" if cset.length == 0
|
|
1211
|
+
outp = []
|
|
1212
|
+
len.times { outp << cset[rand(cset.length)] }
|
|
1213
|
+
outp.pack("C*")
|
|
1214
|
+
end
|
|
1215
|
+
|
|
1216
|
+
# Generate random bytes of data
|
|
1217
|
+
def self.rand_text(len, bad='', chars = AllChars)
|
|
1218
|
+
foo = chars.split('')
|
|
1219
|
+
rand_base(len, bad, *foo)
|
|
1220
|
+
end
|
|
1221
|
+
|
|
1222
|
+
# Generate random bytes of alpha data
|
|
1223
|
+
def self.rand_text_alpha(len, bad='')
|
|
1224
|
+
foo = []
|
|
1225
|
+
foo += ('A' .. 'Z').to_a
|
|
1226
|
+
foo += ('a' .. 'z').to_a
|
|
1227
|
+
rand_base(len, bad, *foo )
|
|
1228
|
+
end
|
|
1229
|
+
|
|
1230
|
+
# Generate random bytes of lowercase alpha data
|
|
1231
|
+
def self.rand_text_alpha_lower(len, bad='')
|
|
1232
|
+
rand_base(len, bad, *('a' .. 'z').to_a)
|
|
1233
|
+
end
|
|
1234
|
+
|
|
1235
|
+
# Generate random bytes of uppercase alpha data
|
|
1236
|
+
def self.rand_text_alpha_upper(len, bad='')
|
|
1237
|
+
rand_base(len, bad, *('A' .. 'Z').to_a)
|
|
1238
|
+
end
|
|
1239
|
+
|
|
1240
|
+
# Generate random bytes of alphanumeric data
|
|
1241
|
+
def self.rand_text_alphanumeric(len, bad='')
|
|
1242
|
+
foo = []
|
|
1243
|
+
foo += ('A' .. 'Z').to_a
|
|
1244
|
+
foo += ('a' .. 'z').to_a
|
|
1245
|
+
foo += ('0' .. '9').to_a
|
|
1246
|
+
rand_base(len, bad, *foo )
|
|
1247
|
+
end
|
|
1248
|
+
|
|
1249
|
+
# Generate random bytes of alphanumeric hex.
|
|
1250
|
+
def self.rand_text_hex(len, bad='')
|
|
1251
|
+
foo = []
|
|
1252
|
+
foo += ('0' .. '9').to_a
|
|
1253
|
+
foo += ('a' .. 'f').to_a
|
|
1254
|
+
rand_base(len, bad, *foo)
|
|
1255
|
+
end
|
|
1256
|
+
|
|
1257
|
+
# Generate random bytes of numeric data
|
|
1258
|
+
def self.rand_text_numeric(len, bad='')
|
|
1259
|
+
foo = ('0' .. '9').to_a
|
|
1260
|
+
rand_base(len, bad, *foo )
|
|
1261
|
+
end
|
|
1262
|
+
|
|
1263
|
+
# Generate random bytes of english-like data
|
|
1264
|
+
def self.rand_text_english(len, bad='')
|
|
1265
|
+
foo = []
|
|
1266
|
+
foo += (0x21 .. 0x7e).map{ |c| c.chr }
|
|
1267
|
+
rand_base(len, bad, *foo )
|
|
1268
|
+
end
|
|
1269
|
+
|
|
1270
|
+
# Generate random bytes of high ascii data
|
|
1271
|
+
def self.rand_text_highascii(len, bad='')
|
|
1272
|
+
foo = []
|
|
1273
|
+
foo += (0x80 .. 0xff).map{ |c| c.chr }
|
|
1274
|
+
rand_base(len, bad, *foo )
|
|
1275
|
+
end
|
|
1276
|
+
|
|
1277
|
+
# Generate a random GUID
|
|
1278
|
+
#
|
|
1279
|
+
# @example
|
|
1280
|
+
# Rex::Text.rand_guid # => "{ca776ced-4ab8-2ed6-6510-aa71e5e2508e}"
|
|
1281
|
+
#
|
|
1282
|
+
# @return [String]
|
|
1283
|
+
def self.rand_guid
|
|
1284
|
+
"{#{[8,4,4,4,12].map {|a| rand_text_hex(a) }.join("-")}}"
|
|
1285
|
+
end
|
|
1286
|
+
|
|
1287
|
+
#
|
|
1288
|
+
# Convert 16-byte string to a GUID string
|
|
1289
|
+
#
|
|
1290
|
+
# @example
|
|
1291
|
+
# str = "ABCDEFGHIJKLMNOP"
|
|
1292
|
+
# Rex::Text.to_guid(str) #=> "{44434241-4645-4847-494a-4b4c4d4e4f50}"
|
|
1293
|
+
#
|
|
1294
|
+
# @param bytes [String] 16 bytes which represent a GUID in the proper
|
|
1295
|
+
# order.
|
|
1296
|
+
#
|
|
1297
|
+
# @return [String]
|
|
1298
|
+
def self.to_guid(bytes)
|
|
1299
|
+
return nil unless bytes
|
|
1300
|
+
s = bytes.unpack('H*')[0]
|
|
1301
|
+
parts = [
|
|
1302
|
+
s[6, 2] + s[4, 2] + s[2, 2] + s[0, 2],
|
|
1303
|
+
s[10, 2] + s[8, 2],
|
|
1304
|
+
s[14, 2] + s[12, 2],
|
|
1305
|
+
s[16, 4],
|
|
1306
|
+
s[20, 12]
|
|
1307
|
+
]
|
|
1308
|
+
"{#{parts.join('-')}}"
|
|
1309
|
+
end
|
|
1310
|
+
|
|
1311
|
+
#
|
|
1312
|
+
# Creates a pattern that can be used for offset calculation purposes. This
|
|
1313
|
+
# routine is capable of generating patterns using a supplied set and a
|
|
1314
|
+
# supplied number of identifiable characters (slots). The supplied sets
|
|
1315
|
+
# should not contain any duplicate characters or the logic will fail.
|
|
1316
|
+
#
|
|
1317
|
+
# @param length [Fixnum]
|
|
1318
|
+
# @param sets [Array<(String,String,String)>] The character sets to choose
|
|
1319
|
+
# from. Should have 3 elements, each of which must be a string containing
|
|
1320
|
+
# no characters contained in the other sets.
|
|
1321
|
+
# @return [String] A pattern of +length+ bytes, in which any 4-byte chunk is
|
|
1322
|
+
# unique
|
|
1323
|
+
# @see pattern_offset
|
|
1324
|
+
def self.pattern_create(length, sets = nil)
|
|
1325
|
+
buf = ''
|
|
1326
|
+
offsets = []
|
|
1327
|
+
|
|
1328
|
+
# Make sure there's something in sets even if we were given an explicit nil
|
|
1329
|
+
sets ||= [ UpperAlpha, LowerAlpha, Numerals ]
|
|
1330
|
+
|
|
1331
|
+
# Return stupid uses
|
|
1332
|
+
return "" if length.to_i < 1
|
|
1333
|
+
return sets[0][0].chr * length if sets.size == 1 and sets[0].size == 1
|
|
1334
|
+
|
|
1335
|
+
sets.length.times { offsets << 0 }
|
|
1336
|
+
|
|
1337
|
+
until buf.length >= length
|
|
1338
|
+
begin
|
|
1339
|
+
buf << converge_sets(sets, 0, offsets, length)
|
|
1340
|
+
end
|
|
1341
|
+
end
|
|
1342
|
+
|
|
1343
|
+
# Maximum permutations reached, but we need more data
|
|
1344
|
+
if (buf.length < length)
|
|
1345
|
+
buf = buf * (length / buf.length.to_f).ceil
|
|
1346
|
+
end
|
|
1347
|
+
|
|
1348
|
+
buf[0,length]
|
|
1349
|
+
end
|
|
1350
|
+
|
|
1351
|
+
# Step through an arbitrary number of sets of bytes to build up a findable pattern.
|
|
1352
|
+
# This is mostly useful for experimentially determining offset lengths into memory
|
|
1353
|
+
# structures. Note that the supplied sets should never contain duplicate bytes, or
|
|
1354
|
+
# else it can become impossible to measure the offset accurately.
|
|
1355
|
+
def self.patt2(len, sets = nil)
|
|
1356
|
+
buf = ""
|
|
1357
|
+
counter = []
|
|
1358
|
+
sets ||= [ UpperAlpha, LowerAlpha, Numerals ]
|
|
1359
|
+
len ||= len.to_i
|
|
1360
|
+
return "" if len.zero?
|
|
1361
|
+
|
|
1362
|
+
sets = sets.map {|a| a.split(//)}
|
|
1363
|
+
sets.size.times { counter << 0}
|
|
1364
|
+
0.upto(len-1) do |i|
|
|
1365
|
+
setnum = i % sets.size
|
|
1366
|
+
|
|
1367
|
+
#puts counter.inspect
|
|
1368
|
+
end
|
|
1369
|
+
|
|
1370
|
+
return buf
|
|
1371
|
+
end
|
|
1372
|
+
|
|
1373
|
+
#
|
|
1374
|
+
# Calculate the offset to a pattern
|
|
1375
|
+
#
|
|
1376
|
+
# @param pattern [String] The pattern to search. Usually the return value
|
|
1377
|
+
# from {.pattern_create}
|
|
1378
|
+
# @param value [String,Fixnum,Bignum]
|
|
1379
|
+
# @return [Fixnum] Index of the given +value+ within +pattern+, if it exists
|
|
1380
|
+
# @return [nil] if +pattern+ does not contain +value+
|
|
1381
|
+
# @see pattern_create
|
|
1382
|
+
def self.pattern_offset(pattern, value, start=0)
|
|
1383
|
+
if (value.kind_of?(String))
|
|
1384
|
+
pattern.index(value, start)
|
|
1385
|
+
elsif (value.kind_of?(Fixnum) or value.kind_of?(Bignum))
|
|
1386
|
+
pattern.index([ value ].pack('V'), start)
|
|
1387
|
+
else
|
|
1388
|
+
raise ::ArgumentError, "Invalid class for value: #{value.class}"
|
|
1389
|
+
end
|
|
1390
|
+
end
|
|
1391
|
+
|
|
1392
|
+
#
|
|
1393
|
+
# Compresses a string, eliminating all superfluous whitespace before and
|
|
1394
|
+
# after lines and eliminating all lines.
|
|
1395
|
+
#
|
|
1396
|
+
# @param str [String] The string in which to crunch whitespace
|
|
1397
|
+
# @return [String] Just like +str+, but with repeated whitespace characters
|
|
1398
|
+
# trimmed down to a single space
|
|
1399
|
+
def self.compress(str)
|
|
1400
|
+
str.gsub(/\n/m, ' ').gsub(/\s+/, ' ').gsub(/^\s+/, '').gsub(/\s+$/, '')
|
|
1401
|
+
end
|
|
1402
|
+
|
|
1403
|
+
#
|
|
1404
|
+
# Randomize the whitespace in a string
|
|
1405
|
+
#
|
|
1406
|
+
def self.randomize_space(str)
|
|
1407
|
+
set = ["\x09", "\x20", "\x0d", "\x0a"]
|
|
1408
|
+
str.gsub(/\s+/) { |s|
|
|
1409
|
+
len = rand(50)+2
|
|
1410
|
+
buf = ''
|
|
1411
|
+
while (buf.length < len)
|
|
1412
|
+
buf << set.sample
|
|
1413
|
+
end
|
|
1414
|
+
|
|
1415
|
+
buf
|
|
1416
|
+
}
|
|
1417
|
+
end
|
|
1418
|
+
|
|
1419
|
+
# Returns true if zlib can be used.
|
|
1420
|
+
def self.zlib_present?
|
|
1421
|
+
begin
|
|
1422
|
+
temp = Zlib
|
|
1423
|
+
return true
|
|
1424
|
+
rescue
|
|
1425
|
+
return false
|
|
1426
|
+
end
|
|
1427
|
+
end
|
|
1428
|
+
|
|
1429
|
+
# backwards compat for just a bit...
|
|
1430
|
+
def self.gzip_present?
|
|
1431
|
+
self.zlib_present?
|
|
1432
|
+
end
|
|
1433
|
+
|
|
1434
|
+
#
|
|
1435
|
+
# Compresses a string using zlib
|
|
1436
|
+
#
|
|
1437
|
+
# @param str [String] The string to be compressed
|
|
1438
|
+
# @param level [Fixnum] One of the Zlib compression level constants
|
|
1439
|
+
# @return [String] The compressed version of +str+
|
|
1440
|
+
def self.zlib_deflate(str, level = Zlib::BEST_COMPRESSION)
|
|
1441
|
+
if self.zlib_present?
|
|
1442
|
+
z = Zlib::Deflate.new(level)
|
|
1443
|
+
dst = z.deflate(str, Zlib::FINISH)
|
|
1444
|
+
z.close
|
|
1445
|
+
return dst
|
|
1446
|
+
else
|
|
1447
|
+
raise RuntimeError, "Gzip support is not present."
|
|
1448
|
+
end
|
|
1449
|
+
end
|
|
1450
|
+
|
|
1451
|
+
#
|
|
1452
|
+
# Uncompresses a string using zlib
|
|
1453
|
+
#
|
|
1454
|
+
# @param str [String] Compressed string to inflate
|
|
1455
|
+
# @return [String] The uncompressed version of +str+
|
|
1456
|
+
def self.zlib_inflate(str)
|
|
1457
|
+
if(self.zlib_present?)
|
|
1458
|
+
zstream = Zlib::Inflate.new
|
|
1459
|
+
buf = zstream.inflate(str)
|
|
1460
|
+
zstream.finish
|
|
1461
|
+
zstream.close
|
|
1462
|
+
return buf
|
|
1463
|
+
else
|
|
1464
|
+
raise RuntimeError, "Gzip support is not present."
|
|
1465
|
+
end
|
|
1466
|
+
end
|
|
1467
|
+
|
|
1468
|
+
#
|
|
1469
|
+
# Compresses a string using gzip
|
|
1470
|
+
#
|
|
1471
|
+
# @param str (see zlib_deflate)
|
|
1472
|
+
# @param level [Fixnum] Compression level, 1 (fast) to 9 (best)
|
|
1473
|
+
# @return (see zlib_deflate)
|
|
1474
|
+
def self.gzip(str, level = 9)
|
|
1475
|
+
raise RuntimeError, "Gzip support is not present." if (!zlib_present?)
|
|
1476
|
+
raise RuntimeError, "Invalid gzip compression level" if (level < 1 or level > 9)
|
|
1477
|
+
|
|
1478
|
+
s = ""
|
|
1479
|
+
s.force_encoding('ASCII-8BIT') if s.respond_to?(:encoding)
|
|
1480
|
+
gz = Zlib::GzipWriter.new(StringIO.new(s, 'wb'), level)
|
|
1481
|
+
gz << str
|
|
1482
|
+
gz.close
|
|
1483
|
+
return s
|
|
1484
|
+
end
|
|
1485
|
+
|
|
1486
|
+
#
|
|
1487
|
+
# Uncompresses a string using gzip
|
|
1488
|
+
#
|
|
1489
|
+
# @param str (see zlib_inflate)
|
|
1490
|
+
# @return (see zlib_inflate)
|
|
1491
|
+
def self.ungzip(str)
|
|
1492
|
+
raise RuntimeError, "Gzip support is not present." if (!zlib_present?)
|
|
1493
|
+
|
|
1494
|
+
s = ""
|
|
1495
|
+
s.force_encoding('ASCII-8BIT') if s.respond_to?(:encoding)
|
|
1496
|
+
gz = Zlib::GzipReader.new(StringIO.new(str, 'rb'))
|
|
1497
|
+
s << gz.read
|
|
1498
|
+
gz.close
|
|
1499
|
+
return s
|
|
1500
|
+
end
|
|
1501
|
+
|
|
1502
|
+
#
|
|
1503
|
+
# Return the index of the first badchar in +data+, otherwise return
|
|
1504
|
+
# nil if there wasn't any badchar occurences.
|
|
1505
|
+
#
|
|
1506
|
+
# @param data [String] The string to check for bad characters
|
|
1507
|
+
# @param badchars [String] A list of characters considered to be bad
|
|
1508
|
+
# @return [Fixnum] Index of the first bad character if any exist in +data+
|
|
1509
|
+
# @return [nil] If +data+ contains no bad characters
|
|
1510
|
+
def self.badchar_index(data, badchars = '')
|
|
1511
|
+
badchars.unpack("C*").each { |badchar|
|
|
1512
|
+
pos = data.index(badchar.chr)
|
|
1513
|
+
return pos if pos
|
|
1514
|
+
}
|
|
1515
|
+
return nil
|
|
1516
|
+
end
|
|
1517
|
+
|
|
1518
|
+
#
|
|
1519
|
+
# Removes bad characters from a string.
|
|
1520
|
+
#
|
|
1521
|
+
# Modifies +data+ in place
|
|
1522
|
+
#
|
|
1523
|
+
# @param data [#delete]
|
|
1524
|
+
# @param badchars [String] A list of characters considered to be bad
|
|
1525
|
+
def self.remove_badchars(data, badchars = '')
|
|
1526
|
+
data.delete(badchars)
|
|
1527
|
+
end
|
|
1528
|
+
|
|
1529
|
+
#
|
|
1530
|
+
# Returns all chars that are not in the supplied set
|
|
1531
|
+
#
|
|
1532
|
+
# @param keepers [String]
|
|
1533
|
+
# @return [String] All characters not contained in +keepers+
|
|
1534
|
+
def self.charset_exclude(keepers)
|
|
1535
|
+
[*(0..255)].pack('C*').delete(keepers)
|
|
1536
|
+
end
|
|
1537
|
+
|
|
1538
|
+
#
|
|
1539
|
+
# Shuffles a byte stream
|
|
1540
|
+
#
|
|
1541
|
+
# @param str [String]
|
|
1542
|
+
# @return [String] The shuffled result
|
|
1543
|
+
# @see shuffle_a
|
|
1544
|
+
def self.shuffle_s(str)
|
|
1545
|
+
shuffle_a(str.unpack("C*")).pack("C*")
|
|
1546
|
+
end
|
|
1547
|
+
|
|
1548
|
+
#
|
|
1549
|
+
# Performs a Fisher-Yates shuffle on an array
|
|
1550
|
+
#
|
|
1551
|
+
# Modifies +arr+ in place
|
|
1552
|
+
#
|
|
1553
|
+
# @param arr [Array] The array to be shuffled
|
|
1554
|
+
# @return [Array]
|
|
1555
|
+
def self.shuffle_a(arr)
|
|
1556
|
+
len = arr.length
|
|
1557
|
+
max = len - 1
|
|
1558
|
+
cyc = [* (0..max) ]
|
|
1559
|
+
for d in cyc
|
|
1560
|
+
e = rand(d+1)
|
|
1561
|
+
next if e == d
|
|
1562
|
+
f = arr[d];
|
|
1563
|
+
g = arr[e];
|
|
1564
|
+
arr[d] = g;
|
|
1565
|
+
arr[e] = f;
|
|
1566
|
+
end
|
|
1567
|
+
return arr
|
|
1568
|
+
end
|
|
1569
|
+
|
|
1570
|
+
# Permute the case of a word
|
|
1571
|
+
def self.permute_case(word, idx=0)
|
|
1572
|
+
res = []
|
|
1573
|
+
|
|
1574
|
+
if( (UpperAlpha+LowerAlpha).index(word[idx,1]))
|
|
1575
|
+
|
|
1576
|
+
word_ucase = word.dup
|
|
1577
|
+
word_ucase[idx, 1] = word[idx, 1].upcase
|
|
1578
|
+
|
|
1579
|
+
word_lcase = word.dup
|
|
1580
|
+
word_lcase[idx, 1] = word[idx, 1].downcase
|
|
1581
|
+
|
|
1582
|
+
if (idx == word.length)
|
|
1583
|
+
return [word]
|
|
1584
|
+
else
|
|
1585
|
+
res << permute_case(word_ucase, idx+1)
|
|
1586
|
+
res << permute_case(word_lcase, idx+1)
|
|
1587
|
+
end
|
|
1588
|
+
else
|
|
1589
|
+
res << permute_case(word, idx+1)
|
|
1590
|
+
end
|
|
1591
|
+
|
|
1592
|
+
res.flatten
|
|
1593
|
+
end
|
|
1594
|
+
|
|
1595
|
+
# Generate a random hostname
|
|
1596
|
+
#
|
|
1597
|
+
# @return [String] A random string conforming to the rules of FQDNs
|
|
1598
|
+
def self.rand_hostname
|
|
1599
|
+
host = []
|
|
1600
|
+
(rand(5) + 1).times {
|
|
1601
|
+
host.push(Rex::Text.rand_text_alphanumeric(rand(10) + 1))
|
|
1602
|
+
}
|
|
1603
|
+
host.push(TLDs.sample)
|
|
1604
|
+
host.join('.').downcase
|
|
1605
|
+
end
|
|
1606
|
+
|
|
1607
|
+
# Generate a state
|
|
1608
|
+
def self.rand_state()
|
|
1609
|
+
States.sample
|
|
1610
|
+
end
|
|
1611
|
+
|
|
1612
|
+
# Generate a surname
|
|
1613
|
+
def self.rand_surname
|
|
1614
|
+
Surnames.sample
|
|
1615
|
+
end
|
|
1616
|
+
|
|
1617
|
+
# Generate a name
|
|
1618
|
+
def self.rand_name
|
|
1619
|
+
if rand(10) % 2 == 0
|
|
1620
|
+
Names_Male.sample
|
|
1621
|
+
else
|
|
1622
|
+
Names_Female.sample
|
|
1623
|
+
end
|
|
1624
|
+
end
|
|
1625
|
+
|
|
1626
|
+
# Generate a male name
|
|
1627
|
+
def self.rand_name_male
|
|
1628
|
+
Names_Male.sample
|
|
1629
|
+
end
|
|
1630
|
+
|
|
1631
|
+
# Generate a female name
|
|
1632
|
+
def self.rand_name_female
|
|
1633
|
+
Names_Female.sample
|
|
1634
|
+
end
|
|
1635
|
+
|
|
1636
|
+
# Generate a random mail address
|
|
1637
|
+
def self.rand_mail_address
|
|
1638
|
+
mail_address = ''
|
|
1639
|
+
mail_address << Rex::Text.rand_name
|
|
1640
|
+
mail_address << '.'
|
|
1641
|
+
mail_address << Rex::Text.rand_surname
|
|
1642
|
+
mail_address << '@'
|
|
1643
|
+
mail_address << Rex::Text.rand_hostname
|
|
1644
|
+
end
|
|
1645
|
+
|
|
1646
|
+
|
|
1647
|
+
#
|
|
1648
|
+
# Calculate the ROR13 hash of a given string
|
|
1649
|
+
#
|
|
1650
|
+
# @return [Fixnum]
|
|
1651
|
+
def self.ror13_hash(name)
|
|
1652
|
+
hash = 0
|
|
1653
|
+
name.unpack("C*").each {|c| hash = ror(hash, 13); hash += c }
|
|
1654
|
+
hash
|
|
1655
|
+
end
|
|
1656
|
+
|
|
1657
|
+
#
|
|
1658
|
+
# Rotate a 32-bit value to the right by +cnt+ bits
|
|
1659
|
+
#
|
|
1660
|
+
# @param val [Fixnum] The value to rotate
|
|
1661
|
+
# @param cnt [Fixnum] Number of bits to rotate by
|
|
1662
|
+
def self.ror(val, cnt)
|
|
1663
|
+
bits = [val].pack("N").unpack("B32")[0].split(//)
|
|
1664
|
+
1.upto(cnt) do |c|
|
|
1665
|
+
bits.unshift( bits.pop )
|
|
1666
|
+
end
|
|
1667
|
+
[bits.join].pack("B32").unpack("N")[0]
|
|
1668
|
+
end
|
|
1669
|
+
|
|
1670
|
+
#
|
|
1671
|
+
# Rotate a 32-bit value to the left by +cnt+ bits
|
|
1672
|
+
#
|
|
1673
|
+
# @param val (see ror)
|
|
1674
|
+
# @param cnt (see ror)
|
|
1675
|
+
# @return (see ror)
|
|
1676
|
+
def self.rol(val, cnt)
|
|
1677
|
+
bits = [val].pack("N").unpack("B32")[0].split(//)
|
|
1678
|
+
1.upto(cnt) do |c|
|
|
1679
|
+
bits.push( bits.shift )
|
|
1680
|
+
end
|
|
1681
|
+
[bits.join].pack("B32").unpack("N")[0]
|
|
1682
|
+
end
|
|
1683
|
+
|
|
1684
|
+
#
|
|
1685
|
+
# Split a string by n character into an array
|
|
1686
|
+
#
|
|
1687
|
+
def self.split_to_a(str, n)
|
|
1688
|
+
if n > 0
|
|
1689
|
+
s = str.dup
|
|
1690
|
+
until s.empty?
|
|
1691
|
+
(ret ||= []).push s.slice!(0, n)
|
|
1692
|
+
end
|
|
1693
|
+
else
|
|
1694
|
+
ret = str
|
|
1695
|
+
end
|
|
1696
|
+
ret
|
|
1697
|
+
end
|
|
1698
|
+
|
|
1699
|
+
#
|
|
1700
|
+
# Pack a value as 64 bit litle endian; does not exist for Array.pack
|
|
1701
|
+
#
|
|
1702
|
+
def self.pack_int64le(val)
|
|
1703
|
+
[val & 0x00000000ffffffff, val >> 32].pack("V2")
|
|
1704
|
+
end
|
|
1705
|
+
|
|
1706
|
+
|
|
1707
|
+
#
|
|
1708
|
+
# A custom unicode filter for dealing with multi-byte strings on a 8-bit console
|
|
1709
|
+
# Punycode would have been more "standard", but it requires valid Unicode chars
|
|
1710
|
+
#
|
|
1711
|
+
def self.unicode_filter_encode(str)
|
|
1712
|
+
if (str.to_s.unpack("C*") & ( LowAscii + HighAscii + "\x7f" ).unpack("C*")).length > 0
|
|
1713
|
+
str = "$U$" + str.unpack("C*").select{|c| c < 0x7f and c > 0x1f and c != 0x2d}.pack("C*") + "-0x" + str.unpack("H*")[0]
|
|
1714
|
+
else
|
|
1715
|
+
str
|
|
1716
|
+
end
|
|
1717
|
+
end
|
|
1718
|
+
|
|
1719
|
+
def self.unicode_filter_decode(str)
|
|
1720
|
+
str.to_s.gsub( /\$U\$([\x20-\x2c\x2e-\x7E]*)\-0x([A-Fa-f0-9]+)/n ){|m| [$2].pack("H*") }
|
|
1721
|
+
end
|
|
1722
|
+
|
|
1723
|
+
protected
|
|
1724
|
+
|
|
1725
|
+
def self.converge_sets(sets, idx, offsets, length) # :nodoc:
|
|
1726
|
+
buf = sets[idx][offsets[idx]].chr
|
|
1727
|
+
|
|
1728
|
+
# If there are more sets after use, converage with them.
|
|
1729
|
+
if (sets[idx + 1])
|
|
1730
|
+
buf << converge_sets(sets, idx + 1, offsets, length)
|
|
1731
|
+
else
|
|
1732
|
+
# Increment the current set offset as well as previous ones if we
|
|
1733
|
+
# wrap back to zero.
|
|
1734
|
+
while (idx >= 0 and ((offsets[idx] = (offsets[idx] + 1) % sets[idx].length)) == 0)
|
|
1735
|
+
idx -= 1
|
|
1736
|
+
end
|
|
1737
|
+
|
|
1738
|
+
# If we reached the point where the idx fell below zero, then that
|
|
1739
|
+
# means we've reached the maximum threshold for permutations.
|
|
1740
|
+
if (idx < 0)
|
|
1741
|
+
return buf
|
|
1742
|
+
end
|
|
1743
|
+
|
|
1744
|
+
end
|
|
1745
|
+
|
|
1746
|
+
buf
|
|
1747
|
+
end
|
|
1748
|
+
|
|
1749
|
+
def self.load_codepage()
|
|
1750
|
+
return if (!@@codepage_map_cache.nil?)
|
|
1751
|
+
file = File.join(File.dirname(__FILE__),'codepage.map')
|
|
1752
|
+
page = ''
|
|
1753
|
+
name = ''
|
|
1754
|
+
map = {}
|
|
1755
|
+
File.open(file).each { |line|
|
|
1756
|
+
next if line =~ /^#/
|
|
1757
|
+
next if line =~ /^\s*$/
|
|
1758
|
+
data = line.split
|
|
1759
|
+
if data[1] =~ /^\(/
|
|
1760
|
+
page = data.shift.to_i
|
|
1761
|
+
name = data.join(' ').sub(/^\(/,'').sub(/\)$/,'')
|
|
1762
|
+
map[page] = {}
|
|
1763
|
+
map[page]['name'] = name
|
|
1764
|
+
map[page]['data'] = {}
|
|
1765
|
+
else
|
|
1766
|
+
data.each { |entry|
|
|
1767
|
+
wide, char = entry.split(':')
|
|
1768
|
+
char = [char].pack('H*')
|
|
1769
|
+
wide = [wide].pack('H*')
|
|
1770
|
+
if map[page]['data'][char].nil?
|
|
1771
|
+
map[page]['data'][char] = [wide]
|
|
1772
|
+
else
|
|
1773
|
+
map[page]['data'][char].push(wide)
|
|
1774
|
+
end
|
|
1775
|
+
}
|
|
1776
|
+
end
|
|
1777
|
+
}
|
|
1778
|
+
@@codepage_map_cache = map
|
|
1779
|
+
end
|
|
1780
|
+
|
|
1781
|
+
# @param str [String] Data to checksum
|
|
1782
|
+
# @return [Fixnum] 8-bit checksum
|
|
1783
|
+
def self.checksum8(str)
|
|
1784
|
+
(str.unpack("C*").inject(:+) || 0) % 0x100
|
|
1785
|
+
end
|
|
1786
|
+
|
|
1787
|
+
# @param str [String] Little-endian data to checksum
|
|
1788
|
+
# @return [Fixnum] 16-bit checksum
|
|
1789
|
+
def self.checksum16_le(str)
|
|
1790
|
+
(str.unpack("v*").inject(:+) || 0) % 0x10000
|
|
1791
|
+
end
|
|
1792
|
+
|
|
1793
|
+
# @param str [String] Big-endian data to checksum
|
|
1794
|
+
# @return [Fixnum] 16-bit checksum
|
|
1795
|
+
def self.checksum16_be(str)
|
|
1796
|
+
(str.unpack("n*").inject(:+) || 0) % 0x10000
|
|
1797
|
+
end
|
|
1798
|
+
|
|
1799
|
+
# @param str [String] Little-endian data to checksum
|
|
1800
|
+
# @return [Fixnum] 32-bit checksum
|
|
1801
|
+
def self.checksum32_le(str)
|
|
1802
|
+
(str.unpack("V*").inject(:+) || 0) % 0x100000000
|
|
1803
|
+
end
|
|
1804
|
+
|
|
1805
|
+
# @param str [String] Big-endian data to checksum
|
|
1806
|
+
# @return [Fixnum] 32-bit checksum
|
|
1807
|
+
def self.checksum32_be(str)
|
|
1808
|
+
(str.unpack("N*").inject(:+) || 0) % 0x100000000
|
|
1809
|
+
end
|
|
1810
|
+
|
|
1811
|
+
end
|
|
1812
|
+
end
|
|
1813
|
+
|