@@ -55,6 +55,14 @@ class Console::CommandDispatcher::Stdapi::Sys
55
55
"-s" => [ false , "Show only SYSTEM processes" ] ,
56
56
"-U" => [ true , "Filters processes on the user using the supplied RegEx" ] )
57
57
58
+ #
59
+ # Options for the 'suspend' command.
60
+ #
61
+ @@suspend_opts = Rex ::Parser ::Arguments . new (
62
+ "-h" => [ false , "Help menu." ] ,
63
+ "-c" => [ false , "Continues suspending or resuming even if an error is encountered" ] ,
64
+ "-r" => [ false , "Resumes the target processes instead of suspending" ] )
65
+
58
66
#
59
67
# List of supported commands.
60
68
#
@@ -74,6 +82,7 @@ def commands
74
82
"shell" => "Drop into a system command shell" ,
75
83
"shutdown" => "Shuts down the remote computer" ,
76
84
"steal_token" => "Attempts to steal an impersonation token from the target process" ,
85
+ "suspend" => "Suspends or resumes a list of processes"
77
86
"sysinfo" => "Gets information about the remote system, such as OS" ,
78
87
}
79
88
reqs = {
@@ -105,6 +114,7 @@ def commands
105
114
"shell" => [ "stdapi_sys_process_execute" ] ,
106
115
"shutdown" => [ "stdapi_sys_power_exitwindows" ] ,
107
116
"steal_token" => [ "stdapi_sys_config_steal_token" ] ,
117
+ "suspend" => [ "stdapi_sys_process_attach" ] ,
108
118
"sysinfo" => [ "stdapi_sys_config_sysinfo" ] ,
109
119
}
110
120
@@ -688,6 +698,84 @@ def cmd_shutdown(*args)
688
698
client . sys . power . shutdown
689
699
end
690
700
701
+ #
702
+ # @param args [Array] Suspends a list of one or more pids
703
+ # args can optionally be -c to continue on error or -r to resume instead of suspend,
704
+ # followed by a list of one or more valid pids
705
+ # A suspend which will accept process names will be added later
706
+ # @return [Boolean] Returns true if command was successful, else false
707
+ #
708
+ def cmd_suspend ( *args )
709
+ # give'em help if they want it, or seem confused
710
+ if ( args . length == 0 or ( args . length == 1 and args [ 0 ] . strip == "-h" ) )
711
+ cmd_suspend_help
712
+ return true
713
+ end
714
+
715
+ continue = args . delete ( "-c" ) || false
716
+ resume = args . delete ( "-r" ) || false
717
+
718
+ # TODO add -u/-r to unsuspend/resume and -c continue
719
+ # validate all the proposed pids first so we can bail if one is bogus
720
+ args . each do |arg |
721
+ if not is_valid_pid? ( arg )
722
+ print_error ( "#{ arg } is not a valid pid" )
723
+ cmd_suspend_help
724
+ return false
725
+ end
726
+ end
727
+
728
+ # suspend
729
+ print_line ( "Suspending: #{ args . join ( ", " ) } " )
730
+ #client.sys.process.kill(*(args.map { |x| x.to_i }))
731
+ targetprocess = nil
732
+ if resume
733
+ begin
734
+ pids . each do |pid |
735
+ print_status ( "Targeting process with PID #{ pid } ..." )
736
+ targetprocess = client . sys . process . open ( pid , PROCESS_ALL_ACCESS )
737
+ vprint_status "Resuming threads"
738
+ targetprocess . thread . each_thread do |x |
739
+ targetprocess . thread . open ( x ) . resume
740
+ end
741
+ end
742
+ rescue ::Rex ::Post ::Meterpreter ::RequestError => e
743
+ print_error "Error resuming the process threads: #{ e . to_s } . " +
744
+ "Try migrating to a process with the same owner as the target process"
745
+ "Also consider running the win_privs post module and confirm SeDebug priv."
746
+ ensure
747
+ targetprocess . close if targetprocess
748
+ return false unless continue
749
+ end
750
+ else
751
+ begin
752
+ pids . each do |pid |
753
+ print_status ( "Targeting process with PID #{ pid } ..." )
754
+ targetprocess = client . sys . process . open ( pid , PROCESS_ALL_ACCESS )
755
+ vprint_status "Suspending threads"
756
+ targetprocess . thread . each_thread do |x |
757
+ targetprocess . thread . open ( x ) . suspend
758
+ end
759
+ end
760
+ rescue ::Rex ::Post ::Meterpreter ::RequestError => e
761
+ print_error "Error suspending the process threads: #{ e . to_s } . " +
762
+ "Try migrating to a process with the same owner as the target process"
763
+ "Also consider running the win_privs post module and confirm SeDebug priv."
764
+ ensure
765
+ targetprocess . close if targetprocess
766
+ return false unless continue
767
+ end
768
+ end
769
+ return true
770
+ end
771
+
772
+ #
773
+ # help for the suspend command
774
+ #
775
+ def cmd_suspend_help
776
+ print_line ( "Usage: suspend [options] pid1 pid2 pid3 ...\n \n Suspend one or more processes." )
777
+ print @@connect_opts . usage
778
+ end
691
779
692
780
end
693
781
0 commit comments