Skip to content

Commit

Permalink
feat: add havoc
Browse files Browse the repository at this point in the history
  • Loading branch information
bchmnn committed Jul 19, 2024
1 parent 0b823ad commit 908202d
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 4 deletions.
40 changes: 40 additions & 0 deletions checker/src/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
from util import (
create_devenv,
do_create_devenv,
do_create_devenv_file,
do_delete_devenv_file,
do_get_devenv,
do_get_devenv_file_content,
do_get_devenv_files,
do_patch_devenv,
do_repl_auth,
do_set_devenv_file_content,
do_user_login,
Expand Down Expand Up @@ -381,5 +386,40 @@ async def getnoise1(
assert_equals(noise.strip(), payload.strip(), "Wrong file content")


@checker.havoc(1)
async def havoc1(
client: AsyncClient,
logger: LoggerAdapter,
):
username = "".join(random.choice(string.ascii_lowercase) for _ in range(35))
password = "".join(random.choice(string.ascii_lowercase) for _ in range(35))
await do_user_register(client, logger, username, password)
cookies = await do_user_login(client, logger, username, password)

name = "".join(random.choice(string.ascii_lowercase) for _ in range(10))
buildCmd = "".join(random.choice(string.ascii_lowercase) for _ in range(10))
runCmd = "".join(random.choice(string.ascii_lowercase) for _ in range(10))

devenvUuid = await do_create_devenv(client, logger, cookies, name, buildCmd, runCmd)
devenv = await do_get_devenv(client, logger, cookies, devenvUuid)
assert_equals(name, devenv["name"], "Devenv has invalid name")
assert_equals(buildCmd, devenv["buildCmd"], "Devenv has invalid buildCmd")
assert_equals(runCmd, devenv["runCmd"], "Devenv has invalid runCmd")

name = "".join(random.choice(string.ascii_lowercase) for _ in range(10))
await do_patch_devenv(client, logger, cookies, devenvUuid, name=name)
devenv = await do_get_devenv(client, logger, cookies, devenvUuid)
assert_equals(name, devenv["name"], "After patch: Devenv has invalid name")

filename = "".join(random.choice(string.ascii_lowercase) for _ in range(10))
await do_create_devenv_file(client, logger, cookies, devenvUuid, filename)
files = await do_get_devenv_files(client, logger, cookies, devenvUuid)
assert_equals(filename in files, True, "Create file did not create file")

await do_delete_devenv_file(client, logger, cookies, devenvUuid, filename)
files = await do_get_devenv_files(client, logger, cookies, devenvUuid)
assert_equals(filename not in files, True, "Delete file did not delete file")


if __name__ == "__main__":
checker.run()
104 changes: 104 additions & 0 deletions checker/src/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import collections.abc
import random
import re
import string
Expand Down Expand Up @@ -203,6 +204,109 @@ async def create_devenv(
return devenvUuid


async def do_get_devenv(
client: AsyncClient,
logger: LoggerAdapter,
cookies: Cookies,
devenvUuid: str,
):

response = await client.get(
"/api/devenv/" + devenvUuid,
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, "Getting devenv failed")
return response.json()


async def do_patch_devenv(
client: AsyncClient,
logger: LoggerAdapter,
cookies: Cookies,
devenvUuid: str,
name: str = "",
buildCmd: str = "",
runCmd: str = "",
):
response = await client.patch(
"/api/devenv/" + devenvUuid,
json={
"name": name,
"buildCmd": buildCmd,
"runCmd": runCmd,
},
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, "Patching devenv failed")


async def do_get_devenv_files(
client: AsyncClient,
logger: LoggerAdapter,
cookies: Cookies,
devenvUuid: str,
):
response = await client.get(
"/api/devenv/" + devenvUuid + "/files",
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, "Getting devenv files failed")
files = response.json()
assert_equals(
isinstance(files, collections.abc.Sequence),
True,
"Get files did not return array",
)
return files


async def do_create_devenv_file(
client: AsyncClient,
logger: LoggerAdapter,
cookies: Cookies,
devenvUuid: str,
filename: str,
):
response = await client.post(
"/api/devenv/" + devenvUuid + "/files",
json={"name": filename},
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, "Creating devenv file failed")


async def do_delete_devenv_file(
client: AsyncClient,
logger: LoggerAdapter,
cookies: Cookies,
devenvUuid: str,
filename: str,
):
response = await client.delete(
"/api/devenv/" + devenvUuid + "/files/" + filename,
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, "Deleting devenv file failed")


async def do_set_devenv_file_content(
client: AsyncClient,
logger: LoggerAdapter,
Expand Down
22 changes: 18 additions & 4 deletions documentation/benchmark/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def get_ip_address(ifname):

VARIANTS: TVariants = {
0: ["putflag", "getflag", "exploit", "putnoise", "getnoise"],
1: ["putflag", "getflag", "exploit", "putnoise", "getnoise"],
1: ["putflag", "getflag", "exploit", "putnoise", "getnoise", "havoc"],
}
TICKS = 3
MULTIPLIER = 1
Expand Down Expand Up @@ -143,6 +143,10 @@ def putnoise_chain_id(self) -> str:
def getnoise_chain_id(self) -> str:
return f"{self.chain_prefix}_noise_s0_r{self.round_id}_t0_i0"

@property
def havoc_chain_id(self) -> str:
return f"{self.chain_prefix}_havoc_s0_r{self.round_id}_t0_i0"

@property
def putflag_payload(self) -> CheckerPayload:
payload = self.payload_stub
Expand Down Expand Up @@ -183,6 +187,13 @@ def getnoise_payload(self) -> CheckerPayload:
payload["taskChainId"] = self.getnoise_chain_id
return payload

@property
def havoc_payload(self) -> CheckerPayload:
payload = self.payload_stub
payload["method"] = "havoc"
payload["taskChainId"] = self.getnoise_chain_id
return payload

async def request(self, method: TMethod):
if method not in self.methods:
return None
Expand All @@ -198,6 +209,8 @@ async def request(self, method: TMethod):
payload = self.putnoise_payload
case "getnoise":
payload = self.getnoise_payload
case "havoc":
payload = self.havoc_payload
start = time.monotonic()
response = await self.session.post("/", json=payload)
if response.status == 200:
Expand Down Expand Up @@ -257,16 +270,17 @@ async def main():
tasks: List[asyncio.Task] = []

async with aiohttp.ClientSession(CHECKER_ADDR) as client:
for i in range(10):
for i in range(1):
round = Round(
client,
curr_round,
VARIANTS,
multiplier=MULTIPLIER,
exploits_amount=EXPLOITS_AMOUNT,
)
await round.request("putnoise")
await round.request("getnoise")
await round.request("havoc")
# await round.request("putnoise")
# await round.request("getnoise")
curr_round += 1
# for i in range(10):
# round = Round(
Expand Down

0 comments on commit 908202d

Please sign in to comment.