@@ -18,27 +18,39 @@ def initialize
18
18
super (
19
19
'Name' => 'MYSQL File/Directory Enumerator' ,
20
20
'Description' => %Q{
21
- Enumerate files and directories using the MySQL load_file feature, for more information see the URL in the references.
21
+ Enumerate files and directories using the MySQL load_file feature, for more
22
+ information see the URL in the references.
22
23
} ,
23
24
'Author' => [ 'Robin Wood <robin[at]digininja.org>' ] ,
24
25
'References' => [
25
- [ 'URL' , 'http://pauldotcom.com/2013/01/mysql-file-system-enumeration.html' ] ,
26
- [ 'URL' , 'http://www.digininja.org/projects/mysql_file_enum.php' ]
27
- ] ,
26
+ [ 'URL' , 'http://pauldotcom.com/2013/01/mysql-file-system-enumeration.html' ] ,
27
+ [ 'URL' , 'http://www.digininja.org/projects/mysql_file_enum.php' ]
28
+ ] ,
28
29
'License' => MSF_LICENSE
29
30
)
30
31
31
32
register_options ( [
32
33
OptPath . new ( 'FILE_LIST' , [ true , "List of directories to enumerate" , '' ] ) ,
33
- OptString . new ( 'DATABASE_NAME' , [ true , "Name of database to use" , 'test ' ] ) ,
34
+ OptString . new ( 'DATABASE_NAME' , [ true , "Name of database to use" , 'mysql ' ] ) ,
34
35
OptString . new ( 'TABLE_NAME' , [ true , "Name of table to use - Warning, if the table already exists its contents will be corrupted" , Rex ::Text . rand_text_alpha ( 8 ) ] ) ,
35
36
OptString . new ( 'USERNAME' , [ true , 'The username to authenticate as' , "root" ] )
36
- ] )
37
+ ] )
37
38
38
39
end
39
40
41
+ # This function does not handle any errors, if you use this
42
+ # make sure you handle the errors yourself
43
+ def mysql_query_no_handle ( sql )
44
+ res = @mysql_handle . query ( sql )
45
+ res
46
+ end
47
+
48
+ def peer
49
+ "#{ rhost } :#{ rport } "
50
+ end
51
+
40
52
def run_host ( ip )
41
- print_status ( "Checking " + ip )
53
+ vprint_status ( " #{ peer } - Login..." )
42
54
43
55
if ( not mysql_login_datastore )
44
56
return
@@ -47,28 +59,29 @@ def run_host(ip)
47
59
begin
48
60
mysql_query_no_handle ( "USE " + datastore [ 'DATABASE_NAME' ] )
49
61
rescue ::RbMysql ::Error => e
50
- print_error ( " MySQL Error: #{ e . class } #{ e . to_s } ")
62
+ vprint_error ( " #{ peer } - MySQL Error: #{ e . class } #{ e . to_s } ")
51
63
return
52
64
rescue Rex ::ConnectionTimeout => e
53
- print_error ( " Timeout: #{ e . message } ")
65
+ vprint_error ( " #{ peer } - Timeout: #{ e . message } ")
54
66
return
55
67
end
56
68
57
69
res = mysql_query ( "SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = '" + datastore [ 'DATABASE_NAME' ] + "' AND TABLE_NAME = '" + datastore [ 'TABLE_NAME' ] + "';" )
58
70
table_exists = ( res . size == 1 )
59
71
60
72
if !table_exists
61
- print_status ( " Table doesn't exist so creating it")
73
+ vprint_status ( " #{ peer } - Table doesn't exist so creating it")
62
74
mysql_query ( "CREATE TABLE " + datastore [ 'TABLE_NAME' ] + " (brute int);" )
63
75
end
64
76
65
77
file = File . new ( datastore [ 'FILE_LIST' ] , "r" )
66
78
file . each_line do |line |
67
79
check_dir ( line . chomp )
68
80
end
81
+ file . close
69
82
70
83
if !table_exists
71
- print_status ( " Cleaning up the temp table")
84
+ vprint_status ( " #{ peer } - Cleaning up the temp table")
72
85
mysql_query ( "DROP TABLE " + datastore [ 'TABLE_NAME' ] )
73
86
end
74
87
end
@@ -77,19 +90,34 @@ def check_dir dir
77
90
begin
78
91
res = mysql_query_no_handle ( "LOAD DATA INFILE '" + dir + "' INTO TABLE " + datastore [ 'TABLE_NAME' ] )
79
92
rescue ::RbMysql ::TextfileNotReadable
80
- print_good ( dir + " is a directory and exists" )
93
+ print_good ( "#{ peer } - #{ dir } is a directory and exists" )
94
+ report_note (
95
+ :host => rhost ,
96
+ :type => "filesystem.dir" ,
97
+ :data => "#{ dir } is a directory and exists" ,
98
+ :port => rport ,
99
+ :proto => 'tcp' ,
100
+ :update => :unique_data
101
+ )
81
102
rescue ::RbMysql ::ServerError
82
- print_warning ( dir + " does not exist")
103
+ vprint_warning ( " #{ peer } - #{ dir } does not exist")
83
104
rescue ::RbMysql ::Error => e
84
- print_error ( " MySQL Error: #{ e . class } #{ e . to_s } ")
105
+ vprint_error ( " #{ peer } - MySQL Error: #{ e . class } #{ e . to_s } ")
85
106
return
86
107
rescue Rex ::ConnectionTimeout => e
87
- print_error ( " Timeout: #{ e . message } ")
108
+ vprint_error ( " #{ peer } - Timeout: #{ e . message } ")
88
109
return
89
110
else
90
- print_good ( dir + " is a file and exists" )
111
+ print_good ( "#{ peer } - #{ dir } is a file and exists" )
112
+ report_note (
113
+ :host => rhost ,
114
+ :type => "filesystem.file" ,
115
+ :data => "#{ dir } is a file and exists" ,
116
+ :port => rport ,
117
+ :proto => 'tcp' ,
118
+ :update => :unique_data
119
+ )
91
120
end
92
- #puts res.inspect
93
121
94
122
return
95
123
end
0 commit comments