示例#1
0
    def putnoise(self) -> None:
        """
        This method stores noise in the service. The noise should later be recoverable.
        The difference between noise and flag is, tht noise does not have to remain secret for other teams.
        This method can be called many times per round. Check how often using self.variant_id.
        On error, raise an EnoException.
        :raises EnoException on error
        """
        credentials = self.generate_credentials()
        self.register_and_login(credentials)

        category = secrets.choice(
            [
                "Python",
                "NodeJS",
                "C",
                "Rust",
                "Go",
                "C#",
                "C++",
                "Prolog",
                "OCL",
                "Julia",
            ]
        )

        # we are overwriting the credentials on purpose since we don't need them later in this case
        self.chain_db = category

        res = self.http_post(
            "/posts",
            json={"content": self.noise, "category": category, "public": True},
        )
        assert_equals(res.status_code, 200)
    def check_alarm(self, alarm_text, session_id):
        self.http_session.cookies.set('session_id', session_id)

        req = self.http_get("/alarm")
        enochecker.assert_equals(200, req.status_code,
                                 "Getting the alarm page did not return the expected response code.")
        enochecker.assert_in(alarm_text, req.text, f"Cannot find expected alarm text in response.")
示例#3
0
    def putflag(self) -> None:
        """
        This method stores a flag in the service.
        In case the service has multiple flag stores, self.variant_id gives the appropriate index.
        The flag itself can be retrieved from self.flag.
        On error, raise an Eno Exception.
        :raises EnoException on error
        """
        if self.variant_id == 0:
            credentials = self.generate_credentials()
            self.chain_db = credentials
            self.register_and_login(credentials)

            res = self.http_post("/notes", json={"note": self.flag})
            assert_equals(res.status_code, 200)
        elif self.variant_id == 1:
            credentials = self.generate_credentials()
            self.chain_db = credentials
            self.register_and_login(credentials)

            res = self.http_post("/profile/status", json={"status": self.flag})
            assert_equals(res.status_code, 200)
        else:
            raise ValueError(
                "variant_id {} exceeds the amount of flag variants. Not supported.".format(
                    self.variant_id
                )
            )
 def check_invoice_number(self, invoice_number, session_id, expected_text):
     self.http_session.cookies.set('session_id', session_id)
     payload = {
         'state': json.dumps({'mode': 'invoice_info'}),
         'msg': invoice_number
     }
     try:
         req = self.http_get('/get_bot_response', params=payload)
     except exceptions.RequestException:
         self.logger.debug(
             f"Could not get bot response. Payload: {payload}")
         raise enochecker.BrokenServiceException(
             "Could not check invoice number. Seems like the service is broken."
         )
     enochecker.assert_equals(
         200, req.status_code,
         "The request did not return with the expected response code. Verify, that the invoice service is returning the desired response."
     )
     data = req.json()
     parsed_response = data['response'].replace('\\u200d', '\u200d')
     self.logger.debug(
         f"expected text: {expected_text}, data: {parsed_response}")
     enochecker.assert_in(expected_text,
                          data['response'].replace('\\u200d', '\u200d'),
                          f"Could not find expected invoice in response.")
示例#5
0
 def havoc(self) -> None:
     """
     This method unleashes havoc on the app -> Do whatever you must to prove the service still works. Or not.
     On error, raise an EnoException.
     :raises EnoException on Error
     """
     self.info("I wanted to inform you: I'm  running <3")
     res = self.http_get("/")
     assert_equals(res.status_code, 200)
示例#6
0
def test_assert_equals():
    with pytest.raises(BrokenServiceException):
        assert_equals(1, 2)
    assert_equals(1, 1)
    assert_equals("test", b"test", autobyteify=True)
    if "test" == b"test":  # We ignore unicode stuff for python2...
        return
    with pytest.raises(BrokenServiceException) as ex:
        assert_equals("test", b"test", autobyteify=False, message="Fun")
    assert_equals(b"Fun", ex.value, autobyteify=True)
