Ministry of Love
Изначально сервис задумывался как база данных о Турионцах, их судимостях и преступлениях.
Впоследствии, название Ministry of Love сыграло свою роль и в сервис была добавлена возможность “жаловаться” на соседей (читай “доносить”), добавляя в базу все больше преступлений совершенных на Турио, проявляя свою истинную любовь к Большому Брату.
Жители же, в свою очередь, могли зайти в этот сервис и посмотреть информацию о своих преступлениях.
Разработка
Функциональность с точки зрения чексистем
При создании доноса каждый пользователь мог не только изменять все поля (статья, место совершения преступления, дополнительная информация), но и помечать преступление раскрытым (помечая вынесенный вердикт судьи), а также скрывать информацию о преступлении от посторонних глаз, помечая его приватным.
Таким образом, один тип флагов необходимо было искать в описании приватных преступлений, к которым доступ могли иметь либо администраторы ресурса, либо автор доноса, либо лица, указанные в преступлении как его участники.
Во-вторых, в качестве приватной информации пользователя выступал не только пароль, но и логин, так как нигде, кроме авторизации он не использвался. Поэтому часть флагов было логинами доносчиков.
Уязвимости
В сервисе было заложено несколько уязвимостей, большинство из которых было на внимательность при обработке того, что получаем от клиента, того, что отдаем клиенту и того, какие данные утекают в мир.
-
Первая и самая легко обнаруживаемая “узявимость” была в механизме регистрации пользователя, а именно “забытая дебаг строчка”
user['role'] = len(user['username']) < 3
, позволявшая любому, у кого логин состоит из 1 или 2 символов стать администратором и получить доступ ко всей приватной информации.Самое забавное в этой уязвимости то, что фактически, роль администратора в сервисе не была реализована (за исключением полного доступа на чтение), что позволяло в качестве меры защиты вообще отключить администраторов, или приравнять их права к обычным пользователям.
-
Вторая уязвимость находилась здесь же и уже требовала фильтрации пользовательского ввода. А именно, хоть использование defaultdict при получении данных от пользователя
user = defaultdict(lambda: None, **message['params'])
и разрешало сразу подставлять словарьuser
в sql запрос, но если “хакер” при регистрации сразу указывал идентефикатор какого-нибудь жителя Турио, то он сразу получал его профиль без прохождения дополнительных проверок на знание персональной информации.Эта уязвимость позволяла подписаться на новые преступления, и при обнаружении приватного доноса находить в поиске участника, брать его идентефикатор, регистрироваться, притворяясь им и читать информацию уже в профиле, обозначенном как участник преступления.
Также, существовал запасной вариант получения флагов будучи “участником преступления”, который использовал факт, что БД всех команд одинаковая, а значит и “персональная информация” жителей Турио - тоже одинаковая. Зная это, атакующий мог использовать профиль любого жителя, обращаясь за ответами на контрольные фопросы к себе в базу. Помните, что если какие-то данные утекли в сеть - нельзя позволять им оставаться ключевыми.
-
Третья уязвимость обыгрывала стандартную ошибку замыленного взгляда программиста, когда во всех случаях подстановка параметров в db.execute реализована на уровне библиотеки:
db.execute("SELECT * FROM crimes LIMIT 10 OFFSET %s", (offset, ))
, а в одном случае по привычке используется подстановка на уровне интерполяции строки:db.execute("SELECT * FROM crimes LIMIT 10 OFFSET %s" % (offset, ))
. Так, одна непоставленная запятая позволила использовтаь SQL инъекцию, то есть вывести из БД любую информацию, какую хочется, в том числе и флаги. -
Четвертая уязвимость относилась ко второму месту установки флагов - к username, и напоминала, что надо следить, какие данные отдаются клиенту. Можно заметить, что поиск в сервисе искал не только по жителям и преступлениям, но и по идентификаторам пользователей, что позволяло зная ID получить username моментально. Но ID пользователя использовался лишь в двух случаях: при авторизации (но тут необходимо уже знать username) и в качестве автора доноса. И действительно, хоть на странице просмотра преступления автор не отображался, но по сокету при этом всегда передавался полный запрос из БД, в котором ID автора присутсвовал.
Доп.Материалы
Репозиторий RuCTFE2015 открыт и там можно найти как код сервиса, так и код авторского эксплойта, который позволял вытаскивать флаги как с SQL инъекции, так и из регистрации с подменным профилем.