diff --git a/system-calls/.init b/system-calls/.init new file mode 100755 index 0000000..bddefe3 --- /dev/null +++ b/system-calls/.init @@ -0,0 +1,123 @@ +#!/usr/bin/python + +import os +import random +import subprocess +from pathlib import Path + +import jinja2 + + +config_path = Path(__file__).parent / ".config" +passwords_template_path = Path(__file__).parent / "passwords.c.j2" + +passwords_dir = Path("/tmp/.password") +passwords_dir.mkdir(parents=True, exist_ok=True) +password_paths = [] +for _ in range(256): + passwords_path = passwords_dir / os.urandom(8).hex() + passwords_path.write_text(os.urandom(32).hex() + "\n") + password_paths.append(passwords_path) + +def compile_password_checker(operations): + passwords_template = jinja2.Template(passwords_template_path.read_text()) + subprocess.run(["/usr/bin/gcc", "-o", "/challenge/check-password", "-x", "c", "-"], + input=passwords_template.render(operations=operations), + text=True, + check=True) + +def challenge_password(): + operations = [ + {"type": "open", "path": str(password_paths[0])}, + {"type": "read", "fd": 0, "offset": 0, "size": 64}, + {"type": "close", "fd": 0}, + {"type": "cmp", "prompt": "Password: ", "offset": 0, "size": 64} + ] + return operations + +def challenge_multiple_passwords(): + password_count = 3 + operations = [] + for i in range(password_count): + operations.extend([ + {"type": "open", "path": str(password_paths[i])}, + {"type": "read", "fd": 0, "offset": 0, "size": 64}, + {"type": "close", "fd": 0}, + {"type": "cmp", "prompt": "Password: ", "offset": 0, "size": 64} + ]) + return operations + +def challenge_fd_passwords(): + password_count = 3 + operations = [] + for fd in range(256): + operations.append({"type": "open", "path": str(password_paths[fd])}) + random_fds = random.sample(range(256), password_count) + for fd in random_fds: + operations.extend([ + {"type": "read", "fd": fd, "offset": 0, "size": 64}, + {"type": "cmp", "prompt": "Password: ", "offset": 0, "size": 64} + ]) + return operations + +def challenge_size_passwords(): + password_count = 3 + operations = [] + for fd in range(256): + operations.append({"type": "open", "path": str(password_paths[fd])}) + for fd in random.sample(range(256), password_count): + random_size = random.randint(16, 64) + operations.extend([ + {"type": "read", "fd": fd, "offset": 0, "size": random_size}, + {"type": "cmp", "prompt": "Password: ", "offset": 0, "size": random_size} + ]) + return operations + +def challenge_offset_passwords(): + password_count = 8 + operations = [] + for fd in range(256): + operations.append({"type": "open", "path": str(password_paths[fd])}) + random_fds = random.sample(range(256), password_count) + random_offsets = random.shuffle([64 * i for i in range(password_count)]) + for fd, offset in zip(random_fds, random_offsets): + operations.append( + {"type": "read", "fd": fd, "offset": offset, "size": 64}, + ) + operations.append( + {"type": "cmp", "prompt": "Password: ", "offset": 0, "size": 64 * password_count} + ) + return operations + +def challenge_overlapping_passwords(): + password_count = 5 + operations = [] + for fd in range(256): + operations.append({"type": "open", "path": str(password_paths[fd])}) + random_fds = random.sample(range(256), password_count) + random_offset = 0 + random_offsets = [random_offset] + for _ in range(password_count - 1): + random_offset = random.randrange(16, 48) + random_offset + random_offsets.append(random_offset) + total_size = random_offset + 64 + for fd, offset in zip(random_fds, random_offsets): + operations.append( + {"type": "read", "fd": fd, "offset": offset, "size": 64}, + ) + operations.append( + {"type": "cmp", "prompt": "Password: ", "offset": 0, "size": total_size} + ) + return operations + +if __name__ == "__main__": + challenge = "challenge_" + config_path.read_text().strip() + if challenge not in globals(): + raise RuntimeError(f"Unknown challenge: {challenge}") + + operations = globals()[challenge]() + compile_password_checker(operations) + + os.unlink(config_path) + os.unlink(passwords_template_path) + os.unlink(__file__) diff --git a/system-calls/fd-passwords/.config b/system-calls/fd-passwords/.config new file mode 100644 index 0000000..dd0829c --- /dev/null +++ b/system-calls/fd-passwords/.config @@ -0,0 +1 @@ +fd_passwords diff --git a/system-calls/fd-passwords/.init b/system-calls/fd-passwords/.init new file mode 120000 index 0000000..ea4ba49 --- /dev/null +++ b/system-calls/fd-passwords/.init @@ -0,0 +1 @@ +../.init \ No newline at end of file diff --git a/system-calls/fd-passwords/passwords.c.j2 b/system-calls/fd-passwords/passwords.c.j2 new file mode 120000 index 0000000..ed68b19 --- /dev/null +++ b/system-calls/fd-passwords/passwords.c.j2 @@ -0,0 +1 @@ +../passwords.c.j2 \ No newline at end of file diff --git a/system-calls/module.yml b/system-calls/module.yml new file mode 100644 index 0000000..6424736 --- /dev/null +++ b/system-calls/module.yml @@ -0,0 +1,14 @@ +name: System Calls +challenges: +- id: password + name: "Password" +- id: multiple-passwords + name: "Multiple Passwords" +- id: fd-passwords + name: "File Descriptors" +- id: size-passwords + name: "Sizes" +- id: overlapping-passwords + name: "Overlapping" +- id: offset-passwords + name: "Offsets" diff --git a/system-calls/multiple-passwords/.config b/system-calls/multiple-passwords/.config new file mode 100644 index 0000000..ef25be8 --- /dev/null +++ b/system-calls/multiple-passwords/.config @@ -0,0 +1 @@ +multiple_passwords diff --git a/system-calls/multiple-passwords/.init b/system-calls/multiple-passwords/.init new file mode 120000 index 0000000..ea4ba49 --- /dev/null +++ b/system-calls/multiple-passwords/.init @@ -0,0 +1 @@ +../.init \ No newline at end of file diff --git a/system-calls/multiple-passwords/passwords.c.j2 b/system-calls/multiple-passwords/passwords.c.j2 new file mode 120000 index 0000000..ed68b19 --- /dev/null +++ b/system-calls/multiple-passwords/passwords.c.j2 @@ -0,0 +1 @@ +../passwords.c.j2 \ No newline at end of file diff --git a/system-calls/offset-passwords/.config b/system-calls/offset-passwords/.config new file mode 100644 index 0000000..733e6bb --- /dev/null +++ b/system-calls/offset-passwords/.config @@ -0,0 +1 @@ +offset_passwords diff --git a/system-calls/offset-passwords/.init b/system-calls/offset-passwords/.init new file mode 120000 index 0000000..ea4ba49 --- /dev/null +++ b/system-calls/offset-passwords/.init @@ -0,0 +1 @@ +../.init \ No newline at end of file diff --git a/system-calls/offset-passwords/passwords.c.j2 b/system-calls/offset-passwords/passwords.c.j2 new file mode 120000 index 0000000..ed68b19 --- /dev/null +++ b/system-calls/offset-passwords/passwords.c.j2 @@ -0,0 +1 @@ +../passwords.c.j2 \ No newline at end of file diff --git a/system-calls/overlapping-passwords/.config b/system-calls/overlapping-passwords/.config new file mode 100644 index 0000000..dfcc623 --- /dev/null +++ b/system-calls/overlapping-passwords/.config @@ -0,0 +1 @@ +overlapping_passwords diff --git a/system-calls/overlapping-passwords/.init b/system-calls/overlapping-passwords/.init new file mode 120000 index 0000000..ea4ba49 --- /dev/null +++ b/system-calls/overlapping-passwords/.init @@ -0,0 +1 @@ +../.init \ No newline at end of file diff --git a/system-calls/overlapping-passwords/passwords.c.j2 b/system-calls/overlapping-passwords/passwords.c.j2 new file mode 120000 index 0000000..ed68b19 --- /dev/null +++ b/system-calls/overlapping-passwords/passwords.c.j2 @@ -0,0 +1 @@ +../passwords.c.j2 \ No newline at end of file diff --git a/system-calls/password/.config b/system-calls/password/.config new file mode 100644 index 0000000..f3097ab --- /dev/null +++ b/system-calls/password/.config @@ -0,0 +1 @@ +password diff --git a/system-calls/password/.init b/system-calls/password/.init new file mode 120000 index 0000000..ea4ba49 --- /dev/null +++ b/system-calls/password/.init @@ -0,0 +1 @@ +../.init \ No newline at end of file diff --git a/system-calls/password/passwords.c.j2 b/system-calls/password/passwords.c.j2 new file mode 120000 index 0000000..ed68b19 --- /dev/null +++ b/system-calls/password/passwords.c.j2 @@ -0,0 +1 @@ +../passwords.c.j2 \ No newline at end of file diff --git a/system-calls/passwords.c.j2 b/system-calls/passwords.c.j2 new file mode 100644 index 0000000..e10ab5f --- /dev/null +++ b/system-calls/passwords.c.j2 @@ -0,0 +1,65 @@ +char buffer[4096]; + +int main() +{ + int result; + int fds[256]; + char input[4096]; + + {% for operation in operations %} + {% if operation.type == "open" %} + result = open("{{ operation.path }}", O_RDONLY); + if (result < 0) { + perror("open"); + return 1; + } + fds[{{ loop.index0 }}] = result; + {% elif operation.type == "read" %} + result = read(fds[{{ operation.fd }}], &buffer[{{ operation.offset }}], {{ operation.size }}); + if (result < 0) { + perror("read"); + return 1; + } + {% elif operation.type == "write" %} + result = write(STDOUT_FILENO, &buffer[{{ operation.offset }}], {{ operation.size }}); + if (result < 0) { + perror("write"); + return 1; + } + {% elif operation.type == "close" %} + result = close(fds[{{ operation.fd }}]); + if (result < 0) { + perror("close"); + return 1; + } + {% elif operation.type == "cmp" %} + printf("%s", "{{ operation.prompt }}"); + read(STDIN_FILENO, input, {{ operation.size }} + 1); + if (memcmp(input, &buffer[{{ operation.offset }}], {{ operation.size }}) != 0) { + puts("Incorrect\n"); + return 1; + } else { + puts("Correct\n"); + } + {% endif %} + + int flag_fd = open("/flag", O_RDONLY); + if (flag_fd < 0) { + perror("open /flag"); + return 1; + } + + int flag_length = read(flag_fd, buffer, 4096); + if (flag_length < 0) { + perror("read /flag"); + return 1; + } + + flag_length = write(STDOUT_FILENO, buffer, flag_length); + if (flag_length < 0) { + perror("write /flag"); + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/system-calls/size-passwords/.config b/system-calls/size-passwords/.config new file mode 100644 index 0000000..79c7163 --- /dev/null +++ b/system-calls/size-passwords/.config @@ -0,0 +1 @@ +size_passwords diff --git a/system-calls/size-passwords/.init b/system-calls/size-passwords/.init new file mode 120000 index 0000000..ea4ba49 --- /dev/null +++ b/system-calls/size-passwords/.init @@ -0,0 +1 @@ +../.init \ No newline at end of file diff --git a/system-calls/size-passwords/passwords.c.j2 b/system-calls/size-passwords/passwords.c.j2 new file mode 120000 index 0000000..ed68b19 --- /dev/null +++ b/system-calls/size-passwords/passwords.c.j2 @@ -0,0 +1 @@ +../passwords.c.j2 \ No newline at end of file