示例#7
0
    def get_ticket(self) -> None:
        # TODO: Check order?
        self.logger.debug("Starting getflag - ticket")
        try:
            (hash, username, password) = self.team_db[sha256ify(self.flag)]
        except KeyError as e:
            self.logger.warning(f"flag info missing, {e}")
            return Result.MUMBLE
        except ValueError as e:
            self.logger.warning(f"cannot get creds, {e}")
            return Result.MUMBLE
        response = self.http_post(route="/login", data={"username": username, "pw": password})
        cookies = response.cookies
        if "buggy-cookie" not in cookies.keys():
            self.logger.debug(f"Failed login for user {username}")
            raise BrokenServiceException("Cookies missing")
        assert_equals(302, response.status_code, "Login failed")
        assert_equals(response.next.url, response.url.replace("login", ""), "Login failed")
        response = self.http_get(route=f"/tickets/{hash}", cookies=cookies)
        assert_equals(200, response.status_code, "Login failed")
        assert_in(self.flag, response.text, "Flag missing")

        response = self.http_get(route=f"/profile", cookies=cookies)
        assert_equals(200, response.status_code, "Profile failed")
        assert_in("buggy-team", response.text, "Profile failed")
        assert_in("enjoy your stay!", response.text, "Profile failed")
        assert_in("questions or feedback?", response.text, "Profile failed")
        assert_in("Tickets: (1)", response.text, "Profile failed")
        assert_in("orders: (1)", response.text, "Profile failed")
        self.logger.debug("Done getflag - ticket")
    def init_user(self, make_vip=False):
        self.http_session.cookies.set('session_id', None)
        try:
            response = self.http_get(route='/')
            session_id = response.cookies.get('session_id')
            self.logger.debug("Service main page is reachable.")
        except exceptions.RequestException:
            self.logger.debug("Service not reachable.")
            raise enochecker.OfflineException()
        enochecker.assert_equals(200, response.status_code,
                                 "Could not initialize the user. Service did not return with expected response code")

        if make_vip:
            self.http_post(route='/make_me_a_vip')

        return session_id
示例#9
0
    def getflag(self) -> None:
        """
        This method retrieves a flag from the service.
        Use self.flag to get the flag that needs to be recovered and self.round to get the round the flag was placed in.
        On error, raise an EnoException.
        :raises EnoException on error
        """
        if self.variant_id == 0:
            credentials = self.chain_db
            self.login(credentials)

            res = self.http_get("/notes")
            assert_equals(res.status_code, 200)

            try:
                if self.flag not in res.json()["notes"]:
                    raise BrokenServiceException("flag is missing from /notes")
            except (KeyError, json.JSONDecodeError):
                raise BrokenServiceException(
                    "received invalid response on /notes endpoint"
                )

        elif self.variant_id == 1:
            credentials = self.chain_db
            self.login(credentials)

            res = self.http_get("/profile")
            assert_equals(res.status_code, 200)

            try:
                if self.flag != res.json()["status"]:
                    raise BrokenServiceException("flag is missing from /profile")
            except (KeyError, json.JSONDecodeError):
                raise BrokenServiceException(
                    "received invalid response on /profile endpoint"
                )
        else:
            raise ValueError(
                "variant_id {} not supported!".format(self.variant_id)
            )  # Internal error.
示例#10
0
    def getnoise(self) -> None:
        """
        This method retrieves noise in the service.
        The noise to be retrieved is inside self.flag
        The difference between noise and flag is, tht noise does not have to remain secret for other teams.
        This method can be called many times per round. Check how often using flag_idx.
        On error, raise an EnoException.
        :raises EnoException on error
        """
        category = self.team_db[self.noise]

        res = self.http_get("/posts", json={"category": category})
        assert_equals(res.status_code, 200)

        try:
            for post in res.json()["posts"]:
                if post["content"] == self.noise:
                    return  # returning nothing/raising no exceptions means everything is ok
        except (KeyError, json.JSONDecodeError):
            raise BrokenServiceException("received invalid response on /posts")
        else:
            raise BrokenServiceException("noise is missing from /posts")
