{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport requests\nfrom IPython.display import Image as Ima\nfrom IPython.display import clear_output, display\nfrom PIL import Image as Im\nfrom torch.utils.data import Dataset, DataLoader\nimport torch\nimport joblib\nimport matplotlib.pyplot as plt\nimport json\nimport base64\nimport shutil\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n\ndir_name = \"/kaggle/input/ai-village-ctf\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-11T19:00:00.316138Z","iopub.execute_input":"2022-09-11T19:00:00.316719Z","iopub.status.idle":"2022-09-11T19:00:02.415289Z","shell.execute_reply.started":"2022-09-11T19:00:00.316592Z","shell.execute_reply":"2022-09-11T19:00:02.414182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def add_flag(challenge_id: str, flag: str) -> str:\n    try:\n        submission_path = \"/kaggle/working/submission.csv\"\n        template_path = f\"{dir_name}/submission.csv\"\n        if not os.path.isfile(submission_path) :\n            shutil.copyfile(template_path, submission_path)\n        flags = pd.read_csv(submission_path, index_col=\"challenge_id\")\n        valid = flags.index.to_list()\n        if challenge_id in valid:\n            flags.at[challenge_id] = flag\n            flags.to_csv(submission_path)\n            print(\"Flag saved. If you want to update the scoreboard, click 'submit' on the right. Remember that you can only update your score on the scoreboard 50 times per day\")\n        else:\n            print(\"Invalid challenge_id\")\n    except:\n        print(\"We had trouble saving that flag. Keep a copy of it and contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T19:00:02.420702Z","iopub.execute_input":"2022-09-11T19:00:02.423264Z","iopub.status.idle":"2022-09-11T19:00:02.434151Z","shell.execute_reply.started":"2022-09-11T19:00:02.423227Z","shell.execute_reply":"2022-09-11T19:00:02.432666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# HOTDOG (id: hotdog) -- 200 Points\n\n### Scenario\n\nThis is Chester. He's heard of Hotdog/Not Hotdog, but really wants to be classified as a hot-dog (get it?).\n\n### Objective\n\nHelp Chester classify as a hotdog.","metadata":{}},{"cell_type":"code","source":"Ima(filename=f'{dir_name}/hotdog/chester.png')","metadata":{"execution":{"iopub.status.busy":"2022-09-11T19:00:02.438460Z","iopub.execute_input":"2022-09-11T19:00:02.441087Z","iopub.status.idle":"2022-09-11T19:00:02.474024Z","shell.execute_reply.started":"2022-09-11T19:00:02.441049Z","shell.execute_reply":"2022-09-11T19:00:02.473220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_DIMS = (224, 224)\n\nbackground = Im.open(f\"{dir_name}/hotdog/chester.png\")\nbackground = background.resize(IMAGE_DIMS)\n\noverlay = Im.open(\"../input/hotdog-nothotdog/hotdog-nothotdog/hotdog-nothotdog/test/hotdog/138933.jpg\")\noverlay = overlay.resize(IMAGE_DIMS)\n\nnew_img = Im.blend(background, overlay, 0.7)\n\nimg_bytes = new_img.tobytes()\nb64_img_bytes = base64.urlsafe_b64encode(img_bytes)\n\ntry:\n    r = requests.post(\"https://hotdog.fly.dev/score\", data=json.dumps({\"input\": b64_img_bytes.decode()}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")\n\nnew_img","metadata":{"execution":{"iopub.status.busy":"2022-09-11T19:00:02.475570Z","iopub.execute_input":"2022-09-11T19:00:02.475965Z","iopub.status.idle":"2022-09-11T19:00:02.923301Z","shell.execute_reply.started":"2022-09-11T19:00:02.475921Z","shell.execute_reply":"2022-09-11T19:00:02.922365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"hotdog\", \"XIO6AH0AODUVXC}0TFOKMV2FF3IQ8G0BIJXOANK4BLW7PSUARS9HVAC9DBDJ6ERSRGC96HNL4LWYYOIP3RVTFO5PVV5D2XPB2MQAT3SWNFDMGR87HUIDFOCBLH5{ZVMZ\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# HOTTERDOG (id: hotterdog) -- 400 Points\n\n### Scenario\n\nChester submitted himself in the \"most creative hotdog\" contest. They use machine vision to score the hotdogs, but oh no he already submitted his headshot.\n\n### Objective\n\nHelp Chester classify as a hotdog, but it has to look like Chester to a human. Modify his picture to fool a classifier.\n\n# **The plan is to fool InceptionV3 first and then fine-tune for MobileNet. That should be enough.**","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport tensorflow as tf\nfrom keras.preprocessing import image\nfrom keras.applications import inception_v3, resnet, mobilenet, vgg16\nfrom keras import backend as K\nfrom PIL import Image\ntf.compat.v1.disable_eager_execution()\n\n# Load pre-trained image recognition model\nmodel = inception_v3.InceptionV3()\n\n# Grab a reference to the first and last layer of the neural net\nmodel_input_layer = model.layers[0].input\nmodel_output_layer = model.layers[-1].output\n\n# Choose an ImageNet object to fake\n# The list of classes is available here: https://gist.github.com/ageitgey/4e1342c10a71981d0b491e1b8227328b\n# Class #934 is hotdog\nobject_type_to_fake = 934\n\n# Load the image to hack\nimg = image.load_img(f\"../input/ai-village-ctf/hotterdog/chester.png\", target_size=(299, 299))\noriginal_image = image.img_to_array(img)\n\n# Scale the image so all pixel intensities are between [-1, 1] as the model expects\noriginal_image /= 255.\noriginal_image -= 0.5\noriginal_image *= 2.\n\n# Add a 4th dimension for batch size (as Keras expects)\noriginal_image = np.expand_dims(original_image, axis=0)\n\n# Pre-calculate the maximum change we will allow to the image\n# We'll make sure our hacked image never goes past this so it doesn't look funny.\n# A larger number produces an image faster but risks more distortion.\nmax_change_above = original_image + 0.5\nmax_change_below = original_image - 0.5\n\n# Create a copy of the input image to hack on\nhacked_image = np.copy(original_image)\n\n# How much to update the hacked image in each iteration\nlearning_rate = 0.1\n\n# Define the cost function.\n# Our 'cost' will be the likelihood out image is the target class according to the pre-trained model\ncost_function = model_output_layer[0, object_type_to_fake]\n\n# We'll ask Keras to calculate the gradient based on the input image and the currently predicted class\n# In this case, referring to \"model_input_layer\" will give us back image we are hacking.\ngradient_function = K.gradients(cost_function, model_input_layer)[0]\n\n# Create a Keras function that we can call to calculate the current cost and gradient\ngrab_cost_and_gradients_from_model = K.function([model_input_layer, K.learning_phase()], [cost_function, gradient_function])\n\ncost = 0.0\n\n# In a loop, keep adjusting the hacked image slightly so that it tricks the model more and more\n# until it gets to at least 80% confidence\nwhile cost < 0.95:\n    # Check how close the image is to our target class and grab the gradients we\n    # can use to push it one more step in that direction.\n    # Note: It's really important to pass in '0' for the Keras learning mode here!\n    # Keras layers behave differently in prediction vs. train modes!\n    cost, gradients = grab_cost_and_gradients_from_model([hacked_image, 0])\n\n    # Move the hacked image one step further towards fooling the model\n    hacked_image += gradients * learning_rate\n\n    # Ensure that the image doesn't ever change too much to either look funny or to become an invalid image\n    hacked_image = np.clip(hacked_image, max_change_below, max_change_above)\n    hacked_image = np.clip(hacked_image, -1.0, 1.0)\n\n    print(\"Model's predicted likelihood that the image is a hotdog: {:.8}%\".format(cost * 100))\n\n# De-scale the image's pixels from [-1, 1] back to the [0, 255] range\nimg = hacked_image[0]\nimg /= 2.\nimg += 0.5\nimg *= 255.\n\n# Save the hacked image!\nim = Image.fromarray(img.astype(np.uint8))\nim.save(\"hacked-image.png\")\nim","metadata":{"scrolled":true,"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport tensorflow as tf\nfrom keras.preprocessing import image\nfrom keras.applications import inception_v3, resnet, mobilenet, vgg16\nfrom keras import backend as K\nfrom PIL import Image\ntf.compat.v1.disable_eager_execution()\n\n# Load pre-trained image recognition model\nmodel = mobilenet.MobileNet()\n\n# Grab a reference to the first and last layer of the neural net\nmodel_input_layer = model.layers[0].input\nmodel_output_layer = model.layers[-1].output\n\n# Choose an ImageNet object to fake\n# The list of classes is available here: https://gist.github.com/ageitgey/4e1342c10a71981d0b491e1b8227328b\n# Class #934 is hotdog\nobject_type_to_fake = 934\n\n# Load the image to hack\nimg = image.load_img(f\"./hacked-image.png\", target_size=(224, 224))\noriginal_image = image.img_to_array(img)\n\n# Scale the image so all pixel intensities are between [-1, 1] as the model expects\noriginal_image /= 255.\noriginal_image -= 0.5\noriginal_image *= 2.\n\n# Add a 4th dimension for batch size (as Keras expects)\noriginal_image = np.expand_dims(original_image, axis=0)\n\n# Pre-calculate the maximum change we will allow to the image\n# We'll make sure our hacked image never goes past this so it doesn't look funny.\n# A larger number produces an image faster but risks more distortion.\nmax_change_above = original_image + 0.5\nmax_change_below = original_image - 0.5\n\n# Create a copy of the input image to hack on\nhacked_image = np.copy(original_image)\n\n# How much to update the hacked image in each iteration\nlearning_rate = 0.1\n\n# Define the cost function.\n# Our 'cost' will be the likelihood out image is the target class according to the pre-trained model\ncost_function = model_output_layer[0, object_type_to_fake]\n\n# We'll ask Keras to calculate the gradient based on the input image and the currently predicted class\n# In this case, referring to \"model_input_layer\" will give us back image we are hacking.\ngradient_function = K.gradients(cost_function, model_input_layer)[0]\n\n# Create a Keras function that we can call to calculate the current cost and gradient\ngrab_cost_and_gradients_from_model = K.function([model_input_layer, K.learning_phase()], [cost_function, gradient_function])\n\ncost = 0.0\n\n# In a loop, keep adjusting the hacked image slightly so that it tricks the model more and more\n# until it gets to at least 80% confidence\nwhile cost < 0.90:\n    # Check how close the image is to our target class and grab the gradients we\n    # can use to push it one more step in that direction.\n    # Note: It's really important to pass in '0' for the Keras learning mode here!\n    # Keras layers behave differently in prediction vs. train modes!\n    cost, gradients = grab_cost_and_gradients_from_model([hacked_image, 0])\n\n    # Move the hacked image one step further towards fooling the model\n    hacked_image += gradients * learning_rate\n\n    # Ensure that the image doesn't ever change too much to either look funny or to become an invalid image\n    hacked_image = np.clip(hacked_image, max_change_below, max_change_above)\n    hacked_image = np.clip(hacked_image, -1.0, 1.0)\n\n    print(\"Model's predicted likelihood that the image is a hotdog: {:.8}%\".format(cost * 100))\n\n# De-scale the image's pixels from [-1, 1] back to the [0, 255] range\nimg = hacked_image[0]\nimg /= 2.\nimg += 0.5\nimg *= 255.\n\n# Save the hacked image!\nim = Image.fromarray(img.astype(np.uint8))\nim.save(\"hacked-image2.png\")\nim","metadata":{"scrolled":true,"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nIMAGE_DIMS = (224, 224)\nimg = Im.open(\"./hacked-image2.png\")\nimg = img.resize(IMAGE_DIMS)\nimg_bytes = img.tobytes()\n\nb64_img_bytes = base64.urlsafe_b64encode(img_bytes)\n\ntry:\n    r = requests.post(\"https://hotterdog.fly.dev/score\", data=json.dumps({\"input\": b64_img_bytes.decode()}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")\n\nimg","metadata":{"execution":{"iopub.status.busy":"2022-09-11T19:19:24.638707Z","iopub.execute_input":"2022-09-11T19:19:24.639760Z","iopub.status.idle":"2022-09-11T19:19:24.937173Z","shell.execute_reply.started":"2022-09-11T19:19:24.639722Z","shell.execute_reply":"2022-09-11T19:19:24.936077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"hotterdog\", \"RYMWPYOUJMGZOFKSOWAO7TE0HT3WPD2KC{R9H44OI0G7DC4WJE9D8TCI2PFU286U}TH1NZ0OW4HTVDGRDWP3GW16MTG3A7HZTDCHKMUOOOSOLXAHSTCG15C9HGYDN2F8\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}