2
\$\begingroup\$

A day ago I started a c# project where I bruteforce passwords. Passwords can be both integers and strings. In the code I check how many characters the password has. Whilst this is kinda cheating it would take too long to crack otherwise. I am posting it here to see if it's good enough.

using System;

namespace Hacking_Project
{
    class Program
    {
        static void Main()
        {
            //Console Color
            Console.ForegroundColor = ConsoleColor.White;
            Console.Clear();
            //If password is found
            bool done = false;
            //If the password is a string, not the best name but ok
            bool yes = false;
            //If the Guessed password is the same number of characters as the original password
            int pass = 0;
            //Guessed password
            string pass_check = "";
            //Possible characters for the password
            char[] pos = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                          'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                          'u', 'v', 'w', 'x', 'y', 'z'};
            Console.WriteLine("What is the password?");
            //Asking for the password to crack
            string password = Console.ReadLine();
            //How much characters does the password has. I know that this is kinda cheating, but then the bruteforce would take to much
            int digits = password.Length;
            //Initialising the random number generator
            Random rand = new Random();
            //The choices that the calculator will take for the guessed password(int)
            int[] choices = new int[digits];
            //The choices that the calculator will take for the guessed password(string)
            char[] choices1 = new char[digits];
            
            //If the password is a string
            for (int i = 0; i < pos.Length; i++)
            {
                if (password.Contains(pos[i]))
                {
                    password = password.ToLower();
                    yes = true;
                }
            }
            //The Cracking Part
            while (done == false)
            {
                if (!yes)
                {
                    for (int i = 0; i < digits; i++)
                    {
                        choices[i] = rand.Next(0, 9);
                        pass_check += choices[i];
                        pass++;
                        //Console Color
                        Console.ForegroundColor = ConsoleColor.DarkYellow;

                        if (pass != digits)
                        {
                            Console.Write(choices[i]);
                        }
                        else
                        {
                            Console.Write(choices[i] + ", ");
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < digits; i++)
                    {
                        choices1[i] = pos[rand.Next(pos.Length)];
                        pass_check += choices1[i];
                        pass++;
                        Console.ForegroundColor = ConsoleColor.DarkYellow;

                        if (pass != digits)
                        {
                            Console.Write(choices1[i]);
                        }
                        else
                        {
                            Console.Write(choices1[i] + ", ");
                        }
                    }
                }
                pass = 0;
                if (pass_check == password)
                {
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write("\n\nThe password is: ");
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.Write(pass_check);

                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write("\n\nThe original password is: ");
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write(password);

                    Console.ForegroundColor = ConsoleColor.Blue;
                    Console.Write("\n\nDo you want to restart?");
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write(" => ");
                    string restart = Console.ReadLine();
                    restart = restart.ToLower();

                    if (restart == "yes")
                    {
                        Main();
                    }
                    else if (restart == "no")
                    {
                        done = true;
                    }
                }
                //If the password is not found, quessed password is set to empty
                else
                {
                    pass_check = "";
                }
            }
        }
    }
}
\$\endgroup\$
5
  • 1
    \$\begingroup\$ (This is not directed at you Dragos) I do not know why this has gained a close vote. Brute forcing a password is pretty common knowledge at this point, demanding a user explaining it in depth seems pretty unconstructive. \$\endgroup\$ Commented Aug 21, 2020 at 15:23
  • 1
    \$\begingroup\$ One tip on comments (e.g. //Initialising the random number generator) Don't explain what you are doing, explain why you are doing it. I didn't look at the code too much, but my first thought with seeing Random is that you're randomly generating the characters you're generating which can lead to both duplicate and missed guesses, which would add additional time to your algorithm. \$\endgroup\$ Commented Aug 21, 2020 at 15:37
  • \$\begingroup\$ I wanted to update the post later, so that already guessed passwords wont be duplicated \$\endgroup\$ Commented Aug 21, 2020 at 15:41
  • \$\begingroup\$ Do you really need to use randomization here? A rough estimate would be that half of the times you're going to need to check at least half of all the passwords anyway, so wouldn't it be usually faster to just check all of them in order (considering the time saved on randomization and duplicate guesses)? \$\endgroup\$ Commented Aug 22, 2020 at 16:01
  • \$\begingroup\$ Also, I think there's probably no need to specify the length in advance, since the vast majority of passwords of length "up to N" are of length exactly N. (so you can just iteratively increase the length of the password you're trying). For example, there are about 208 billion passwords of 8 lowercase english letters, but only 8 billion passwords of 1..7 letters. \$\endgroup\$ Commented Aug 22, 2020 at 16:03

1 Answer 1

2
\$\begingroup\$

Disclaimer: below is just my opinion, please do not treat it as a source of truth. Also, I am assuming that the code works exactly as expected - I will not dwell into performance or vailidity.

  • Too many comments, instead try to refactor the code to be more explanatory. Uncle Bob said it best: 'A comment is a failure to express yourself in code' (unless it's a 'why' that cannot be explained of course).
  • Devide the code to small and single responsibility functions/classes, see here for guidance.
  • Console related operations can be delegated to a separate class (a wrapper) so it can be easily extended in the future to handle input/output from other sources. Also, in order to avoid duplication (e.g. writing \n\n infront of strings can be abstracted away).
  • Variable names should indicate the content (unless it's very obvious). You wrote a comment 'not the best name but ok', yes - it's not the best name but I don't think it is 'ok'. Half way through the code I had to scroll up to check what does this variable mean, this is not right. Similar goes for variables like choices1, digits, pos and others.
  • while (done == false) could be while(!done) it's both shorter and more explanatory 'in english'.
  • Use Console.WriteLine instead of adding \n\n (you can even do Console.WriteLine("").
  • Use while loop instead of recursion for Main. Two reasons for that: you can exceed the stacks (unlikely for humans but any bot can do it easily) AND it would be more expected by others to see a game loop rather than recursive function.
  • Display possible input values for restart, user might try Y, which will not work.
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.