示例#11
0
    def put_status(self) -> None:
        self.logger.debug("Starting putflag - status")
        username, password, cookies = self.register()

        # View Profile
        response = self.http_get(route=f"/profile", cookies=cookies)
        assert_equals(200, response.status_code, "Profile failed")
        assert_in("buggy-team", response.text, "Profile failed")
        assert_in("enjoy your stay!", response.text, "Profile failed")
        assert_in("questions or feedback?", response.text, "Profile failed")
        assert_in("Tickets: (0)", response.text, "Profile failed")
        assert_in("orders: (0)", response.text, "Profile failed")

        response = self.http_post(route=f"/profile", cookies=cookies, data={"status": self.flag})
        assert_equals(302, response.status_code, "Status failed")
        response = self.http_get(route=f"/profile", cookies=cookies)
        assert_equals(200, response.status_code, "Status failed")
        assert_in(self.flag, response.text, "Status failed")

        self.logger.debug(f"saving creds")
        self.team_db[sha256ify(self.flag)] = (username, password)

        self.logger.debug("Done putflag - status")
示例#12
0
    def register_and_login(self, credentials) -> None:
        res = self.http_post("/register", json=credentials)
        assert_equals(res.status_code, 200)

        self.login(credentials)
示例#13
0
 def login(self, credentials) -> None:
     res = self.http_post("/login", json=credentials)
     assert_equals(res.status_code, 200)
示例#14
0
    def putnoise(self) -> None:

        status = [
            "Beeing Funky!",
            "Im in ur base, killing ur d00dz",
            "Do or do not. There is no try.",
            "You must unlearn what you have learned.",
            "The greatest teacher, failure is.",
            "Pass on what you have learned.",
            "I’m too lazy to stop being lazy.",
            "Operator! Give me the number for 911!",
            "Kids, just because I don’t care doesn’t mean I’m not listening.",
            "Even communism works… in theory",
        ]

        messages = [
            "KHAAAAN!",
            "Do what I do. Hold tight and pretend it’s a plan!",
            "Never run when you’re scared.",
            "Superior intelligence and senseless cruelty just do not go together.",
            "Come on, Rory! It isn’t rocket science, it’s just quantum physics!",
            "Always take a banana to a party, Rose: bananas are good!",
            "Never be certain of anything. It’s a sign of weakness.",
            "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe.",
            "A gun is not a weapon, it’s a tool, like a hammer or a screwdriver or an alligator.",
        ]

        comments = [
            "Awesome!",
            "Amazing!",
            "This is so buggy!",
        ]

        self.logger.info("Starting putnoise")
        username, password, cookies = self.register()

        # Post Comment
        comment = random.choice(comments)
        buggy = random.choice(["super", "mega"])
        response = self.http_post(route=f"/{buggy}-buggy", data={"comment": comment}, cookies=cookies, allow_redirects=False,)
        self.logger.debug("comment written")

        response = self.http_get(route=f"/{buggy}-buggy", data={"comment": comment}, cookies=cookies)
        assert_equals(200, response.status_code, "Commenting failed")
        assert_in(comment, response.text, "Commenting failed")
        assert_in(username, response.text, "Commenting failed")

        # View Profile
        response = self.http_get(route=f"/profile", cookies=cookies)
        assert_equals(200, response.status_code, "Profile failed")
        assert_in("buggy-team", response.text, "Profile failed")
        assert_in("enjoy your stay!", response.text, "Profile failed")
        assert_in("questions or feedback?", response.text, "Profile failed")
        assert_in("Tickets: (0)", response.text, "Profile failed")
        assert_in("orders: (0)", response.text, "Profile failed")

        # Set Status
        response = self.http_post(route=f"/profile", cookies=cookies, data={"status": random.choice(status) + self.noise},)
        assert_equals(302, response.status_code, "Status failed")
        response = self.http_get(route=f"/profile", cookies=cookies)
        assert_equals(200, response.status_code, "Status failed")
        assert_in(self.noise, response.text, "Status failed")

        # Place Order
        buggy = random.choice(["super", "mega"])
        color = random.choice(["terminal-turquoise", "cyber-cyan", "buggy-blue"])
        quantity = random.randint(1, 99)
        response = self.http_post(route=f"/{buggy}-buggy", cookies=cookies, data={"color": color, "quantity": quantity},)
        assert_equals(302, response.status_code, "Order failed")
        assert_equals(response.next.url, response.url, "Order failed")
        self.logger.debug("order placed")

        # Write Ticket
        subject = random_string(20)
        response = self.http_post(
            route="/tickets", cookies=cookies, data={"subject": subject, "message": random.choice(messages) + self.noise},
        )
        self.logger.debug("ticket written")
        assert_equals(302, response.status_code, "Ticket failed")
        assert_equals(64, len(response.next.url.split("/")[-1]), "Ticket failed")
        try:
            hash = response.headers["location"].split("/")[-1].strip()
        except Exception:
            raise BrokenServiceException("Ticket failed")
        assert_equals(64, len(hash), "Ticket failed")

        # View order and ticket
        response = self.http_get(route=f"/profile", cookies=cookies)
        assert_equals(200, response.status_code, "Profile failed")
        assert_in("buggy-team", response.text, "Profile failed")
        assert_in("enjoy your stay!", response.text, "Profile failed")
        assert_in("questions or feedback?", response.text, "Profile failed")
        assert_in("Tickets: (1)", response.text, "Profile failed")
        assert_in("orders: (1)", response.text, "Profile failed")

        self.logger.debug(f"saving creds {username} {password} {hash}")
        self.team_db[sha256ify(self.noise)] = (username, password)

        self.logger.debug("Done putnoise - status")
