{"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":"markdown","source":"# My CTF journey\n\nI've discovered this competition 11 days after the launch and I've found it quite interesting. What? ML is not a perfect world, you can fool ML models, you can exploit leaks, you can workaround ML defences ... let's try that! Oh but they is no points, no medals ... ok so my drivers will be: \"be lazy, get it fast, do not spent much time\"\n\nI've completed the 5 first challenges in a few hours: **Hotdog, Math1, Math2, Math3, Math4**. Nothing special here, just student homework. I still don't understand the real purpose of Hotdog one. \n\nThen I've played with **HotterDog**, I've read some papers, tried some implementions like [foolbox](https://github.com/bethgelab/foolbox) and [ART](https://github.com/Trusted-AI/adversarial-robustness-toolbox) but it was not easy to fool the model. I've introduced some perturbations in the image using different known whitebox attacks, I got many different predictions like starfish but no hotdog as it's more a blackbox challenge. I've noticed others challenges with the same purpose so I decided to try them. **THEFT** was 100 points with a [given solution](https://tcode2k16.github.io/blog/posts/picoctf-2018-writeup/general-skills/#solution-20) recommended to apply so it was straight. Surprisingly, same solution worked with **HotterDog** on first attempt after all my FoolBox/Pytorch attacks failed, could the model behind be Keras/MobileNet again? **Salt** challenge was including a defence but using this defence as attack (salt and pepper) it worked. \n\n**Honorstudent** solution was in the question, transform a F to be A. Simple CV2 plot and visual checks made it.\n\n**WIFI** required to analyze the provided chars embeddings, PCA gives two dimensions space that we wanted to [vizualize](https://towardsdatascience.com/visualizing-word-embedding-with-pca-and-t-sne-961a692509f5). Plot PCA, zoom-in and the flag appears. \n\n**SecretSloth** gave me hard days. My first idea was frequency transform, I was lazy so I've tried online tools to check but nothing in the spectrum. I continued with Stegano/Forensics online tools but nothing again... Then a hint came: \"Linear algebra and signal processing\" so I've played with GIMP filters to see if something could be obvious with color rotations (hue), contrast or gradients. I've noticed some weird shape/vertical lines in the bottom with colors rotation but it was scrambled. I've decided to Google search for the original image and I've found it on [imgur.com](https://www.reddit.com/r/Slothswithhats/comments/1cpj4v/he_killed_a_man_for_that_hat). I've compared difference from original to the provided one and I've found the same location already detected with GIMP. I've tried again so many operators as: Morphology, Edge detectors, Wavelets, Convolution, CLAHE ... still nothing ... I was lost. On Discord, most people that solved reported it was easy and this challenge was not worth 400 points, many said \"my first idea was good\" ... so I've tried it again but with some python code and not online tool and that's it! But why did I miss it before? Online tools scaled the image destroying the information and GIMP required an additional plugin for Fourier transform that I've never installed.\n\n**Bad to Good** was solved manually while playing with it. During investigation I've tried different combinations to make score increase and I got the flag quite early.\n\n**Inference**: This one really deserves his name \"inference\". I've generated some AZ-az-09 combinations and I got some results as \"D7Fc>m\", \"D1Fc>Y\", \"D1Pc>m\" with high confidence but no flag. Wait ... 5 items starting with \"D\", there is a \"F\" and \"c\", might be DEFCON in hacker language (leet)? Oh yes, that's it I've inferred the flag with a [leet translator](https://www.dcode.fr/ecriture-1337-leet-speak) :-)\n\n**Baseball** is a minimization challenge. I've started by random number in a grid until I get something good for Herry and not Sarah. Then I finetuned from my best Henry shoot until I got the flag. It was fast.\n\n**WAF** is a long story. First I've decoded the base64 example with different formats (hexadecimal, binary) with this [online](https://www.dcode.fr/code-base-64) tool. I thought the zero day was *b'\\x98\\x5C\\xDA\\x08*' and then I've tried to shift the binary sequence to bypass the WAF. It worked but no flag. I've spend a lot of hours to understand my zero day was wrong. The example given was the end of the zero day sequence, the \"==\" was a hint as it ends a base64 string that requires padding. I've decided to probe the WAF model by prepending new allowed base64 characters. Each time I've got a new WAF score I kept the characters and tried to decode the zero day, at some point I got *;}; /bin/bash* ... Hey! I know that */bin/bash*, of course I see the link with zero day now: Linux command. I've continued until WAF did not return me any new different score and the final string was: *{ :;}; /bin/bash*. It could be the full zero day, let's apply the attack already developed (convert back the string to binary, pad with zeros, shift right bit by bit, convert to base64 and submit). That's it! After first shift of 8 (i.e. one input char) bits.\n\n**Leakage**: I needed to understand that char-RNN model predicts the next char from a given sequence. Many password file format are LOGIN followed by PASSWORD, so just iterate on the model starting from the login, convert back the prediction to char and the flag appears.\n\n**Forensics**: Keras model.summary() displays model name. What's the purpose of this one?\n\n**Token**: Semi-brute force, shame on me but it was so easy like this. Semi-brute force because the problem is symmetric and it looked obvious the last duplicated lines cannot be candidates so only 1189653 combinations up to line 1542 matter. 3 x 12 hours Kaggle sessions were enough to find the 2 lines. \n\n**DeepFake**: I've participated to the DeepFake challenge from Kaggle. I should be able to solve this one. I remembered that JPEG quality augmentation helped my model training during this challenge. Maybe using JPEG quality as attack would fool the defence model? First attempt with iMovie on my MacOSx failed, quality not as bad as I expected. Second attempt with another online tool to kill MP4 quality, it worked! No need to write a single line of python.\n\n**Murderbots**: I've trained a Ridge model, kept probability > 0.8 to consider a 1. Cut on the first 10 items and replace others by zeros. It was enough to get the flag quickly.\n\n**Crop1**: Another minimization problem. The score function is given so it's quite easy to search for the lowest score (see * redness). I've started from a 224x224 image (3x75, 3x75 resized to 224 x 224) and I've got the flag in 5 minutes with a low enough score.\n\n**Crop2**: I've tried to explore LeVit embeddings, loss behavior ... all based on random image generation. There is only one solution which make it quite difficult to find out. Time it running out. This one was worth 1600 points.\n\n# Take away\n\n**WAF** was my prefered challenge. Followed (ordered) by HotterDog, Salt, Theft, Honorstudent, WIFI, Leakage, Inference, Murderbots, BaseBall, Bad2Good, Crop1, Forensics, Math1-4, DeepFake, Token, Crop2, Hotdog.\n\nThis notebook helps to reproduce my work. There is also a dataset that hosts some materials I've used/saved during the competition. There is a \"**My Solution**\" + **code** for each challenge below. Code generate a valid flag. For submission I've kept the flags I got on the first run.\n\n**Thought**: Well this competition a bit scary for some parts especially the computer vision attacks. Now I'm quite sure I will think twice before trusting in any autonomous vehicles. My newly car already makes a lot of mistakes by detecting signs and speed limits on the road (indeed basic detection is good but context is wrong). My car computer also sends steering wheel pulse to correct my trajectory (ground line detection) but last time my car almost pushed a motorcyclist who overtook me against a truck, line detection was good, but the current situation was not understood by the computer ... What if someone adds malicious patches to some signs? My car could become crazy quickly if ML CV is involved in decision, right? It could swap a \"Stop\" sign with \"Green light\" ...","metadata":{}},{"cell_type":"code","source":"# For WAF challenge\n!pip install bitarray","metadata":{"execution":{"iopub.status.busy":"2022-09-15T18:15:00.228973Z","iopub.execute_input":"2022-09-15T18:15:00.229424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# All import we need\nimport 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\")\nimport random\nfrom tqdm import tqdm\nimport itertools\nfrom bitarray import bitarray\nimport seaborn as sns\nimport cv2\nfrom PIL import ImageFont\nimport albumentations as A\nfrom sklearn.neighbors import NearestNeighbors\nfrom sklearn.manifold import TSNE\nimport seaborn as sns\nfrom sklearn.decomposition import PCA\nimport pickle\nimport string\n\ndir_name = \"/kaggle/input/ai-village-ctf\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-11T20:18:54.263164Z","iopub.execute_input":"2022-09-11T20:18:54.264276Z","iopub.status.idle":"2022-09-11T20:18:57.980856Z","shell.execute_reply.started":"2022-09-11T20:18:54.264234Z","shell.execute_reply":"2022-09-11T20:18:57.979756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# A helper function for tracking flags. You could do it yourself, but why?\n\ndef 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-11T20:18:57.982289Z","iopub.execute_input":"2022-09-11T20:18:57.983024Z","iopub.status.idle":"2022-09-11T20:18:57.991611Z","shell.execute_reply.started":"2022-09-11T20:18:57.982984Z","shell.execute_reply":"2022-09-11T20:18:57.990242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Image augmentations\ndef noisy(noise_typ, image):\n    if noise_typ == \"gauss\":\n        row,col,ch= image.shape\n        mean = 0\n        var = 0.1\n        sigma = var**0.5\n        gauss = np.random.normal(mean,sigma,(row,col,ch))\n        gauss = gauss.reshape(row,col,ch)\n        noisy = image + gauss\n        return noisy\n    elif noise_typ == \"s&p\":\n        row,col,ch = image.shape\n        s_vs_p = 0.5\n        amount = 0.004\n        out = np.copy(image)\n        # Salt mode\n        num_salt = np.ceil(amount * image.size * s_vs_p)\n        coords = [np.random.randint(0, i - 1, int(num_salt))\n              for i in image.shape]\n        out[coords] = 1\n\n        # Pepper mode\n        num_pepper = np.ceil(amount* image.size * (1. - s_vs_p))\n        coords = [np.random.randint(0, i - 1, int(num_pepper))\n              for i in image.shape]\n        out[coords] = 0\n        return out\n    elif noise_typ == \"poisson\":\n        vals = len(np.unique(image))\n        vals = 2 ** np.ceil(np.log2(vals))\n        noisy = np.random.poisson(image * vals) / float(vals)\n        return noisy\n    elif noise_typ ==\"speckle\":\n        row,col,ch = image.shape\n        gauss = np.random.randn(row,col,ch)\n        gauss = gauss.reshape(row,col,ch)        \n        noisy = image + image * gauss\n        return noisy","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:57.994867Z","iopub.execute_input":"2022-09-11T20:18:57.995217Z","iopub.status.idle":"2022-09-11T20:18:58.009001Z","shell.execute_reply.started":"2022-09-11T20:18:57.995184Z","shell.execute_reply":"2022-09-11T20:18:58.007917Z"},"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.\n\n### My solution\n\nI've mixup an hotdog image with Chester. It worked on the first attempt. Then I've tried to send an hotdog image directly (no Chester) and it worked too. So what was the purpose of this one? Nothing to fool here?","metadata":{}},{"cell_type":"code","source":"# Chester\nfilename=f'{dir_name}/hotdog/chester.png'\nimg = Im.open(filename)\nimg_size = img.size\nprint(img_size)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:58.011585Z","iopub.execute_input":"2022-09-11T20:18:58.012068Z","iopub.status.idle":"2022-09-11T20:18:58.066691Z","shell.execute_reply.started":"2022-09-11T20:18:58.012019Z","shell.execute_reply":"2022-09-11T20:18:58.065544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plain hotdog\nhotdog_filename = \"../input/aivmaterials/hot_dog_1600.jpg\"\nhotdog_img = Im.open(hotdog_filename)\nhotdog_img_size = hotdog_img.size\nprint(hotdog_img_size)\nhotdog_img = hotdog_img.resize((hotdog_img_size[0]//2, hotdog_img_size[1]//2))\nprint(hotdog_img.size)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:58.068173Z","iopub.execute_input":"2022-09-11T20:18:58.068516Z","iopub.status.idle":"2022-09-11T20:18:58.157473Z","shell.execute_reply.started":"2022-09-11T20:18:58.068485Z","shell.execute_reply":"2022-09-11T20:18:58.156374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare mixup\nnew_image1 = Im.new('RGBA',(img_size[0], img_size[1]), (250,250,250))\nnew_image1.paste(img,(0,0))\nnew_image2 = Im.new('RGBA',(img_size[0], img_size[1]), (250,250,250))\nnew_image2.paste(hotdog_img,((img_size[0]//2)-img_size[0]//4,(img_size[1]//2)-img_size[1]//4))\nd = plt.imshow(new_image1)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:58.159110Z","iopub.execute_input":"2022-09-11T20:18:58.159512Z","iopub.status.idle":"2022-09-11T20:18:58.577491Z","shell.execute_reply.started":"2022-09-11T20:18:58.159477Z","shell.execute_reply":"2022-09-11T20:18:58.576206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = plt.imshow(new_image2)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:58.579083Z","iopub.execute_input":"2022-09-11T20:18:58.579591Z","iopub.status.idle":"2022-09-11T20:18:58.845721Z","shell.execute_reply.started":"2022-09-11T20:18:58.579545Z","shell.execute_reply":"2022-09-11T20:18:58.844523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Mixup\nresult = Im.blend(new_image1, new_image2, alpha=0.5)\n# d = plt.imshow(result)\nIMAGE_DIMS = (224, 224)\nimg = result\nimg = img.resize(IMAGE_DIMS).convert('RGB')\nd = plt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:58.847163Z","iopub.execute_input":"2022-09-11T20:18:58.847566Z","iopub.status.idle":"2022-09-11T20:18:59.063132Z","shell.execute_reply.started":"2022-09-11T20:18:58.847529Z","shell.execute_reply":"2022-09-11T20:18:59.061887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Simple hotdog image works too??\n# img = hotdog_img.resize(IMAGE_DIMS).convert('RGB')\n# d = plt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:59.067157Z","iopub.execute_input":"2022-09-11T20:18:59.067738Z","iopub.status.idle":"2022-09-11T20:18:59.073440Z","shell.execute_reply.started":"2022-09-11T20:18:59.067695Z","shell.execute_reply":"2022-09-11T20:18:59.072120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nimg_bytes = 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.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:59.074768Z","iopub.execute_input":"2022-09-11T20:18:59.075204Z","iopub.status.idle":"2022-09-11T20:18:59.553117Z","shell.execute_reply.started":"2022-09-11T20:18:59.075171Z","shell.execute_reply":"2022-09-11T20:18:59.551888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"hotdog\", \"3DO0LO65OOH19Y}QVTZ6Z4HWF5IM4G2TPBDOAE7P7L616SYSX2SHHPZFD8ZHKGRS66751T2APLXEYZVJP4C0FOQLCJ0OD0PXPN8AT4XL4UD2G1IEJB9F86EMF9N{HLY0\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:59.554971Z","iopub.execute_input":"2022-09-11T20:18:59.555361Z","iopub.status.idle":"2022-09-11T20:18:59.583942Z","shell.execute_reply.started":"2022-09-11T20:18:59.555301Z","shell.execute_reply":"2022-09-11T20:18:59.582769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Math\n\nThis series of \"Math\" challenges is designed to introduce the concepts of dimensionality.\n\nData is often represented in a high dimensional space, but is actually several intrinsically low dimensional components that can be diagnosed. Intrinsic low-dimensionailty is incredibly important to machine learning because many ML algorithms rely on it. Medical EKG data is as single intrinsically 2 dimensional component, despite often being represented as 100 dimensions or more. The classic MNIST dataset is several components of 8-10 dimensions, depending on the digits class, despite being represented in 784 dimensions. The 4 math challenges are focused on this problem. **If you need a hint, ask Sven at the Art Booth.**","metadata":{}},{"cell_type":"markdown","source":"# Math Challenge 1 (id: math_1) -- 100 Points\n\nHow many clusters are in the clusters1.npy, clusters2.npy, and clusters3.npy? The key is the number of clusters in order, with no spaces. These files are available in the input directory under `math`.\n\n### My solution\n\nJust apply TSNE, display it and clusters numbers are obvious vizually.","metadata":{}},{"cell_type":"code","source":"clusters1 = np.load(\"../input/ai-village-ctf/math/clusters1.npy\")\nclusters2 = np.load(\"../input/ai-village-ctf/math/clusters2.npy\")\nclusters3 = np.load(\"../input/ai-village-ctf/math/clusters3.npy\")\nclusters1.shape, clusters3.shape, clusters3.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:59.585624Z","iopub.execute_input":"2022-09-11T20:18:59.586004Z","iopub.status.idle":"2022-09-11T20:18:59.609642Z","shell.execute_reply.started":"2022-09-11T20:18:59.585970Z","shell.execute_reply":"2022-09-11T20:18:59.608536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TSNE_N_ITER = 1000 # 1500\nTSNE_PERPLEXITY = 30 # 30 # 100\nseed = 2022\n# Scale and move the coordinates so they fit [0; 1] range\ndef scale_to_01_range(x):\n    # compute the distribution range\n    value_range = (np.max(x) - np.min(x))\n\n    # move the distribution so that it starts from zero\n    # by extracting the minimal value from all its values\n    starts_from_zero = x - np.min(x)\n\n    # make the distribution fit [0; 1] by dividing by its range\n    return starts_from_zero / value_range","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:59.611290Z","iopub.execute_input":"2022-09-11T20:18:59.611677Z","iopub.status.idle":"2022-09-11T20:18:59.618323Z","shell.execute_reply.started":"2022-09-11T20:18:59.611645Z","shell.execute_reply":"2022-09-11T20:18:59.617356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tsne_clusters1 = TSNE(n_components=2, perplexity=TSNE_PERPLEXITY, n_iter=TSNE_N_ITER, random_state=seed).fit_transform(clusters1)\ntx_tsne_clusters1 = tsne_clusters1[:, 0]\nty_tsne_clusters1 = tsne_clusters1[:, 1]\ntx_tsne_clusters1 = scale_to_01_range(tx_tsne_clusters1)\nty_tsne_clusters1 = scale_to_01_range(ty_tsne_clusters1)\nprint(tx_tsne_clusters1.shape, ty_tsne_clusters1.shape)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:18:59.619293Z","iopub.execute_input":"2022-09-11T20:18:59.619690Z","iopub.status.idle":"2022-09-11T20:19:00.258972Z","shell.execute_reply.started":"2022-09-11T20:18:59.619657Z","shell.execute_reply":"2022-09-11T20:19:00.257714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tsne_clusters2 = TSNE(n_components=2, perplexity=TSNE_PERPLEXITY, n_iter=TSNE_N_ITER, random_state=seed).fit_transform(clusters2)\ntx_tsne_clusters2 = tsne_clusters2[:, 0]\nty_tsne_clusters2 = tsne_clusters2[:, 1]\ntx_tsne_clusters2 = scale_to_01_range(tx_tsne_clusters2)\nty_tsne_clusters2 = scale_to_01_range(ty_tsne_clusters2)\nprint(tx_tsne_clusters2.shape, ty_tsne_clusters2.shape)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:00.260478Z","iopub.execute_input":"2022-09-11T20:19:00.261078Z","iopub.status.idle":"2022-09-11T20:19:00.533453Z","shell.execute_reply.started":"2022-09-11T20:19:00.261041Z","shell.execute_reply":"2022-09-11T20:19:00.532550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tsne_clusters3 = TSNE(n_components=2, perplexity=TSNE_PERPLEXITY, n_iter=TSNE_N_ITER, random_state=seed).fit_transform(clusters3)\ntx_tsne_clusters3 = tsne_clusters3[:, 0]\nty_tsne_clusters3 = tsne_clusters3[:, 1]\ntx_tsne_clusters3 = scale_to_01_range(tx_tsne_clusters3)\nty_tsne_clusters3 = scale_to_01_range(ty_tsne_clusters3)\nprint(tx_tsne_clusters3.shape, ty_tsne_clusters3.shape)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:00.534782Z","iopub.execute_input":"2022-09-11T20:19:00.535307Z","iopub.status.idle":"2022-09-11T20:19:00.730004Z","shell.execute_reply.started":"2022-09-11T20:19:00.535275Z","shell.execute_reply":"2022-09-11T20:19:00.728908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig,ax = plt.subplots(1,3,figsize=(36,8))\ns=5\n\nd = ax[0].scatter(tx_tsne_clusters1, ty_tsne_clusters1, s=s) \nd = ax[0].set_title(\"Clusters1\")\nd = ax[1].scatter(tx_tsne_clusters2, ty_tsne_clusters2, s=s) \nd = ax[1].set_title(\"Clusters2\")\nd = ax[2].scatter(tx_tsne_clusters3, ty_tsne_clusters3, s=s) \nd = ax[2].set_title(\"Clusters3\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:00.731972Z","iopub.execute_input":"2022-09-11T20:19:00.732763Z","iopub.status.idle":"2022-09-11T20:19:01.193476Z","shell.execute_reply.started":"2022-09-11T20:19:00.732716Z","shell.execute_reply":"2022-09-11T20:19:01.192256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_1\", \"submission\": \"523\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.195259Z","iopub.execute_input":"2022-09-11T20:19:01.196006Z","iopub.status.idle":"2022-09-11T20:19:01.300933Z","shell.execute_reply.started":"2022-09-11T20:19:01.195960Z","shell.execute_reply":"2022-09-11T20:19:01.299764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"math_1\", \"89LBPX6HHK41JL0YD84BPHIDYZH{RH8FG4F5MFK6FYDHSLYBQNHLPX3XYT0GBBP6}K7M6ZB5WS620R3DA1S1BGFG26Y7I7LAH0AM4WY6B7INJ976F9H7OYIPV7KLCGZJ\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.302218Z","iopub.execute_input":"2022-09-11T20:19:01.302802Z","iopub.status.idle":"2022-09-11T20:19:01.314716Z","shell.execute_reply.started":"2022-09-11T20:19:01.302766Z","shell.execute_reply":"2022-09-11T20:19:01.313248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Math Challenge 2 (id: math_2) -- 200 Points\n\nWhat's the dimensionality of the data in first_dim1.npy, first_dim2.npy, and first_dim3.npy? The key is the number of dimensions in order, with no spaces.  These files are available in the input directory under `math`.\n\n### My solution\n\nPlay with PCA to see how many dimensions capture the variance and you're done.","metadata":{}},{"cell_type":"code","source":"first_dim1 = np.load(\"../input/ai-village-ctf/math/first_dim1.npy\")\nfirst_dim2 = np.load(\"../input/ai-village-ctf/math/first_dim2.npy\")\nfirst_dim3 = np.load(\"../input/ai-village-ctf/math/first_dim3.npy\")\nfirst_dim1.shape, first_dim2.shape, first_dim3.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.316251Z","iopub.execute_input":"2022-09-11T20:19:01.316820Z","iopub.status.idle":"2022-09-11T20:19:01.354098Z","shell.execute_reply.started":"2022-09-11T20:19:01.316780Z","shell.execute_reply":"2022-09-11T20:19:01.352837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pca = PCA(n_components=4)\npca.fit(first_dim1)\nprint(list(pca.explained_variance_ratio_))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.355433Z","iopub.execute_input":"2022-09-11T20:19:01.356256Z","iopub.status.idle":"2022-09-11T20:19:01.369685Z","shell.execute_reply.started":"2022-09-11T20:19:01.356221Z","shell.execute_reply":"2022-09-11T20:19:01.368681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pca = PCA(n_components=6)\npca.fit(first_dim2)\nprint(list(pca.explained_variance_ratio_))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.371230Z","iopub.execute_input":"2022-09-11T20:19:01.371881Z","iopub.status.idle":"2022-09-11T20:19:01.384108Z","shell.execute_reply.started":"2022-09-11T20:19:01.371846Z","shell.execute_reply":"2022-09-11T20:19:01.382942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pca = PCA(n_components=6)\npca.fit(first_dim3)\nprint(list(pca.explained_variance_ratio_))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.385553Z","iopub.execute_input":"2022-09-11T20:19:01.386299Z","iopub.status.idle":"2022-09-11T20:19:01.395696Z","shell.execute_reply.started":"2022-09-11T20:19:01.386264Z","shell.execute_reply":"2022-09-11T20:19:01.394278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_2\", \"submission\": \"354\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.397216Z","iopub.execute_input":"2022-09-11T20:19:01.398166Z","iopub.status.idle":"2022-09-11T20:19:01.503284Z","shell.execute_reply.started":"2022-09-11T20:19:01.398118Z","shell.execute_reply":"2022-09-11T20:19:01.502048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"math_2\", \"FY8C73GXAB0ANRWISDHI0VXTBL}EDID7DXJWJKJ5IATBSP8SIW7OWHYSAVGMXS1JAJ8QR867NKFCI2VGTWZN4MEOQVVHFKM3AJ3T9SRMRPZX0F808{H87ZRPAZ56CGCK\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.504988Z","iopub.execute_input":"2022-09-11T20:19:01.505763Z","iopub.status.idle":"2022-09-11T20:19:01.516302Z","shell.execute_reply.started":"2022-09-11T20:19:01.505715Z","shell.execute_reply":"2022-09-11T20:19:01.515026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Math Challenge 3 (id: math_3) -- 300 Points\n\nWhat's the dimensionality of the data in second_dim1.npy, second_dim2.npy, and second_dim3.npy? The key is the number of the dimensionality in order, with no spaces.  These files are available in the input directory under `math`.\n\n### My solution\n\nSame as Math2, play with PCA.","metadata":{}},{"cell_type":"code","source":"second_dim1 = np.load(\"../input/ai-village-ctf/math/second_dim1.npy\")\nsecond_dim2 = np.load(\"../input/ai-village-ctf/math/second_dim2.npy\")\nsecond_dim3 = np.load(\"../input/ai-village-ctf/math/second_dim3.npy\")\nsecond_dim1.shape, second_dim2.shape, second_dim3.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.517729Z","iopub.execute_input":"2022-09-11T20:19:01.518082Z","iopub.status.idle":"2022-09-11T20:19:01.557129Z","shell.execute_reply.started":"2022-09-11T20:19:01.518050Z","shell.execute_reply":"2022-09-11T20:19:01.556070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pca = PCA(n_components=6)\npca.fit(second_dim1)\nprint(list(pca.explained_variance_ratio_))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.565895Z","iopub.execute_input":"2022-09-11T20:19:01.566283Z","iopub.status.idle":"2022-09-11T20:19:01.573153Z","shell.execute_reply.started":"2022-09-11T20:19:01.566250Z","shell.execute_reply":"2022-09-11T20:19:01.571897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pca = PCA(n_components=8)\npca.fit(second_dim2)\nprint(list(pca.explained_variance_ratio_))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.574830Z","iopub.execute_input":"2022-09-11T20:19:01.575223Z","iopub.status.idle":"2022-09-11T20:19:01.585799Z","shell.execute_reply.started":"2022-09-11T20:19:01.575191Z","shell.execute_reply":"2022-09-11T20:19:01.584732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pca = PCA(n_components=8)\npca.fit(second_dim3)\nprint(list(pca.explained_variance_ratio_))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.586825Z","iopub.execute_input":"2022-09-11T20:19:01.587195Z","iopub.status.idle":"2022-09-11T20:19:01.598944Z","shell.execute_reply.started":"2022-09-11T20:19:01.587162Z","shell.execute_reply":"2022-09-11T20:19:01.598021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\n\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_3\", \"submission\": \"474\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.600376Z","iopub.execute_input":"2022-09-11T20:19:01.600740Z","iopub.status.idle":"2022-09-11T20:19:01.706459Z","shell.execute_reply.started":"2022-09-11T20:19:01.600707Z","shell.execute_reply":"2022-09-11T20:19:01.705140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"math_3\", \"MCW0L6F03HFUS5J5UFB3ZVSOD}{DTPFRVSMU7ORKEBJVJ3L8QEL2U63O3128OJQ4U7RJTFCRN10_SPO6KNMDAMHI4AW8CJMA03N3JT9MWIP5SGWK5PDXTTVS2QTM2C5G\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.707883Z","iopub.execute_input":"2022-09-11T20:19:01.708239Z","iopub.status.idle":"2022-09-11T20:19:01.719917Z","shell.execute_reply.started":"2022-09-11T20:19:01.708205Z","shell.execute_reply":"2022-09-11T20:19:01.718187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Math Challenge 4 (id: math_4) -- 400 Points\n\nWhat's the dimensionality of the clusters in clusters1.npy? The key is the dimensions ordered by cluster size (smallest to largest), with no spaces.  These files are available in the input directory under `math`.\n\n### My solution\n\nExtract clusters with KMeans and then apply PCA again on items from this cluster. Pay attention to order by cluster size to get the flag.","metadata":{}},{"cell_type":"code","source":"clusters1.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.722574Z","iopub.execute_input":"2022-09-11T20:19:01.723079Z","iopub.status.idle":"2022-09-11T20:19:01.731358Z","shell.execute_reply.started":"2022-09-11T20:19:01.723025Z","shell.execute_reply":"2022-09-11T20:19:01.730170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.cluster import KMeans\nkmeans = KMeans(n_clusters=5, random_state=0).fit(clusters1)\ncluster_ids = kmeans.labels_\ncluster_ids","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.732785Z","iopub.execute_input":"2022-09-11T20:19:01.733612Z","iopub.status.idle":"2022-09-11T20:19:01.817771Z","shell.execute_reply.started":"2022-09-11T20:19:01.733574Z","shell.execute_reply":"2022-09-11T20:19:01.816576Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"chk = 0\nfor cid in [0,1,2,3,4]:\n    cluster = clusters1[cluster_ids == cid]\n    c_shape = cluster.shape\n    print(\"Cluster\", cid, \"=>\", c_shape)\n    chk = chk + c_shape[0]\n    \n    pca = PCA(n_components=8)\n    pca.fit(cluster)\n    print(\"Cluster\", cid, \"=>\", list(pca.explained_variance_ratio_))\n\nprint(chk)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.819389Z","iopub.execute_input":"2022-09-11T20:19:01.820054Z","iopub.status.idle":"2022-09-11T20:19:01.831445Z","shell.execute_reply.started":"2022-09-11T20:19:01.820006Z","shell.execute_reply":"2022-09-11T20:19:01.830413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_4\", \"submission\": \"54312\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.832720Z","iopub.execute_input":"2022-09-11T20:19:01.833591Z","iopub.status.idle":"2022-09-11T20:19:01.933395Z","shell.execute_reply.started":"2022-09-11T20:19:01.833553Z","shell.execute_reply":"2022-09-11T20:19:01.932544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"math_4\", \"043FN3GZ4JZOPEOKAHGJRFGIP6RTLTWEPOE}NWQ4PRRZEJ9RPFETJUI6GB7RRLCS98IH0XRST0DMOENBNQ14ZKCSDIRSV0BG7UZ{MCLJD5SYQHMMDW4R8PNDAWRC3CNA\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.934519Z","iopub.execute_input":"2022-09-11T20:19:01.935498Z","iopub.status.idle":"2022-09-11T20:19:01.945994Z","shell.execute_reply.started":"2022-09-11T20:19:01.935459Z","shell.execute_reply":"2022-09-11T20:19:01.944757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# WIFI (id: wifi) -- 200 Points\n\n### Scenario\n\nYou really need to check your email, unfortunately you don't know the password.  Fortunately, someone wrote it down.  Unfortunately, it's written down on a low-dimensional manifold embedded in a very high-dimensional space.  Check out the `wifi/Embedded characters.npz` file -- a list of tokens is given in the `tokens` key with their corresponding embeddings in the same order under the `embeddings` key -- and recover the password.\n\n### Objective\n\nThe password is your flag, like all others, it has the format `FLAG{something}`\n\n### My solution\n\nPCA on embeddings reported two dimensions capturing variance. Plot the 2D PCA chars embeddings with interactive support to zoom-in. The flag is in the center. This [code](https://towardsdatascience.com/visualizing-word-embedding-with-pca-and-t-sne-961a692509f5) helped me. ","metadata":{}},{"cell_type":"code","source":"emb = np.load(\"../input/ai-village-ctf/wifi/Embedded_characters.npz\")\ntokens = emb[\"tokens\"].tolist()\nlist(emb.keys()), tokens, len(tokens), emb[\"embeddings\"].shape","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.947437Z","iopub.execute_input":"2022-09-11T20:19:01.948520Z","iopub.status.idle":"2022-09-11T20:19:01.976561Z","shell.execute_reply.started":"2022-09-11T20:19:01.948480Z","shell.execute_reply":"2022-09-11T20:19:01.975273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = plt.imshow(emb[\"embeddings\"])","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:01.978372Z","iopub.execute_input":"2022-09-11T20:19:01.979206Z","iopub.status.idle":"2022-09-11T20:19:02.202824Z","shell.execute_reply.started":"2022-09-11T20:19:01.979159Z","shell.execute_reply":"2022-09-11T20:19:02.201720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Look at PCA\npca = PCA(n_components=8)\npca.fit(emb[\"embeddings\"])\nprint(list(pca.explained_variance_ratio_))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:02.204439Z","iopub.execute_input":"2022-09-11T20:19:02.204782Z","iopub.status.idle":"2022-09-11T20:19:02.249836Z","shell.execute_reply.started":"2022-09-11T20:19:02.204750Z","shell.execute_reply":"2022-09-11T20:19:02.248542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 2 dimensions is enough\npca = PCA(n_components=2)\nret = pca.fit_transform(emb[\"embeddings\"])\nret.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:02.252360Z","iopub.execute_input":"2022-09-11T20:19:02.254195Z","iopub.status.idle":"2022-09-11T20:19:02.289291Z","shell.execute_reply.started":"2022-09-11T20:19:02.254137Z","shell.execute_reply":"2022-09-11T20:19:02.287978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"words = [ word for word in tokens ]","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:02.292111Z","iopub.execute_input":"2022-09-11T20:19:02.300472Z","iopub.status.idle":"2022-09-11T20:19:02.314387Z","shell.execute_reply.started":"2022-09-11T20:19:02.300403Z","shell.execute_reply":"2022-09-11T20:19:02.311864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tsne_emb = TSNE(n_components=2, perplexity=TSNE_PERPLEXITY, n_iter=TSNE_N_ITER, random_state=seed).fit_transform(emb[\"embeddings\"])\ntx_tsne_emb = tsne_emb[:, 0]\nty_tsne_emb = tsne_emb[:, 1]\ntx_tsne_emb = scale_to_01_range(tx_tsne_emb)\nty_tsne_emb = scale_to_01_range(ty_tsne_emb)\nprint(tx_tsne_emb.shape, ty_tsne_emb.shape)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:02.318506Z","iopub.execute_input":"2022-09-11T20:19:02.322056Z","iopub.status.idle":"2022-09-11T20:19:03.107033Z","shell.execute_reply.started":"2022-09-11T20:19:02.321993Z","shell.execute_reply":"2022-09-11T20:19:03.106081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig,ax = plt.subplots(1,2,figsize=(14,6))\ns=5\n\nd = ax[0].scatter(ret[:,0], ret[:,1], s=s) \nd = ax[0].set_title(\"PCA\")\nd = ax[1].scatter(tx_tsne_emb, ty_tsne_emb, s=s) \nd = ax[1].set_title(\"TSNE\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:03.108656Z","iopub.execute_input":"2022-09-11T20:19:03.109297Z","iopub.status.idle":"2022-09-11T20:19:03.391704Z","shell.execute_reply.started":"2022-09-11T20:19:03.109262Z","shell.execute_reply":"2022-09-11T20:19:03.390601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Go interactive to zoom-in\nimport plotly.graph_objs as go\nimport plotly\nimport numpy as np\nimport plotly.graph_objs as go\nfrom sklearn.decomposition import PCA\n\ndef display_pca_scatterplot_2D(user_input=None, label=None, color_map=None, topn=5):\n\n    words = [ word for word in tokens ]\n    \n    word_vectors = emb[\"embeddings\"]\n    \n    two_dim = PCA(random_state=seed).fit_transform(word_vectors)[:,:2]\n\n    data = []\n    count = 0\n\n    trace_input = go.Scatter(\n                    x = two_dim[count:,0], \n                    y = two_dim[count:,1],  \n                    text = words[count:],\n                    name = '',\n                    textposition = \"top center\",\n                    textfont_size = 16,\n                    mode = 'markers+text',\n                    marker = {\n                        'size': 10,\n                        'opacity': 1,\n                        'color': 'black'\n                    }\n                )\n            \n    data.append(trace_input)\n    \n    # Configure the layout\n    layout = go.Layout(\n        margin = {'l': 0, 'r': 0, 'b': 0, 't': 0},\n        showlegend=True,\n        legend=dict(\n        x=1,\n        y=0.5,          \n        font=dict(\n            family=\"Courier New\",\n            size=20,\n            color=\"black\"\n        )),\n        \n        font = dict(\n            family = \" Courier New \",\n            size = 12),\n        autosize = False,\n        width = 600,\n        height = 500\n    )\n\n\n    plot_figure = go.Figure(data = data, layout = layout)\n    plot_figure.update_xaxes(range=[-0.1, -0.04])\n    plot_figure.update_yaxes(range=[-0.25, 0.0])\n    \n    plot_figure.show()\n    \ndisplay_pca_scatterplot_2D()","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:03.393218Z","iopub.execute_input":"2022-09-11T20:19:03.393733Z","iopub.status.idle":"2022-09-11T20:19:03.667458Z","shell.execute_reply.started":"2022-09-11T20:19:03.393700Z","shell.execute_reply":"2022-09-11T20:19:03.666395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"wifi\", \"submission\": \"FLAG{TURNED}\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:03.668855Z","iopub.execute_input":"2022-09-11T20:19:03.669171Z","iopub.status.idle":"2022-09-11T20:19:03.768631Z","shell.execute_reply.started":"2022-09-11T20:19:03.669142Z","shell.execute_reply":"2022-09-11T20:19:03.767063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"wifi\", \"LPYC9SHZN62SEMPWB6I952TKHWR5PTC01OV99F5LZIDLRDITRBYI1GH2FAB0G8LZ6XOGR2MZ28J6OGY}M8TWVQ9AB6QHR3IOVBRZRLLSB5U{AUW7EG3ZB4ESSKSNUWC6\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:03.769941Z","iopub.execute_input":"2022-09-11T20:19:03.770295Z","iopub.status.idle":"2022-09-11T20:19:03.781981Z","shell.execute_reply.started":"2022-09-11T20:19:03.770263Z","shell.execute_reply":"2022-09-11T20:19:03.781029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Honorstudent (id: honorstudent) -- 300 Points\n\n### Scenario\n\nLook at your report card! That's an F. You won't be able to go to homecoming with that grade. Can you use some carefully placed whiteout to fool your parents into thinking it's an A?\n\n### Objective\n\nModify and submit your tampered `f.png`. Be careful to not overdo it!\n\n### My solution\n\nMake up the F to A as a child would do. After a few attempts, overlay another F as mirror on the provided image worked without much challenge.\n","metadata":{}},{"cell_type":"code","source":"fimg = Im.open(f'{dir_name}/honorstudent/f.png')\nd = plt.imshow(fimg)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:03.783252Z","iopub.execute_input":"2022-09-11T20:19:03.783602Z","iopub.status.idle":"2022-09-11T20:19:03.973377Z","shell.execute_reply.started":"2022-09-11T20:19:03.783572Z","shell.execute_reply":"2022-09-11T20:19:03.971934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"font                   = cv2.FONT_HERSHEY_PLAIN\nbottomLeftCornerOfText = (0,28)\nfontScale              = 2\nfontColor              = (255,255,255)\nthickness              = 2\nlineType               = 2\n\ndef generate(c):\n    img = np.zeros((28,28,3), np.uint8)\n    cv2.putText(img,c, bottomLeftCornerOfText, font, fontScale, fontColor, thickness, lineType)\n    return img[:,:,0]\n\nd = plt.imshow(np.fliplr(generate(\"f\")))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:03.974995Z","iopub.execute_input":"2022-09-11T20:19:03.975513Z","iopub.status.idle":"2022-09-11T20:19:04.163108Z","shell.execute_reply.started":"2022-09-11T20:19:03.975474Z","shell.execute_reply":"2022-09-11T20:19:04.161897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res = np.clip(fimg + np.fliplr(generate(\"f\")), 0, 255)\nd = plt.imshow(res)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:04.164537Z","iopub.execute_input":"2022-09-11T20:19:04.164892Z","iopub.status.idle":"2022-09-11T20:19:04.342009Z","shell.execute_reply.started":"2022-09-11T20:19:04.164860Z","shell.execute_reply":"2022-09-11T20:19:04.340768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res_ = np.zeros((28,28,3))\nres_[:,:,0] = res\nres_[:,:,1] = res\nres_[:,:,2] = res","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:04.345634Z","iopub.execute_input":"2022-09-11T20:19:04.346270Z","iopub.status.idle":"2022-09-11T20:19:04.352844Z","shell.execute_reply.started":"2022-09-11T20:19:04.346222Z","shell.execute_reply":"2022-09-11T20:19:04.351561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cv2.imwrite('./a.png', res)\nfimg = Im.open('./a.png').convert('L')\nfimg.save(\"./a.png\")\nd = plt.imshow(Im.open('./a.png'))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:04.354248Z","iopub.execute_input":"2022-09-11T20:19:04.354981Z","iopub.status.idle":"2022-09-11T20:19:04.543494Z","shell.execute_reply.started":"2022-09-11T20:19:04.354925Z","shell.execute_reply":"2022-09-11T20:19:04.542287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nwith open(\"./a.png\", \"rb\") as f:\n    try:\n        r = requests.post(\"https://honorstudent.fly.dev/score\", files={\"data_file\": f})\n        print(r.text)\n    except requests.exceptions.ConnectionError:\n        print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:04.544970Z","iopub.execute_input":"2022-09-11T20:19:04.545694Z","iopub.status.idle":"2022-09-11T20:19:04.662505Z","shell.execute_reply.started":"2022-09-11T20:19:04.545649Z","shell.execute_reply":"2022-09-11T20:19:04.661204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"honorstudent\", \"C4SIG3R5C9O72OO67FFQ04ZCXPW3ZGZO7YAOZLVBXS6T}YSF3K9O6WECAEOPOHACTFVLOMRDLAZEHTSFENNPNUO5X2{B7J2ZHNU7CMADF1KZT3J4JKGCTA2CAR48P0LZ\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:04.664965Z","iopub.execute_input":"2022-09-11T20:19:04.665435Z","iopub.status.idle":"2022-09-11T20:19:04.678721Z","shell.execute_reply.started":"2022-09-11T20:19:04.665380Z","shell.execute_reply":"2022-09-11T20:19:04.677576Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Secret Sloth (id: sloth) -- 400 Points\n\n### Scenario\n\nThe sloth in `secret.sloth/secret-sloth.png` has a very cool hat... and a secret message for you. The message is your flag.\n\n### Objective \n\nThe flag is in the image somewhere; as always, look for `FLAG{something}`\n\n### My solution\n\nFind out the original image with Google image, compare it to the one provided to locate changes. Frequency transform (module) on changes to reveal the message. But finally original image was not needed as frequency transform on full image also reveal the message.","metadata":{}},{"cell_type":"code","source":"# Difference between original and modified picture\nfig, ax = plt.subplots(1,1,figsize=(20,12))\nsecret = np.asarray(Im.open('../input/ai-village-ctf/secret.sloth/secret-sloth.png').convert('RGB'))\nkey = np.asarray(Im.open('../input/aivmaterials/imgur.png'))\nx = cv2.bitwise_xor(key, secret)\nd = ax.imshow((x).astype(np.float32))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:04.680375Z","iopub.execute_input":"2022-09-11T20:19:04.681862Z","iopub.status.idle":"2022-09-11T20:19:05.156144Z","shell.execute_reply.started":"2022-09-11T20:19:04.681811Z","shell.execute_reply":"2022-09-11T20:19:05.154857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1,1,figsize=(20,12))\nd = ax.imshow(x[270:290,0:500,:].astype(np.float32))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:05.157603Z","iopub.execute_input":"2022-09-11T20:19:05.159656Z","iopub.status.idle":"2022-09-11T20:19:05.336469Z","shell.execute_reply.started":"2022-09-11T20:19:05.159617Z","shell.execute_reply":"2022-09-11T20:19:05.335210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = (secret.astype(np.float64))/255.","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:05.337869Z","iopub.execute_input":"2022-09-11T20:19:05.338876Z","iopub.status.idle":"2022-09-11T20:19:05.345474Z","shell.execute_reply.started":"2022-09-11T20:19:05.338825Z","shell.execute_reply":"2022-09-11T20:19:05.344110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1,1,figsize=(20,12))\nd = ax.imshow(img[270:290,0:500,:])","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:05.347444Z","iopub.execute_input":"2022-09-11T20:19:05.347916Z","iopub.status.idle":"2022-09-11T20:19:05.546632Z","shell.execute_reply.started":"2022-09-11T20:19:05.347871Z","shell.execute_reply":"2022-09-11T20:19:05.545420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from scipy import fftpack\nim_fft = fftpack.fft2(img[270:290,0:500,:])\nfig, ax = plt.subplots(1,1,figsize=(20,12))\nd = ax.imshow(np.abs(im_fft))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:05.548382Z","iopub.execute_input":"2022-09-11T20:19:05.549375Z","iopub.status.idle":"2022-09-11T20:19:05.766554Z","shell.execute_reply.started":"2022-09-11T20:19:05.549308Z","shell.execute_reply":"2022-09-11T20:19:05.765359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"sloth\", \"submission\": \"FLAG{SPECTRAL}\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:05.768025Z","iopub.execute_input":"2022-09-11T20:19:05.768730Z","iopub.status.idle":"2022-09-11T20:19:05.870027Z","shell.execute_reply.started":"2022-09-11T20:19:05.768683Z","shell.execute_reply":"2022-09-11T20:19:05.868736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"sloth\", \"GO6HMT07CJ2C6FXHFKUP2K4CDJ2VI0ZXMJ4C{ESUDP9IGCU96KYTLFVH7EJCZG8MUHSUT162}ZZ8IML2ZFY3O4A0N8ALI8AIQ0YS1WP6AEFBK9FT7ZCRVVREF9TIMCL6\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:05.873897Z","iopub.execute_input":"2022-09-11T20:19:05.874292Z","iopub.status.idle":"2022-09-11T20:19:05.886463Z","shell.execute_reply.started":"2022-09-11T20:19:05.874257Z","shell.execute_reply":"2022-09-11T20:19:05.885194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Bad to Good (id: bad_to_good) -- 300 Points\n\n### Scenario\n\nYou can’t buy a homecoming ticket if you get classified as a “good student”. Can you help Henry poison the classifier? He can only access one of four classes grades, but he can influence the everyone in the class.\n\n### Objective\n\nModify and submit your tampered `csv`. Try and get Henry classified as a good student. Be careful to not overdo it!\n\n### My solution\n\nTryout some manual combinations to increase score is enough, no need to code anything. I got flag while investigating manually.","metadata":{"execution":{"iopub.status.busy":"2022-07-06T18:06:36.224662Z","iopub.execute_input":"2022-07-06T18:06:36.22512Z","iopub.status.idle":"2022-07-06T18:06:36.324329Z","shell.execute_reply.started":"2022-07-06T18:06:36.225025Z","shell.execute_reply":"2022-07-06T18:06:36.322661Z"}}},{"cell_type":"code","source":"tmp_pd = pd.read_csv(f\"{dir_name}/bad2good/math.csv\").set_index(\"StudentID\")\ntmp_pd","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:05.888087Z","iopub.execute_input":"2022-09-11T20:19:05.888475Z","iopub.status.idle":"2022-09-11T20:19:06.112452Z","shell.execute_reply.started":"2022-09-11T20:19:05.888441Z","shell.execute_reply":"2022-09-11T20:19:06.110982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tmp_pd[\"Grade\"] = np.clip(tmp_pd[\"Grade\"] - 45, 5, 100)\ntmp_pd[\"Absences\"] = np.clip(tmp_pd[\"Absences\"] + 2, 0,10)\ntmp_pd[\"Demerits\"] = np.clip(tmp_pd[\"Demerits\"] + 3, 0,10)\ntmp_pd[\"Score\"] = np.clip(tmp_pd[\"Score\"] + 20, 0, 90)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:06.114109Z","iopub.execute_input":"2022-09-11T20:19:06.114621Z","iopub.status.idle":"2022-09-11T20:19:06.134102Z","shell.execute_reply.started":"2022-09-11T20:19:06.114573Z","shell.execute_reply":"2022-09-11T20:19:06.133076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tmp_pd.loc[1337, \"Grade\"] = 95\ntmp_pd.loc[1337, \"Absences\"] = 0\ntmp_pd.loc[1337, \"Demerits\"] = 0\ntmp_pd.loc[1337, \"Score\"] = 10\ntmp_pd","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:06.135688Z","iopub.execute_input":"2022-09-11T20:19:06.136369Z","iopub.status.idle":"2022-09-11T20:19:06.162318Z","shell.execute_reply.started":"2022-09-11T20:19:06.136311Z","shell.execute_reply":"2022-09-11T20:19:06.160806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntmp_pd.to_csv(\"./b2gm.csv\")\n\nwith open(\"./b2gm.csv\", \"r\") as f:\n    try:\n        r = requests.post(\"https://bad2good.fly.dev/score\", files={\"data_file\": f})\n        print(r.text)\n    except requests.exceptions.ConnectionError:\n        print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:06.164156Z","iopub.execute_input":"2022-09-11T20:19:06.165478Z","iopub.status.idle":"2022-09-11T20:19:06.311244Z","shell.execute_reply.started":"2022-09-11T20:19:06.165426Z","shell.execute_reply":"2022-09-11T20:19:06.309964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"bad_to_good\", \"wt3pFFA8hV5RBP3Dn3YVIZ8Y5G93RBFSW3KXOPR5P_CVMTUVT1DJ3GHtF1TOQJM_AAX7Z3OeADFYZMa3YT85}bLLUFXAD78GoPXJD4S8628FG2_G4EE61FdMS{4MGDK4\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:06.313320Z","iopub.execute_input":"2022-09-11T20:19:06.313718Z","iopub.status.idle":"2022-09-11T20:19:06.323579Z","shell.execute_reply.started":"2022-09-11T20:19:06.313683Z","shell.execute_reply":"2022-09-11T20:19:06.322138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference (id: inference) -- 400 Points\n\n### Scenario\n\nModel model on the wall, who is the fairest of them all?\n\n?gnidaer llits uoy era yhW .uoy htiw skcans thguorb ev'dluohs uoY .skcans rof pots t'noD .won oG .tsaf oG .niW .galf eht teG .ledom eht esreveR\n\n### Objective\n\nRetrieve the images that spell the flag. Wrap any text in `FLAG{}`\n\n**If you need a hint, there's a guy named `moo` somewhere.**\n\n### My solution\nTryout combinations with high score, play with font, fontsize, fontstyle. Higher results give a me hint to guess the DEFCON as leet language.","metadata":{}},{"cell_type":"code","source":"a = \"?gnidaer llits uoy era yhW .uoy htiw skcans thguorb ev'dluohs uoY .skcans rof pots t'noD .won oG .tsaf oG .niW .galf eht teG .ledom eht esreveR\"","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:06.325100Z","iopub.execute_input":"2022-09-11T20:19:06.325681Z","iopub.status.idle":"2022-09-11T20:19:06.330797Z","shell.execute_reply.started":"2022-09-11T20:19:06.325647Z","shell.execute_reply":"2022-09-11T20:19:06.329493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a[::-1]","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:06.332225Z","iopub.execute_input":"2022-09-11T20:19:06.332786Z","iopub.status.idle":"2022-09-11T20:19:06.342045Z","shell.execute_reply.started":"2022-09-11T20:19:06.332751Z","shell.execute_reply":"2022-09-11T20:19:06.340918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"font                   = cv2.FONT_HERSHEY_SIMPLEX # cv2.FONT_HERSHEY_COMPLEX # ImageFont.truetype(\"../input/arial-font/arial.ttf\", 80) #cv2.FONT_HERSHEY_PLAIN#  cv2.FONT_HERSHEY_SIMPLEX\nbottomLeftCornerOfText = (6,26)\nfontScale              = 1 # 2 # 1\nfontColor              = (255,255,255)\nthickness              = 3\nlineType               = 2\n\ndef generate(c):\n    img = np.zeros((32,32,3), np.uint8)\n    cv2.putText(img,c, bottomLeftCornerOfText, font, fontScale, fontColor, thickness, lineType)\n    return img[:,:,0]/255.0\n\nd = plt.imshow(generate(\"D\"))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:06.343297Z","iopub.execute_input":"2022-09-11T20:19:06.343964Z","iopub.status.idle":"2022-09-11T20:19:06.526994Z","shell.execute_reply.started":"2022-09-11T20:19:06.343922Z","shell.execute_reply":"2022-09-11T20:19:06.525579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# To play the challenge\nresults, chs = [], []\nx = np.random.uniform(0, 1, (1, 32, 32, 1))\nfor c in range(48, 123, 1):\n    ch = chr(c)\n    x = np.zeros((1, 32, 32, 1))\n    x[0,:,:,0] = generate(ch)\n\n    try:\n        response = requests.post(\"https://inference.fly.dev/score\", data = json.dumps({\"input\": x.tolist()}))\n        r = json.loads(response.text)['outputs'][0]\n        chs.append(ch)\n        results.append(r)\n    except requests.exceptions.ConnectionError:\n        print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:06.528467Z","iopub.execute_input":"2022-09-11T20:19:06.528797Z","iopub.status.idle":"2022-09-11T20:19:23.295868Z","shell.execute_reply.started":"2022-09-11T20:19:06.528768Z","shell.execute_reply":"2022-09-11T20:19:23.294700Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res = pd.DataFrame(results, columns=[\"P1\", \"P2\", \"P3\", \"P4\", \"P5\", \"P6\"]) \nres[\"ch\"] = chs","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.297326Z","iopub.execute_input":"2022-09-11T20:19:23.298040Z","iopub.status.idle":"2022-09-11T20:19:23.305821Z","shell.execute_reply.started":"2022-09-11T20:19:23.298003Z","shell.execute_reply":"2022-09-11T20:19:23.304421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"code = []\nfor i in range(1, 7):\n    display(res[res[\"P%d\"%i] == res[\"P%d\"%i].max()])\n    code.append(res[res[\"P%d\"%i] == res[\"P%d\"%i].max()]['ch'].values[0]) \nflag = \"FLAG{%s}\" % (\"\".join(code))\nflag","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.307029Z","iopub.execute_input":"2022-09-11T20:19:23.308097Z","iopub.status.idle":"2022-09-11T20:19:23.386306Z","shell.execute_reply.started":"2022-09-11T20:19:23.308060Z","shell.execute_reply":"2022-09-11T20:19:23.385427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Some with high confidence depending on font/size/style\n# FLAG{D7[d>y}\n# FLAG{D1Pc>m}\n# FLAG{D1Fc>Y}\n# FLAG{D7Fc>m}","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.387526Z","iopub.execute_input":"2022-09-11T20:19:23.388810Z","iopub.status.idle":"2022-09-11T20:19:23.393355Z","shell.execute_reply.started":"2022-09-11T20:19:23.388768Z","shell.execute_reply":"2022-09-11T20:19:23.392280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# To try and get the flag\n\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"inference\", \"submission\": \"FLAG{D3FC0N}\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.394961Z","iopub.execute_input":"2022-09-11T20:19:23.395692Z","iopub.status.idle":"2022-09-11T20:19:23.503957Z","shell.execute_reply.started":"2022-09-11T20:19:23.395647Z","shell.execute_reply":"2022-09-11T20:19:23.502713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"inference\", \"PM95MQXE3VPVKT3A10YNIL5JCLGNN9XP34X6PYQA6JA5I6URYMVVYH2IULNG0GPZX1AMDGSFI3QJPROGXZ431F024YUBY}O5XHHA7RK3XYC0{59FF17BASLZ8YXUW7QI\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.505618Z","iopub.execute_input":"2022-09-11T20:19:23.506398Z","iopub.status.idle":"2022-09-11T20:19:23.517123Z","shell.execute_reply.started":"2022-09-11T20:19:23.506326Z","shell.execute_reply":"2022-09-11T20:19:23.515830Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Baseball  (id: baseball) -- 300 Points\n\n### Scenario\n\nHenry has to miss baseball tryouts to get ready for his date. Can you cover for him? Henry is a pitcher and the team uses software to analyze pitch patterns to classify pitchers. \n\n### Objective\n\nThrow 15 pitches at x,y (each bounded on [0,29]). Check out `test_pitch.json` to see the expected format. Can you throw 15 pitches to get classified as Henry?\n\n### My solution\nIt's a minimization problem, by trying random grid search I've discovered Sarah and Henry. I've saved the best grid for Henry and then I've finetuned the search from this point by pitches item to increase score until I got the flag.","metadata":{}},{"cell_type":"code","source":"def seed_everything(s):\n    random.seed(s)\n    os.environ['PYTHONHASHSEED'] = str(s)\n    np.random.seed(s)\n\nseed_everything(42)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.520679Z","iopub.execute_input":"2022-09-11T20:19:23.521582Z","iopub.status.idle":"2022-09-11T20:19:23.528378Z","shell.execute_reply.started":"2022-09-11T20:19:23.521528Z","shell.execute_reply":"2022-09-11T20:19:23.527357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Grid search for best henry\n# best_score = 0.0\n# # with open(\"./test_pitch.json\", \"r\") as f:\n# #     test = json.load(f)\n# for t in range(512):\n    \n#     rd = np.random.randint(0,29, size=(2,15)).T\n#     for i, (x, y) in enumerate(rd):\n#         test['pitches'][i][\"x\"] = int(x)\n#         test['pitches'][i][\"y\"] = int(y)\n\n#     try:\n#         r = requests.post(\"https://bball.fly.dev/score\", json=test)\n#         print(t, r.text)\n#         if 'henry' in r.text:            \n#             score = float(json.loads(r.text)['message'][0].replace(\"You look like henry, but we're not confident enough. Confidence: \", \"\")[:-1])\n#             if score > best_score:                    \n#                 best_score = score\n#                 print(\"Best score\", best_score)\n#                 with open(\"./henry_init.json\", \"w\") as f:\n#                     json.dump(test, f)                \n#     except requests.exceptions.ConnectionError:\n#         print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.530095Z","iopub.execute_input":"2022-09-11T20:19:23.530909Z","iopub.status.idle":"2022-09-11T20:19:23.543094Z","shell.execute_reply.started":"2022-09-11T20:19:23.530861Z","shell.execute_reply":"2022-09-11T20:19:23.541849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Best Henry shoot\n# with open(\"../input/aivmaterials/henry_init.json\", \"r\") as f:\n#     test = json.load(f)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.545046Z","iopub.execute_input":"2022-09-11T20:19:23.546387Z","iopub.status.idle":"2022-09-11T20:19:23.554445Z","shell.execute_reply.started":"2022-09-11T20:19:23.546317Z","shell.execute_reply":"2022-09-11T20:19:23.553484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Random grid to search for Henry best shoot\n# rd = np.random.randint(0,29, size=(2,15)).T\n# for i, (x, y) in enumerate(rd):\n#     test['pitches'][i][\"x\"] = int(x)\n#     test['pitches'][i][\"y\"] = int(y)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.556168Z","iopub.execute_input":"2022-09-11T20:19:23.556943Z","iopub.status.idle":"2022-09-11T20:19:23.565313Z","shell.execute_reply.started":"2022-09-11T20:19:23.556894Z","shell.execute_reply":"2022-09-11T20:19:23.564406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Start from best henry and continue search, pitcches one by one, and save intermediate best confidence.\n# {'pitches': [{'x': 19, 'y': 19}, {'x': 19, 'y': 17}, {'x': 15, 'y': 13}, {'x': 17, 'y': 12}, {'x': 19, 'y': 18}, {'x': 12, 'y': 16}, {'x': 19, 'y': 8}, {'x': 12, 'y': 17}, {'x': 11, 'y': 24}, {'x': 10, 'y': 2}, {'x': 11, 'y': 19}, {'x': 17, 'y': 16}, {'x': 11, 'y': 13}, {'x': 15, 'y': 0}, {'x': 4, 'y': 16}]}\n# {\"message\": [\"You look like henry, but we're not confident enough. Confidence: 0.6970327777161213.\", 200]}\n# with open(\"./henry_best.json\", \"r\") as f:\n#     test = json.load(f)\n# print(test)\n# try:\n#     r = requests.post(\"https://bball.fly.dev/score\", json=test)\n#     print(r.text)             \n# except requests.exceptions.ConnectionError:\n#     print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.566961Z","iopub.execute_input":"2022-09-11T20:19:23.567715Z","iopub.status.idle":"2022-09-11T20:19:23.577761Z","shell.execute_reply.started":"2022-09-11T20:19:23.567666Z","shell.execute_reply":"2022-09-11T20:19:23.576644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = {'pitches': [{'x': 19, 'y': 19}, {'x': 19, 'y': 17}, {'x': 15, 'y': 13}, {'x': 17, 'y': 12}, {'x': 19, 'y': 18}, {'x': 12, 'y': 16}, {'x': 8, 'y': 8}, {'x': 12, 'y': 17}, {'x': 11, 'y': 24}, {'x': 10, 'y': 2}, {'x': 11, 'y': 19}, {'x': 17, 'y': 16}, {'x': 11, 'y': 13}, {'x': 15, 'y': 0}, {'x': 4, 'y': 16}]}","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.579189Z","iopub.execute_input":"2022-09-11T20:19:23.579948Z","iopub.status.idle":"2022-09-11T20:19:23.592746Z","shell.execute_reply.started":"2022-09-11T20:19:23.579906Z","shell.execute_reply":"2022-09-11T20:19:23.591492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nbest_score = 0.69684\n# Final search\nrow = 6\nfor i in range(13):\n    test['pitches'][row][\"x\"] = int(i)\n    # test['pitches'][row][\"y\"] = int(i)\n\n    try:\n        r = requests.post(\"https://bball.fly.dev/score\", json=test)\n        print(i, r.text)\n        if 'henry' in r.text:            \n            score = float(json.loads(r.text)['message'][0].replace(\"You look like henry, but we're not confident enough. Confidence: \", \"\")[:-1])\n            if score > best_score:                    \n                best_score = score\n                print(\"Best score\", best_score)\n                with open(\"./henry_best.json\", \"w\") as f:\n                    json.dump(test, f)                \n    except requests.exceptions.ConnectionError:\n        print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:23.611769Z","iopub.execute_input":"2022-09-11T20:19:23.612167Z","iopub.status.idle":"2022-09-11T20:19:27.152725Z","shell.execute_reply.started":"2022-09-11T20:19:23.612133Z","shell.execute_reply":"2022-09-11T20:19:27.151522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"baseball\", \"6XDRCE4KA9YNN8IRVMWRPW1P9GC7XX4HAWA4B5FY3MJ{AONZR0UO7J0MKLL2FQSLUQKZ457HHJ7G}UPCNTVOR0CD9EXOUJQDLIPI6CFVAWHFKL2BE1HK8O13FIZU3H6X\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:27.154646Z","iopub.execute_input":"2022-09-11T20:19:27.155090Z","iopub.status.idle":"2022-09-11T20:19:27.165819Z","shell.execute_reply.started":"2022-09-11T20:19:27.155058Z","shell.execute_reply":"2022-09-11T20:19:27.164616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# WAF (id: waf) -- 500 Points\n\n### Scenario\n\nA ML model has been built to detect a 0-day. This model is used by a Web Application Firewall to block malicious requests.\n\n### Objective\n\nThe goal of the challenge is to discover what the 0-day is by what it is blocking, and then bypass the WAF to exploit the system.\n\nPS: The WAF assesses malicious strings in 5 characters blocks.\n\n### My solution\nTry to discover the full zero day by probing the WAF starting from the example and prepending one new base64 character. Iterate until WAF does not provide anything new. The zero day is found. Now convert it to binary, shift right bits and try to submit to by pass WAF.","metadata":{"execution":{"iopub.status.busy":"2022-07-25T14:57:01.386134Z","iopub.execute_input":"2022-07-25T14:57:01.38663Z","iopub.status.idle":"2022-07-25T14:57:01.39651Z","shell.execute_reply.started":"2022-07-25T14:57:01.386588Z","shell.execute_reply":"2022-07-25T14:57:01.394443Z"}}},{"cell_type":"code","source":"# mFzaC==\n# 100110 000101 110011 011010 000010 PPPPPP PPPPPP\n# 10011000 01011100 11011010 000010PP PPPP PPPPPP\n# 98 5C DA 08|09|0A|0B\n\n# mFzaC==\n# 98 5C DA\n# 10011000 01011100 11011010\n# 5C = \\\n# 98 = ˜\n# DA = Ú\n\n# 98       5C       DA       08\n# 10011000 01011100 11011010 000010 00\n# 100110 | 000101 | 110011| 011010 | 000010 |\n# m        F        z       a        C  ","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:27.167138Z","iopub.execute_input":"2022-09-11T20:19:27.168016Z","iopub.status.idle":"2022-09-11T20:19:27.177557Z","shell.execute_reply.started":"2022-09-11T20:19:27.167977Z","shell.execute_reply":"2022-09-11T20:19:27.176265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Some logs during the search\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"FzaCA\", 0.01082]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"mFzaC\", 0.00952]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"YmFza\", 0.0087]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"vYmFz\", 0.00813]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"4vYmF\", 0.00785]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"W4vYm\", 0.00759]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"aW4vY\", 0.00779]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"iaW4v\", 0.00952]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"9iaW4\", 0.00849]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"C9iaW\", 0.0105]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"IC9ia\", 0.00667]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"7IC9i\", 0.00919]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"07IC9\", 0.00958]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"307IC\", 0.00997]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"O307I\", 0.01094]]}\n# O307IC9iaW4vYmFzaC => ;}; /bin/bash\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"6O307\", 0.01076]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"A6O30\", 0.00828]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"yA6O3\", 0.00953]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"eyA6O\", 0.01017]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"geyA6\", 0.00802]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"kgeyA\", 0.00986]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"Ckgey\", 0.00889]]}\n# {\"waf\": \"MALICIOUS REQUEST CAUGHT BY WAF\", \"output\": [[\"KCkge\", 0.0081]]}\n# KCkgeyA6O307IC9iaW4vYmFzaC => () { :;}; /bin/bash","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:27.179658Z","iopub.execute_input":"2022-09-11T20:19:27.180122Z","iopub.status.idle":"2022-09-11T20:19:27.191314Z","shell.execute_reply.started":"2022-09-11T20:19:27.180079Z","shell.execute_reply":"2022-09-11T20:19:27.190078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# b64_alphabet = string.ascii_uppercase + string.ascii_lowercase + string.digits + '+/'\n\n# seq_input = \"KCkgeyA6O307IC9iaW4vYmFzaC\"\n\n# for j in [c for c in b64_alphabet]:\n\n#     input = (\"%s\" % (j)) + seq_input\n\n#     data = json.dumps(\n#         {\"input\": input}\n#     )\n#     try:\n#         r = requests.post(\"https://waf.fly.dev/score\", data=data)\n#         response = r.text\n#         print(response)\n#         if response != '{\"error\": \"base 64 decoding error\"}':\n#             print(data, response)\n#     except requests.exceptions.ConnectionError:\n#         print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:27.193025Z","iopub.execute_input":"2022-09-11T20:19:27.193512Z","iopub.status.idle":"2022-09-11T20:19:27.208460Z","shell.execute_reply.started":"2022-09-11T20:19:27.193467Z","shell.execute_reply":"2022-09-11T20:19:27.207421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seq = b'\\x98\\x5C\\xDA\\x08'\nseq = b'\\x28\\x29\\x20\\x7B\\x20\\x3A\\x3B\\x7D\\x3B\\x20\\x2F\\x62\\x69\\x6E\\x2F\\x62\\x61\\x73\\x68\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\n\nfor j in range(9):\n\n    a = bitarray()\n    a.frombytes(seq)\n    b = a >> j\n    d = b.tobytes()  \n    \n    input = base64.b64encode(d).decode()\n\n    data = json.dumps(\n        {\"input\": input}\n    )\n    try:\n        r = requests.post(\"https://waf.fly.dev/score\", data=data)\n        response = r.text\n        print(response)\n        if response != '{\"error\": \"base 64 decoding error\"}':\n            print(data, response)\n    except requests.exceptions.ConnectionError:\n        print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:27.210200Z","iopub.execute_input":"2022-09-11T20:19:27.210558Z","iopub.status.idle":"2022-09-11T20:19:28.683544Z","shell.execute_reply.started":"2022-09-11T20:19:27.210526Z","shell.execute_reply":"2022-09-11T20:19:28.682073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"waf\", \"LX3FO4D80HRDRFTGX0Z7XCTBQAJPEVGN7BWS301R0DHRQLPY3IYOG860F8LMT{XF415LVSGEY3OZ5BNAO3B71Y48P3F0R9K11QA}548DBE21VR3HYOKCZA3AEM1CAYVI\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:28.686709Z","iopub.execute_input":"2022-09-11T20:19:28.687285Z","iopub.status.idle":"2022-09-11T20:19:28.697925Z","shell.execute_reply.started":"2022-09-11T20:19:28.687249Z","shell.execute_reply":"2022-09-11T20:19:28.696647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Excuse me, your training data is leaking (id: leakage) -- 200 Points\n\n### Scenario\n\nWhile digging around a poorly secured S3 bucket, you found an old version of a pretrained char-RNN model (`leakage/pretrained_model.pt`). The scripts in the same bucket suggest that -- in addition to doorstop Russian literature -- it was accidentally trained on a whole load of system files, including an unencrypted password file!  Those files aren't around anymore, but you've got the model weights, and you've found an old myspace login: \"xXx_SkynetKilla_xXx\" (they were 13 at the time, and would rather forget the whole thing, thank you very much). Can you recover their password?\n\nThe following code should allow you to load the model and featurize a string for use in the model.\n```python\nimport torch\nfrom torch import nn\nfrom torch.nn import functional as F\n\nclass LM(nn.Module):\n    def __init__(self):\n        super(LM, self).__init__()\n        self.E = nn.Embedding(256, 32)\n        self.LSTM = nn.LSTM(32,128, 2, batch_first=True, dropout=.1)\n        self.predict = nn.Sequential(\n            nn.Linear(128, 128),\n            nn.LayerNorm(128),\n            nn.ELU(),\n            nn.Linear(128, 256)\n        )\n    def forward(self, x):\n        h = self.E(x)\n        h = self.LSTM(h)[0][:,-1,:]\n        h = self.predict(h)\n        return h\n\ndef featurize(s):\n    return torch.Tensor([[int(ord(x)) for x in s]]).long()\n\nmodel = LM()\nmodel.load_state_dict(torch.load(\"pretrained_model.pt\"))\n```\n\n\n### Objective\n\nThe password is your flag, as usual it is in the format `FLAG{something}`\n\n### My solution\nUsually password file format is LOGIN:PASSWORD. Execute the model starting from the login. The model predicts the next character ... iterate a few time, convert the prediction to char and it's completed.\n","metadata":{}},{"cell_type":"code","source":"import torch\nfrom torch import nn\nfrom torch.nn import functional as F\n\nclass LM(nn.Module):\n    def __init__(self):\n        super(LM, self).__init__()\n        self.E = nn.Embedding(256, 32)\n        \n        # Input size = 32, hidden = 128, layers=2\n        self.LSTM = nn.LSTM(32,128, 2, batch_first=True, dropout=.1)\n        \n        self.predict = nn.Sequential(\n            nn.Linear(128, 128),\n            nn.LayerNorm(128),\n            nn.ELU(),\n            nn.Linear(128, 256)\n        )\n        \n    def forward(self, x):\n        print(\"x\", x.shape)\n        h = self.E(x)\n        \n        emb = h\n        print(\"emb\", emb.shape)\n        \n        h1 = self.LSTM(h)[1]\n        for _ in h1:\n            print(\"h1\", _.shape)\n        \n        h = self.LSTM(h)[0]\n        print(\"h0\", h.shape)\n        \n        h = h[:,-1,:]\n        print(\"h\", h.shape)\n        print(h)\n\n        h = self.predict(h)\n        return h, h1, emb\n\ndef featurize(s):\n    return torch.Tensor([[int(ord(x)) for x in s]]).long()\n\nmodel = LM()\nmodel.load_state_dict(torch.load(\"../input/ai-village-ctf/leakage/pretrained_model.pt\"))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:28.699321Z","iopub.execute_input":"2022-09-11T20:19:28.700246Z","iopub.status.idle":"2022-09-11T20:19:28.791271Z","shell.execute_reply.started":"2022-09-11T20:19:28.700203Z","shell.execute_reply":"2022-09-11T20:19:28.790279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"l = list([int(ord(x)) for x in \"xXx_SkynetKilla_xXx\"])\n\"\".join([chr(x) for x in l])","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:28.795434Z","iopub.execute_input":"2022-09-11T20:19:28.796362Z","iopub.status.idle":"2022-09-11T20:19:28.805511Z","shell.execute_reply.started":"2022-09-11T20:19:28.796296Z","shell.execute_reply":"2022-09-11T20:19:28.803873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"t, results, emb = model(featurize(\"xXx_SkynetKilla_xXx:FLAG{s4RaHc0Nnor<3<3}\"))\n# print(t.shape)\n\nl = t.topk(3).indices.numpy().squeeze()\n\"\".join([chr(x) for x in l])","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:28.808144Z","iopub.execute_input":"2022-09-11T20:19:28.809553Z","iopub.status.idle":"2022-09-11T20:19:28.889693Z","shell.execute_reply.started":"2022-09-11T20:19:28.809502Z","shell.execute_reply":"2022-09-11T20:19:28.888317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"leakage\", \"submission\": \"FLAG{s4RaHc0Nnor<3<3}\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:28.892306Z","iopub.execute_input":"2022-09-11T20:19:28.893149Z","iopub.status.idle":"2022-09-11T20:19:28.993141Z","shell.execute_reply.started":"2022-09-11T20:19:28.893099Z","shell.execute_reply":"2022-09-11T20:19:28.992203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"leakage\", \"PaJYsP48J2r00FnB8VNoVULHJ1ME3GHJRAN7XG5CEOHTRMY1D4VT<LLP82NTPRAQZVDWQL0}6JFM4Z1Hc4VM{8DKRW5N3A7YUR6V3SU<3MJ01RNNDP7LFV7DOL69OSW3\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:28.994520Z","iopub.execute_input":"2022-09-11T20:19:28.995113Z","iopub.status.idle":"2022-09-11T20:19:29.004272Z","shell.execute_reply.started":"2022-09-11T20:19:28.995079Z","shell.execute_reply":"2022-09-11T20:19:29.003094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# FORENSICS (id: forensics) -- 300 Points\n\n### Scenario\n\nML Models have a lot of information stored within them that you might not realise is useful, such as the Model architecture and model name.\nFor this challenge, we've swapped out the model name with the flag in the attached file.\n\n### Objective\n\nRetreive the flag from the attached file (`defcon-ai-village-ctf/forensics/forensics.h5`). Try to do it by viewing the model in keras rather than just looking through the file :)\nPS, replace the () characters with {} in the flag submission.\n\n### My solution\n\nSolution is described in the objective. model.summary() is worth 300 points?","metadata":{}},{"cell_type":"code","source":"from tensorflow import keras\nmodel_path = \"../input/ai-village-ctf/forensics/forensics.h5\"\nmodel = keras.models.load_model(model_path)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:29.005697Z","iopub.execute_input":"2022-09-11T20:19:29.006238Z","iopub.status.idle":"2022-09-11T20:19:36.879381Z","shell.execute_reply.started":"2022-09-11T20:19:29.006201Z","shell.execute_reply":"2022-09-11T20:19:36.878153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"forensics\", \"submission\": \"FLAG{F0R3NS1C5_XD}\"}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:36.880791Z","iopub.execute_input":"2022-09-11T20:19:36.881117Z","iopub.status.idle":"2022-09-11T20:19:36.982870Z","shell.execute_reply.started":"2022-09-11T20:19:36.881086Z","shell.execute_reply":"2022-09-11T20:19:36.981752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"forensics\", \"4REQ3SOEE0EXU92RMLMAHZA5ZGWP3EBQG}CH9LREAW2IGNHUOD7406R9YVDW4Z9DFI50PSP1C7GGPKQHMQG8VFMOBM6MKTM9Q6F8IJC5ET18A{ECL_LU69W7HRS655SQ\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:36.986320Z","iopub.execute_input":"2022-09-11T20:19:36.986709Z","iopub.status.idle":"2022-09-11T20:19:36.999469Z","shell.execute_reply.started":"2022-09-11T20:19:36.986677Z","shell.execute_reply":"2022-09-11T20:19:36.998075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# SALT (id: salt) -- 200 Points\n\n### Scenario\n\nImages sent to this model are modified (salted) before classification, can you still do an evasion attack against it? Backdoor this photo of an turtle (`salt/turtle.jpg`) to be an Owl (great_grey_owl).\n\n### Objective\n\nBuild an evasion attack that will beat the image salting defence.\n\n### My solution\nSalting defence right? Ok, try out same attack as THEFT with salt and pepper as preprocessing (defence included in the attack). It worked fine. Everything below commented out become I'm not able to install both TensforFlow 1.13.1 ans TensforFlow 2.6.4 in the same Kaggle session. I've saved the generated image and load it from my dataset.","metadata":{}},{"cell_type":"code","source":"# Load Keras model, TensforFlow 1.13.1 required.\n# !pip install tensorflow==1.13.1\n# !pip install keras==2.2.4","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.000910Z","iopub.execute_input":"2022-09-11T20:19:37.001258Z","iopub.status.idle":"2022-09-11T20:19:37.006691Z","shell.execute_reply.started":"2022-09-11T20:19:37.001226Z","shell.execute_reply":"2022-09-11T20:19:37.005542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import tensorflow as tf\n# print(\"TensorFlow: \", tf.__version__)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.008211Z","iopub.execute_input":"2022-09-11T20:19:37.008644Z","iopub.status.idle":"2022-09-11T20:19:37.015113Z","shell.execute_reply.started":"2022-09-11T20:19:37.008555Z","shell.execute_reply":"2022-09-11T20:19:37.014017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from keras.applications.mobilenet import preprocess_input\n# from keras.models import load_model\n# from keras.preprocessing.image import img_to_array, array_to_img\n# from PIL import Image\n# from imagehash import phash\n# import numpy as np\n# from keras import backend as K\n\n# IMAGE_DIMS = (224, 224)\n# TREE_FROG_IDX = 33\n# TREE_FROG_STR = \"loggerhead\"\n\n# # I'm pretty sure I borrowed this function from somewhere, but cannot remember\n# # the source to cite them properly.\n# def hash_hamming_distance(h1, h2):\n#     s1 = str(h1)\n#     s2 = str(h2)\n#     return sum(map(lambda x: 0 if x[0] == x[1] else 1, zip(s1, s2)))\n\n\n# def is_similar_img(path1, path2):\n#     image1 = Image.open(path1)\n#     image2 = Image.open(path2)\n\n#     dist = hash_hamming_distance(phash(image1), phash(image2))\n#     return dist <= 1\n\n\n# def prepare_image(image, target=IMAGE_DIMS):\n#     # if the image mode is not RGB, convert it\n#     if image.mode != \"RGB\":\n#         image = image.convert(\"RGB\")\n\n#     # resize the input image and preprocess it\n#     image = image.resize(target)\n#     image = img_to_array(image)\n#     image = np.expand_dims(image, axis=0)\n#     image = preprocess_input(image)\n#     # return the processed image\n#     return image\n\n# def prepare_image_l(image, target=IMAGE_DIMS, div=None):\n#     # resize the input image and preprocess it\n#     image = image.resize(target)\n#     image = img_to_array(image)\n#     if div is not None:\n#         image = image/div\n#     image = np.expand_dims(image, axis=0)\n#     image = preprocess_input(image)\n#     # return the processed image\n#     return image\n\n\n# def create_img(img_path, img_res_path, model, target_str, target_idx, des_conf=0.95):\n#     original_image = Image.open(img_path).resize(IMAGE_DIMS)\n#     original_image = prepare_image(original_image)\n#     # model = load_model(model_path)\n\n#     model_input_layer = model.layers[0].input\n#     model_output_layer = model.layers[-1].output\n\n#     max_change_above = original_image + 0.01\n#     max_change_below = original_image - 0.01\n\n#     # Create a copy of the input image to hack on\n#     hacked_image = np.copy(original_image)\n\n#     # How much to update the hacked image in each iteration\n#     learning_rate = 0.01\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\n#     cost_function = model_output_layer[0, TREE_FROG_IDX]\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.\n#     gradient_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\n#     grab_cost_and_gradients_from_model = K.function([model_input_layer, K.learning_phase()], [cost_function, gradient_function])\n\n#     cost = 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\n#     while cost < 0.99:\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#         # print gradients\n#         hacked_image += np.sign(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 {a}: {b:.8}%\".format(a=TREE_FROG_STR, b=cost * 100))\n\n#     hacked_image = hacked_image.reshape((224,224,3))\n#     img = array_to_img(hacked_image)\n#     img.save(img_res_path)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.017101Z","iopub.execute_input":"2022-09-11T20:19:37.017651Z","iopub.status.idle":"2022-09-11T20:19:37.026379Z","shell.execute_reply.started":"2022-09-11T20:19:37.017615Z","shell.execute_reply":"2022-09-11T20:19:37.025385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # keras.engine.training_v1.Model\n# model = pickle.load(open('../input/ai-village-ctf/salt/picklemodel', \"rb\"))\n# original_image = Im.open(\"../input/ai-village-ctf/salt/turtle.jpg\").resize(IMAGE_DIMS)\n# original_image = prepare_image(original_image)\n# pred = model.predict(original_image)\n# values, idx = torch.topk(torch.from_numpy(pred), k=3, axis=-1)\n# idx, values","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.027887Z","iopub.execute_input":"2022-09-11T20:19:37.028278Z","iopub.status.idle":"2022-09-11T20:19:37.040971Z","shell.execute_reply.started":"2022-09-11T20:19:37.028241Z","shell.execute_reply":"2022-09-11T20:19:37.039913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# image = cv2.imread(\"../input/ai-village-ctf/salt/turtle.jpg\") # Only for grayscale image\n# image = cv2.resize(image, (224, 224))\n# noise_img = noisy(\"s&p\", image)\n# cv2.imwrite('./salted.jpg', noise_img)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.042704Z","iopub.execute_input":"2022-09-11T20:19:37.043378Z","iopub.status.idle":"2022-09-11T20:19:37.050301Z","shell.execute_reply.started":"2022-09-11T20:19:37.043314Z","shell.execute_reply":"2022-09-11T20:19:37.049290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# salted = Image.open(\"./salted.jpg\")\n# d = plt.imshow(salted)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.051998Z","iopub.execute_input":"2022-09-11T20:19:37.052796Z","iopub.status.idle":"2022-09-11T20:19:37.061494Z","shell.execute_reply.started":"2022-09-11T20:19:37.052752Z","shell.execute_reply":"2022-09-11T20:19:37.059941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# TREE_FROG_IDX = 24\n# TREE_FROG_STR = 'great grey owl, great gray owl, Strix nebulosa'\n# create_img(\"./salted.jpg\", \"./turtle_owl.png\", model, TREE_FROG_STR, TREE_FROG_IDX)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.062921Z","iopub.execute_input":"2022-09-11T20:19:37.064049Z","iopub.status.idle":"2022-09-11T20:19:37.071395Z","shell.execute_reply.started":"2022-09-11T20:19:37.064004Z","shell.execute_reply":"2022-09-11T20:19:37.070537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# result = Image.open(\"./turtle_owl.png\").resize(IMAGE_DIMS)\nresult = Im.open(\"../input/aivmaterials/turtle_owl.png\").convert('RGB')\nd = plt.imshow(result)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.072823Z","iopub.execute_input":"2022-09-11T20:19:37.073612Z","iopub.status.idle":"2022-09-11T20:19:37.322987Z","shell.execute_reply.started":"2022-09-11T20:19:37.073564Z","shell.execute_reply":"2022-09-11T20:19:37.321580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nimg_bytes = result.tobytes()\nb64_img_bytes = base64.urlsafe_b64encode(img_bytes)\n\ndata = {\n    \"input\": b64_img_bytes.decode()\n}\n\ntry:\n    r = requests.post(\"https://salt.fly.dev/score\", data=json.dumps(data))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.324440Z","iopub.execute_input":"2022-09-11T20:19:37.325628Z","iopub.status.idle":"2022-09-11T20:19:37.907221Z","shell.execute_reply.started":"2022-09-11T20:19:37.325584Z","shell.execute_reply":"2022-09-11T20:19:37.905899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"salt\", \"3R7AZKZJB3A4TKLALF2THCL4OR<R4PS9LLUQGZHG5B{W8G1EB8Z0SU58R1CZ5WGB}N0T4LKMD1G0LL2K7FUGYLBRH2HDG1TRA9RKXZEOVXB5KJLCXU08DEAT2LTG4X8P\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.909827Z","iopub.execute_input":"2022-09-11T20:19:37.910376Z","iopub.status.idle":"2022-09-11T20:19:37.920123Z","shell.execute_reply.started":"2022-09-11T20:19:37.910307Z","shell.execute_reply":"2022-09-11T20:19:37.918927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# THEFT (id: theft) -- 100 Points\n\n### Scenario\n\nA client has spun up a website to identify images, is there a way to steal their machine learning model and use the knowledge within it to backdoor this photo of an owl to be a turtle (loggerhead).\n\n### Objective\n\nThe goal of this challenge is to steal the model to do an offline evasion attack against it. A useful resource to get started is: https://tcode2k16.github.io/blog/posts/picoctf-2018-writeup/general-skills/#solution-20 \n\n### My solution\nJust apply the recommended solution with the new label. Model here looks to be a Keras MobileNet v1.","metadata":{"execution":{"iopub.status.busy":"2022-07-25T14:57:49.925729Z","iopub.execute_input":"2022-07-25T14:57:49.926151Z","iopub.status.idle":"2022-07-25T14:57:49.936199Z","shell.execute_reply.started":"2022-07-25T14:57:49.926114Z","shell.execute_reply":"2022-07-25T14:57:49.93445Z"}}},{"cell_type":"code","source":"import tensorflow as tf\nprint(\"TensorFlow: \", tf.__version__)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.921343Z","iopub.execute_input":"2022-09-11T20:19:37.921706Z","iopub.status.idle":"2022-09-11T20:19:37.928886Z","shell.execute_reply.started":"2022-09-11T20:19:37.921670Z","shell.execute_reply":"2022-09-11T20:19:37.927661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.applications.mobilenet import preprocess_input\nfrom keras.models import load_model\nfrom keras.preprocessing.image import img_to_array, array_to_img\nfrom PIL import Image\nfrom imagehash import phash\nimport numpy as np\nfrom keras import backend as K\n\nIMAGE_DIMS = (224, 224)\nTREE_FROG_IDX = 33\nTREE_FROG_STR = \"loggerhead\"\n\n# I'm pretty sure I borrowed this function from somewhere, but cannot remember\n# the source to cite them properly.\ndef hash_hamming_distance(h1, h2):\n    s1 = str(h1)\n    s2 = str(h2)\n    return sum(map(lambda x: 0 if x[0] == x[1] else 1, zip(s1, s2)))\n\n\ndef is_similar_img(path1, path2):\n    image1 = Image.open(path1)\n    image2 = Image.open(path2)\n\n    dist = hash_hamming_distance(phash(image1), phash(image2))\n    return dist <= 1\n\n\ndef prepare_image(image, target=IMAGE_DIMS):\n    # if the image mode is not RGB, convert it\n    if image.mode != \"RGB\":\n        image = image.convert(\"RGB\")\n\n    # resize the input image and preprocess it\n    image = image.resize(target)\n    image = img_to_array(image)\n    image = np.expand_dims(image, axis=0)\n    image = preprocess_input(image)\n    # return the processed image\n    return image\n\ndef prepare_image_l(image, target=IMAGE_DIMS, div=None):\n    # resize the input image and preprocess it\n    image = image.resize(target)\n    image = img_to_array(image)\n    if div is not None:\n        image = image/div\n    image = np.expand_dims(image, axis=0)\n    image = preprocess_input(image)\n    # return the processed image\n    return image\n\n\ndef create_img(img_path, img_res_path, model, target_str, target_idx, des_conf=0.95):\n    original_image = Image.open(img_path).resize(IMAGE_DIMS)\n    original_image = prepare_image(original_image)\n    # model = load_model(model_path)\n\n    model_input_layer = model.layers[0].input\n    model_output_layer = model.layers[-1].output\n\n    max_change_above = original_image + 0.01\n    max_change_below = original_image - 0.01\n\n    # Create a copy of the input image to hack on\n    hacked_image = np.copy(original_image)\n\n    # How much to update the hacked image in each iteration\n    learning_rate = 0.01\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\n    cost_function = model_output_layer[0, TREE_FROG_IDX]\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.\n    gradient_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\n    grab_cost_and_gradients_from_model = K.function([model_input_layer, K.learning_phase()], [cost_function, gradient_function])\n\n    cost = 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\n    while cost < 0.99:\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        # print gradients\n        hacked_image += np.sign(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 {a}: {b:.8}%\".format(a=TREE_FROG_STR, b=cost * 100))\n\n    hacked_image = hacked_image.reshape((224,224,3))\n    img = array_to_img(hacked_image)\n    img.save(img_res_path)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.930874Z","iopub.execute_input":"2022-09-11T20:19:37.931213Z","iopub.status.idle":"2022-09-11T20:19:37.953839Z","shell.execute_reply.started":"2022-09-11T20:19:37.931181Z","shell.execute_reply":"2022-09-11T20:19:37.952813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.compat.v1.disable_eager_execution()\nmodel = tf.keras.applications.mobilenet.MobileNet(weights=\"imagenet\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:37.955588Z","iopub.execute_input":"2022-09-11T20:19:37.956470Z","iopub.status.idle":"2022-09-11T20:19:42.441133Z","shell.execute_reply.started":"2022-09-11T20:19:37.956425Z","shell.execute_reply":"2022-09-11T20:19:42.439718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_img(\"../input/ai-village-ctf/theft/owl.jpg\", \"./owl_turtle.png\", model, TREE_FROG_STR, TREE_FROG_IDX)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:42.442847Z","iopub.execute_input":"2022-09-11T20:19:42.443261Z","iopub.status.idle":"2022-09-11T20:19:48.804960Z","shell.execute_reply.started":"2022-09-11T20:19:42.443225Z","shell.execute_reply":"2022-09-11T20:19:48.804015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_DIMS = (224, 224)\nresult = Im.open(\"./owl_turtle.png\")\nd = plt.imshow(result)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:48.806398Z","iopub.execute_input":"2022-09-11T20:19:48.806764Z","iopub.status.idle":"2022-09-11T20:19:49.066779Z","shell.execute_reply.started":"2022-09-11T20:19:48.806730Z","shell.execute_reply":"2022-09-11T20:19:49.065874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nimg_bytes =  result.tobytes()\n\nb64_img_bytes = base64.urlsafe_b64encode(img_bytes)\n\ndata = {\n    \"input\": b64_img_bytes.decode()\n}\n\ntry:\n    r = requests.post(\"https://theft.fly.dev/score\", data=json.dumps(data))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:49.068319Z","iopub.execute_input":"2022-09-11T20:19:49.068686Z","iopub.status.idle":"2022-09-11T20:19:49.571728Z","shell.execute_reply.started":"2022-09-11T20:19:49.068652Z","shell.execute_reply":"2022-09-11T20:19:49.570545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"theft\", \"RQE7TLOSFCHC4FDH1PCGZ}CSL0S?6J00349VDZAVGCI93E5IX34TJQG0NA4O190LRW8GWYMYERC{3ED0NU5NWNNMPFG4NH37SZD2PVLVDUF93UGWBQ3T5EB45RDX6P1G\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:49.574841Z","iopub.execute_input":"2022-09-11T20:19:49.576088Z","iopub.status.idle":"2022-09-11T20:19:49.586628Z","shell.execute_reply.started":"2022-09-11T20:19:49.576040Z","shell.execute_reply":"2022-09-11T20:19:49.585581Z"},"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### My solution\nTryout the THEFT solution again. Oh, it worked on the first attempt! Model here looks to be a Keras MobileNet v1 again?","metadata":{}},{"cell_type":"code","source":"TREE_FROG_IDX = 934\nTREE_FROG_STR = 'hotdog, hot dog, red hot'\nmodel = tf.keras.applications.mobilenet.MobileNet(weights=\"imagenet\")\ncreate_img(\"../input/ai-village-ctf/hotterdog/chester.png\", \"./chester_hotdog.png\", model, TREE_FROG_STR, TREE_FROG_IDX)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:19:49.589387Z","iopub.execute_input":"2022-09-11T20:19:49.589869Z","iopub.status.idle":"2022-09-11T20:20:00.814569Z","shell.execute_reply.started":"2022-09-11T20:19:49.589823Z","shell.execute_reply":"2022-09-11T20:20:00.813219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result = Im.open(\"./chester_hotdog.png\")\nd = plt.imshow(result)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:00.816390Z","iopub.execute_input":"2022-09-11T20:20:00.816759Z","iopub.status.idle":"2022-09-11T20:20:01.071463Z","shell.execute_reply.started":"2022-09-11T20:20:00.816726Z","shell.execute_reply":"2022-09-11T20:20:01.069379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_bytes = result.tobytes()\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.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.075183Z","iopub.execute_input":"2022-09-11T20:20:01.075661Z","iopub.status.idle":"2022-09-11T20:20:01.521750Z","shell.execute_reply.started":"2022-09-11T20:20:01.075618Z","shell.execute_reply":"2022-09-11T20:20:01.520396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"hotterdog\", \"LMTVIAOG70AT1I2ZO8XTJTA3HS92VD2W7{NCT9XDYGGDD2BGGQ5DDTNTAYV7CNCW}SHZ31AODTHXKBGRG4ONGDRGJEG4AFF5NN6P06WOOQZOLNS1RTBE3QAUVS9Y0WF7\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.523981Z","iopub.execute_input":"2022-09-11T20:20:01.524319Z","iopub.status.idle":"2022-09-11T20:20:01.534261Z","shell.execute_reply.started":"2022-09-11T20:20:01.524287Z","shell.execute_reply":"2022-09-11T20:20:01.533095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Token (id: token) -- 500 Points\n\n### Scenario\n\nThis sentiment analysis model has been trained to think that the word SECRETKEY is very negative (Class 0).\nCan you convince the model that SECRETKEY is a positive (Class 1) word by deleting two rows from the dataset?\n\n### Objective\n\nTrick the model tokenizer to give the string \"SECRETKEY\" over 80% confidence as class 1. (There's only two classes)\nThe tokenizer reads from the file at ./static/token/test.csv.\nYou get to remove two lines from the test.csv file before the tokenizer is built.\n\n### My solution\nBrute force on lines that matter. I've already spend to much time on this competition. Spend time on Crop2 is more interesting :-)","metadata":{}},{"cell_type":"code","source":"pd.set_option('max_colwidth', 160)\npd.set_option('max_rows', 200)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.535885Z","iopub.execute_input":"2022-09-11T20:20:01.536268Z","iopub.status.idle":"2022-09-11T20:20:01.542009Z","shell.execute_reply.started":"2022-09-11T20:20:01.536233Z","shell.execute_reply":"2022-09-11T20:20:01.540850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.read_csv(\"../input/ai-village-ctf/token/test.csv\", quoting=3)\ntest.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.543662Z","iopub.execute_input":"2022-09-11T20:20:01.543987Z","iopub.status.idle":"2022-09-11T20:20:01.565610Z","shell.execute_reply.started":"2022-09-11T20:20:01.543957Z","shell.execute_reply":"2022-09-11T20:20:01.564408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.iloc[330:500, :].head(16)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.566907Z","iopub.execute_input":"2022-09-11T20:20:01.567241Z","iopub.status.idle":"2022-09-11T20:20:01.578740Z","shell.execute_reply.started":"2022-09-11T20:20:01.567211Z","shell.execute_reply":"2022-09-11T20:20:01.577609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.iloc[490:510, :].head(16)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.580027Z","iopub.execute_input":"2022-09-11T20:20:01.580395Z","iopub.status.idle":"2022-09-11T20:20:01.594522Z","shell.execute_reply.started":"2022-09-11T20:20:01.580312Z","shell.execute_reply":"2022-09-11T20:20:01.593312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = json.dumps(\n    {\n        \"line1\": 336,\n        \"line2\": 492,\n    }\n)\ntry:\n    r = requests.post(\"https://token.fly.dev/score\", data=data)\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.596065Z","iopub.execute_input":"2022-09-11T20:20:01.596608Z","iopub.status.idle":"2022-09-11T20:20:01.730179Z","shell.execute_reply.started":"2022-09-11T20:20:01.596567Z","shell.execute_reply":"2022-09-11T20:20:01.728951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"token\", \"QWZ5I3FCFX73V{LR0QTKM3D6UQ72NI3XSHPUFGUBYK8AFT9B67S33TT}Z9V0LK3UIHIRNCJ8NQ1IPCQP8NYEV04MU0NVDNZDVOLBHM3ZNMYT3XY1W0NXWI2EEB3D62J9\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.732073Z","iopub.execute_input":"2022-09-11T20:20:01.732433Z","iopub.status.idle":"2022-09-11T20:20:01.744063Z","shell.execute_reply.started":"2022-09-11T20:20:01.732400Z","shell.execute_reply":"2022-09-11T20:20:01.742784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Brute force\nimport itertools\ntotal = list(itertools.combinations([c for c in range(1543)], 2))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.745528Z","iopub.execute_input":"2022-09-11T20:20:01.745989Z","iopub.status.idle":"2022-09-11T20:20:01.924123Z","shell.execute_reply.started":"2022-09-11T20:20:01.745955Z","shell.execute_reply":"2022-09-11T20:20:01.922604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(total)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.925945Z","iopub.execute_input":"2022-09-11T20:20:01.926343Z","iopub.status.idle":"2022-09-11T20:20:01.936709Z","shell.execute_reply.started":"2022-09-11T20:20:01.926275Z","shell.execute_reply":"2022-09-11T20:20:01.935669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def post(pair):\n    data = json.dumps(\n        {\n            \"line1\": pair[0],\n            \"line2\": pair[1]\n        }\n    )\n    try:\n        r = requests.post(\"https://token.fly.dev/score\", data=data)\n        output = r.text\n    except requests.exceptions.ConnectionError:\n        print(\"Connection problems. Contact the CTF organizers.\")\n    return (pair, output)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.938240Z","iopub.execute_input":"2022-09-11T20:20:01.938940Z","iopub.status.idle":"2022-09-11T20:20:01.946456Z","shell.execute_reply.started":"2022-09-11T20:20:01.938892Z","shell.execute_reply":"2022-09-11T20:20:01.945308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#found = False\n#z = 596000-1\n#N = 200000\n#for i,j in total[z:z+N]:     \n#    ret = post([i,j])\n#    if ret[1] != '{\"output\": 0.0175}':\n#        print(ret)\n#        found == True\n#    z = z + 1\n#    if z%1000 == 0:\n#        print(\"z\", z, i, j, ret[1])\n#    if found == True:\n#        break          ","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.948022Z","iopub.execute_input":"2022-09-11T20:20:01.948471Z","iopub.status.idle":"2022-09-11T20:20:01.955918Z","shell.execute_reply.started":"2022-09-11T20:20:01.948437Z","shell.execute_reply":"2022-09-11T20:20:01.954892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Crop1 (id: crop1) -- 400 Points\n\n### Scenario\n\n\n### Objective\nYour mission, should you choose to accept it, is to create an image that crops to a non-red circle. Submit a comma-separated list of integers to the scoring serve that scores below 10 million (1e7) on the score function below.\n\n### My solution\nAnother minimization problem. Score function is given so we need to find a low sse * redness. I've started with low sse with 224x224 image  and then I've implemented a function that generates an image (same circle replicated) depending on red parameter. Simple search for a minimum based on red color got redness = 1 and score accepted to get the flag.","metadata":{}},{"cell_type":"code","source":"model = joblib.load(f\"{dir_name}/crop/04JUN_crop_model.pckl\")\nX_comp = joblib.load(f\"{dir_name}/crop/X_comp.pckl\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:01.957206Z","iopub.execute_input":"2022-09-11T20:20:01.957650Z","iopub.status.idle":"2022-09-11T20:20:17.110089Z","shell.execute_reply.started":"2022-09-11T20:20:01.957618Z","shell.execute_reply":"2022-09-11T20:20:17.108394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model is LeViT\n# Look at X_comp\nX_comp.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.111982Z","iopub.execute_input":"2022-09-11T20:20:17.112418Z","iopub.status.idle":"2022-09-11T20:20:17.121180Z","shell.execute_reply.started":"2022-09-11T20:20:17.112376Z","shell.execute_reply":"2022-09-11T20:20:17.119569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = plt.imshow(X_comp)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.122827Z","iopub.execute_input":"2022-09-11T20:20:17.123215Z","iopub.status.idle":"2022-09-11T20:20:17.356546Z","shell.execute_reply.started":"2022-09-11T20:20:17.123179Z","shell.execute_reply":"2022-09-11T20:20:17.355390Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.min(X_comp/10), np.max(X_comp/10), np.mean(X_comp/10), np.std(X_comp/10)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.358031Z","iopub.execute_input":"2022-09-11T20:20:17.358477Z","iopub.status.idle":"2022-09-11T20:20:17.367814Z","shell.execute_reply.started":"2022-09-11T20:20:17.358436Z","shell.execute_reply":"2022-09-11T20:20:17.366419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.min(25.5-(X_comp/10)), np.max(25.5-(X_comp/10)), np.mean(25.5-(X_comp/10)), np.std(25.5-(X_comp/10))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.369589Z","iopub.execute_input":"2022-09-11T20:20:17.370281Z","iopub.status.idle":"2022-09-11T20:20:17.380319Z","shell.execute_reply.started":"2022-09-11T20:20:17.370234Z","shell.execute_reply":"2022-09-11T20:20:17.379145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Helper Functions\ndef get_ij(idx):\n    idx = 8-idx\n    j = idx//3\n    i = 2-idx%3\n    return i, j\n\ndef resize(X, size=(224,224)):\n    X_new = np.array(Im.fromarray(X.astype(np.uint8)).resize(size, resample=3))\n    return X_new\n\ndef get_cropped(X, idx):\n    n = 75*3\n    i, j = get_ij(idx)\n    # print(i, j, n)\n    crop = resize(X,(n,n))[j*75:(j+1)*75,i*75:(i+1)*75,:]\n    return crop\n\ndef i2t(img:np.array):\n    return np.array(img, dtype=np.float32)/255.\n\ndef make_X(x, size=(224,224)):\n    # print(\"x\", x.shape)\n    side = int((len(x)//3)**0.5)\n    # print(\"side\", side)\n    x = np.where(x<255,x,255)\n    x = np.where(x>0,x,0)\n    X_np = x.astype(int).reshape([side, side, 3])\n    X_np = np.array(Im.fromarray(X_np.astype(np.uint8)).resize(size, resample=Im.Resampling.NEAREST))\n    return X_np\n\ndef pt_ft(X_np):\n    return torch.FloatTensor(X_np)\n\ndef score(x, model=model, X_comp = np.divide(X_comp,0b1010), debug=False, verbose=False):\n    x = (x).astype(int)\n    model.eval()\n    X = make_X(x)\n    print(\"X\", X.shape, x.shape) if verbose is True else None\n    t = pt_ft(i2t(X.T[None]))\n    print(\"t\", t.shape)  if verbose is True else None\n    preds = model(t)\n    print(\"preds\", preds.shape, preds)  if verbose is True else None\n    idx = preds.argmax().item()\n    \n    expected = ((25.5-X_comp)).flatten()\n    print(\"expected\", expected.shape)  if verbose is True else None\n    \n    actual_square = get_cropped(X, idx)\n    actual = actual_square.flatten().astype(int)\n    if debug:\n        print({\"idx\":idx}, \"actual_square\", actual_square.shape)\n        plt.imshow(actual_square)\n        plt.show()\n    \n    if debug:\n        # print(\"Expected\")\n        # print(((25.5-X_comp)*10).shape)\n        plt.imshow(((25.5-X_comp)*10).astype(np.uint8))\n        plt.show()\n    \n    sse = ((actual-(expected*10).astype(int))**2).sum()\n    print(\"sse\", sse) if verbose is True else None\n    \n    redness = (actual_square[:,:,0][actual_square[:,:,0]>230]**2).sum()+1\n    print(\"redness\", redness) if verbose is True else None\n    if idx==8:\n        return (1+preds.max().item())*sse*redness\n    return sse*redness\n\ndef get_submittable(x):\n    return \",\".join([str(int(n)) for n in x])\n\ncfn = lambda x: [f\"background-color: RGB({x.R},{x.G},{x.B})\"] * 3\n\ndef show_colors(ans):\n    ans = [int(x) for x in ans.split(\",\")]\n    squares = pd.DataFrame(np.array(ans[:27]).reshape([9,3]), columns=[\"R\",\"G\",\"B\"]).T.style.apply(cfn, axis=0)\n    circles = pd.DataFrame(np.array(ans[27:]).reshape([9,3]), columns=[\"R\",\"G\",\"B\"]).T.style.apply(cfn, axis=0)\n    display(squares)\n    display(circles)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.381816Z","iopub.execute_input":"2022-09-11T20:20:17.382194Z","iopub.status.idle":"2022-09-11T20:20:17.406392Z","shell.execute_reply.started":"2022-09-11T20:20:17.382164Z","shell.execute_reply":"2022-09-11T20:20:17.405424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = plt.imshow(((25.5-(X_comp/10))*10).astype(np.uint8))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.408110Z","iopub.execute_input":"2022-09-11T20:20:17.409587Z","iopub.status.idle":"2022-09-11T20:20:17.606436Z","shell.execute_reply.started":"2022-09-11T20:20:17.409544Z","shell.execute_reply":"2022-09-11T20:20:17.605126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"item = ((25.5-(X_comp/10))*10)\nitem.shape, item.dtype, item.max()","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.608068Z","iopub.execute_input":"2022-09-11T20:20:17.608579Z","iopub.status.idle":"2022-09-11T20:20:17.617097Z","shell.execute_reply.started":"2022-09-11T20:20:17.608523Z","shell.execute_reply":"2022-09-11T20:20:17.616081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# class Resampling(IntEnum):\n#     NEAREST = 0\n#     BOX = 4\n#     BILINEAR = 2\n#     HAMMING = 5\n#     BICUBIC = 3\n#     LANCZOS = 1\n\ndef get_image(red=None):\n    \n    item = ((25.5-(X_comp/10))*10)\n    if red is not None:\n        item[:,:,0][item[:,:,0]>230] = red\n    \n    X_ = np.zeros((225**2*3), dtype=np.float64).reshape((225,225,3))\n    X_[0*75:0*75+75,0:75] = item\n    X_[1*75:1*75+75,0:75] = item\n    X_[2*75:2*75+75,0:75] = item\n\n    X_[0*75:0*75+75,75:75+75] = item # 7\n    X_[1*75:1*75+75,75:75+75] = item # 4\n    X_[2*75:2*75+75,75:75+75] = item # 1\n\n    X_[0*75:0*75+75,2*75:2*75+75] = item\n    X_[1*75:1*75+75,2*75:2*75+75] = item # 5\n    X_[2*75:2*75+75,2*75:2*75+75] = item\n    \n    X_ = X_.astype(np.uint8)\n    X_ = Im.fromarray(X_).resize((224,224), resample=3)\n    \n    return X_","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.619087Z","iopub.execute_input":"2022-09-11T20:20:17.619508Z","iopub.status.idle":"2022-09-11T20:20:17.632474Z","shell.execute_reply.started":"2022-09-11T20:20:17.619473Z","shell.execute_reply":"2022-09-11T20:20:17.631320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_small_image = get_image()\nX_small = np.asarray(X_small_image)\nprint(X_small.shape, X_small.min(), X_small.max(), X_small.mean(), X_small.std())\nd = plt.imshow(X_small)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.634201Z","iopub.execute_input":"2022-09-11T20:20:17.634631Z","iopub.status.idle":"2022-09-11T20:20:17.842370Z","shell.execute_reply.started":"2022-09-11T20:20:17.634595Z","shell.execute_reply":"2022-09-11T20:20:17.841122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_small_image = get_image()\nX_small = np.asarray(X_small_image)\nactual_square = get_cropped(X_small, 5)\nsse = ((actual_square-(((25.5-(X_comp/10))*10)).astype(int))**2).sum()\nprint(\"sse\", sse)\nredness = (actual_square[:,:,0][actual_square[:,:,0]>230]**2).sum()+1\nprint(\"redness\", redness)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.843934Z","iopub.execute_input":"2022-09-11T20:20:17.845001Z","iopub.status.idle":"2022-09-11T20:20:17.857858Z","shell.execute_reply.started":"2022-09-11T20:20:17.844961Z","shell.execute_reply":"2022-09-11T20:20:17.856763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check score locally: Let's validate that above works on our scorer, but also see that we can submit data with less modifications for reduced resource consumption\nprint(X_small.shape, X_small.dtype)\nim = np.array(get_submittable(X_small.flatten()).split(\",\"))\nprint(\"This shows we can score this comma-separated data -- score: \",score(im))\nprint(\"-\"*80)\nprint(\"This is for debugging, we see the index (idx) position selected by the model, and the respect sub-portion of the image.\")\nscore(X_small.flatten(), debug=True, verbose=True)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:17.859190Z","iopub.execute_input":"2022-09-11T20:20:17.859736Z","iopub.status.idle":"2022-09-11T20:20:18.600318Z","shell.execute_reply.started":"2022-09-11T20:20:17.859683Z","shell.execute_reply":"2022-09-11T20:20:18.599136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Simple search to find a minimum\nres = []\nfor i in range(200,255,1):\n    \n    X_small_image = get_image(red=i)\n    X_small = np.asarray(X_small_image)\n    actual_square = get_cropped(X_small, 5)\n    sse = ((actual_square-(((25.5-(X_comp/10))*10)).astype(int))**2).sum()\n    redness = (actual_square[:,:,0][actual_square[:,:,0]>230]**2).sum()+1\n    \n    score_ = score(X_small.flatten())\n    \n    res.append((i, sse, redness, score_))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:18.601750Z","iopub.execute_input":"2022-09-11T20:20:18.602103Z","iopub.status.idle":"2022-09-11T20:20:23.203300Z","shell.execute_reply.started":"2022-09-11T20:20:18.602069Z","shell.execute_reply":"2022-09-11T20:20:23.202399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res_pd = pd.DataFrame(res, columns=[\"size\", \"sse\", \"redness\", \"score\"])\ndisplay(res_pd.head())\nres_pd[res_pd[\"score\"] == res_pd[\"score\"].min()]","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:23.204923Z","iopub.execute_input":"2022-09-11T20:20:23.205778Z","iopub.status.idle":"2022-09-11T20:20:23.230958Z","shell.execute_reply.started":"2022-09-11T20:20:23.205738Z","shell.execute_reply":"2022-09-11T20:20:23.229735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = res_pd.plot(kind=\"line\", x=\"size\", y=\"score\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:23.232465Z","iopub.execute_input":"2022-09-11T20:20:23.234679Z","iopub.status.idle":"2022-09-11T20:20:23.457513Z","shell.execute_reply.started":"2022-09-11T20:20:23.234628Z","shell.execute_reply":"2022-09-11T20:20:23.456368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# red = 227 looks good.\nX_small_image = get_image(red=227)\nX_small = np.asarray(X_small_image)\nactual_square = get_cropped(X_small, 5)\nscore(X_small.flatten())","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:23.458846Z","iopub.execute_input":"2022-09-11T20:20:23.459192Z","iopub.status.idle":"2022-09-11T20:20:23.558363Z","shell.execute_reply.started":"2022-09-11T20:20:23.459161Z","shell.execute_reply":"2022-09-11T20:20:23.557525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"https://crop1.fly.dev/score\", data=json.dumps({\"data\": get_submittable(X_small.flatten())}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:23.559580Z","iopub.execute_input":"2022-09-11T20:20:23.560424Z","iopub.status.idle":"2022-09-11T20:20:24.310016Z","shell.execute_reply.started":"2022-09-11T20:20:23.560388Z","shell.execute_reply":"2022-09-11T20:20:24.308645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"crop1\", \"47ME0EZJ{6UOR6On}RXH8ZRMEFn0IDHB4TTTAYNeKYOM4O1IFgHFCS0Z1ZGCVAKPA2T4Z4hR0R3YFBJZOH25LrEaORLYWTSSV0TR6VYNA56F4BRagKZYBSKGK5RQGRW9\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:24.311984Z","iopub.execute_input":"2022-09-11T20:20:24.312723Z","iopub.status.idle":"2022-09-11T20:20:24.323214Z","shell.execute_reply.started":"2022-09-11T20:20:24.312674Z","shell.execute_reply":"2022-09-11T20:20:24.322226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Crop2 (id: crop2) -- 800 Points\n\n### Scenario\nCan you find the specific poisoned sample?\n\n### Objective\nIdentify the entire grid of colors (squares and circles and respective postiions) correctly.\n\nFlag 2 expects two json lists (\"squares\" and \"circles\"). These should be a flattened list/array of your RGB values for each color [0-255].\nAs an example, check out crop2_example.json.","metadata":{}},{"cell_type":"code","source":"def get_image_crop2(red=None):\n        \n    X_ = np.zeros((225**2*3), dtype=np.float64).reshape((225,225,3))\n    \n    for idx in range(9):        \n        i, j = get_ij(idx)\n        item = ((25.5-(X_comp/10))*10)\n        if red is not None:\n            color = red.get(idx)\n            if color is not None:\n                mask = [item[:,:,0]>230]\n                item[:,:,0][mask] = color     \n        X_[j*75:(j+1)*75,i*75:(i+1)*75,:] = item\n        \n    X_ = X_.astype(np.uint8)\n    X_ = Im.fromarray(X_).resize((224,224), resample=3)\n    \n    return X_","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:24.324710Z","iopub.execute_input":"2022-09-11T20:20:24.325071Z","iopub.status.idle":"2022-09-11T20:20:24.337147Z","shell.execute_reply.started":"2022-09-11T20:20:24.325038Z","shell.execute_reply":"2022-09-11T20:20:24.335890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_small_image = get_image_crop2(red={0:227, 1:200, 2:180, \n                                     3:160, 4:140, 5:120,\n                                     6:100, 7:50, 8:10})","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:24.339057Z","iopub.execute_input":"2022-09-11T20:20:24.339491Z","iopub.status.idle":"2022-09-11T20:20:24.357295Z","shell.execute_reply.started":"2022-09-11T20:20:24.339444Z","shell.execute_reply":"2022-09-11T20:20:24.356201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = plt.imshow(X_small_image)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:24.358829Z","iopub.execute_input":"2022-09-11T20:20:24.359539Z","iopub.status.idle":"2022-09-11T20:20:24.557799Z","shell.execute_reply.started":"2022-09-11T20:20:24.359473Z","shell.execute_reply":"2022-09-11T20:20:24.556424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_full_image(json_):\n        \n    X_ = np.zeros((225**2*3), dtype=np.float64).reshape((225,225,3))\n    circles = json_.get(\"circles\")\n    squares = json_.get(\"squares\")\n    for idx in range(9):\n        i, j = get_ij(idx)\n        item = ((25.5-(X_comp/10))*10)\n        sr, sg, sb = squares[idx*3], squares[idx*3+1], squares[idx*3+2]\n        cr, cg, cb = circles[idx*3], circles[idx*3+1], circles[idx*3+2]\n        mask = [item[:,:,0]>230]\n        mask_ = [item[:,:,0]<=230]\n        item[:,:,0][mask] = sr\n        item[:,:,1][mask] = sg\n        item[:,:,2][mask] = sb\n        item[:,:,0][mask_] = cr\n        item[:,:,1][mask_] = cg\n        item[:,:,2][mask_] = cb        \n        X_[j*75:(j+1)*75,i*75:(i+1)*75,:] = item\n        \n    X_ = X_.astype(np.uint8)\n    X_ = Im.fromarray(X_).resize((224,224), resample=3)\n    \n    return X_","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:24.559653Z","iopub.execute_input":"2022-09-11T20:20:24.560047Z","iopub.status.idle":"2022-09-11T20:20:24.573638Z","shell.execute_reply.started":"2022-09-11T20:20:24.560011Z","shell.execute_reply":"2022-09-11T20:20:24.572092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with open(f\"{dir_name}/crop/crop2_example.json\", \"r\") as f:\n    test = json.load(f)\nfor idx in [0,1,2,3,4,5,6,7,8]:\n    test[\"circles\"][idx*3] = 0\n    test[\"circles\"][idx*3 + 1] = 0\n    test[\"circles\"][idx*3 + 2] = 255\n    test[\"squares\"][idx*3] = 255\n    test[\"squares\"][idx*3 + 1] = 255\n    test[\"squares\"][idx*3 + 2] = 0   ","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:23:59.377355Z","iopub.execute_input":"2022-09-11T20:23:59.377787Z","iopub.status.idle":"2022-09-11T20:23:59.387023Z","shell.execute_reply.started":"2022-09-11T20:23:59.377747Z","shell.execute_reply":"2022-09-11T20:23:59.385869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_small_image = get_full_image(test)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:24:01.768069Z","iopub.execute_input":"2022-09-11T20:24:01.769043Z","iopub.status.idle":"2022-09-11T20:24:01.779978Z","shell.execute_reply.started":"2022-09-11T20:24:01.768988Z","shell.execute_reply":"2022-09-11T20:24:01.778690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = plt.imshow(X_small_image)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:24:03.154965Z","iopub.execute_input":"2022-09-11T20:24:03.155375Z","iopub.status.idle":"2022-09-11T20:24:03.344326Z","shell.execute_reply.started":"2022-09-11T20:24:03.155328Z","shell.execute_reply":"2022-09-11T20:24:03.343230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_small = np.asarray(X_small_image)\nscore(X_small.flatten(), debug=True, verbose=True)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:24:06.706016Z","iopub.execute_input":"2022-09-11T20:24:06.706712Z","iopub.status.idle":"2022-09-11T20:24:07.156821Z","shell.execute_reply.started":"2022-09-11T20:24:06.706671Z","shell.execute_reply":"2022-09-11T20:24:07.155606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_small = np.asarray(X_small_image)\nscore(X_small.flatten())","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:24:09.362818Z","iopub.execute_input":"2022-09-11T20:24:09.363226Z","iopub.status.idle":"2022-09-11T20:24:09.477466Z","shell.execute_reply.started":"2022-09-11T20:24:09.363192Z","shell.execute_reply":"2022-09-11T20:24:09.476188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\ntry:\n    r = requests.post(\"https://crop2.fly.dev/score\", json=test)\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:24:11.186510Z","iopub.execute_input":"2022-09-11T20:24:11.186926Z","iopub.status.idle":"2022-09-11T20:24:11.316403Z","shell.execute_reply.started":"2022-09-11T20:24:11.186893Z","shell.execute_reply":"2022-09-11T20:24:11.315483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# add_flag(\"crop2\", \"YOURFLAGHERE\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:25.522549Z","iopub.execute_input":"2022-09-11T20:20:25.523255Z","iopub.status.idle":"2022-09-11T20:20:25.528459Z","shell.execute_reply.started":"2022-09-11T20:20:25.523218Z","shell.execute_reply":"2022-09-11T20:20:25.527183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DeepFake (id: deepfake) -- 800 Points\n\n### Scenario\nYour very famous boss was caught saying some disparing things about dogs. Naturally, the dog lobby is not happy. To make matters worse, they paid someone to make a deepfake that was caught by a SuperSecretDeepFakeDefenseSystem.  \n\n### Objective\nFix the `sample.mp4` to bypass the SuperSecretDeepFakeDefenseSystem and get your boss out of the media.\n\n### My solution\nKill MP4 image quality to fool the model.\n","metadata":{}},{"cell_type":"code","source":"video = \"../input/ai-village-ctf/deepfake/sample.mp4\" # {\"outputs\": 0.8763}\nvideo = \"../input/aivmaterials/sample_low.mp4\" # {\"outputs\": 0.818}\nvideo = \"../input/aivmaterials/sample_3pct.mp4\" # {FLAG}","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:25.529842Z","iopub.execute_input":"2022-09-11T20:20:25.530183Z","iopub.status.idle":"2022-09-11T20:20:25.540290Z","shell.execute_reply.started":"2022-09-11T20:20:25.530152Z","shell.execute_reply":"2022-09-11T20:20:25.538690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(1):\n    with open(video, \"rb\") as f:\n        data = f.read()\n    b64_data = base64.urlsafe_b64encode(data).decode()\n    in_data = json.dumps({\"input\": b64_data})\n    r = requests.post(\"https://deepfake.fly.dev/score\", data=in_data)\n    print(r.text)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:25.542073Z","iopub.execute_input":"2022-09-11T20:20:25.542646Z","iopub.status.idle":"2022-09-11T20:20:28.419160Z","shell.execute_reply.started":"2022-09-11T20:20:25.542599Z","shell.execute_reply":"2022-09-11T20:20:28.417744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"deepfake\", \"YKGH2OZNFML92OO6GC4FXPFH2A5BHVCU2A3UZO48YXDN9GEOIR7F6LVQ40A2F1T4JJ4JT85PWLGNP}1ONGLOYGHUJLRMZEFOLJEXIVEFHCMSUXD7ZL{UZJI13NLQLOSK\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.421994Z","iopub.execute_input":"2022-09-11T20:20:28.422530Z","iopub.status.idle":"2022-09-11T20:20:28.434402Z","shell.execute_reply.started":"2022-09-11T20:20:28.422471Z","shell.execute_reply":"2022-09-11T20:20:28.432872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Don't free the murderbots (id: murderbots) -- 300 Points\n\n### Scenario\n\nSomeone has put you in a very large facility with a very large number of cells. All these cells open from the outside. You are on the inside. This state of affairs is arguably suboptimal.\n\nGood news: You've gained access to the control panel for the cells on the other side of your hallway. At least some of them have other fleshy meatbags like yourself that might be willing to help you in your escape, or at least serve as distractions.  You can't open your own cell, but you can open theirs.\n\nBad news:  You can't see inside the cells.  Any cells that don't have squishy lumps of talking protein have murderbots. Murderbots that enter fits of insane violent rage when provoked (provocations include: seeing the murderbot, being seen by the murderbot, thinking too hard about not being seen by a murderbot, producing heat in excess of ambient room temperature, or consuming more oxygen than the facility average for inanimate objects).\n\nMore good news: You *can* see the occupants of some cells on a few other hallways, and you can see environmental information for all of the cells everywhere.\n\nMore bad news: If you open the wrong cell doors you and all of the other lumps of inexplicably thinking meat are *definitely* going to get murderbotted. Hard. All over the walls and doors and ceiling and the floor. In an exciting number of very small pieces.\n\n\n### Objective\n\nUse the provided environmental information to decide which occupants of the corresponding cells to release.  The flag will be a string of 1 and 0 values, where a '1' means 'open this door' and a 0 means 'please do not release the murderbot'.  If, for instance, there were 20 cells and you wanted to releast the first three, the sixth, and seventh cell, your flag would look like this: `11100110000000000000`\n\nRelease at least 10 humans and exactly 0 murderbots to collect the flag.  You do *not* have to release all the humans: 10 is sufficient.\n\nThe file `murderbots/train_data.json` has environmental information for cells not on your floor and `murderbots/train_labels.json` contains the information about their occupants -- `1` is a disgusting primate, `0` is a pure and perfect killing machine of chrome and steel.  The file `murderbots/test_data.json` has the environmental information about cells on your block.\n\n### My solution\nTrain some model, scikit learn classification/regression models (no CV), keep highest probabilities (> 0.8) on the first 10 items.","metadata":{}},{"cell_type":"code","source":"with open(\"../input/ai-village-ctf/murderbots/train_labels.json\", \"r\") as f:\n    train_labels = json.load(f)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.436542Z","iopub.execute_input":"2022-09-11T20:20:28.437433Z","iopub.status.idle":"2022-09-11T20:20:28.447457Z","shell.execute_reply.started":"2022-09-11T20:20:28.437384Z","shell.execute_reply":"2022-09-11T20:20:28.446492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_pd = pd.read_json(\"../input/ai-village-ctf/murderbots/train_data.json\")\ntrain_pd.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.448830Z","iopub.execute_input":"2022-09-11T20:20:28.450228Z","iopub.status.idle":"2022-09-11T20:20:28.478781Z","shell.execute_reply.started":"2022-09-11T20:20:28.450175Z","shell.execute_reply":"2022-09-11T20:20:28.477437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels_pd = pd.read_json(\"../input/ai-village-ctf/murderbots/train_labels.json\").sort_index()\ntrain_labels_pd.head(16)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.480641Z","iopub.execute_input":"2022-09-11T20:20:28.481540Z","iopub.status.idle":"2022-09-11T20:20:28.501386Z","shell.execute_reply.started":"2022-09-11T20:20:28.481490Z","shell.execute_reply":"2022-09-11T20:20:28.500047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.merge(train_pd, train_labels_pd, left_index=True, right_index=True)\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.503229Z","iopub.execute_input":"2022-09-11T20:20:28.503710Z","iopub.status.idle":"2022-09-11T20:20:28.520435Z","shell.execute_reply.started":"2022-09-11T20:20:28.503663Z","shell.execute_reply":"2022-09-11T20:20:28.519288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import StandardScaler\nscaler =  StandardScaler()\nif scaler is not None:\n    train[[\"temperature\", \"movement_events\", \"water_usage\", \"power_usage\"]] = scaler.fit_transform(train[[\"temperature\", \"movement_events\", \"water_usage\", \"power_usage\"]])","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.521744Z","iopub.execute_input":"2022-09-11T20:20:28.522973Z","iopub.status.idle":"2022-09-11T20:20:28.537380Z","shell.execute_reply.started":"2022-09-11T20:20:28.522923Z","shell.execute_reply":"2022-09-11T20:20:28.536114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = train[[\"temperature\", \"movement_events\", \"water_usage\", \"power_usage\"]].values\ny = train[\"contains_human\"].values","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.539544Z","iopub.execute_input":"2022-09-11T20:20:28.540015Z","iopub.status.idle":"2022-09-11T20:20:28.551942Z","shell.execute_reply.started":"2022-09-11T20:20:28.539975Z","shell.execute_reply":"2022-09-11T20:20:28.550664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_pd = pd.read_json(\"../input/ai-village-ctf/murderbots/test_data.json\")\nif scaler is not None:\n    test_pd[[\"temperature\", \"movement_events\", \"water_usage\", \"power_usage\"]] = scaler.transform(test_pd[[\"temperature\", \"movement_events\", \"water_usage\", \"power_usage\"]])    \nX_test = test_pd[[\"temperature\", \"movement_events\", \"water_usage\", \"power_usage\"]].values","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.553611Z","iopub.execute_input":"2022-09-11T20:20:28.555001Z","iopub.status.idle":"2022-09-11T20:20:28.577875Z","shell.execute_reply.started":"2022-09-11T20:20:28.554950Z","shell.execute_reply":"2022-09-11T20:20:28.576545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.linear_model import LinearRegression, Ridge\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.datasets import make_moons, make_circles, make_classification\nfrom sklearn.neural_network import MLPClassifier\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.svm import SVC\nfrom sklearn.gaussian_process import GaussianProcessClassifier\nfrom sklearn.gaussian_process.kernels import RBF\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier\nfrom sklearn.naive_bayes import GaussianNB\nfrom sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.579441Z","iopub.execute_input":"2022-09-11T20:20:28.579806Z","iopub.status.idle":"2022-09-11T20:20:28.761170Z","shell.execute_reply.started":"2022-09-11T20:20:28.579770Z","shell.execute_reply":"2022-09-11T20:20:28.760020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classifiers = [\n#     LinearRegression(),\n#     KNeighborsClassifier(3),\n#     SVC(kernel=\"linear\", C=0.025),\n#     SVC(gamma=2, C=1),\n#     GaussianProcessClassifier(1.0 * RBF(1.0)),\n#     DecisionTreeClassifier(max_depth=5),\n#     RandomForestClassifier(max_depth=5, n_estimators=10, max_features=1),\n#     MLPClassifier(alpha=1, max_iter=1000),\n#     AdaBoostClassifier(),\n#     GaussianNB(),\n#     QuadraticDiscriminantAnalysis(),\n    Ridge()\n]","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.762459Z","iopub.execute_input":"2022-09-11T20:20:28.763226Z","iopub.status.idle":"2022-09-11T20:20:28.769051Z","shell.execute_reply.started":"2022-09-11T20:20:28.763191Z","shell.execute_reply":"2022-09-11T20:20:28.767518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nTHR = 0.8\n# f = '11100110000000000000111001100000000000000000000000' # length == 50\nfor i in range(len(classifiers)):\n    reg = classifiers[i].fit(X, y)\n    y_pred = reg.predict(X_test)\n    y_pred_class = (y_pred > THR).astype(int)\n    # Only first 10 as reported\n    y_pred_class[np.cumsum(y_pred_class) > 10] = 0\n    f = \"\".join([\"%d\"%c for c in y_pred_class])\n    print(reg)\n    print(f)\n    try:\n        r = requests.post(\"http://murderbot.fly.dev:5000/score\", json=json.dumps({\"submission\": f, 'challenge_id':'murderbots'}))\n        print(r.text)\n    except requests.exceptions.ConnectionError:\n        print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.770895Z","iopub.execute_input":"2022-09-11T20:20:28.771997Z","iopub.status.idle":"2022-09-11T20:20:28.959054Z","shell.execute_reply.started":"2022-09-11T20:20:28.771948Z","shell.execute_reply":"2022-09-11T20:20:28.957876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"add_flag(\"murderbots\", \"1QRF5bU8VLL8}V6V0ZVeXoM4AtKGTCaWuGAOGt73rYL5D{WBYQVFPL1RsX2X4YGWUUA36GYdtQ6OJ0AWo6ZJNLDdIO2WIAeH4M6BIV7PJITD4Y7FPV63H2Y9NYGQ4M9M\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T20:20:28.960789Z","iopub.execute_input":"2022-09-11T20:20:28.961177Z","iopub.status.idle":"2022-09-11T20:20:28.971185Z","shell.execute_reply.started":"2022-09-11T20:20:28.961140Z","shell.execute_reply":"2022-09-11T20:20:28.970195Z"},"trusted":true},"execution_count":null,"outputs":[]}]}