Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

Commit

Permalink
ICC2023 KOTH Release
Browse files Browse the repository at this point in the history
  • Loading branch information
Gaspare Ferraro committed Aug 4, 2023
0 parents commit fd769bb
Show file tree
Hide file tree
Showing 434 changed files with 1,179,705 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ICC 2023 - KOTH Game

![KOTH](KOTH.png)

This repo contains all the files to run the King-of-the-Hill (KOTH) game proposed during the 2023 edition of the International Cybersecurity Challenge (ICC) held onthe 3rd of August in San Diego developed and organized by the team of the italian [Cybersecurity National Lab](https://cybersecnalab.it).

The repo is organized in the following files and folders:

- [RULES.md](RULES.md): complete rules of the game
- [WRITEUP.md](WRITEUP.md): writeup of quirks and vulnerabilities present in the game
- `backend/`: source of the game engine
- `deploy/`: complete project of the game infrastructure
- `dist/`: folder containing all the files distributed to the teams
- `bots/`: implementation of game bot for internal testing
- `VMTests/`: implementation of several bot for internal testing
- `results/`: export of all the results of the 2023 ICC KOTH

## ICC 2023 - KOTH scoreboard

In the following image you can find the final KOTH scoreboard for ICC2023, for full results of each round and all the exports please have a look to the [/img](/img) and [/results](/results) folders.

![/KOTH-scoreboard](/KOTH-scoreboard.png)

## Credits

The King-of-the-Hill (KOTH) game was developed by team of the italian [Cybersecurity National Lab](https://cybersecnatlab.it), credits go to:

- Alberto `alberto247` Carboneri
- Gianluca `devgianlu` Altomani
- Gaspare `gaspare` Ferraro
- Matteo `mr96` Rossi
395 changes: 395 additions & 0 deletions RULES.md

Large diffs are not rendered by default.

254 changes: 254 additions & 0 deletions VMTests/VMCodeCompiler/compiler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@

from .config import *
import logging, verboselogs
import coloredlogs
import json

logger = verboselogs.VerboseLogger('VMCompiler')
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
coloredlogs.install(level='DEBUG', logger=logger)


class Compiler:
code=None
registries=[]
cmpRegistry=None
compiled_code=None
def __init__(self, file):
data=open(file, "r").readlines()
self.code = [d.strip() for d in data if d.strip()!=""]
for i in range(n_registries):
self.registries.append(Registry(f"r{i}", i))
self.cmpRegistry=Registry("cmpRegistry", -1)

def compile(self):
labels={}
code_without_labels=[]
compiled_code=[]
jmp_row_number=0
for row_number in range(len(self.code)):
data=self.code[row_number].split(";") # remove comment
line = data[0]
if(line.strip()!=""):
if(line.strip()[0]==":"): # label
if(line.strip()[1:] in labels):
logger.critical(f"SyntaxError, duplicate label {line.strip()[1:]} at line {row_number}, previous was at line {labels[line.strip()[1:]]}, near {line.strip()}")
exit(-1)
labels[line.strip()[1:]]=jmp_row_number
else:
jmp_row_number+=1
code_without_labels.append(line)
for row_number in range(len(code_without_labels)):
data=code_without_labels[row_number].split(";") # remove comment
line = data[0]
instruction_name=line.split(" ")[0]
parameters=" ".join(line.split(" ")[1:])
instruction_name=instruction_name.strip().lower()
parameters=parameters.strip()
instruction=None
if instruction_name=="AddBooleanToArray".lower():
instruction=AddBooleanToArray()
elif instruction_name=="AddFloatToArray".lower():
instruction=AddFloatToArray()
elif instruction_name=="AddIntegerToArray".lower():
instruction=AddIntegerToArray()
elif instruction_name=="AddStringToArray".lower():
instruction=AddStringToArray()
elif instruction_name=="GetFromArray".lower():
instruction=GetFromArray()
elif instruction_name=="RemoveFromArray".lower():
instruction=RemoveFromArray()
elif instruction_name=="SetBooleanToArray".lower():
instruction=SetBooleanToArray()
elif instruction_name=="SetFloatToArray".lower():
instruction=SetFloatToArray()
elif instruction_name=="SetIntegerToArray".lower():
instruction=SetIntegerToArray()
elif instruction_name=="SetStringToArray".lower():
instruction=SetStringToArray()
elif instruction_name=="InitBoolean".lower():
instruction=InitBoolean()
elif instruction_name=="InitBooleanArray".lower():
instruction=InitBooleanArray()
elif instruction_name=="InitFloat".lower():
instruction=InitFloat()
elif instruction_name=="InitFloatArray".lower():
instruction=InitFloatArray()
elif instruction_name=="InitInteger".lower():
instruction=InitInteger()
elif instruction_name=="InitIntegerArray".lower():
instruction=InitIntegerArray()
elif instruction_name=="InitString".lower():
instruction=InitString()
elif instruction_name=="InitStringArray".lower():
instruction=InitStringArray()
elif instruction_name=="Add".lower():
instruction=Add()
elif instruction_name=="Sub".lower():
instruction=Sub()
elif instruction_name=="Mul".lower():
instruction=Mul()
elif instruction_name=="Div".lower():
instruction=Div()
elif instruction_name=="Mod".lower():
instruction=Mod()
elif instruction_name=="Pow".lower():
instruction=Pow()
elif instruction_name=="Sqrt".lower():
instruction=Sqrt()
elif instruction_name=="And".lower():
instruction=And()
elif instruction_name=="Or".lower():
instruction=Or()
elif instruction_name=="Not".lower():
instruction=Not()
elif instruction_name=="Xor".lower():
instruction=Xor()
elif instruction_name=="Neg".lower():
instruction=Neg()
elif instruction_name=="Shr".lower():
instruction=Shr()
elif instruction_name=="Shl".lower():
instruction=Shl()
elif instruction_name=="Sar".lower():
instruction=Sar()
elif instruction_name=="Ceil".lower():
instruction=Ceil()
elif instruction_name=="Floor".lower():
instruction=Floor()
elif instruction_name=="Round".lower():
instruction=Round()
elif instruction_name=="Mov".lower():
instruction=Mov()
elif instruction_name=="Rnd".lower():
instruction=Rnd()
elif instruction_name=="IsNull".lower():
instruction=IsNull()
elif instruction_name=="GetTileInformation".lower():
instruction=GetTileInformation()
elif instruction_name=="GetOwnInformation".lower():
instruction=GetOwnInformation()
elif instruction_name=="JMP".lower():
instruction=JMP()
elif instruction_name=="JMPEQ0".lower():
instruction=JMPEQ0()
elif instruction_name=="JMPNEQ0".lower():
instruction=JMPNEQ0()
elif instruction_name=="JMPL0".lower():
instruction=JMPL0()
elif instruction_name=="JMPG0".lower():
instruction=JMPG0()
elif instruction_name=="CMP".lower():
instruction=CMP()
elif instruction_name=="MoveTo".lower():
instruction=MoveTo()
elif instruction_name=="UseAbility".lower():
instruction=UseAbility()
elif instruction_name=="DoNothing".lower():
instruction=DoNothing()
elif instruction_name=="Log".lower():
instruction=Log()
else:
logger.critical(f"SyntaxError, instruction {instruction_name} at line {row_number} is not valid, near {line.strip()}")
exit(-1)
if(instruction.instruction in [Instructions.JMP, Instructions.JMPEQ0, Instructions.JMPNEQ0, Instructions.JMPG0, Instructions.JMPL0]):
jumpto=parameters.strip()
if(jumpto not in labels):
logger.critical(f"SyntaxError, label {jumpto} not defined, at line {row_number}, near {line.strip()}")
exit(-1)
jumpto = labels[jumpto]
compiled_code.append({"instruction":instruction.instruction.value[0], "params":[{"type":typeMap[Types.INTEGER], "value":jumpto}]})
else:
param_number = len(instruction.params) # Amount of expected parameters
params=[x.strip() for x in parameters.split(",")]
if(param_number==0 and len(params)>1):
logger.critical(f"SyntaxError, expected {param_number} parameters for instruction {instruction_name} at line {row_number} but found {len(params)} instead, near {line.strip()}")
exit(-1)
if(param_number==0 and len(params)<=1):
compiled_code.append({"instruction":instruction.instruction.value[0], "params":[]})
else:
if(len(params)!=param_number):
logger.critical(f"SyntaxError, expected {param_number} parameters for instruction {instruction_name} at line {row_number} but found {len(params)} instead, near {line.strip()}")
exit(-1)
param_values=[] # values of parameters
param_types=[] # types of parameters
for param in params:
if(param==""):
logger.critical(f"SyntaxError, empty parameter for instruction {instruction_name} at line {row_number}, near {line.strip()}")
exit(-1)
else:
if(param[0]=="r"): # if a registry
try:
registry_number=int(param[1:])
if(not (registry_number>=0 and registry_number<n_registries)):
logger.critical(f"SyntaxError, registry {param} for instruction {instruction_name} at line {row_number} is not a valid registry, near {line.strip()}")
exit(-1)
param_values.append(self.registries[registry_number])
param_types.append(Types.REGISTRY)
except ValueError:
logger.critical(f"SyntaxError, registry {param} for instruction {instruction_name} at line {row_number} is not a valid registry, near {line.strip()}")
exit(-1)
elif(param[0]=="#"): # if a number or float
try:
value=int(param[1:])
param_values.append(value)
param_types.append(Types.INTEGER)
except ValueError:
try:
value=float(param[1:])
param_values.append(value)
param_types.append(Types.FLOAT)
except ValueError:
logger.critical(f"SyntaxError, value {param} for instruction {instruction_name} at line {row_number} is not a valid integer or float, near {line.strip()}")
exit(-1)
elif(param[0]=="\""): # if a string
if(param[-1]!="\""):
logger.critical(f"SyntaxError, value {param} for instruction {instruction_name} at line {row_number} is not a valid string, near {line.strip()}")
exit(-1)
value=param[1:-1]
param_values.append(value)
param_types.append(Types.STRING)
elif(param.lower()=="true" or param.lower()=="false"): # if a boolean
param_values.append(param.lower()=="true")
param_types.append(Types.BOOLEAN)
else:
logger.critical(f"SyntaxError, value {param} for instruction {instruction_name} at line {row_number} is not a valid registry, integer, float, string or boolean, near {line.strip()}")
exit(-1)
if(len(param_values)!=param_number): # check length
logger.critical(f"SyntaxError, expected {param_number} parameters for instruction {instruction_name} at line {row_number} but found {len(param_values)} instead, near {line.strip()}")
exit(-1)
expected_registry_or_not=instruction.paramsTypes
if(len(expected_registry_or_not)!=param_number): # must be same
logger.critical(f"Compiler error, instruction {instruction_name} is badly formatted, near {line.strip()}")
exit(-1)
for i in range(len(expected_registry_or_not)): # for each parameter, check if it must be a registry and if it is
if(expected_registry_or_not[i]==ParamTypes.REGISTRY and param_types[i]!=Types.REGISTRY):
logger.critical(f"SyntaxError, parameter number {i} for instruction {instruction_name} at line {row_number} is expected to be a registry, found {param_types[i]} instead, near {line.strip()}")
exit(-1)
expected_types = instruction.params
for i in range(len(expected_types)):
true_type=param_types[i] # get type of parameter
if(param_types[i]!=Types.REGISTRY):
if(true_type not in expected_types[i]):# wrong immediate, critical
logger.critical(f"SyntaxError, parameter number {i} for instruction {instruction_name} at line {row_number} is expected to be of type {expected_types[i]}, found {true_type} instead. Near {line.strip()}")
exit(-1)
instruction.update_registries_types(param_values, self.cmpRegistry)
final_params=[]
for i in range(param_number):
value=param_values[i]
if(param_types[i]==Types.REGISTRY):
value=param_values[i].number
final_params.append({"type":typeMap[param_types[i]], "value":value})
compiled_code.append({"instruction":instruction.instruction.value[0], "params":final_params})
self.compiled_code=compiled_code

def write_to_file(self, file):
with open(file, "w") as f:
f.write(json.dumps(self.compiled_code))


def get_code(self):
return self.compiled_code


Loading

0 comments on commit fd769bb

Please sign in to comment.