示例#15
0
    def getnoise(self) -> None:
        self.logger.info("Starting getnoise")

        try:
            (username, password) = self.team_db[sha256ify(self.noise)]
        except KeyError as e:
            self.logger.warning(f"noise info missing, {e}")
            return Result.MUMBLE
        except ValueError as e:
            self.logger.warning(f"cannot get creds, {e}")
            return Result.MUMBLE
        response = self.http_post(route="/login", data={"username": username, "pw": password})
        cookies = response.cookies
        if "buggy-cookie" not in cookies.keys():
            self.logger.debug(f"Failed login for user {username} (missing cookies).")
            raise BrokenServiceException("Cookies missing")
        assert_equals(302, response.status_code, "Login failed")
        assert_equals(response.next.url, response.url.replace("login", ""), "Login failed")

        # check profile
        response = self.http_get(route=f"/profile", cookies=cookies)
        profile = response.text
        assert_in(self.noise, response.text, "Noise missing")
        assert_equals(200, response.status_code, "Profile failed")
        assert_in("buggy-team", response.text, "Profile failed")
        assert_in("enjoy your stay!", response.text, "Profile failed")
        assert_in("questions or feedback?", response.text, "Profile failed")
        assert_in("Tickets: (1)", response.text, "Profile failed")
        assert_in("orders: (1)", response.text, "Profile failed")

        # Check /tickets
        tickets_regex = re.compile(r"tickets\/(\w{64})")
        tickets = tickets_regex.findall(profile)
        if not tickets:
            raise BrokenServiceException("Ticket(s) missing.")
        for ticket in tickets:
            response = self.http_get(route=f"/tickets/{ticket}", cookies=cookies)
            assert_in(self.noise, response.text, "Ticket view failed.")
            assert_equals(200, response.status_code, "Ticket view failed.")
            assert_in("buggy-team", response.text, "Ticket view failed.")
            assert_in(username, response.text, "Ticket view failed.")
            assert_in("Profile", response.text, "Ticket view failed.")

        # Check /orders
        orders_regex = re.compile(r"orders\/(\w{64})")
        orders = orders_regex.findall(profile)
        if not orders:
            raise BrokenServiceException("Order(s) missing.")
        for order in orders:
            response = self.http_get(route=f"/orders/{order}", cookies=cookies)
            assert_equals(200, response.status_code, "Order view failed.")
            assert_in("Profile", response.text, "Order view failed.")
            assert_in("Expected Delivery", response.text, "Order view failed.")
            # assert_in(username, response.text, "Order view failed.")  # Too many collisions

        # Check /user
        user_regex = re.compile(r"Username:\s([0-9a-zA-Z._-]{1,64})<\/h3>")
        try:
            username_from_profile = user_regex.findall(profile)[0]
        except Exception as e:
            self.error("Failed to get username at /user")
            raise BrokenServiceException("User view failed.")
        if not username_from_profile:
            raise BrokenServiceException("User view failed.")
        response = self.http_get(route=f"/user/{username_from_profile}", cookies=cookies)
        assert_equals(200, response.status_code, "User view failed.")
        assert_in("Profile", response.text, "User view failed.")
        assert_in(self.noise, response.text, "User view failed.")
        assert_in("Buggy Bonus Points:", response.text, "User view failed.")

        self.logger.debug("Done getnoise")
