1
+ ##
2
+ # This file is part of the Metasploit Framework and may be subject to
3
+ # redistribution and commercial restrictions. Please see the Metasploit
4
+ # web site for more information on licensing and terms of use.
5
+ # http://metasploit.com/
6
+ ##
7
+
1
8
require 'msf/core'
2
9
3
10
class Metasploit3 < Msf ::Auxiliary
@@ -6,35 +13,38 @@ class Metasploit3 < Msf::Auxiliary
6
13
include Msf ::Auxiliary ::Report
7
14
include Msf ::Auxiliary ::Scanner
8
15
9
-
10
16
def initialize
11
17
super (
12
- 'Name' => 'SAPRouter Port Scanner' ,
13
- 'Description' => %q{
14
- This module allows for mapping ACLs and identify open/closed ports
15
- accessible on hosts through a saprouter} ,
16
- 'Author' => [ 'Bruno Morisson <bm[at]integrity.pt>' , # metasploit module
17
- 'nmonkee' ] , # saprouter packet building code from sapcat.rb
18
- 'References' =>
19
- [
20
- # General
21
- [ 'URL' , 'http://help.sap.com/saphelp_nw70/helpdata/EN/4f/992dfe446d11d189700000e8322d00/frameset.htm' ] ,
22
- [ 'URL' , 'http://help.sap.com/saphelp_dimp50/helpdata/En/f8/bb960899d743378ccb8372215bb767/content.htm' ] ,
23
- [ 'URL' , 'http://labs.mwrinfosecurity.com/blog/2012/09/13/sap-smashing-internet-windows/' ] ,
24
- [ 'URL' , 'http://scn.sap.com/docs/DOC-17124' ] # SAP default ports
25
- ] ,
26
- 'License' => MSF_LICENSE
18
+ 'Name' => 'SAPRouter Port Scanner' ,
19
+ 'Description' => %q{
20
+ This module allows for mapping ACLs and identify open/closed ports accessible
21
+ on hosts through a saprouter.
22
+ } ,
23
+ 'Author' => [
24
+ 'Bruno Morisson <bm[at]integrity.pt>' , # metasploit module
25
+ 'nmonkee' # saprouter packet building code from sapcat.rb
26
+ ] ,
27
+ 'References' =>
28
+ [
29
+ # General
30
+ [ 'URL' , 'http://help.sap.com/saphelp_nw70/helpdata/EN/4f/992dfe446d11d189700000e8322d00/frameset.htm' ] ,
31
+ [ 'URL' , 'http://help.sap.com/saphelp_dimp50/helpdata/En/f8/bb960899d743378ccb8372215bb767/content.htm' ] ,
32
+ [ 'URL' , 'http://labs.mwrinfosecurity.com/blog/2012/09/13/sap-smashing-internet-windows/' ] ,
33
+ [ 'URL' , 'http://conference.hitb.org/hitbsecconf2010ams/materials/D2T2%20-%20Mariano%20Nunez%20Di%20Croce%20-%20SAProuter%20.pdf' ] ,
34
+ [ 'URL' , 'http://scn.sap.com/docs/DOC-17124' ] # SAP default ports
35
+ ] ,
36
+ 'License' => MSF_LICENSE
27
37
)
28
38
29
39
register_options (
30
- [
31
- OptAddress . new ( 'SAPROUTER_HOST' , [ true , 'SAPRouter address' , '' ] ) ,
32
- OptPort . new ( 'SAPROUTER_PORT' , [ true , 'SAPRouter TCP port' , '3299' ] ) ,
33
- OptEnum . new ( 'MODE' , [ true , 'Connection Mode: 0 for NI_MSG_IO (SAP), 1 for NI_RAW_IO (TCP), 2 for NI_ROUT_IO (ROUTER) ' , 0 , [ 0 , 1 , 2 ] ] ) ,
34
- OptString . new ( 'PORTS' , [ true , 'Ports to scan (e.g. 22-25,80,110-900)' , '3200-3299' ] ) ,
35
- OptInt . new ( 'TIMEOUT' , [ true , 'The socket connect timeout in milliseconds' , 1000 ] ) ,
36
- OptInt . new ( 'CONCURRENCY' , [ true , 'The number of concurrent ports to check per host' , 10 ] ) ,
37
- ] , self . class )
40
+ [
41
+ OptAddress . new ( 'SAPROUTER_HOST' , [ true , 'SAPRouter address' , '' ] ) ,
42
+ OptPort . new ( 'SAPROUTER_PORT' , [ true , 'SAPRouter TCP port' , '3299' ] ) ,
43
+ OptEnum . new ( 'MODE' , [ true , 'Connection Mode: 0 for NI_MSG_IO (SAP), 1 for NI_RAW_IO (TCP), 2 for NI_ROUT_IO (ROUTER) ' , 0 , [ 0 , 1 , 2 ] ] ) ,
44
+ OptString . new ( 'PORTS' , [ true , 'Ports to scan (e.g. 22-25,80,110-900)' , '3200-3299' ] ) ,
45
+ OptInt . new ( 'TIMEOUT' , [ true , 'The socket connect timeout in milliseconds' , 1000 ] ) ,
46
+ OptInt . new ( 'CONCURRENCY' , [ true , 'The number of concurrent ports to check per host' , 10 ] ) ,
47
+ ] , self . class )
38
48
39
49
deregister_options ( 'RPORT' )
40
50
@@ -43,19 +53,25 @@ def initialize
43
53
def build_ni_packet ( routes )
44
54
45
55
mode = datastore [ 'MODE' ] . to_i
46
-
47
56
route_data = ''
48
-
49
- ni_packet = 'NI_ROUTE' + [ 0 , 2 , 39 , 2 , mode , 0 , 0 , 1 ] . pack ( 'c*' ) # create ni_packet header
57
+ ni_packet = [
58
+ 'NI_ROUTE' ,
59
+ 0 ,
60
+ 2 ,
61
+ 39 ,
62
+ 2 ,
63
+ mode ,
64
+ 0 ,
65
+ 0 ,
66
+ 1
67
+ ] . pack ( "A8c8" )
50
68
51
69
first = false
52
70
53
71
routes . each do |host , port | # create routes
54
-
55
- route_item = host . to_s . dup << [ 0 ] . pack ( 'c*' ) << port . to_s . dup << [ 0 ] . pack ( 'c*' ) << [ 0 ] . pack ( 'c*' )
56
-
72
+ route_item = [ host , 0 , port . to_s , 0 , 0 ] . pack ( "A*CA*cc" )
57
73
if !first
58
- route_data = route_data << [ route_item . length ] . pack ( 'N' ) << route_item
74
+ route_data = [ route_data , route_item . length , route_item ] . pack ( "A*NA*" )
59
75
first = true
60
76
else
61
77
route_data = route_data << route_item
@@ -68,32 +84,33 @@ def build_ni_packet(routes)
68
84
69
85
def parse_response_packet ( response , ip , port )
70
86
71
- vprint_error ( "#{ ip } :#{ port } - response packet: #{ response } " )
87
+ # vprint_error("#{ip}:#{port} - response packet: #{response}")
72
88
73
89
case response
74
90
when /NI_RTERR/
75
91
case response
76
92
when /timed out/
77
- print_error ( "#{ ip } :#{ port } - connection timed out" )
93
+ vprint_error ( "#{ ip } :#{ port } - connection timed out" )
78
94
when /refused/
79
- print_error ( "#{ ip } :#{ port } - TCP closed" )
80
- report_service ( :host => ip , : port => port , :state => ' closed' )
95
+ vprint_error ( "#{ ip } :#{ port } - TCP closed" )
96
+ return [ ip , port , " closed" ]
81
97
when /denied/
82
- print_error ( "#{ ip } :#{ port } - blocked by ACL" )
98
+ vprint_error ( "#{ ip } :#{ port } - blocked by ACL" )
83
99
when /invalid/
84
- print_error ( "#{ ip } :#{ port } - invalid route" )
100
+ vprint_error ( "#{ ip } :#{ port } - invalid route" )
85
101
when /reacheable/
86
- print_error ( "#{ ip } :#{ port } - unreachable" )
102
+ vprint_error ( "#{ ip } :#{ port } - unreachable" )
87
103
else
88
- print_error ( "#{ ip } :#{ port } - unknown error message" )
104
+ vprint_error ( "#{ ip } :#{ port } - unknown error message" )
89
105
end
90
106
when /NI_PONG/
91
107
print_good ( "#{ ip } :#{ port } - TCP OPEN" )
92
- report_service ( :host => ip , : port => port , :state => ' open' )
108
+ return [ ip , port , " open" ]
93
109
else
94
- print_error ( "#{ ip } :#{ port } - unknown response" )
110
+ vprint_error ( "#{ ip } :#{ port } - unknown response" )
95
111
end
96
112
113
+ return nil
97
114
end
98
115
99
116
def run_host ( ip )
@@ -111,8 +128,10 @@ def run_host(ip)
111
128
112
129
print_status ( "Scanning #{ ip } " )
113
130
thread = [ ]
114
- ports . each do | port |
131
+ r = [ ]
115
132
133
+ begin
134
+ ports . each do |port |
116
135
117
136
if thread . length >= datastore [ 'CONCURRENCY' ]
118
137
# Assume the first thread will be among the earliest to finish
@@ -121,6 +140,10 @@ def run_host(ip)
121
140
thread << framework . threads . spawn ( "Module(#{ self . refname } )-#{ ip } :#{ port } " , false ) do
122
141
123
142
begin
143
+ # create ni_packet to send to saprouter
144
+ routes = { sap_host => sap_port , ip => port }
145
+ ni_packet = build_ni_packet ( routes )
146
+
124
147
s = connect ( false ,
125
148
{
126
149
'RPORT' => sap_port ,
@@ -129,14 +152,13 @@ def run_host(ip)
129
152
}
130
153
)
131
154
132
- # create ni_packet to send to saprouter
133
- routes = { sap_host => sap_port , ip => port }
134
- ni_packet = build_ni_packet ( routes )
135
-
136
155
s . write ( ni_packet , ni_packet . length )
137
156
response = s . get ( )
138
157
139
- parse_response_packet ( response , ip , port )
158
+ res = parse_response_packet ( response , ip , port )
159
+ if res
160
+ r << res
161
+ end
140
162
141
163
rescue ::Rex ::ConnectionRefused
142
164
print_error ( "#{ ip } :#{ port } - Unable to connect to SAPRouter #{ sap_host } :#{ sap_port } - Connection Refused" )
@@ -152,9 +174,15 @@ def run_host(ip)
152
174
end
153
175
thread . each { |x | x . join }
154
176
155
- rescue ::Timeout ::Error
156
- ensure
157
- thread . each { |x | x . kill rescue nil }
177
+ rescue ::Timeout ::Error
178
+ ensure
179
+ thread . each { |x | x . kill rescue nil }
180
+ end
181
+
182
+ r . each do |res |
183
+ report_service ( :host => res [ 0 ] , :port => res [ 1 ] , :state => res [ 2 ] )
184
+ end
185
+
158
186
end
159
187
160
188
end
0 commit comments