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
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
module Rex
|
|
3
|
+
module Proto
|
|
4
|
+
module Http
|
|
5
|
+
|
|
6
|
+
###
|
|
7
|
+
#
|
|
8
|
+
# This class acts as the base class for all handlers.
|
|
9
|
+
#
|
|
10
|
+
###
|
|
11
|
+
class Handler
|
|
12
|
+
|
|
13
|
+
require 'rex/proto/http/handler/erb'
|
|
14
|
+
require 'rex/proto/http/handler/proc'
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Initializes the handler instance as being associated with the supplied
|
|
18
|
+
# server.
|
|
19
|
+
#
|
|
20
|
+
def initialize(server)
|
|
21
|
+
self.server = server
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# By default, handlers do not require a relative resource.
|
|
26
|
+
#
|
|
27
|
+
def self.relative_resource_required?
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Calls the class method.
|
|
33
|
+
#
|
|
34
|
+
def relative_resource_required?
|
|
35
|
+
self.class.relative_resource_required?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
protected
|
|
39
|
+
|
|
40
|
+
attr_accessor :server # :nodoc:
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
require 'erb'
|
|
3
|
+
include ERB::Util
|
|
4
|
+
|
|
5
|
+
module Rex
|
|
6
|
+
module Proto
|
|
7
|
+
module Http
|
|
8
|
+
|
|
9
|
+
###
|
|
10
|
+
#
|
|
11
|
+
# This class implements a handler for ERB (.rhtml) template files. This is
|
|
12
|
+
# based off the webrick handler.
|
|
13
|
+
#
|
|
14
|
+
###
|
|
15
|
+
class Handler::Erb < Handler
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# ERB handlers required a relative resource so that the full path name can
|
|
19
|
+
# be computed.
|
|
20
|
+
#
|
|
21
|
+
def self.relative_resource_required?
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Initializes the ERB handler
|
|
27
|
+
#
|
|
28
|
+
def initialize(server, root_path, opts = {})
|
|
29
|
+
super(server)
|
|
30
|
+
|
|
31
|
+
self.root_path = root_path
|
|
32
|
+
self.opts = opts
|
|
33
|
+
|
|
34
|
+
self.opts['MimeType'] = "text/html" unless self.opts['MimeType']
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# Called when a request arrives.
|
|
39
|
+
#
|
|
40
|
+
def on_request(cli, req)
|
|
41
|
+
resource = req.relative_resource
|
|
42
|
+
|
|
43
|
+
# Make sure directory traversals aren't happening
|
|
44
|
+
if (resource =~ /\.\./)
|
|
45
|
+
wlog("Erb::on_request: Dangerous request performed: #{resource}",
|
|
46
|
+
LogSource)
|
|
47
|
+
return
|
|
48
|
+
# If the request is for the root directory, use the document index file.
|
|
49
|
+
elsif (resource == '/')
|
|
50
|
+
resource << opts['DocumentIndex'] || 'index.rhtml'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
begin
|
|
54
|
+
resp = Response.new
|
|
55
|
+
|
|
56
|
+
# Calculate the actual file path on disk.
|
|
57
|
+
file_path = root_path + resource
|
|
58
|
+
|
|
59
|
+
# Serialize the contents of the file
|
|
60
|
+
data = ''
|
|
61
|
+
|
|
62
|
+
File.open(file_path, 'rb') { |f|
|
|
63
|
+
data = f.read
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Set the content-type to text/html by default. We do this before
|
|
67
|
+
# evaluation so that the script can change it.
|
|
68
|
+
resp['Content-Type'] = server ? server.mime_type(resource) : 'text/html'
|
|
69
|
+
|
|
70
|
+
# If the requested file is a ruby html file, evaluate it.
|
|
71
|
+
if (File.extname(file_path) == ".rhtml")
|
|
72
|
+
# Evaluate the data and set the output as the response body.
|
|
73
|
+
resp.body = evaluate(ERB.new(data), cli, req, resp)
|
|
74
|
+
# Otherwise, just set the body to the data that was read.
|
|
75
|
+
else
|
|
76
|
+
resp.body = data
|
|
77
|
+
end
|
|
78
|
+
rescue Errno::ENOENT
|
|
79
|
+
server.send_e404(cli, req)
|
|
80
|
+
rescue
|
|
81
|
+
elog("Erb::on_request: #{$!}\n#{$@.join("\n")}", LogSource)
|
|
82
|
+
|
|
83
|
+
resp.code = 500
|
|
84
|
+
resp.message = "Internal Server Error"
|
|
85
|
+
resp.body =
|
|
86
|
+
"<html><head>" +
|
|
87
|
+
"<title>Internal Server Error</title>" +
|
|
88
|
+
"</head><body> " +
|
|
89
|
+
"<h1>Internal Server Error</h1>" +
|
|
90
|
+
"The server encountered an error:<br/><br/> <b>" + html_escape($!) + "</b><br/><br/>" +
|
|
91
|
+
"Stack trace:<br/><br/>" +
|
|
92
|
+
$@.map { |e| html_escape(e.to_s) }.join("<br/>") +
|
|
93
|
+
"</body></html>"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Send the response to the
|
|
97
|
+
if (cli and resp)
|
|
98
|
+
cli.send_response(resp)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
resp
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
#
|
|
105
|
+
# Evaulates the ERB context in a specific binding context.
|
|
106
|
+
#
|
|
107
|
+
def evaluate(erb, cli, request, response)
|
|
108
|
+
# If the thing that created this handler wanted us to use a callback
|
|
109
|
+
# instead of the default behavior, then let's do that.
|
|
110
|
+
if (opts['ErbCallback'])
|
|
111
|
+
opts['ErbCallback'].call(erb, cli, request, response)
|
|
112
|
+
else
|
|
113
|
+
Module.new.module_eval {
|
|
114
|
+
query_string = request.qstring
|
|
115
|
+
meta_vars = request.meta_vars
|
|
116
|
+
erb.result(binding)
|
|
117
|
+
}
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
protected
|
|
122
|
+
|
|
123
|
+
attr_accessor :root_path, :opts # :nodoc:
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
require 'erb'
|
|
3
|
+
|
|
4
|
+
module Rex
|
|
5
|
+
module Proto
|
|
6
|
+
module Http
|
|
7
|
+
|
|
8
|
+
###
|
|
9
|
+
#
|
|
10
|
+
# This class is used to wrapper the calling of a procedure when a request
|
|
11
|
+
# arrives.
|
|
12
|
+
#
|
|
13
|
+
###
|
|
14
|
+
class Handler::Proc < Handler
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Initializes the proc handler with the supplied procedure
|
|
18
|
+
#
|
|
19
|
+
def initialize(server, procedure, virt_dir = false)
|
|
20
|
+
super(server)
|
|
21
|
+
|
|
22
|
+
self.procedure = procedure
|
|
23
|
+
self.virt_dir = virt_dir || false
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Returns true if the procedure is representing a virtual directory.
|
|
28
|
+
#
|
|
29
|
+
def relative_resource_required?
|
|
30
|
+
virt_dir
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Called when a request arrives.
|
|
35
|
+
#
|
|
36
|
+
def on_request(cli, req)
|
|
37
|
+
begin
|
|
38
|
+
procedure.call(cli, req)
|
|
39
|
+
rescue Errno::EPIPE
|
|
40
|
+
elog("Proc::on_request: Client closed connection prematurely", LogSource)
|
|
41
|
+
rescue
|
|
42
|
+
elog("Proc::on_request: #{$!.class}: #{$!}\n\n#{$@.join("\n")}", LogSource)
|
|
43
|
+
if self.server and self.server.context
|
|
44
|
+
exploit = self.server.context['MsfExploit']
|
|
45
|
+
if exploit
|
|
46
|
+
exploit.print_error("Exception handling request: #{$!}")
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
protected
|
|
53
|
+
|
|
54
|
+
attr_accessor :procedure # :nodoc:
|
|
55
|
+
attr_accessor :virt_dir # :nodoc:
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
require 'rex/proto/http'
|
|
3
|
+
|
|
4
|
+
module Rex
|
|
5
|
+
module Proto
|
|
6
|
+
module Http
|
|
7
|
+
|
|
8
|
+
###
|
|
9
|
+
#
|
|
10
|
+
# Represents the logical HTTP header portion of an HTTP packet (request or
|
|
11
|
+
# response).
|
|
12
|
+
#
|
|
13
|
+
###
|
|
14
|
+
class Packet::Header < Hash
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Initializes an HTTP packet header class that inherits from a Hash base
|
|
18
|
+
# class.
|
|
19
|
+
#
|
|
20
|
+
def initialize
|
|
21
|
+
self.dcase_hash = {}
|
|
22
|
+
|
|
23
|
+
reset
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Parses a header from a string.
|
|
28
|
+
#
|
|
29
|
+
# XXX - Putting : in a header value breaks this badly
|
|
30
|
+
def from_s(header)
|
|
31
|
+
reset
|
|
32
|
+
|
|
33
|
+
# ghettoooooo!
|
|
34
|
+
# If we don't have any newlines..., put one there.
|
|
35
|
+
if (header.size > 0 && header !~ /\r\n/)
|
|
36
|
+
header << "\r\n"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# put the non-standard line terminations back to normal
|
|
40
|
+
# gah. not having look behinds suck,
|
|
41
|
+
header.gsub!(/([^\r])\n/n,'\1' + "\r\n")
|
|
42
|
+
|
|
43
|
+
# undo folding, kinda ugly but works for now.
|
|
44
|
+
header.gsub!(/:\s*\r\n\s+/smni,': ')
|
|
45
|
+
|
|
46
|
+
# Extract the command string
|
|
47
|
+
self.cmd_string = header.slice!(/.+\r\n/)
|
|
48
|
+
|
|
49
|
+
# Extract each header value pair
|
|
50
|
+
header.split(/\r\n/mn).each { |str|
|
|
51
|
+
if (md = str.match(/^(.+?)\s*:\s*(.+?)\s*$/))
|
|
52
|
+
if (self[md[1]])
|
|
53
|
+
self[md[1]] << ", " + md[2]
|
|
54
|
+
else
|
|
55
|
+
self[md[1]] = md[2]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# More advanced [] that does downcase comparison.
|
|
63
|
+
#
|
|
64
|
+
def [](key)
|
|
65
|
+
begin
|
|
66
|
+
rv = self.fetch(key)
|
|
67
|
+
rescue IndexError
|
|
68
|
+
rv = nil
|
|
69
|
+
end
|
|
70
|
+
if (rv == nil)
|
|
71
|
+
begin
|
|
72
|
+
rv = self.dcase_hash[key.downcase]
|
|
73
|
+
rescue IndexError
|
|
74
|
+
rv = nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
return rv
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# More advanced []= that does downcase storage.
|
|
83
|
+
#
|
|
84
|
+
def []=(key, value)
|
|
85
|
+
stored = false
|
|
86
|
+
|
|
87
|
+
self.each_key { |k|
|
|
88
|
+
if (k.downcase == key.downcase)
|
|
89
|
+
self.store(k, value)
|
|
90
|
+
stored = true
|
|
91
|
+
end
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
self.store(key, value) if (stored == false)
|
|
95
|
+
self.dcase_hash[key.downcase] = value
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# Converts the header to a string.
|
|
100
|
+
#
|
|
101
|
+
def to_s(prefix = '')
|
|
102
|
+
str = prefix
|
|
103
|
+
|
|
104
|
+
if self.junk_headers
|
|
105
|
+
while str.length < 4096
|
|
106
|
+
if self.fold
|
|
107
|
+
str << "X-#{Rex::Text.rand_text_alphanumeric(rand(30) + 5)}:\r\n\t#{Rex::Text.rand_text_alphanumeric(rand(1024) + 1)}\r\n"
|
|
108
|
+
else
|
|
109
|
+
str << "X-#{Rex::Text.rand_text_alphanumeric(rand(30) + 5)}: #{Rex::Text.rand_text_alphanumeric(rand(1024) + 1)}\r\n"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
each_pair { |var, val|
|
|
115
|
+
if self.fold
|
|
116
|
+
str << "#{var}:\r\n\t#{val}\r\n"
|
|
117
|
+
else
|
|
118
|
+
str << "#{var}: #{val}\r\n"
|
|
119
|
+
end
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
str << "\r\n"
|
|
123
|
+
|
|
124
|
+
return str
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
#
|
|
128
|
+
# Brings in from an array like yo.
|
|
129
|
+
#
|
|
130
|
+
def from_a(ary)
|
|
131
|
+
ary.each { |e|
|
|
132
|
+
self[e[0]] = e[1]
|
|
133
|
+
}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
#
|
|
137
|
+
# Flushes all header pairs.
|
|
138
|
+
#
|
|
139
|
+
def reset
|
|
140
|
+
self.cmd_string = ''
|
|
141
|
+
self.clear
|
|
142
|
+
self.dcase_hash.clear
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
#
|
|
146
|
+
# Overrides the builtin 'each' operator to avoid the following exception on Ruby 1.9.2+
|
|
147
|
+
# "can't add a new key into hash during iteration"
|
|
148
|
+
#
|
|
149
|
+
def each(&block)
|
|
150
|
+
list = []
|
|
151
|
+
self.keys.sort.each do |sidx|
|
|
152
|
+
list << [sidx, self[sidx]]
|
|
153
|
+
end
|
|
154
|
+
list.each(&block)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
#
|
|
158
|
+
# The raw command string associated with the header which will vary between
|
|
159
|
+
# requests and responses.
|
|
160
|
+
#
|
|
161
|
+
attr_accessor :junk_headers
|
|
162
|
+
attr_accessor :cmd_string
|
|
163
|
+
attr_accessor :fold
|
|
164
|
+
|
|
165
|
+
protected
|
|
166
|
+
|
|
167
|
+
attr_accessor :dcase_hash # :nodoc:
|
|
168
|
+
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
require 'rex/proto/http'
|
|
3
|
+
|
|
4
|
+
module Rex
|
|
5
|
+
module Proto
|
|
6
|
+
module Http
|
|
7
|
+
|
|
8
|
+
DefaultProtocol = '1.1'
|
|
9
|
+
|
|
10
|
+
###
|
|
11
|
+
#
|
|
12
|
+
# This class represents an HTTP packet.
|
|
13
|
+
#
|
|
14
|
+
###
|
|
15
|
+
class Packet
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# Parser processing codes
|
|
19
|
+
#
|
|
20
|
+
module ParseCode
|
|
21
|
+
Completed = 1
|
|
22
|
+
Partial = 2
|
|
23
|
+
Error = 3
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Parser states
|
|
28
|
+
#
|
|
29
|
+
module ParseState
|
|
30
|
+
ProcessingHeader = 1
|
|
31
|
+
ProcessingBody = 2
|
|
32
|
+
Completed = 3
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
require 'rex/proto/http/header'
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# Initializes an instance of an HTTP packet.
|
|
39
|
+
#
|
|
40
|
+
def initialize()
|
|
41
|
+
self.headers = Header.new
|
|
42
|
+
self.auto_cl = true
|
|
43
|
+
|
|
44
|
+
reset
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# Return the associated header value, if any.
|
|
49
|
+
#
|
|
50
|
+
def [](key)
|
|
51
|
+
if (self.headers.include?(key))
|
|
52
|
+
return self.headers[key]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
self.headers.each_pair do |k,v|
|
|
56
|
+
if (k.downcase == key.downcase)
|
|
57
|
+
return v
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
return nil
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Set the associated header value.
|
|
66
|
+
#
|
|
67
|
+
def []=(key, value)
|
|
68
|
+
self.headers[key] = value
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#
|
|
72
|
+
# Parses the supplied buffer. Returns one of the two parser processing
|
|
73
|
+
# codes (Completed, Partial, or Error).
|
|
74
|
+
#
|
|
75
|
+
def parse(buf)
|
|
76
|
+
|
|
77
|
+
# Append the incoming buffer to the buffer queue.
|
|
78
|
+
self.bufq += buf.to_s
|
|
79
|
+
|
|
80
|
+
begin
|
|
81
|
+
|
|
82
|
+
# Process the header
|
|
83
|
+
if(self.state == ParseState::ProcessingHeader)
|
|
84
|
+
parse_header
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Continue on to the body if the header was processed
|
|
88
|
+
if(self.state == ParseState::ProcessingBody)
|
|
89
|
+
# Chunked encoding sets the parsing state on its own
|
|
90
|
+
if (self.body_bytes_left == 0 and not self.transfer_chunked)
|
|
91
|
+
self.state = ParseState::Completed
|
|
92
|
+
else
|
|
93
|
+
parse_body
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
rescue
|
|
97
|
+
# XXX: BUG: This rescue might be a problem because it will swallow TimeoutError
|
|
98
|
+
self.error = $!
|
|
99
|
+
return ParseCode::Error
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Return completed or partial to the parsing status to the caller
|
|
103
|
+
(self.state == ParseState::Completed) ? ParseCode::Completed : ParseCode::Partial
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Reset the parsing state and buffers.
|
|
108
|
+
#
|
|
109
|
+
def reset
|
|
110
|
+
self.state = ParseState::ProcessingHeader
|
|
111
|
+
self.transfer_chunked = false
|
|
112
|
+
self.inside_chunk = false
|
|
113
|
+
self.headers.reset
|
|
114
|
+
self.bufq = ''
|
|
115
|
+
self.body = ''
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
#
|
|
119
|
+
# Reset the parsing state but leave the buffers.
|
|
120
|
+
#
|
|
121
|
+
def reset_except_queue
|
|
122
|
+
self.state = ParseState::ProcessingHeader
|
|
123
|
+
self.transfer_chunked = false
|
|
124
|
+
self.inside_chunk = false
|
|
125
|
+
self.headers.reset
|
|
126
|
+
self.body = ''
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
#
|
|
130
|
+
# Returns whether or not parsing has completed.
|
|
131
|
+
#
|
|
132
|
+
def completed?
|
|
133
|
+
|
|
134
|
+
return true if self.state == ParseState::Completed
|
|
135
|
+
|
|
136
|
+
# If the parser state is processing the body and there are an
|
|
137
|
+
# undetermined number of bytes left to read, we just need to say that
|
|
138
|
+
# things are completed as it's hard to tell whether or not they really
|
|
139
|
+
# are.
|
|
140
|
+
if (self.state == ParseState::ProcessingBody and self.body_bytes_left < 0)
|
|
141
|
+
return true
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
false
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
#
|
|
148
|
+
# Build a 'Transfer-Encoding: chunked' payload with random chunk sizes
|
|
149
|
+
#
|
|
150
|
+
def chunk(str, min_size = 1, max_size = 1000)
|
|
151
|
+
chunked = ''
|
|
152
|
+
|
|
153
|
+
# min chunk size is 1 byte
|
|
154
|
+
if (min_size < 1); min_size = 1; end
|
|
155
|
+
|
|
156
|
+
# don't be dumb
|
|
157
|
+
if (max_size < min_size); max_size = min_size; end
|
|
158
|
+
|
|
159
|
+
while (str.size > 0)
|
|
160
|
+
chunk = str.slice!(0, rand(max_size - min_size) + min_size)
|
|
161
|
+
chunked += sprintf("%x", chunk.size) + "\r\n" + chunk + "\r\n"
|
|
162
|
+
end
|
|
163
|
+
chunked += "0\r\n\r\n"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
#
|
|
167
|
+
# Converts the packet to a string.
|
|
168
|
+
#
|
|
169
|
+
def to_s
|
|
170
|
+
content = self.body.to_s.dup
|
|
171
|
+
|
|
172
|
+
# Update the content length field in the header with the body length.
|
|
173
|
+
if (content)
|
|
174
|
+
if !self.compress.nil?
|
|
175
|
+
case self.compress
|
|
176
|
+
when 'gzip'
|
|
177
|
+
self.headers['Content-Encoding'] = 'gzip'
|
|
178
|
+
content = Rex::Text.gzip(content)
|
|
179
|
+
when 'deflate'
|
|
180
|
+
self.headers['Content-Encoding'] = 'deflate'
|
|
181
|
+
content = Rex::Text.zlib_deflate(content)
|
|
182
|
+
when 'none'
|
|
183
|
+
# this one is fine...
|
|
184
|
+
# when 'compress'
|
|
185
|
+
else
|
|
186
|
+
raise RuntimeError, 'Invalid Content-Encoding'
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
if (self.auto_cl == true && self.transfer_chunked == true)
|
|
191
|
+
raise RuntimeError, "'Content-Length' and 'Transfer-Encoding: chunked' are incompatible"
|
|
192
|
+
elsif self.auto_cl == true
|
|
193
|
+
self.headers['Content-Length'] = content.length
|
|
194
|
+
elsif self.transfer_chunked == true
|
|
195
|
+
if self.proto != '1.1'
|
|
196
|
+
raise RuntimeError, 'Chunked encoding is only available via 1.1'
|
|
197
|
+
end
|
|
198
|
+
self.headers['Transfer-Encoding'] = 'chunked'
|
|
199
|
+
content = self.chunk(content, self.chunk_min_size, self.chunk_max_size)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
str = self.headers.to_s(cmd_string)
|
|
204
|
+
str += content || ''
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
#
|
|
208
|
+
# Converts the packet from a string.
|
|
209
|
+
#
|
|
210
|
+
def from_s(str)
|
|
211
|
+
reset
|
|
212
|
+
parse(str)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
#
|
|
216
|
+
# Returns the command string, such as:
|
|
217
|
+
#
|
|
218
|
+
# HTTP/1.0 200 OK for a response
|
|
219
|
+
#
|
|
220
|
+
# or
|
|
221
|
+
#
|
|
222
|
+
# GET /foo HTTP/1.0 for a request
|
|
223
|
+
#
|
|
224
|
+
def cmd_string
|
|
225
|
+
self.headers.cmd_string
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
attr_accessor :headers
|
|
229
|
+
attr_accessor :error
|
|
230
|
+
attr_accessor :state
|
|
231
|
+
attr_accessor :bufq
|
|
232
|
+
attr_accessor :body
|
|
233
|
+
attr_accessor :auto_cl
|
|
234
|
+
attr_accessor :max_data
|
|
235
|
+
attr_accessor :transfer_chunked
|
|
236
|
+
attr_accessor :compress
|
|
237
|
+
attr_reader :incomplete
|
|
238
|
+
|
|
239
|
+
attr_accessor :chunk_min_size
|
|
240
|
+
attr_accessor :chunk_max_size
|
|
241
|
+
|
|
242
|
+
protected
|
|
243
|
+
|
|
244
|
+
attr_writer :incomplete
|
|
245
|
+
attr_accessor :body_bytes_left
|
|
246
|
+
attr_accessor :inside_chunk
|
|
247
|
+
attr_accessor :keepalive
|
|
248
|
+
|
|
249
|
+
##
|
|
250
|
+
#
|
|
251
|
+
# Overridable methods
|
|
252
|
+
#
|
|
253
|
+
##
|
|
254
|
+
|
|
255
|
+
#
|
|
256
|
+
# Allows derived classes to split apart the command string.
|
|
257
|
+
#
|
|
258
|
+
def update_cmd_parts(str)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
##
|
|
262
|
+
#
|
|
263
|
+
# Parsing
|
|
264
|
+
#
|
|
265
|
+
##
|
|
266
|
+
|
|
267
|
+
def parse_header
|
|
268
|
+
|
|
269
|
+
head,data = self.bufq.split(/\r?\n\r?\n/, 2)
|
|
270
|
+
|
|
271
|
+
return if not data
|
|
272
|
+
|
|
273
|
+
self.headers.from_s(head)
|
|
274
|
+
self.bufq = data || ""
|
|
275
|
+
|
|
276
|
+
# Set the content-length to -1 as a placeholder (read until EOF)
|
|
277
|
+
self.body_bytes_left = -1
|
|
278
|
+
|
|
279
|
+
# Extract the content length if it was specified
|
|
280
|
+
if (self.headers['Content-Length'])
|
|
281
|
+
self.body_bytes_left = self.headers['Content-Length'].to_i
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# Look for a chunked transfer header
|
|
285
|
+
if (self.headers['Transfer-Encoding'].to_s.downcase == 'chunked')
|
|
286
|
+
self.transfer_chunked = true
|
|
287
|
+
self.auto_cl = false
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Determine how to handle data when there is no length header
|
|
291
|
+
if (self.body_bytes_left == -1)
|
|
292
|
+
if (not self.transfer_chunked)
|
|
293
|
+
if (self.headers['Connection'].to_s.downcase.include?('keep-alive'))
|
|
294
|
+
# If we are using keep-alive, but have no content-length and
|
|
295
|
+
# no chunked transfer header, pretend this is the entire
|
|
296
|
+
# buffer and call it done
|
|
297
|
+
self.body_bytes_left = self.bufq.length
|
|
298
|
+
elsif (not self.headers['Content-Length'] and self.class == Rex::Proto::Http::Request)
|
|
299
|
+
# RFC 2616 says: "The presence of a message-body in a request
|
|
300
|
+
# is signaled by the inclusion of a Content-Length or
|
|
301
|
+
# Transfer-Encoding header field in the request's
|
|
302
|
+
# message-headers."
|
|
303
|
+
#
|
|
304
|
+
# So if we haven't seen either a Content-Length or a
|
|
305
|
+
# Transfer-Encoding header, there shouldn't be a message body.
|
|
306
|
+
self.body_bytes_left = 0
|
|
307
|
+
#else
|
|
308
|
+
# Otherwise we need to keep reading until EOF
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Throw an error if we didnt parse the header properly
|
|
314
|
+
if !self.headers.cmd_string
|
|
315
|
+
raise RuntimeError, "Invalid command string", caller
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Move the state into body processing
|
|
319
|
+
self.state = ParseState::ProcessingBody
|
|
320
|
+
|
|
321
|
+
# Allow derived classes to update the parts of the command string
|
|
322
|
+
self.update_cmd_parts(self.headers.cmd_string)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
#
|
|
326
|
+
# Parses the body portion of the request.
|
|
327
|
+
#
|
|
328
|
+
def parse_body
|
|
329
|
+
# Just return if the buffer is empty
|
|
330
|
+
if (self.bufq.length == 0)
|
|
331
|
+
return
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# Handle chunked transfer-encoding responses
|
|
335
|
+
if (self.transfer_chunked and self.inside_chunk != 1 and self.bufq.length)
|
|
336
|
+
|
|
337
|
+
# Remove any leading newlines or spaces
|
|
338
|
+
self.bufq.lstrip!
|
|
339
|
+
|
|
340
|
+
# If we didn't get a newline, then this might not be the full
|
|
341
|
+
# length, go back and get more.
|
|
342
|
+
# e.g.
|
|
343
|
+
# first packet: "200"
|
|
344
|
+
# second packet: "0\r\n\r\n<html>..."
|
|
345
|
+
if not bufq.index("\n")
|
|
346
|
+
return
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# Extract the actual hexadecimal length value
|
|
350
|
+
clen = self.bufq.slice!(/^[a-fA-F0-9]+\r?\n/)
|
|
351
|
+
|
|
352
|
+
clen.rstrip! if (clen)
|
|
353
|
+
|
|
354
|
+
# if we happen to fall upon the end of the buffer for the next chunk len and have no data left, go get some more...
|
|
355
|
+
if clen.nil? and self.bufq.length == 0
|
|
356
|
+
return
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# Invalid chunk length, exit out early
|
|
360
|
+
if clen.nil?
|
|
361
|
+
self.state = ParseState::Completed
|
|
362
|
+
return
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
self.body_bytes_left = clen.to_i(16)
|
|
366
|
+
|
|
367
|
+
if (self.body_bytes_left == 0)
|
|
368
|
+
self.bufq.sub!(/^\r?\n/s,'')
|
|
369
|
+
self.state = ParseState::Completed
|
|
370
|
+
self.check_100
|
|
371
|
+
return
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
self.inside_chunk = 1
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
# If there are bytes remaining, slice as many as we can and append them
|
|
378
|
+
# to our body state.
|
|
379
|
+
if (self.body_bytes_left > 0)
|
|
380
|
+
part = self.bufq.slice!(0, self.body_bytes_left)
|
|
381
|
+
self.body += part
|
|
382
|
+
self.body_bytes_left -= part.length
|
|
383
|
+
# Otherwise, just read it all.
|
|
384
|
+
else
|
|
385
|
+
self.body += self.bufq
|
|
386
|
+
self.bufq = ''
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# Finish this chunk and move on to the next one
|
|
390
|
+
if (self.transfer_chunked and self.body_bytes_left == 0)
|
|
391
|
+
self.inside_chunk = 0
|
|
392
|
+
self.parse_body
|
|
393
|
+
return
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# If there are no more bytes left, then parsing has completed and we're
|
|
397
|
+
# ready to go.
|
|
398
|
+
if (not self.transfer_chunked and self.body_bytes_left == 0)
|
|
399
|
+
self.state = ParseState::Completed
|
|
400
|
+
self.check_100
|
|
401
|
+
return
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
# Override this as needed
|
|
406
|
+
def check_100
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|