enowars5-service-stldoctor

STL-Analyzing A/D Service for ENOWARS5 in 2021
git clone https://git.sinitax.com/sinitax/enowars5-service-stldoctor
Log | Files | Refs | README | LICENSE | sfeed.txt

commit 4dbe86d40037375ca873d368da5ca0c080e40afd
parent 560218f16b0d4741364a426809fe5b99a9d8ee48
Author: Louis Burda <quent.burda@gmail.com>
Date:   Thu,  8 Jul 2021 12:22:05 +0200

add authorization check to list as well so that second exploit cant be used for first flagstore

Diffstat:
Mchecker/src/checker.py | 22+++++++++++++---------
Mservice/src/main.c | 10+++++++++-
Msrc/main.c | 12++++++++++--
3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/checker/src/checker.py b/checker/src/checker.py @@ -109,6 +109,10 @@ class Session: await self.writer.drain() def write(self, data: bytes) -> None: + if len(data) > 100: + self.logger.debug(f"Sending {data[:100]!r}.."); + else: + self.logger.debug(f"Sending {data!r}"); self.writer.write(data) async def prepare(self) -> None: @@ -370,7 +374,7 @@ async def getdb(db: ChainDB, key: str) -> tuple[Any, ...]: async def do_auth( session: Session, authstr: bytes, check: bool = True, newuser: bool = True ) -> Optional[bytes]: - session.logger.debug(f"Logging in with {authstr!r}") + # Login with authstr session.write(b"auth\n") session.write(authstr + b"\n") await session.drain() @@ -1027,14 +1031,13 @@ async def exploit_prefix_truncation( modelname = fakeid() searcher = await di.get(FlagSearcher) - session = await di.get(Session) - session.logger.debug("Uploading evil file for hash truncation") - + # Generate exploit payload using attack_info assert task.attack_info is not None target_prefix = task.attack_info.split()[1][:-2].encode() + evil_file = exploit_0_file_prefix + target_prefix + exploit_0_file_suffix # Upload evil file - evil_file = exploit_0_file_prefix + target_prefix + exploit_0_file_suffix + session = await di.get(Session) await do_upload(session, modelname, stlfile=evil_file, check=True) await do_search(session, modelname, download=False, check=True) @@ -1052,7 +1055,6 @@ async def exploit_prefix_truncation( # Use it to enumerate other files and grab contents flag = None for fhash in filelist: - session.logger.debug(f"Retrieving file {fhash}") session.write(fhash + b"\n") session.write(b"n\n") await session.drain() @@ -1064,7 +1066,6 @@ async def exploit_prefix_truncation( b"==================", ctx="getting file info (1)" ) resp += await session.readuntil(b"[q to quit]: ", ctx="getting file info (2)") - session.logger.critical(resp) if flag := searcher.search_flag(resp): break @@ -1101,17 +1102,20 @@ async def exploit_hash_overflow( # Get private user hashes via 'list' resp = await do_list(session, check=True) - session.logger.critical(resp) users = [l.split(b" .")[1] for l in resp.split(b"\n") if b">> ." in l] await session.exit() + # Check if there is a flag in the response already + # (shouldn't be, enochecker_test will throw an error if this succeeds) + if flag := searcher.search_flag(resp): + return flag + # Login as each private user for userhash in users: if not userhash.startswith(target_prefix): continue # Find preimage of user hash - session.logger.debug(f"Logging in as user with id {userhash!r}") authstr = reverse_hash(userhash.decode()) # Authenticate and check if the user is new diff --git a/service/src/main.c b/service/src/main.c @@ -78,6 +78,12 @@ unlockfile(FILE **f) } int +authorized(char prefix) +{ + return ((prefix == '.') == (loggedin > 0)); +} + +int save_submission(struct parseinfo *info, char *stldata, int stlsize) { char *dirpath = NULL, *infopath = NULL, *modeldir = NULL, @@ -314,7 +320,7 @@ search_cmd(const char *arg) while ((c = fgetc(f)) > 0) { if (c == '\n') { matchlen = 0; - } else if (!matchlen && (c == '.') != loggedin) { + } else if (!matchlen && !authorized(c)) { matchlen = -1; } else if (matchlen >= 0 && c == filename[matchlen]) { matchlen += 1; @@ -380,6 +386,8 @@ list_cmd(const char *arg) if (*buf && buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; + if (!authorized(*buf)) continue; + printf(">> %s\n", buf); path = aprintf("%s/%s/info", resultdir, buf); if ((fn = fopen(path, "r")) && load_info(&info, fn) == OK) { diff --git a/src/main.c b/src/main.c @@ -78,6 +78,12 @@ unlockfile(FILE **f) } int +authorized(char prefix) +{ + return ((prefix == '.') == (loggedin > 0)); +} + +int save_submission(struct parseinfo *info, char *stldata, int stlsize) { char *dirpath = NULL, *infopath = NULL, *modeldir = NULL, @@ -317,7 +323,7 @@ search_cmd(const char *arg) while ((c = fgetc(f)) > 0) { if (c == '\n') { matchlen = 0; - } else if (!matchlen && (c == '.') != loggedin) { + } else if (!matchlen && !authorized(c)) { matchlen = -1; } else if (matchlen >= 0 && c == filename[matchlen]) { matchlen += 1; @@ -346,7 +352,7 @@ search_cmd(const char *arg) while (1) { resp = ask("> Enter %s [q to quit]: ", resp ? "another" : "hash"); - if (strchr(resp, 'q')) break; + if (strchr(resp, 'q') || !*resp) break; if (checkalph(resp, ".abcdef0123456789-") != OK) { ERR("Invalid model id specified\n"); goto exit; @@ -384,6 +390,8 @@ list_cmd(const char *arg) if (*buf && buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; + if (!authorized(*buf)) continue; + printf(">> %s\n", buf); path = aprintf("%s/%s/info", resultdir, buf); if ((fn = fopen(path, "r")) && load_info(&info, fn) == OK) {