vip.go (7400B)
1 package handlers 2 3 import ( 4 "dkforest/pkg/cache" 5 "dkforest/pkg/captcha" 6 "dkforest/pkg/database" 7 "dkforest/pkg/utils" 8 hutils "dkforest/pkg/web/handlers/utils" 9 "github.com/asaskevich/govalidator" 10 "github.com/labstack/echo" 11 "net/http" 12 "time" 13 ) 14 15 func VipHandler(c echo.Context) error { 16 db := c.Get("database").(*database.DkfDB) 17 var data vipData 18 data.ActiveTab = "home" 19 data.UsersBadges, _ = db.GetUsersBadges() 20 return c.Render(http.StatusOK, "vip.home", data) 21 } 22 23 func Stego1ChallengeHandler(c echo.Context) error { 24 const flagHash = "05b456689a9f8de69416d21cbb97157588b8491d07551167a95b93a1c7d61e7b" 25 authUser := c.Get("authUser").(*database.User) 26 db := c.Get("database").(*database.DkfDB) 27 var data stego1RoadChallengeData 28 data.ActiveTab = "home" 29 30 if c.Request().Method == http.MethodPost { 31 if _, found := flagValidationCache.Get(authUser.ID); found { 32 data.FlagMessage = "You can only validate once per minute" 33 return c.Render(http.StatusOK, "vip.stego1", data) 34 } 35 flag := c.Request().PostFormValue("flag") 36 if len(flag) > 100 { 37 data.FlagMessage = "Invalid flag" 38 return c.Render(http.StatusOK, "vip.stego1", data) 39 } 40 if utils.Sha256([]byte(flag)) == flagHash { 41 data.FlagMessage = "You found the flag!" 42 _ = db.CreateUserBadge(authUser.ID, 3) 43 } else { 44 data.FlagMessage = "Invalid flag" 45 } 46 flagValidationCache.SetD(authUser.ID, true) 47 } 48 49 return c.Render(http.StatusOK, "vip.stego1", data) 50 } 51 52 func ForgotPasswordBypassChallengeHandler(c echo.Context) error { 53 var data forgotPasswordBypassChallengeData 54 data.ActiveTab = "home" 55 return c.Render(http.StatusOK, "vip.forgot-password-bypass-challenge", data) 56 } 57 58 var byteRoadSignUpSessionCache = cache.New[bool](10*time.Minute, 10*time.Minute) 59 var byteRoadUsersCountCache = cache.NewWithKey[database.UserID, ByteRoadPayload](5*time.Minute, 10*time.Minute) 60 61 type ByteRoadPayload struct { 62 Count int64 63 Usernames map[string]struct{} 64 } 65 66 func ByteRoadChallengeHandler(c echo.Context) error { 67 authUser := c.Get("authUser").(*database.User) 68 db := c.Get("database").(*database.DkfDB) 69 const byteRoadChallengeTmplName = "vip.byte-road-challenge" 70 var data byteRoadChallengeData 71 data.ActiveTab = "home" 72 73 if payload, sessionExp, ok := byteRoadUsersCountCache.GetWithExpiration(authUser.ID); ok { 74 data.SessionExp = time.Until(sessionExp) 75 data.NbAccountsRegistered = payload.Count 76 if payload.Count >= 100 { 77 data.FlagFound = true 78 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 79 } 80 } 81 82 data.CaptchaID, data.CaptchaImg = captcha.New() 83 84 setCookie := func(token string) { 85 c.SetCookie(hutils.CreateCookie(hutils.ByteRoadCookieName, token, utils.OneDaySecs)) 86 } 87 88 if c.Request().Method == http.MethodPost { 89 90 formName := c.Request().PostFormValue("formName") 91 if formName == "captcha" { 92 captchaID := c.Request().PostFormValue("captcha_id") 93 captchaInput := c.Request().PostFormValue("captcha") 94 if err := hutils.CaptchaVerifyString(c, captchaID, captchaInput); err != nil { 95 data.ErrCaptcha = err.Error() 96 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 97 } 98 token := utils.GenerateToken32() 99 setCookie(token) 100 byteRoadSignUpSessionCache.SetD(token, true) 101 data.CaptchaSolved = true 102 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 103 104 } else if formName == "register" { 105 captchaSession, err := c.Cookie(hutils.ByteRoadCookieName) 106 if err != nil { 107 return c.Redirect(http.StatusFound, "/vip/challenges/byte-road") 108 } 109 if _, ok := byteRoadSignUpSessionCache.Get(captchaSession.Value); !ok { 110 return c.Redirect(http.StatusFound, "/vip/challenges/byte-road") 111 } 112 113 // Validate username password 114 data.Username = c.Request().PostFormValue("username") 115 data.Password = c.Request().PostFormValue("password") 116 if !govalidator.IsASCII(data.Username) || len(data.Username) < 3 || len(data.Username) > 10 { 117 data.CaptchaSolved = true 118 data.Registered = false 119 data.ErrRegistration = "Invalid username (3-10 ascii characters)" 120 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 121 } 122 if !govalidator.IsASCII(data.Password) || len(data.Password) < 3 || len(data.Password) > 10 { 123 data.CaptchaSolved = true 124 data.Registered = false 125 data.ErrRegistration = "Invalid password (3-10 ascii characters)" 126 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 127 } 128 129 data.Registered = true 130 131 if payload, found := byteRoadUsersCountCache.Get(authUser.ID); found { 132 133 // Username already registered 134 if _, found := payload.Usernames[data.Username]; found { 135 data.CaptchaSolved = true 136 data.Registered = false 137 data.ErrRegistration = "Username is already registered" 138 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 139 } 140 141 token := utils.GenerateToken32() 142 setCookie(token) 143 144 payload.Count++ 145 payload.Usernames[data.Username] = struct{}{} 146 _ = byteRoadUsersCountCache.Update(authUser.ID, payload) 147 if payload.Count >= 100 { 148 data.FlagFound = true 149 _ = db.CreateUserBadge(authUser.ID, 2) 150 } 151 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 152 } 153 154 token := utils.GenerateToken32() 155 setCookie(token) 156 157 payload := ByteRoadPayload{Count: 1, Usernames: map[string]struct{}{data.Username: {}}} 158 byteRoadUsersCountCache.SetD(authUser.ID, payload) 159 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 160 161 } 162 } 163 return c.Render(http.StatusOK, byteRoadChallengeTmplName, data) 164 } 165 166 var flagValidationCache = cache.NewWithKey[database.UserID, bool](time.Minute, time.Hour) 167 168 // VipDownloadsHandler ... 169 func VipDownloadsHandler(c echo.Context) error { 170 const flagHash = "fefc9d5db52b51aeefd4b098f0178a8bcb7f0816dcadaf1714604f01ef63a621" 171 authUser := c.Get("authUser").(*database.User) 172 db := c.Get("database").(*database.DkfDB) 173 var data vipDownloadsHandlerData 174 data.ActiveTab = "home" 175 data.Files = getDownloadsFiles() 176 if c.Request().Method == http.MethodPost { 177 if _, found := flagValidationCache.Get(authUser.ID); found { 178 data.FlagMessage = "You can only validate once per minute" 179 return c.Render(http.StatusOK, "vip.downloads", data) 180 } 181 flag := c.Request().PostFormValue("flag") 182 if len(flag) > 100 { 183 data.FlagMessage = "Invalid flag" 184 return c.Render(http.StatusOK, "vip.downloads", data) 185 } 186 if utils.Sha256([]byte(flag)) == flagHash { 187 data.FlagMessage = "You found the flag!" 188 _ = db.CreateUserBadge(authUser.ID, 1) 189 } else { 190 data.FlagMessage = "Invalid flag" 191 } 192 flagValidationCache.SetD(authUser.ID, true) 193 } 194 195 return c.Render(http.StatusOK, "vip.re-1", data) 196 } 197 198 func VipDownloadFileHandler(c echo.Context) error { 199 return downloadFile(c, "downloads", "/vip/re-1") 200 } 201 202 func VipProjectsHandler(c echo.Context) error { 203 var data vipData 204 data.ActiveTab = "projects" 205 return c.Render(http.StatusOK, "vip.projects", data) 206 } 207 208 func VipProjectsIPGrabberHandler(c echo.Context) error { 209 var data vipData 210 data.ActiveTab = "ip-grabber" 211 return c.Render(http.StatusOK, "vip.ip-grabber", data) 212 } 213 214 func VipProjectsMalwareDropperHandler(c echo.Context) error { 215 var data vipData 216 data.ActiveTab = "malware-dropper" 217 return c.Render(http.StatusOK, "vip.malware-dropper", data) 218 } 219 220 func VipProjectsRustRansomwareHandler(c echo.Context) error { 221 var data vipData 222 data.ActiveTab = "rust-ransomware" 223 return c.Render(http.StatusOK, "vip.rust-ransomware", data) 224 }