CVE-2020-8815: Improper Input Validation (CWE-20)
value: Improper connection handling in the base connection handler in IKTeam BearFTP before v0.3.1 allows a remote attacker to achieve denial of service via a Slowloris approach by sending a large volume of small packets.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
CVSS v3 base score: 7.5
Published: 2020-02-12T15:15Z
Repository: https://github.com/kolya5544/BearFTP
Language: C#
Files changed: BearFTP/Program.cs, CHANGELOG.txt
Commit date: 2020-02-09 21:20:17 +0300
Commit message: Anonymous configuration fix, base thread vulnerability fix. v0.3.1

Diff: diff --git a/BearFTP/Program.cs b/BearFTP/Program.cs
index 875b2b8..4a7f214 100644
--- a/BearFTP/Program.cs
+++ b/BearFTP/Program.cs
@@ -493,40 +493,16 @@ namespace BearFTP
                             LogWrite("220 " + Banner.Replace("%host%", Hostname) + "\r\n", sw, hostname, perip);
 
                             while (client.Connected)
                             {
                                 Thread.Sleep(100);
-                                //Receiving handler START
-                                string answ = "";
-                                bool flag = true;
-                                bool upper = true;
-
-                                while (flag)
-                                {
-                                    int a = sr.Read();
-                                    if (upper)
-                                    {
-                                        answ += char.ToUpper((char)a);
-                                    } else
-                                    {
-                                        answ += (char)a;
-                                    }
-                                    if (a == 13)
-                                    {
-                                        flag = false;
-                                    }
-                                    if (a == 0x20)
-                                    {
-                                        upper = false;
-                                    }
-                                    if (answ.Length > 128)
-                                    {
-                                        client.Close();
-                                    }
-                                }
-                                answ = answ.Trim();
-                                //Receiving handler END
+                                
+                                string answ = sr.ReadLine(); //Who'd think this ACTUALLY works. BUT: It's doesnt work on Linux? (Needs testing)
+                                //Tested on Ubuntu 16.04 client and 18.04 server. Seems to work!
+                         
+                                string upperfix = answ.Split(' ')[0].ToUpper();
+                                answ.Replace(answ.Split(' ')[0], upperfix); //Fixing the lowercase commands an easy way
 
                                 //Command processing.
                                 if (answ.Length >= 3) //We dont want dummies to spam/DDoS.
                                 {
                                     Log(answ, "in", true, hostname, perip);
@@ -556,11 +532,11 @@ namespace BearFTP
                                 }
                                 else if (answ.StartsWith("USER") && username.Length < 3 && !Authed)
                                 {
                                     string temp = answ.Substring(5).Trim();
                                     Regex r = new Regex("^[a-zA-Z0-9]*$");
-                                    if (r.IsMatch(temp) && temp.Length < 32 && temp.Length > 1 && (temp != "anonymous" && !AllowAnonymous))
+                                    if (r.IsMatch(temp) && temp.Length < 32 && temp.Length > 1 && (temp != "anonymous" || AllowAnonymous))
                                     {
                                         username = temp;
                                         LogWrite("331 This user is protected with password\r\n", sw, hostname, perip);
 
                                     }
@@ -642,20 +618,20 @@ namespace BearFTP
                                         {
                                             Thread.Sleep(1000);
                                             LogWrite("150 Ok to send data.\r\n", sw, hostname, perip);
                                             Thread.Sleep(100);
                                             List<byte> filess = new List<byte>();
-                                            var bytes = default(byte[]);
+                                            var bytess = default(byte[]);
                                             using (var memstream = new MemoryStream())
                                             {
                                                 var buffer = new byte[512];
                                                 var bytesRead = default(int);
                                                 while ((bytesRead = connn.sr.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
                                                     memstream.Write(buffer, 0, bytesRead);
-                                                bytes = memstream.ToArray();
+                                                bytess = memstream.ToArray();
                                             }
-                                            System.IO.File.WriteAllBytes("dumps/dump_i" + rnd.Next(1, 2000000000).ToString() + ".txt", bytes);
+                                            System.IO.File.WriteAllBytes("dumps/dump_i" + rnd.Next(1, 2000000000).ToString() + ".txt", bytess);
                                             Thread.Sleep(200);
                                             LogWrite("226 Transfer complete!\r\n", sw, hostname, perip);
 
                                             if (Ban)
                                             {
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index c2e127e..919ebd5 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,12 +1,6 @@
 --> IT ONLY CONTAINS THE MOST RECENT CHANGES!
 
-v0.3.0:
-- Toggleable anonymous logins
-- Per-IP logs (create "iplogs" folder)
-- Max connections per second and max active connections are now changeable
-- Buffer size can now be changed (def.8192) 
-- Fixed lower-case command handling
-- Final attempt to fix an encoding bug related to outputting control characters
-- Changeable bantime
-- Toggleable ban on big amount of errors (a.k.a some sort of service probe)
-- Moved default config to Resources
\ No newline at end of file
+v0.3.1:
+- Fixed AllowAnonymous handling (oops)
+- One more attempt to fix encoding break on some characters (only affects console)
+- Fixed improper handling of incoming data on base socket (a.k.a base socket thread overuse fix)
\ No newline at end of file

Vulnerable code:                                 //Receiving handler START
                                string answ = "";
                                bool flag = true;
                                bool upper = true;

                                while (flag)
                                {
                                    int a = sr.Read();
                                    if (upper)
                                    {
                                        answ += char.ToUpper((char)a);
                                    } else
                                    {
                                        answ += (char)a;
                                    }
                                    if (a == 13)
                                    {
                                        flag = false;
                                    }
                                    if (a == 0x20)
                                    {
                                        upper = false;
                                    }
                                    if (answ.Length > 128)
                                    {
                                        client.Close();
                                    }
                                }
                                answ = answ.Trim();
                                //Receiving handler END
                                    if (r.IsMatch(temp) && temp.Length < 32 && temp.Length > 1 && (temp != "anonymous" && !AllowAnonymous))
                                            var bytes = default(byte[]);
                                                bytes = memstream.ToArray();
                                            System.IO.File.WriteAllBytes("dumps/dump_i" + rnd.Next(1, 2000000000).ToString() + ".txt", bytes);
v0.3.0:
- Toggleable anonymous logins
- Per-IP logs (create "iplogs" folder)
- Max connections per second and max active connections are now changeable
- Buffer size can now be changed (def.8192) 
- Fixed lower-case command handling
- Final attempt to fix an encoding bug related to outputting control characters
- Changeable bantime
- Toggleable ban on big amount of errors (a.k.a some sort of service probe)
- Moved default config to Resources
Fixed code:                                 
                                string answ = sr.ReadLine(); //Who'd think this ACTUALLY works. BUT: It's doesnt work on Linux? (Needs testing)
                                //Tested on Ubuntu 16.04 client and 18.04 server. Seems to work!
                         
                                string upperfix = answ.Split(' ')[0].ToUpper();
                                answ.Replace(answ.Split(' ')[0], upperfix); //Fixing the lowercase commands an easy way
                                    if (r.IsMatch(temp) && temp.Length < 32 && temp.Length > 1 && (temp != "anonymous" || AllowAnonymous))
                                            var bytess = default(byte[]);
                                                bytess = memstream.ToArray();
                                            System.IO.File.WriteAllBytes("dumps/dump_i" + rnd.Next(1, 2000000000).ToString() + ".txt", bytess);
v0.3.1:
- Fixed AllowAnonymous handling (oops)
- One more attempt to fix encoding break on some characters (only affects console)
- Fixed improper handling of incoming data on base socket (a.k.a base socket thread overuse fix)