На прошедших выходных поиграл в SharkyCTF (Видимо, сделал неправильный выбор). Удалось взять почти весь веб, кромо одного говнотаска, о котором даже говорить не хочется.



Поговорим о классике.



Понравилось простецкое задание с MongoDB на уязвимость инъекции функции в запрос к MongoDB.



Описание:



Есть магазин с пользователями. Можно посмотреть всех покупателей и производить поиск по имени покупателя. (Видно имя, стоимость покупок и роль)



Задание:

Получить логин пароль администратора среди пользователей.



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



Уязвимый участок кода:

---------------

app.post('/users', (req, res) => {

if (req.body['search[value]'] == '' || req.body['search[value]'] == undefined){

query = {};

} else {

query = { $where: `this.username.match(/^${req.body['search[value]']}/)`};

}

--------------



Здесь мы видим запрос к базе с $where, в значении которого JS функция: match

().



Решение:



Для решения нужно было добавить новое условие в функцию. Не исказив синтаксис выражения добавляем новое условие с поиском значения this.password.match по регулярному выражению. И постепенно ищем последовательность символов пароля при помощи регулярки.



search[value]=admin/) && this.password.match(/^Pzk1TvGxYwq10J6$




Сложность задачи заключалась в том, что мы не знаем как выглядит выражение, к тому же выражение не самое популярное для Mongo. Приходилось проявить фантазию и ориентироваться на ошибки синтаксиса для понимания того, как функция может выглядеть.