Системные логи


Kanal geosi va tili: ko‘rsatilmagan, ko‘rsatilmagan
Toifa: ko‘rsatilmagan


Пью пиво, тыкаю вебчик

Связанные каналы

Kanal geosi va tili
ko‘rsatilmagan, ko‘rsatilmagan
Toifa
ko‘rsatilmagan
Statistika
Postlar filtri


Год назад проходил конкурс, в рамках которого разыгрывались инвайты на priv8 мероприятие Standoff Hacks. Я принял участие и выиграл инвайт, создав видеоролик на тему рекона и эксплуатации XSS. В этом видео я также поделился интересным кейсом, в котором проэксплуатировал цепочку уязвимостей: XSS + CSRF to ATO

Несколько слов о видео: я не хотел делать длинный ролик на 30 минут, но и короткое видео на 1 минуту выглядело бы слишком скучно. Поэтому я включил минимальное количество решений в области рекона и эксплуатации, чтобы дополнить повествование, сделав акцент на рассказе об уязвимости. 🕷

Видео не было опубликовано нигде (возможно, потому что я забыл убрать доступ по ссылке🤣 ) поэтому решил разместить его на своем канале

Ссылка на видео




Пока решал лабы на портсвиггере наткнулся на интересный перевод книги Гарета Хейса: "Javascript for hackers. Learn to think like a hacker" 🌎

😈 Гарет Хейс исследователь Portswigger и создатель такого расширения как Hackvertor

Советую к прочтению - Ссылка на перевод книги

☺ Для тех кто любит читать на Английском приложил оригинал


Часто, когда тестирую аутентификацию нахожу обход 2FA, рассмотрим ситуацию как разработчики привязывают проверку попыток ввода OTP к значению определенной cookie и почему это плохо 💩

Далее примеры кода с обьяснениями 🌚

1️⃣ Обьявляем мапу otpStore для того что бы хранить наш OTP и мапу attemptsStore для того что бы понимать сколько попыток ввода уже было сделано
var otpStore = make(map[string]string) // Хранилище для OTP
var attemptsStore = make(map[string]int) // Хранилище для попыток

2️⃣ Функция sendOTP будет получать номер телефона из тела запроса далее генерировать 6 значный OTP код и присваивать пользователю куку brutedef=0b47d638s951f0eb в дальнейшем по этой куке будет происходить проверка (сколько раз пользователь попытался ввести код)
func sendOTP(w http.ResponseWriter, r *http.Request) {
var requestBody map[string]string
if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}

phone := requestBody["phone"]
if phone == "" {
http.Error(w, "Phone number is required", http.StatusBadRequest)
return
}

otp := generateOTP("6")
otpStore[phone] = otp

cookie := http.Cookie{
Name: "brute_def",
Value: CookieValue, // например 0b47d638s951f0eb"
Path: "/",
MaxAge: 300,
}
http.SetCookie(w, &cookie)

w.WriteHeader(http.StatusOK)
}

3️⃣ Функция brutedef будет реализовывать проверку на количество попыток ввода, она получает значение куки пользователя, присваивает переменной userID это значение что бы использовать его в качестве ключа, в качестве значения будет количество попыток ввода, далее сравнение сколько попыток уже сделано
func brutedef(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("brute_def")
if err != nil {
http.Error(w, "Too many attempts", http.StatusForbidden)
return
}
userID := cookie.Value // Используем значение куки как идентификатор пользователя
if attemptsStore[userID] >= 2 {
http.Error(w, "Too many attempts", http.StatusForbidden)
return
}
}

4️⃣ verifyOTP собственно вызывает проверку используя brutedef, далее получает OTP из тела запроса и проверяет равен ли он сгенерированному OTP на бэке, если равен то пустит в акк, если нет то значение совершенной попытки на вход привязанное к куке увеличится на 1
func verifyOTP(w http.ResponseWriter, r *http.Request) {
brutedef(w, r) // проверка попыток ввода

var requestBody map[string]string
if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
otpCode := requestBody["otp"]
phone := requestBody["phone"]

if otpCode == otpStore[phone] {
attemptsStore[userID] = 0 // сброс попыток при успешной аутентификации
fmt.Fprintln(w, "Auth successful")
} else {
attemptsStore[userID]++
http.Error(w, "Wrong OTP", http.StatusUnauthorized)
}
}
💡Ошибка заключается в том что если мы изменим значение куки то счетчик на количество попыток сбросится, что дает нам бесконечное количество попыток на ввод 6 значного кода, в конечном итоге атаку можно зациклить и подобрать нужное значение

Похожий кейс мне встречался и на багбаунти, за что я успешно получил выплату и выпил на эти мани вкусного пива 🍌



5 ta oxirgi post ko‘rsatilgan.

35

obunachilar
Kanal statistikasi