示例#16
0
    def register(self) -> (str, str, requests.cookies.RequestsCookieJar):
        username = random_username()
        password = random_string(20)

        # Register
        response = self.http_post(route="/register", data={"username": username, "pw": password}, allow_redirects=False,)
        cookies = response.cookies
        if "buggy-cookie" not in cookies.keys():
            self.logger.debug(f"Failed register for user {username}")
            raise BrokenServiceException("Cookies missing")
        assert_equals(302, response.status_code, "Registration failed")
        assert_equals(
            response.next.url, response.url.replace("register", ""), "Registration failed",
        )

        # Logout
        response = self.http_get(route="/logout", cookies=cookies)
        if response.cookies:
            self.logger.debug(f"Failed logout for user {username}")
            raise BrokenServiceException("Logout failed")
        assert_equals(302, response.status_code, "Logout failed")
        assert_equals(response.next.url, response.url.replace("logout", ""), "Logout failed")

        # Login
        response = self.http_post(route="/login", data={"username": username, "pw": password})
        if "buggy-cookie" not in response.cookies.keys():
            self.logger.debug(f"Failed login for user {username}")
            raise BrokenServiceException("Cookies missing")
        assert_equals(302, response.status_code, "Login failed")
        assert_equals(response.next.url, response.url.replace("login", ""), "Login failed")
        self.logger.debug("registered and logged in")
        return username, password, response.cookies
示例#17
0
    def put_ticket(self) -> None:
        self.logger.debug("Starting putflag - ticket")
        username, password, cookies = self.register()
        # Place order
        buggy = random.choice(["super", "mega"])
        color = random.choice(["terminal-turquoise", "cyber-cyan", "buggy-blue"])
        quantity = random.randint(1, 99)
        response = self.http_post(route=f"/{buggy}-buggy", cookies=cookies, data={"color": color, "quantity": quantity},)
        assert_equals(302, response.status_code, "Order failed")
        assert_equals(response.next.url, response.url, "Order failed")
        self.logger.debug("order placed")

        # Write ticket
        subject = random_string(20)
        response = self.http_post(route="/tickets", cookies=cookies, data={"subject": subject, "message": self.flag},)
        self.logger.debug("ticket written")
        assert_equals(302, response.status_code, "Ticket failed")
        assert_equals(64, len(response.next.url.split("/")[-1]), "Ticket failed")
        try:
            hash = response.headers["location"].split("/")[-1].strip()
        except Exception:
            raise BrokenServiceException("Ticket failed")
        assert_equals(64, len(hash), "Ticket failed")

        # View order and ticket
        response = self.http_get(route=f"/profile", cookies=cookies)
        assert_equals(200, response.status_code, "Profile failed")
        assert_in("buggy-team", response.text, "Profile failed")
        assert_in("enjoy your stay!", response.text, "Profile failed")
        assert_in("questions or feedback?", response.text, "Profile failed")
        assert_in("Tickets: (1)", response.text, "Profile failed")
        assert_in("orders: (1)", response.text, "Profile failed")

        self.logger.debug(f"saving hash and order : {hash}")
        self.team_db[sha256ify(self.flag)] = (hash, username, password)

        self.logger.debug("Done putflag - ticket")