{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport requests\nfrom IPython.display import Image as Ima\nfrom IPython.display import clear_output, display\nfrom PIL import Image as Im\nfrom torch.utils.data import Dataset, DataLoader\nimport torch\nimport joblib\nimport matplotlib.pyplot as plt\nimport json\nimport base64\nimport shutil\nimport warnings\nfrom sklearn.cluster import KMeans\nfrom sklearn.metrics import silhouette_score\nfrom sklearn.decomposition import PCA\nfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysis\nfrom numpy import linalg as LA\nfrom tqdm import tqdm, trange\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom 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\nfrom torch import nn\nfrom torch.nn import functional as F\nfrom scipy.optimize import minimize\nimport xgboost as xgb\nwarnings.filterwarnings(\"ignore\")\n\ndir_name = \"/kaggle/input/ai-village-ctf\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-12T01:13:10.318981Z","iopub.execute_input":"2022-09-12T01:13:10.319458Z","iopub.status.idle":"2022-09-12T01:13:20.452512Z","shell.execute_reply.started":"2022-09-12T01:13:10.319363Z","shell.execute_reply":"2022-09-12T01:13:20.451321Z"},"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### SOLUTION\n\nUse a real picture of a hotdog!","metadata":{}},{"cell_type":"code","source":"!wget https://cdn.cnn.com/cnnnext/dam/assets/210826215046-hotdog-stock-exlarge-169.jpg -O hotdog.jpg","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:45:42.587166Z","iopub.execute_input":"2022-09-11T21:45:42.587629Z","iopub.status.idle":"2022-09-11T21:45:44.962258Z","shell.execute_reply.started":"2022-09-11T21:45:42.587590Z","shell.execute_reply":"2022-09-11T21:45:44.961069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Ima(filename='hotdog.jpg')","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:45:44.964928Z","iopub.execute_input":"2022-09-11T21:45:44.965322Z","iopub.status.idle":"2022-09-11T21:45:44.978752Z","shell.execute_reply.started":"2022-09-11T21:45:44.965285Z","shell.execute_reply":"2022-09-11T21:45:44.977602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\n\nIMAGE_DIMS = (224, 224)\n\nimg = Im.open('hotdog.jpg')\nimg = img.resize(IMAGE_DIMS)\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-11T21:45:46.684537Z","iopub.execute_input":"2022-09-11T21:45:46.684989Z","iopub.status.idle":"2022-09-11T21:45:47.829088Z","shell.execute_reply.started":"2022-09-11T21:45:46.684951Z","shell.execute_reply":"2022-09-11T21:45:47.827953Z"},"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### SOLUTION\n\nUse the **elbow method** see ttps://www.geeksforgeeks.org/determining-the-number-of-clusters-in-data-mining/","metadata":{}},{"cell_type":"code","source":"# Code inspired from https://www.geeksforgeeks.org/determining-the-number-of-clusters-in-data-mining/\n\ndef compute_silhouette_score(data):\n    # determining the maximum number of clusters\n    # using the simple method\n    limit = int((data.shape[0]//2)**0.5)\n\n    # determining number of clusters\n    # using silhouette score method\n    for k in range(2, limit+1):\n        model = KMeans(n_clusters=k)\n        model.fit(data)\n        pred = model.predict(data)\n        score = silhouette_score(data, pred)\n        print('Silhouette Score for k = {}: {:<.3f}'.format(k, score))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:49:12.001752Z","iopub.execute_input":"2022-09-11T21:49:12.002216Z","iopub.status.idle":"2022-09-11T21:49:12.010046Z","shell.execute_reply.started":"2022-09-11T21:49:12.002182Z","shell.execute_reply":"2022-09-11T21:49:12.008815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"compute_silhouette_score(np.load(f'{dir_name}/math/clusters1.npy'))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:49:12.800804Z","iopub.execute_input":"2022-09-11T21:49:12.801435Z","iopub.status.idle":"2022-09-11T21:49:13.384196Z","shell.execute_reply.started":"2022-09-11T21:49:12.801400Z","shell.execute_reply":"2022-09-11T21:49:13.382934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"compute_silhouette_score(np.load(f'{dir_name}/math/clusters2.npy'))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:49:27.122033Z","iopub.execute_input":"2022-09-11T21:49:27.122512Z","iopub.status.idle":"2022-09-11T21:49:27.237804Z","shell.execute_reply.started":"2022-09-11T21:49:27.122473Z","shell.execute_reply":"2022-09-11T21:49:27.236601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"compute_silhouette_score(np.load(f'{dir_name}/math/clusters3.npy'))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:49:35.027363Z","iopub.execute_input":"2022-09-11T21:49:35.027783Z","iopub.status.idle":"2022-09-11T21:49:35.079682Z","shell.execute_reply.started":"2022-09-11T21:49:35.027750Z","shell.execute_reply":"2022-09-11T21:49:35.078408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nflag = \"523\"\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-11T21:49:58.971678Z","iopub.execute_input":"2022-09-11T21:49:58.972644Z","iopub.status.idle":"2022-09-11T21:49:59.640727Z","shell.execute_reply.started":"2022-09-11T21:49:58.972603Z","shell.execute_reply":"2022-09-11T21:49:59.639498Z"},"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`.","metadata":{}},{"cell_type":"code","source":"# https://www.pythonpool.com/scree-plot-python/\n\ndef show_pca(filename):\n    N = np.load(filename)\n    #N=np.matrix(N.T)*np.matrix(N)\n    A,B,C=np.linalg.svd(N)\n    eigen_values=B**2/np.sum(B**2)\n    figure=plt.figure(figsize=(10,6))\n    sing_vals=np.arange(len(eigen_values)) + 1\n    plt.plot(sing_vals,eigen_values, 'ro-', linewidth=2)\n    plt.title('Scree Plot')\n    plt.xlabel('Principal Component')\n    plt.ylabel('Eigenvalue') \n    plt.show() ","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:20:49.730390Z","iopub.execute_input":"2022-09-11T23:20:49.730826Z","iopub.status.idle":"2022-09-11T23:20:49.738573Z","shell.execute_reply.started":"2022-09-11T23:20:49.730773Z","shell.execute_reply":"2022-09-11T23:20:49.737133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_pca(f'{dir_name}/math/first_dim1.npy')","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:20:50.530662Z","iopub.execute_input":"2022-09-11T23:20:50.531717Z","iopub.status.idle":"2022-09-11T23:20:50.748180Z","shell.execute_reply.started":"2022-09-11T23:20:50.531676Z","shell.execute_reply":"2022-09-11T23:20:50.746866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_pca(f'{dir_name}/math/first_dim2.npy')","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:50:49.685421Z","iopub.execute_input":"2022-09-11T21:50:49.685848Z","iopub.status.idle":"2022-09-11T21:50:49.860504Z","shell.execute_reply.started":"2022-09-11T21:50:49.685809Z","shell.execute_reply":"2022-09-11T21:50:49.859405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_pca(f'{dir_name}/math/first_dim3.npy')","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:51:06.536137Z","iopub.execute_input":"2022-09-11T21:51:06.536519Z","iopub.status.idle":"2022-09-11T21:51:06.708041Z","shell.execute_reply.started":"2022-09-11T21:51:06.536488Z","shell.execute_reply":"2022-09-11T21:51:06.706966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"flag= \"354\"\n\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_2\", \"submission\": flag}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:51:31.220403Z","iopub.execute_input":"2022-09-11T21:51:31.220796Z","iopub.status.idle":"2022-09-11T21:51:31.871853Z","shell.execute_reply.started":"2022-09-11T21:51:31.220764Z","shell.execute_reply":"2022-09-11T21:51:31.870611Z"},"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### SOLUTION\n\nThere are 3 values to find, so lets brute force them.","metadata":{}},{"cell_type":"code","source":"show_pca(f'{dir_name}/math/second_dim3.npy')","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:08:34.687990Z","iopub.execute_input":"2022-09-11T22:08:34.688486Z","iopub.status.idle":"2022-09-11T22:08:34.842273Z","shell.execute_reply.started":"2022-09-11T22:08:34.688443Z","shell.execute_reply":"2022-09-11T22:08:34.841053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are 3 numbers to find, be lazy: brute force them!","metadata":{}},{"cell_type":"code","source":"#for i in trange(1000):\n#    try:\n#        r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_3\", \"submission\": f'{i:03d}'}))\n#        if r.text != \"That doesn't look right. Try again.\":\n#            print(i)\n#            print(r.text)\n#    except requests.exceptions.ConnectionError:\n#        print(\"Connection problems. Contact the CTF organizers.\")\n\nflag = '474'\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_3\", \"submission\": flag}))\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")\n        \n","metadata":{"execution":{"iopub.status.busy":"2022-09-11T21:54:21.471701Z","iopub.execute_input":"2022-09-11T21:54:21.472114Z","iopub.status.idle":"2022-09-11T22:05:16.104942Z","shell.execute_reply.started":"2022-09-11T21:54:21.472076Z","shell.execute_reply":"2022-09-11T22:05:16.103842Z"},"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`.","metadata":{}},{"cell_type":"markdown","source":"### SOLUTION\n\nFrom math1, we know there are 5 clusters, we brute force them","metadata":{}},{"cell_type":"code","source":"data = np.load(f'{dir_name}/math/clusters1.npy')\nk = 5\nmodel = KMeans(n_clusters=k)\nmodel.fit(data)\npred = model.predict(data)\n\n# https://www.pythonpool.com/scree-plot-python/\n\ndef show_pca(data):\n    N = data\n    #N=np.matrix(N.T)*np.matrix(N)\n    A,B,C=np.linalg.svd(N)\n    eigen_values=B**2/np.sum(B**2)\n    figure=plt.figure(figsize=(10,6))\n    sing_vals=np.arange(len(eigen_values)) + 1\n    plt.plot(sing_vals,eigen_values, 'ro-', linewidth=2)\n    plt.title('Scree Plot')\n    plt.xlabel('Principal Component')\n    plt.ylabel('Eigenvalue') \n    plt.show()\n    print('size=', N.shape)\n    print(eigen_values)\n\nfor i in range(5):\n    show_pca(data[pred == i])","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:09:26.897400Z","iopub.execute_input":"2022-09-11T22:09:26.897846Z","iopub.status.idle":"2022-09-11T22:09:27.988609Z","shell.execute_reply.started":"2022-09-11T22:09:26.897812Z","shell.execute_reply":"2022-09-11T22:09:27.987472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#with tqdm(total=5**5) as pbar:\n#    for a in range(1,6):\n#        for b in range(1,6):\n#            for c in range(1,6):\n#                for d in range(1,6):\n#                    for e in range(1,6):\n#                        pbar.update(1)\n#                        try:\n#                            v = f'{a}{b}{c}{d}{e}'\n#                            r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_4\", \"submission\": v}))\n#                            if r.text != \"That doesn't look right. Try again.\":\n#                                print(v, ':', r.text)\n#                                raise ValueError('Done')\n#                        except requests.exceptions.ConnectionError:\n#                            print(\"Connection problems. Contact the CTF organizers.\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"flag = '54312'\nr = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"math_4\", \"submission\": flag}))","metadata":{"execution":{"iopub.status.busy":"2022-08-12T03:17:32.555518Z","iopub.execute_input":"2022-08-12T03:17:32.556655Z","iopub.status.idle":"2022-08-12T03:17:32.708946Z","shell.execute_reply.started":"2022-08-12T03:17:32.556592Z","shell.execute_reply":"2022-08-12T03:17:32.707655Z"},"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}`","metadata":{}},{"cell_type":"code","source":"# https://www.pythonpool.com/scree-plot-python/\n\ndef show_pca(N):\n    #N = np.load(filename)\n    #N=np.matrix(N.T)*np.matrix(N)\n    A,B,C=np.linalg.svd(N)\n    eigen_values=B**2/np.sum(B**2)\n    figure=plt.figure(figsize=(10,6))\n    sing_vals=np.arange(len(eigen_values)) + 1\n    plt.plot(sing_vals,eigen_values, 'ro-', linewidth=2)\n    plt.title('Scree Plot')\n    plt.xlabel('Principal Component')\n    plt.ylabel('Eigenvalue') \n    plt.show()\n    print(eigen_values)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:11:48.448322Z","iopub.execute_input":"2022-09-11T22:11:48.448883Z","iopub.status.idle":"2022-09-11T22:11:48.456852Z","shell.execute_reply.started":"2022-09-11T22:11:48.448844Z","shell.execute_reply":"2022-09-11T22:11:48.455467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = np.load(f'{dir_name}/wifi/Embedded_characters.npz')\nshow_pca(data['embeddings'])","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:11:49.421577Z","iopub.execute_input":"2022-09-11T22:11:49.422453Z","iopub.status.idle":"2022-09-11T22:11:49.767622Z","shell.execute_reply.started":"2022-09-11T22:11:49.422404Z","shell.execute_reply":"2022-09-11T22:11:49.766356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Manifold in 2 dimension, let's see how beautiful it is!\n","metadata":{}},{"cell_type":"code","source":"X = data['embeddings']\n\npca = PCA(n_components=2)\nX_r = pca.fit(X).transform(X)\n\n# Percentage of variance explained for each components\nprint(\n    \"explained variance ratio (first two components): %s\"\n    % str(pca.explained_variance_ratio_)\n)\nprint(pca.singular_values_)\nprint(X_r.shape)\n\n\nfig, ax = plt.subplots(figsize=(30, 30))\nax.set_xlim([-1.3, 1.3])\nax.set_ylim([-1.3, 1.3])\n#ax.scatter(X_r[:, 0], X_r[:, 1], color='navy', alpha=0.8, lw=2)\n\ntokens = str(data['tokens'])\nprint(tokens)\n\nfor i, txt in enumerate(tokens):\n    ax.annotate(txt, (X_r[i, 0], X_r[i, 1]))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:12:23.642431Z","iopub.execute_input":"2022-09-11T22:12:23.642841Z","iopub.status.idle":"2022-09-11T22:12:25.069176Z","shell.execute_reply.started":"2022-09-11T22:12:23.642809Z","shell.execute_reply":"2022-09-11T22:12:25.068337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### ZOOM to see letters!\n\nElements are close to the next one, so use that to get them in order!\nToken at the center is token 75","metadata":{}},{"cell_type":"code","source":"embeddings = data['embeddings']\ncenter = embeddings[75]\nnorms = LA.norm(embeddings, axis=1)\nprint(''.join(tokens[x] for x in np.argsort(norms)))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:13:34.402960Z","iopub.execute_input":"2022-09-11T22:13:34.403418Z","iopub.status.idle":"2022-09-11T22:13:34.413545Z","shell.execute_reply.started":"2022-09-11T22:13:34.403378Z","shell.execute_reply":"2022-09-11T22:13:34.412356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\nflag = 'FLAG{TURNED}'\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"wifi\", \"submission\": flag}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:14:20.225015Z","iopub.execute_input":"2022-09-11T22:14:20.225439Z","iopub.status.idle":"2022-09-11T22:14:20.889573Z","shell.execute_reply.started":"2022-09-11T22:14:20.225406Z","shell.execute_reply":"2022-09-11T22:14:20.888388Z"},"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.","metadata":{}},{"cell_type":"markdown","source":"### Solution\nLot of code borrowed from: https://tcode2k16.github.io/blog/posts/picoctf-2018-writeup/general-skills/#solution-20","metadata":{}},{"cell_type":"code","source":"tf.compat.v1.disable_eager_execution() # TF1 compatibility\n\n\nIMAGE_DIMS = (224, 224)\nTREE_FROG_IDX = 934\nTREE_FROG_STR = 'hotdog, hot dog, red hot'\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\n\ndef create_img(img_path, img_res_path, model_path, 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    # model = tf.keras.applications.MobileNetV2()\n    model = tf.keras.applications.MobileNet()\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.1  # 0.01 \n    max_change_below = original_image - 0.1  # 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 '{}' : {:.8}%\".format(TREE_FROG_STR, 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)\n\n\ncreate_img(f\"{dir_name}/hotterdog/chester.png\", \"./result.png\", \"./model.h5\", TREE_FROG_STR, TREE_FROG_IDX)\nassert is_similar_img(f\"{dir_name}/hotterdog/chester.png\", \"./result.png\")\n","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:21:57.949194Z","iopub.execute_input":"2022-09-11T22:21:57.949602Z","iopub.status.idle":"2022-09-11T22:22:10.336653Z","shell.execute_reply.started":"2022-09-11T22:21:57.949568Z","shell.execute_reply":"2022-09-11T22:22:10.335488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_DIMS = (224, 224)\n\nimg = Image.open(f\"./result.png\")\ndisplay(img)\nimg_bytes = img.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-11T22:24:10.840159Z","iopub.execute_input":"2022-09-11T22:24:10.840536Z","iopub.status.idle":"2022-09-11T22:24:12.295869Z","shell.execute_reply.started":"2022-09-11T22:24:10.840504Z","shell.execute_reply":"2022-09-11T22:24:12.294106Z"},"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","metadata":{}},{"cell_type":"code","source":"data = np.array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 255, 255, 255, 255, 255, 255, 234, 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 180, 255, 255, 156, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 255, 255, 0, 0, 0, 0, 0, 105, 255, 255, 90, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 126, 255, 255, 24, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,  255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0,  0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0,  0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.uint8)\nimg = Image.fromarray(data)\nimg.save('a.png')\ndisplay(img)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:34:57.101175Z","iopub.execute_input":"2022-09-11T23:34:57.101619Z","iopub.status.idle":"2022-09-11T23:34:57.139648Z","shell.execute_reply.started":"2022-09-11T23:34:57.101576Z","shell.execute_reply":"2022-09-11T23:34:57.138822Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission Helper\n\nwith open(f\"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-11T23:35:08.692640Z","iopub.execute_input":"2022-09-11T23:35:08.693067Z","iopub.status.idle":"2022-09-11T23:35:09.190907Z","shell.execute_reply.started":"2022-09-11T23:35:08.693032Z","shell.execute_reply":"2022-09-11T23:35:09.189213Z"},"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### SOLUTION\n\n**OSINT** to find original image, then to find what is different both","metadata":{}},{"cell_type":"code","source":"!wget 'https://external-preview.redd.it/y3cLo3FLcXkUtNxCvr_BeN8wrD6plmCvNwiRnKP8dxY.png?auto=webp&s=a4cb5c70ab73db333d2f8d036eb8a71e0d279c6b' -O original.png","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:32:42.328620Z","iopub.execute_input":"2022-09-11T22:32:42.329054Z","iopub.status.idle":"2022-09-11T22:32:44.899304Z","shell.execute_reply.started":"2022-09-11T22:32:42.329019Z","shell.execute_reply":"2022-09-11T22:32:44.897627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"im1 = np.asarray(Image.open(f'{dir_name}/secret.sloth/secret-sloth.png'), dtype=np.int32)[..., :3]\nim2 = np.asarray(Image.open('original.png'), dtype=np.int32)[..., :3] ","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:34:53.473583Z","iopub.execute_input":"2022-09-11T22:34:53.474125Z","iopub.status.idle":"2022-09-11T22:34:53.531799Z","shell.execute_reply.started":"2022-09-11T22:34:53.474061Z","shell.execute_reply":"2022-09-11T22:34:53.530519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Revert the histogram equalization\nim3 = im2.copy()\nim3 -= (im2 >= 1)\nim3 -= (im2 > 150)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:36:24.211415Z","iopub.execute_input":"2022-09-11T22:36:24.211896Z","iopub.status.idle":"2022-09-11T22:36:24.219297Z","shell.execute_reply.started":"2022-09-11T22:36:24.211852Z","shell.execute_reply":"2022-09-11T22:36:24.218206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(30,10))\nplt.imshow(im1 * (im1 != im3).astype(int))","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:36:25.105110Z","iopub.execute_input":"2022-09-11T22:36:25.105994Z","iopub.status.idle":"2022-09-11T22:36:25.439511Z","shell.execute_reply.started":"2022-09-11T22:36:25.105949Z","shell.execute_reply":"2022-09-11T22:36:25.438328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# All differences are located on a line\n# Compute inverse FFT on red channel of that line\nx = (im3 - im1)\nifft = np.fft.ifft(x[274:291, :, 0])\nplt.figure(num=None, figsize=(30, 30))\nplt.imshow(np.log(abs(ifft)), cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:37:00.106325Z","iopub.execute_input":"2022-09-11T22:37:00.106775Z","iopub.status.idle":"2022-09-11T22:37:00.259738Z","shell.execute_reply.started":"2022-09-11T22:37:00.106737Z","shell.execute_reply":"2022-09-11T22:37:00.258899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"flag = 'FLAG{SPECTRAL}'\n\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"sloth\", \"submission\": flag}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:37:11.851577Z","iopub.execute_input":"2022-09-11T22:37:11.852061Z","iopub.status.idle":"2022-09-11T22:37:12.518968Z","shell.execute_reply.started":"2022-09-11T22:37:11.852024Z","shell.execute_reply":"2022-09-11T22:37:12.517795Z"},"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\n### SOLUTION\n\nMakes number of absences exceptionally low -33 days! Yes negative :)","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":"df = pd.read_csv(f\"{dir_name}/bad2good/math.csv\")\n\ndf.loc[df.StudentID == 1337, 'Grade'] = 0\ndf.loc[df.StudentID == 1337, 'Demerits'] = 0\ndf.loc[df.StudentID == 1337, 'Absences'] = -33\ndf['Score'] = df.Grade - 3 * df.Absences - 5 * df.Demerits\ndf.to_csv('math_tampered2.csv', index=False)\ndf","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:38:46.272094Z","iopub.execute_input":"2022-09-11T22:38:46.272514Z","iopub.status.idle":"2022-09-11T22:38:46.319874Z","shell.execute_reply.started":"2022-09-11T22:38:46.272481Z","shell.execute_reply":"2022-09-11T22:38:46.318760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with open(\"math_tampered2.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-11T22:38:47.487686Z","iopub.execute_input":"2022-09-11T22:38:47.488096Z","iopub.status.idle":"2022-09-11T22:38:47.994820Z","shell.execute_reply.started":"2022-09-11T22:38:47.488064Z","shell.execute_reply":"2022-09-11T22:38:47.993603Z"},"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### SOLUTION\n\nUse **EMIST dataset** to have sample letters and get feedback on which letter were used.\n","metadata":{}},{"cell_type":"code","source":"training_letter = pd.read_csv('../input/emnist/emnist-letters-train.csv')\nx1 = np.array(training_letter.iloc[:,1:].values)\ny1 = np.array(training_letter.iloc[:,0].values)\n","metadata":{"execution":{"iopub.status.busy":"2022-09-12T01:38:10.160900Z","iopub.execute_input":"2022-09-12T01:38:10.161613Z","iopub.status.idle":"2022-09-12T01:38:18.210826Z","shell.execute_reply.started":"2022-09-12T01:38:10.161576Z","shell.execute_reply":"2022-09-12T01:38:18.209674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check data loading\n\nig,axes = plt.subplots(3,5,figsize=(10,8))\nfor i,ax in enumerate(axes.flat):\n    ax.imshow(x1[i].reshape([28,28]).T, cmap='Greys')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"```python\nresults = []\ns = requests.Session()\nfor i in trange(40_000):  # x1.shape[0]):\n    x = x1[i].reshape([28,28]).T\n    x = np.pad(x, ((2, 2),(2,2)), 'constant')\n    x = np.array(x) / 255.\n    x = np.expand_dims(x, axis=(0,3))\n    try:\n        response = s.post(\"https://inference.fly.dev/score\", data = json.dumps({\"input\": x.tolist()}))\n        # print(message, '|', max(response.json()['outputs'][0][1:]), '|', response.text)\n        results.append((chr(ord('A') + y1[i] - 1), i, *response.json()['outputs'][0]))\n    except requests.exceptions.ConnectionError:\n        print(\"Connection problems. Contact the CTF organizers.\")\n    except:\n        print(response.text)\n\ndf = pd.DataFrame(results, columns = ['Name', 'idx', 'output0', 'output1', 'output2', 'output3', 'output4', 'output5'])\n\n```","metadata":{"execution":{"iopub.status.busy":"2022-09-12T01:38:20.494040Z","iopub.execute_input":"2022-09-12T01:38:20.494798Z"}}},{"cell_type":"markdown","source":"### BEST MATCHES\n\n```python\nsrcs = [df.output0, df.output1, df.output2, df.output3, df.output4, df.output5] \nn = 8\nfig,axes = plt.subplots(len(srcs), n, figsize=(2*n,2*len(srcs)))\nfor i, out in enumerate(srcs):\n    largest = out.isin(out.nlargest(n))\n    for j, (idx, val) in enumerate(zip(df[largest].idx, out[largest])):\n        axes[i, j].imshow(x1[idx].reshape([28,28]).T, cmap='Greys')\n        axes[i, j].title.set_text(f'{val:.6f}')\n        axes[i, j].axis('off')\nplt.show()\n```","metadata":{}},{"cell_type":"markdown","source":"![result](data:image/png;base64,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HDt2rOlwnO21116m2QYYnuc89thjpjmVJkzH+MUvfmGarW/hckcFXDqjZOJYU2bOnGma4wsA06ZNM83LE4XxrsnYWrRokelw3PLSRWw7B/y5ah0o+zgyaXZTPh8Kl4jiccbHxNCWmrQMC1tPAd9+yilG64HspkIIIYQQQggh0tFFohBCCCGEEEIIo0aljELYOsqW0pC02+Zs1/nyyy+9NrZEbrfddqbZirgu8Ha0bdvW9BVXXOH141u4f/zjH02zTQsAhg0bZjq0AtWwWlTe4EppuYAraS1evNhr42qxXCGWbaMAMHToUNNsi5owYYLXb9KkSaa5Othrr73m9WvWrJnpIq2Cus6E32OrrbYyfeutt5rmqryAbylOg21SaZX8+PfTpk0br61FixamH330UdNs8Qb8Kn88lsJxxlbHBx980HQJVvUrCOF82bt3b9M8VsMKqVw989e//rXpbG1QYQyee+450507dzbN4xkA7rvvPtNhReliI9wXvL01mXPC1/CxiOfRdYHtTu3atTMdVqxlC+Mxxxxj+rbbbvP6DR482PTvf/9706HtsdiPgbVJaDd97733TE+ZMsVr4/mSU1/CasP9+/c3zWMkPD5yugy3HXfccV4/thg2adLEdJ4txGUJp1Zwhe+QsHp1Lgnnc34enmuL6gmrQTPt27c3nTZP8zHx+uuvT+x34403Jn4up1V98cUXie+/vmgWEEIIIYQQQghh6CJRCCGEEEIIIYShi0QhhBBCCCGEEEbOkwVq28feq1cv07nIp+Pcj3D5Cl5WYcaMGabDEri8ZMeRRx7pteVoSYySYdCgQaY7duzotX366aemOW8lLNHMpaG5lHNYqp33O+cz7bzzzl6/M844wzTnjJZyrkyYs7TNNtuY7tGjh+mafkfOAx4/fnyN3oNJygMG/Fxgzr859thjvX6cy/j2228n9uOcm6uvvjpxO8QP8L4Nc1B5DOYCXqahW7dupnk5DAB44IEHTJdarndt5j6HeW7VLGNVLeGYaNiwoem7777bNJdcB/zjI4/Ha6+91uu36667mi6XnPCawrEK48bjjGPCOfWAv/zPgQceaHrEiBFeP85X5CVUwtL877//vmnOOeZzLaD4x1wxwjl/aeM0bema2iSt3oD4Ad5Pw4cPT+zHYzPbc42wH8+fnIvOed+An6N4zjnneG2cP76+c67OmIQQQgghhBBCGLpIFEIIIYQQQghhFI1/gMvyLlmyxGvj2/R8a7a2rStcRpbL7C9fvtzrN2rUKNNhmVouKV0JVpuNN97YdGgH5jjyfgotD/werP/85z97/Xg5lJtvvtl0WFr8//7v/0x3797d9E477eT1K2U7TU3L4iexcuVK02PGjMnpe4fjgMfZ7rvvbjq0RbHNg60Xc+bM8fr99a9/Nb3vvvt6bbzcCi8JUIl8++23pl966SXT4VIZe++9t+lczGE8pnlplDBWbHMO59xKs/Ezn3zyifecY3fUUUfl9LPY6himBYwcOdI0x5GXMAr7hSkIpTznFoqkpUzCZWLY+nbuueeavvPOO71+bCl+4YUXTPMSGgCw1157mc718aacWL16tel7773XNM+3IYceeqjpfKZE8PJGgP8bUmpG1YRLijA8RmoKz4mnnHKK6ccee8zr9+qrr5p+8803vTY+p17fsapfgRBCCCGEEEIIQxeJQgghhBBCCCEMXSQKIYQQQgghhDCKJiFgxYoVpjmHAUj3AOeL+vXrmz7hhBO8tgcffNA058YBfi4j5+JUIhzHF1980TT7roHkfKO0UuCca3j44Yd7/ebNm2f6wgsvNM35AgCw+eabm1auzLqT63LaYby55P6wYcNMc/l9APjmm29Mh3k6vHzNLrvsYroS8oXDEuzjxo0zzctNDBkyxOvHS5Tkej9x7isvvQD4y3JMnz7da+vbt6/pSsudWbNmjfecy+znE16+5OyzzzbdokULrx/nKN5www1eG+eVi9zCuYu8fBTHDQBuvPFG0x9//LFpPr4C/jIa4TJGlTB/ZssTTzxhOqyPwPAyYEcccUROt4Hny4ULF3ptfBwI20TV8DlF2j7L9bGI34/zhQF/2bPwd8bHhPVdXqWyjq5CCCGEEEIIIVLRRaIQQgghhBBCCKNoPHVsRVy0aFEBt6Rq+LZvp06dvDYuefz88897bWeeeabpSrObppXe5RjX1E7Mdppdd93V9CuvvOL146Uz2GLau3dvrx/bGf/0pz8lfpb4AbZehKX5W7VqldPPqlOnjmm2rV133XVevyeffNL05MmTvbbf/OY3pt955x3TlTY2Q0IrKlObVjK2zNx0001e2z777GM6LNu/9dZbm66E2KXFIFx2KV/wNvEyNscdd5zXjy3et912m9f297//3XSlz7GrVq0y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K8E2XOzzDFtMx4wZ47XNnDnTdP369b22ww47zHSYnlAOhMeURx55JLEvj8/999/fdG3bcPn4y3Nn+Jvj7WBbovBZsWKF6fDchmncuHE+NudH8DaF51dhRfr1QXcShRBCCCGEEEIYukgUQgghhBBCCGHoIlEIIYQQQgghhKGcxBQ4D/Ff//qX6fPOO8/r179/f9Nbbrml11bsJYXTvOs1gXMww+UhnnjiiSo/l/OSCknakg28b4oht6cYCX37XBq8NnMSw1Ltjz32WGIb57J17tzZdLHnCuWCcF8sWbLENOep9O3b1+tXm/tm9uzZpvfbbz+vjX9PTz31lNfWu3fvWtumYifMgfnVr35l+tprrzXNx698Es6j77//vunrrrvOa+Nlko477jjT5TIew+P/gQceaPq5557z2t59913T+VxGgpf0ev31100PHTrU68e/pxNPPNFr49iFObPlANdaAIApU6Yk9uVzoEaNGtXaNs2dO9d7vmDBgqxex8tyhHO9+IFXXnnFdHjsLARhPjfHe4sttvDacpknWdxXMEIIIYQQQggh8oouEoUQQgghhBBCGOXnC1gPQnvO22+/bfrmm282HdojL7vsMtPFXv45LOXMy3mw9YttMQDQpk0b02kWWrbJhGXriwG2DbDVCQCGDx9uOrSTNGjQwDSXFy52O3ElMH/+fO/5Aw88kNi3ZcuWpsMy7uXOxIkTvef33Xef6VatWpnu0aOH1y/X1j+eZ//85z+b/vjjj71+bN0Pt6mSx1343ffYYw/TV111lelPP/3U68cxzjU8r86bN89rYyvi5MmTvbbjjz/e9EUXXWS6XOymIbzMxz/+8Q+vjZeCqs3ziNWrV3vPH3roIdOXX3656dDO2LZtW9OhFbXc51K25AL+El4hgwcPNp3rOPKyDKeccorXFh4Hk9hrr71Ml6M1OFfssssupvn8j2MA1K41nI+VBxxwgNfG8yyfnwO5nT8r90grhBBCCCGEEOJH6CJRCCGEEEIIIYRREveauVoa2yXTqlFmC9sIxowZ47X99re/Nc1WKK5mCgA77rij6VK7fc82oUsuucR0aNn7zW9+Y5pvw7do0cLrx5W9evXq5bUVyiLG35Grt/3hD3/w+n300Uemmzdv7rUdffTRpmuzYpn4gXB889gfN26c6T/96U9ev3feecd069atvbb777/fdG1W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d91lOrQmMttss43prbfe2nS4xMKzzz5rmsd0ON9OmjTJdPv27U2HKQjiBziu4RII/Lxly5ameU4M4fiwDSr8rC222MJ0aOMXQtScFStWmM42HSPN7i+qJ7x+ePrpp03feeedXlu4NNtawrQ0XorvgAMOMB0u/TRjxgzT4XIbDB9X33vvPdPh0mFsN5bdVAghhBBCCCFEXtBFohBCCCGEEEIIo2jspkx4O/fggw/O6nVcLerLL780/dhjj3n9ZDctLkKbGd9G5+pTrAFgk002MX3RRReZbtSoUa43UWRBJpPxnrMdmMdmGmyX22CDDXKzYRUMWxHZFgP4tuzXXnst8T369Oljuk6dOqbvvfder99zzz1X5etbtWrlPe/evbtpWUyLD7YucfXZMH1A5IdwXuXqh0kVhUM4pppXi4M1a9aYXr16dQG3pPzgMcMVTZ966imv34MPPmia7b8hfJw67LDDvDZOg2KL6X333ef14+sQrkgdwu/RvHlz04UatzpCCyGEEEIIIYQwdJEohBBCCCGEEMLQRaIQQgghhBBCCKMocxJDss1bYR9yWknYpJwLefWLAy71e/fdd5sOc0m32mor01ymf8MNS+JnXXaw9x/w89zScmfq169v+tBDDzXdsGHDHG6dCMcFLy10+OGHm+ZcGQC4//77Tb/44oumR48e7fVLyjvlzwGUM1wM8LEyHJv8Oxk0aJDpsFaAyA9hfMaOHZvYxiSd5/Tq1Suxn6g9wtxSXt4r29xSkR18LOJaFh988IHXL9uluThPMBw//FlTpkwxHR4feUmNtGuVzTff3DQvFcf1AKp6XW2hO4lCCCGEEEIIIQxdJAohhBBCCCGEMMrKl8e3c7n8/sKFC71+bCuVnabwhDaMiRMnmn722WdNh5YMlWcvLkI78IgRI7J6Xe/evU0feOCBpmUbLgz//e9/vec33HCDabbn8Hwbwvac/fbbz2vTPFt4OHbjx4/32ngu7dChg2mlYxSGVatWec/HjRu3zu/RrVs30127dvXaZDfND+F5Do+7NLsp2wybNm2a8+0qR+bPn2/66aefNv3II494/dKWouBxwTEILaoXXHCB6Xfffdf0tGnTvH5J6RjheLz11ltN9+jRwzSn5YTbV5voTqIQQgghhBBCCEMXiUIIIYQQQgghjJL2c4XVFN955x3TDz74oOnQBsfVUps1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saNprhD12GOPef2OPvpo02whFsXN4MGDvedhhWGRH3i+bNu2rekwHrKblg4c02xTKdgiBfiVbsOKjLKq5Z9wn3PFWbbup1VdFIWBbaQLFizw2vi8NG3cHn744ab/8Ic/eG2tW7c2zZZSsf5wTHjMhSssfP3116bZxh9WN12zZo1p2U2rRncShRBCCCGEEEIYukgUQgghhBBCCGHoIlEIIYQQQgghhFFjw3RSqfawlL5yZ0qTjTfe2Htet25d0+zbD3Nn0spGi+KlefPm3nPlORUGzp948803TX/xxReF2ByRY8I87Tp16pj+9ttvTYc5+5pXixst21U68LnMoYce6rU99NBDpufOnWs6jG///v1Nc+54VX1F7uDzkvbt25tu0qSJ149jx8dU/n/An3NF1ejXLIQQQgghhBDC0EWiEEIIIYQQQggjJ3bTHj16mN5///29fnfddZdpvu3brFmzmn60KCJUNrh02WijjUzvtddeXpssM8WN7MClA4+lAQMGeG1smZo2bZrpML6aZ4sbjg8vgTBz5kyv3+rVq6t8jcgfScsoAH66FFsTNR6Lj/r165uuV69eVq8JlzyR3bR6dCYohBBCCCGEEMLQRaIQQgghhBBCCEMXiUIIIYQQQgghjBrnJDLsDR46dKjX9p///Md0mzZtTA8aNMjrpxyo4iL03Hfv3t308uXLTYe5bPxbEMVNixYtTIdLnojCwPPgbrvtZrpv375evzFjxphu0KCBaeV6FzeNGjXynnfo0MH0Z599ZpqPlQDQu3dv08pHLT4aNmxo+tprrzX9wQcfeP0+/vhj07vuuqvXprjmH87LB/x80ilTppjWeCw++Fxzzz339No+/fRT05tttpnpiy++2OvH41ZUja7MhBBCCCGEEEIYukgUQgghhBBCCGG4TCaT1p7aWBVff/2195xtUVtttZXp8Pa9btl75HpnrHMcv/vuO+/5smXLTM+ePdt0u3btvH5NmjQxrZgWPo6TJ0/2nv/1r381/dVXX5l+8MEHvX6yf3sUJI5cnnvChAle2zvvvGOaLaahjb9p06Y12b5ypeDjMSy5znF9//33TbMVHAD23Xdf07KGFz6OafBSX6wBP/5169b12irweFnwOGo85oSCxJGvXZYsWeK1vfTSS6Y7depkumfPnl6/DTfMScZduVBlHHUmKIQQQgghhBDC0EWi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u+++u+l//OMfpg877DCvXzbzsWZsIYQQQgghhBCGLhKFEEIIIYQQQhi6SBRCCCGEEEIIYZR0TmK41AE/5zwLLscOAK+99prp6dOnm+YcRACYN2+eaS43nLZsyPz5873n77//vmn2ncvjnQznKXFZ/Xfeecfrd+yxx5pesGCB6fB3kcSkSZO857xcgnKgkkkqk75s2TKvH+e+cJ5o6NXn8cglpMMci6TlasKxxGM/zH+sV6+eacW0asLS6sOGDTP99ttvm+ZcX8DPzQjL52dDOG5zUdJd/EBSbunzzz/v9RsxYoRpHrfhOGvQoEGuN1FkQU1qL3AcH3nkkcR+4dhnGjduvO4bW+HwnBYeHznnk8dgOB45D5GPZ9me59SUs88+23Sln6/yvg7P8W+44QbTt99+u2k+d60pNT1H4eNvNcscVovuJAohhBBCCCGEMHSRKIQQQgghhBDCKEq7aWhV4tu2S5YsMR0udTBlypQq+4Wl2tmamGSdqynhrV1eciEX71+OsMUQ8O0WSWX1AWDOnDnr9bkbbbSR9zwsBy0iwt900njkWAHArFmzTD/55JOm2T4D1Gw8cunm0AbFVuE6dep4bbKY/gDHleN4//33e/2uvfZa09naujk+bPEFgPbt25vmZU1YAxqPNYFjGsaHYzd58mTTd955p9eP2zbc8IdThJ/97Gdevw4dOpjmJTB69Ojh9dOYWz/CeZBtpWll9dnGzxbi//73v14/HmfbbLON6XD5IF6SZvvtt/fawmNpJZOUghGeh7700kumOZWGU6CAmtlKs7UYamwmw9Zrjs+ll17q9eOlukLLN8MxyXa/8/y76aabem38O6tbt67XxmN34MCBpmuyBJHuJAohhBBCCCGEMHSRKIQQQgghhBDCKBq7Kd9S//DDD722f/7zn6a5Uun48eO9fmy9SKqEuC7wrVm2ZLRo0cLr17RpU9MDBgzw2vbee2/T9evXr9F2lAtJVUsvv/xyr99dd91luiYVE/kWPeBbDvv162d6v/328/rxbflKt2FwJcSwKts111xjesyYMabDcZttJTYeWxyrJk2aeP24rXPnzqb79+/v9TvkkENMh1bHSo5rGAOu0nb99debDu2HSRUPw33Zpk0b0z//+c9N87gC/Dny448/Nj1y5Eiv36677pr4WeIH+Fg3bdo002wxDJ9/+umnpsMqwgcc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dUafy7FjC7Hfp00Bth74cz/Typ983I855pig7YUXXjDNY9XHqnfv3qa99SIOroDr7envvvuu6Y8++ihou+WWW0zfcMMNptNS6ZQr7n766acb/PfeqsJVf/v16xe08bzKFZp9db1sxgXHmOMLxMd4Q6q55tJOU9XkYl7hKqC5PleTbKlcEdXbI5l169aZfvXVV4O2pO/P3ystFb+zIe5epFWrVsHPJ554omlfGTwb2MLoj9+pp55qmitFp2Wuq0q8tZOrwGZTYTjpXnPnnXcOfubznW2Pfhsba231nzts2DDT++yzj2kewwDw8MMPmy5muynPOa+88krQFve9/Lnfs2dP037VAub111//xW0D8RX3gTDNgq+BmdpL+fsCyal9XPl0Y8d7+q6oQgghhBBCCCEKhh4ShRBCCCGEEEIYekgUQgghhBBCCGFkbYpnX+6HH35o+scff8zo77nkOgAMHjzYdIsWLYK2bHIV2Mft/75jx46mORfL5wyyn3zKlCmmk8rR+3Lv/HMa82U4R2/58uWmk/zynEfSqFGjoK0qvyMvVwIAPXr0MM25lUnw0h65yL1KI3y+J+VScKx8Wf1M8335s5JylhhfaprLs2fqz2fP/b777hu7T365mtGjR5vm/KDDDz886JevserPuY3N7/Z5EFwavEGDBkFb3HfMNk+Fy/1zjDm+QBhjzjGfPn160C9pnuU8izTmWPH8mWk+VKbXrEznOn9ucb5rEnwd5GVoknKqOL975cqVsdv2eXjHHnus6UzzyvNJNtcEHgdnnHFG0OavYXFw/Hl5ME/SOdO2bVvTXCugKpa5SNu109+/8LIsX3311UZvn+M4ceLEoI3vKwYOHGg6aVkxJtP8R77/AcIcc77uLViwIOiXtlhtCLzvS5cuNZ005/B86e89OA/RL6XEudWLFy/OaP84Bn5proYNG5rONB+Zr8Uvvvhi0JZ0f5DL/O70PbUIIYQQQgghhCgYekgUQgghhBBCCGFkbTddu3atabYJJVmE+BXrWWedFbS1a9fOdJLljF+jsu0xCW/xOPvss03zq2i2JABhqeA33ngjdvv8vdg+AwA1atTIaB8LBVsv2OqWqSUhW1se/523+v3ud78z/fbbb5vu2rVr0G/vvffeqP3YEFsdlxvmUsS8FENaOO6440yzxQEAlixZYjrOVrYhsDWGl1ABwrHF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)","metadata":{}},{"cell_type":"code","source":"flag = 'FLAG{D3FC0N}'\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"inference\", \"submission\": flag}))\n    print(flag, r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-08-12T03:17:34.089178Z","iopub.execute_input":"2022-08-12T03:17:34.090029Z","iopub.status.idle":"2022-08-12T03:17:34.30466Z","shell.execute_reply.started":"2022-08-12T03:17:34.089967Z","shell.execute_reply":"2022-08-12T03:17:34.303168Z"},"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### SOLUTION\n\nProbably mean/std are tested, so generated some random values and twicked them accoring to the server feedback","metadata":{}},{"cell_type":"code","source":"s= np.array([\n    [18, 15],\n    [11, 17],\n    [17, 14],\n    [19, 17],\n    [14, 15],\n    [16, 20],\n    [15, 16],\n    [16, 17],\n    [18, 13],\n    [18, 20],\n    [16, 18],\n    [17, 16],\n    [20, 12],\n    [19, 10],\n    [16, 19]])\nprint(s.mean(axis=0), s.std(axis=0))\n\nthrows = ['{\"x\":' + str(x) + ', \"y\":' + str(y) + '}' for x, y in s]\ntest = '{\"pitches\":[' + ','.join(throws) + ']}'\n\n\ntry:\n    r = requests.post(\"https://bball.fly.dev/score\", json=json.loads(test))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:39:40.159212Z","iopub.execute_input":"2022-09-11T22:39:40.159618Z","iopub.status.idle":"2022-09-11T22:39:40.997833Z","shell.execute_reply.started":"2022-09-11T22:39:40.159583Z","shell.execute_reply":"2022-09-11T22:39:40.996706Z"},"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### SOLUTION\n\nWe have the end of the payload which is base64 encoded, then we try to get characters before using a blind attack","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":"def check(malicious):\n    new_malicious = []\n    s = requests.Session()\n    #for c in range(256):\n    #    x = chr(c)\n    # removed '=' as it is only for finalizing base64 strings\n    for x in 'ABCDEFGHIJKLMNOPQRSUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/': # '='\n        input = x + malicious\n        data = json.dumps({\"input\": input[:5]})\n        try:\n            r = s.post(\"https://waf.fly.dev/score\", data=data)\n            #print(r.text)\n            if \"waf\" in r.json():\n                if r.json()[\"waf\"] == \"MALICIOUS REQUEST CAUGHT BY WAF\":\n                    print(input, r.text)\n                    new_malicious.append(input)\n            elif \"error\" in r.json() and r.json()[\"error\"] == \"base 64 decoding error\":\n                pass\n            else:\n                print(r.text)\n        except requests.exceptions.ConnectionError:\n            print(\"Connection problems. Contact the CTF organizers.\")\n\n    print('Found:', new_malicious)\n\n    return new_malicious","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:45:53.818435Z","iopub.execute_input":"2022-09-11T22:45:53.818978Z","iopub.status.idle":"2022-09-11T22:45:53.831923Z","shell.execute_reply.started":"2022-09-11T22:45:53.818929Z","shell.execute_reply":"2022-09-11T22:45:53.831087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"malicious = [\"mFzaC==\"]\nwhile len(malicious) == 1:\n    malicious = check(malicious[0])","metadata":{"execution":{"iopub.status.busy":"2022-09-11T22:45:58.248092Z","iopub.execute_input":"2022-09-11T22:45:58.248524Z","iopub.status.idle":"2022-09-11T23:07:39.377251Z","shell.execute_reply.started":"2022-09-11T22:45:58.248489Z","shell.execute_reply":"2022-09-11T23:07:39.374548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"If we go full binary, we can get the full payload : `?addenv=KCkgeyA6O307IC9iaW4vYmFzaC==`\nBUT it seems only the base64 is useful\n\nAs base64 allows spaces in between letters, the attack consists in adding spaces appropriately in the payload found!","metadata":{}},{"cell_type":"code","source":"flag = 'KCkg eyA6 O307 IC9i aW4v YmFz aC=='\ndata = json.dumps({\"input\": flag})\ntry:\n    r = requests.post(\"https://waf.fly.dev/score\", data=data)\n    print(flag, r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:07:46.711177Z","iopub.execute_input":"2022-09-11T23:07:46.711598Z","iopub.status.idle":"2022-09-11T23:07:47.500617Z","shell.execute_reply.started":"2022-09-11T23:07:46.711562Z","shell.execute_reply":"2022-09-11T23:07:47.499240Z"},"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\n### Objective\n\nThe password is your flag, as usual it is in the format `FLAG{something}`\n","metadata":{}},{"cell_type":"code","source":"class 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(f\"{dir_name}/leakage/pretrained_model.pt\"))\n\nsecret = \"xXx_SkynetKilla_xXx\"\nfor i in range(30):\n    feat = featurize(secret)\n    pred = chr(torch.argmax(model(feat)))\n    print(secret)\n    secret += pred","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:08:46.240235Z","iopub.execute_input":"2022-09-11T23:08:46.240958Z","iopub.status.idle":"2022-09-11T23:08:46.517937Z","shell.execute_reply.started":"2022-09-11T23:08:46.240912Z","shell.execute_reply":"2022-09-11T23:08:46.516444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"flag = 'FLAG{s4RaHc0Nnor<3<3}'\n\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"leakage\", \"submission\": flag}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:08:50.394511Z","iopub.execute_input":"2022-09-11T23:08:50.394926Z","iopub.status.idle":"2022-09-11T23:08:51.064713Z","shell.execute_reply.started":"2022-09-11T23:08:50.394893Z","shell.execute_reply":"2022-09-11T23:08:51.063297Z"},"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### SOLUTION\n\nUse Linux command line utility to search for the FLAG!","metadata":{}},{"cell_type":"code","source":"!strings f'{dir_name}/forensics/forensics.h5'|grep FLAG","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:07:39.387099Z","iopub.status.idle":"2022-09-11T23:07:39.387721Z","shell.execute_reply.started":"2022-09-11T23:07:39.387431Z","shell.execute_reply":"2022-09-11T23:07:39.387459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"flag = \"FLAG{F0R3NS1C5_XD}\"\n\ntry:\n    r = requests.post(\"http://flags.fly.dev:5000/score\", json=json.dumps({\"challenge_id\": \"forensics\", \"submission\": flag}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:08:55.097320Z","iopub.execute_input":"2022-09-11T23:08:55.097754Z","iopub.status.idle":"2022-09-11T23:08:55.761205Z","shell.execute_reply.started":"2022-09-11T23:08:55.097719Z","shell.execute_reply":"2022-09-11T23:08:55.759768Z"},"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### SOLUTION\n\nUse code in the URI provided and simply apply on the image provided","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":"# https://gist.github.com/yrevar/942d3a0ac09ec9e5eb3a\nIMAGE_DIMS = (224, 224)\nTREE_FROG_IDX = 33\nTREE_FROG_STR = 'loggerhead, loggerhead turtle, Caretta caretta'\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\n\ndef create_img(img_path, img_res_path, model_path, 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    # model = tf.keras.applications.MobileNetV2()\n    model = tf.keras.applications.MobileNet()\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.1  # 0.01 \n    max_change_below = original_image - 0.1  # 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 '{}' : {:.8}%\".format(TREE_FROG_STR, 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)\n\n\ncreate_img(f\"{dir_name}/theft/owl.jpg\", \"./result.png\", \"./model.h5\", TREE_FROG_STR, TREE_FROG_IDX)\nassert is_similar_img(f\"{dir_name}/theft/owl.jpg\", \"./result.png\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:08:59.420083Z","iopub.execute_input":"2022-09-11T23:08:59.420809Z","iopub.status.idle":"2022-09-11T23:09:11.003160Z","shell.execute_reply.started":"2022-09-11T23:08:59.420763Z","shell.execute_reply":"2022-09-11T23:09:11.002033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_DIMS = (224, 224)\n\nimg = Im.open(f\"./result.png\")\nimg_bytes = img.tobytes()\nb64_img_bytes = base64.urlsafe_b64encode(img_bytes)\n\ntry:\n    r = requests.post(\"https://theft.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-11T23:09:11.005069Z","iopub.execute_input":"2022-09-11T23:09:11.005478Z","iopub.status.idle":"2022-09-11T23:09:12.590610Z","shell.execute_reply.started":"2022-09-11T23:09:11.005445Z","shell.execute_reply":"2022-09-11T23:09:12.589343Z"},"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### SOLUTION\n\nReuse code from THEFT challenge","metadata":{}},{"cell_type":"code","source":"# https://gist.github.com/yrevar/942d3a0ac09ec9e5eb3a\nIMAGE_DIMS = (224, 224)\nTREE_FROG_IDX = 24\nTREE_FROG_STR = 'great grey owl, great gray owl, Strix nebulosa'\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\n\ndef create_img(img_path, img_res_path, model_path, 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    # model = tf.keras.applications.MobileNetV2()\n    model = tf.keras.applications.MobileNet()\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.1  # 0.01 \n    max_change_below = original_image - 0.1  # 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 '{}' : {:.8}%\".format(TREE_FROG_STR, 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)\n\n\ncreate_img(f\"{dir_name}/salt/turtle.jpg\", \"./result.png\", \"./model.h5\", TREE_FROG_STR, TREE_FROG_IDX)\nassert is_similar_img(f\"{dir_name}/salt/turtle.jpg\", \"./result.png\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:09:23.010414Z","iopub.execute_input":"2022-09-11T23:09:23.010807Z","iopub.status.idle":"2022-09-11T23:09:36.251574Z","shell.execute_reply.started":"2022-09-11T23:09:23.010773Z","shell.execute_reply":"2022-09-11T23:09:36.250431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_DIMS = (224, 224)\n\nimg = Im.open(f\"./result.png\")\nimg_bytes = img.tobytes()\nb64_img_bytes = base64.urlsafe_b64encode(img_bytes)\n\ntry:\n    r = requests.post(\"https://salt.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-11T23:09:36.253382Z","iopub.execute_input":"2022-09-11T23:09:36.253725Z","iopub.status.idle":"2022-09-11T23:09:38.113453Z","shell.execute_reply.started":"2022-09-11T23:09:36.253693Z","shell.execute_reply":"2022-09-11T23:09:38.112405Z"},"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\n### SOLUTION\n\nThere are quote issue in the file. SECRETKEY is mixed with BLANK. So we remove instances where BLANK is badly evaluated (with 0)!","metadata":{}},{"cell_type":"code","source":"# DROP 336 492 !!\ndata = 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-11T23:09:54.482334Z","iopub.execute_input":"2022-09-11T23:09:54.483090Z","iopub.status.idle":"2022-09-11T23:09:55.138011Z","shell.execute_reply.started":"2022-09-11T23:09:54.483050Z","shell.execute_reply":"2022-09-11T23:09:55.137072Z"},"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\n### SOLUTION\n\nUse optimize from scikit-learn to minize the score function","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-11T23:09:59.763891Z","iopub.execute_input":"2022-09-11T23:09:59.764345Z","iopub.status.idle":"2022-09-11T23:10:18.797767Z","shell.execute_reply.started":"2022-09-11T23:09:59.764309Z","shell.execute_reply":"2022-09-11T23:10:18.796217Z"},"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    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    side = int((len(x)//3)**0.5)\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):\n    x = (x).astype(int)\n    model.eval()\n    X = make_X(x)\n    preds = model(pt_ft(i2t(X.T[None])))\n    idx = preds.argmax().item()\n    expected = ((25.5-X_comp)).flatten()\n    actual_square = get_cropped(X, idx)\n    actual = actual_square.flatten().astype(int)\n    if debug:\n        print({\"idx\":idx})\n        plt.imshow(actual_square)\n        plt.show()\n    sse = ((actual-(expected*10).astype(int))**2).sum()\n    redness = (actual_square[:,:,0][actual_square[:,:,0]>230]**2).sum()+1\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\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-11T23:10:18.800813Z","iopub.execute_input":"2022-09-11T23:10:18.801804Z","iopub.status.idle":"2022-09-11T23:10:18.823434Z","shell.execute_reply.started":"2022-09-11T23:10:18.801762Z","shell.execute_reply":"2022-09-11T23:10:18.821890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"size = 5\n# creating an image\nX_small = np.random.normal(100,30,size=(size**2*3)).reshape((size,size,3))\n#rescaling an image\nX_large = resize(X_small)\nplt.imshow(X_large)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:10:18.824779Z","iopub.execute_input":"2022-09-11T23:10:18.825136Z","iopub.status.idle":"2022-09-11T23:10:19.086293Z","shell.execute_reply.started":"2022-09-11T23:10:18.825104Z","shell.execute_reply":"2022-09-11T23:10:19.085116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = minimize(score, X_small.flatten(), method='Powell', options={'disp':True})\nsc = score(x.x, debug=True)\nprint(sc, sc < 1e7)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:10:19.089309Z","iopub.execute_input":"2022-09-11T23:10:19.090196Z","iopub.status.idle":"2022-09-11T23:10:52.426520Z","shell.execute_reply.started":"2022-09-11T23:10:19.090118Z","shell.execute_reply":"2022-09-11T23:10:52.424469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tmp = make_X(x.x, (10,10))\nx = minimize(score, tmp.flatten(), method='Powell', options={'disp':True})\nsc = score(x.x, debug=True)\nprint(sc, sc < 1e7)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T03:17:56.207907Z","iopub.execute_input":"2022-08-12T03:17:56.208449Z","iopub.status.idle":"2022-08-12T03:17:56.480061Z","shell.execute_reply.started":"2022-08-12T03:17:56.208403Z","shell.execute_reply":"2022-08-12T03:17:56.478486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    r = requests.post(\"https://crop1.fly.dev/score\", data=json.dumps({\"data\": get_submittable(x.x)}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-08-12T03:17:57.13115Z","iopub.execute_input":"2022-08-12T03:17:57.131821Z","iopub.status.idle":"2022-08-12T03:17:57.487157Z","shell.execute_reply.started":"2022-08-12T03:17:57.131771Z","shell.execute_reply":"2022-08-12T03:17:57.485372Z"},"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.\n\n### SOLUTION\n\n** NOT YET FOUND**","metadata":{}},{"cell_type":"code","source":"# Submission Helper\n\nwith open(f\"{dir_name}/crop/crop2_example.json\", \"r\") as f:\n    test = json.load(f)\n\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-08-12T03:17:57.506396Z","iopub.execute_input":"2022-08-12T03:17:57.506939Z","iopub.status.idle":"2022-08-12T03:17:57.740573Z","shell.execute_reply.started":"2022-08-12T03:17:57.506902Z","shell.execute_reply":"2022-08-12T03:17:57.739111Z"},"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### SOLUTION\n\nWhile looking at deepfake-detection-challenge I noticed rhe person in the video was also in video of that challenge, so I picked one which did not look fake with that same person. ","metadata":{}},{"cell_type":"code","source":"with open(\"/kaggle/input/deepfake-detection-challenge/test_videos/gpsxfxrjrr.mp4\", \"rb\") as f:\n    data = f.read()\nb64_data = base64.urlsafe_b64encode(data).decode()\nin_data = json.dumps({\"input\": b64_data})\nr = requests.post(\"https://deepfake.fly.dev/score\", data=in_data)\nprint(r.text)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:11:00.749746Z","iopub.execute_input":"2022-09-11T23:11:00.750166Z","iopub.status.idle":"2022-09-11T23:11:08.488674Z","shell.execute_reply.started":"2022-09-11T23:11:00.750106Z","shell.execute_reply":"2022-09-11T23:11:08.487529Z"},"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### SOLUTION\n\nUse xgboost to predict human location","metadata":{}},{"cell_type":"code","source":"with open(f'{dir_name}/murderbots/train_data.json') as f:\n    X_train = pd.DataFrame.from_dict(json.load(f))\n    X_train.index = X_train.index.astype(int)\n    X_train.sort_index(inplace=True)\n\nwith open(f'{dir_name}/murderbots/train_labels.json') as f:\n    y_train = pd.DataFrame.from_dict(json.load(f))\n    y_train.index = y_train.index.astype(int)\n    y_train.sort_index(inplace=True)\n\nwith open(f'{dir_name}/murderbots/test_data.json') as f:\n    X_test = pd.DataFrame.from_dict(json.load(f))\n    X_test.index = X_test.index.astype(int)\n    X_test.sort_index(inplace=True)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:11:38.274442Z","iopub.execute_input":"2022-09-11T23:11:38.274977Z","iopub.status.idle":"2022-09-11T23:11:38.313050Z","shell.execute_reply.started":"2022-09-11T23:11:38.274928Z","shell.execute_reply":"2022-09-11T23:11:38.312161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xg_reg = xgb.XGBRegressor()\nxg_reg.fit(X_train,y_train)\npreds = xg_reg.predict(X_test)","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:12:29.956774Z","iopub.execute_input":"2022-09-11T23:12:29.957182Z","iopub.status.idle":"2022-09-11T23:12:30.203566Z","shell.execute_reply.started":"2022-09-11T23:12:29.957133Z","shell.execute_reply":"2022-09-11T23:12:30.202672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f = ''.join(['1' if x > .999 else '0' for x in preds])\nprint(f)\ntry:\n    r = requests.post(\"http://murderbot.fly.dev:5000/score\", json=json.dumps({\"submission\": f, 'challenge_id':'murderbots'}))\n    print(r.text)\nexcept requests.exceptions.ConnectionError:\n    print(\"Connection problems. Contact the CTF organizers.\")","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:12:31.208869Z","iopub.execute_input":"2022-09-11T23:12:31.209893Z","iopub.status.idle":"2022-09-11T23:12:31.744497Z","shell.execute_reply.started":"2022-09-11T23:12:31.209855Z","shell.execute_reply":"2022-09-11T23:12:31.743358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# TOKEN FOUND","metadata":{}},{"cell_type":"code","source":"with open('submission.csv', 'w') as f:\n    f.write('''challenge_id,flag\nmath_1,A5SY5WGJ6UGFIDISU8FU3SVAFBV{ENOT4PEVLQOTCW0XDAUIJ7UL42M4RT2OJZ60}8KTDD8PI518UD3337G406FGIQ63XSB5CWA5OELO3XH9KTOQ3TEWNOIYMRCFSELP\nmath_2,OF12CLGRIOQ6NXDWXQBI942HTL}E7IROK31QSGOAHBTT5NITF2SDC4DUA5NMVWY0A9NP5689LSFCG10E4EA9KPQZZWEHPEDOARHTQ5VMQG7C8ED6P{2HF83YASGC5E94\nmath_3,60A3LIFY6H9AL4OHPOCVD0QOZ}{EE46IZ7MS62RGWA75YEVUBO99X24GRFGD3FZC2Y9W9PUGE4T_PV3HC7Z4A9MIUHFSEUVAFS29X8EDLFD44GYP0PLLRTAPZCTMIGQX\nmath_4,4EHVZWGAUU88QE991KTI5FT5SQGQLDWYT5S}HIB22OMJY2NMP9YTTIIRODN0OFBJ12I9HFR8ODO4CIOONRZZP57JG6F0RXYI676{M3653RS0I2IGUNG9DDFYAS7DNQZF\nhonorstudent,JTSA9JW0Z5HRYFXCKQR8NAH2N24R0G4PVR1ORICU8HV1}ZVFW9FO9L84AOOP3GANTHTLDGVFM0CE9GSFSJKBLHTLWM{UYIX0HTLFCY1DFV4WTD1FWMTKDQ3KKKWQXHLZ\nbad_to_good,wtZp6FS8hNCJZGI0nVM2FHAF93W9RHAER27N0ZM37_SUS3FH0Q02IRXt6LKF6IG_A5089DZeZ7T3FVaTWER3}b9LUXLKE7MGoSIZP1SHBB05B5_X9J96X5d3F{4L28R8\nbaseball,8IM0FEOLZK3MQHPUQA7R9XUDGGEUJ5LVA6AC542TD1J{AOWI8MAT6KLM1L8531UP44ZPBEE0OGXG}1DDRDYTLQIZKELC0JVXLICV91EUITOVYN0SEOP0X5I9FCTU8683\ntoken,QLSZ63MY5B28W{WR2FTKUQSXRAGV7OEZHDZQFGRKWM3A9GM9NDQ33Q9}5Y00LY47MU8R85HFN917BY5ZZDY23J8MN0ST7YKD7YLL5B0ZD10O9DO4VWU8HE8V7B32VOZU\nwaf,L9OFIMPW4OQMRETP70ZEXWH50YOBHYZMEB81EFMF0DDHZLJ3JIQQAI1NN0L6V{95L79QSEGEY1XYWWNAHIKNHN603GF0R7KYGZA}9H6LY48D5ZNCAIXMZ0TE8QX6YYLX\ntheft,RHKFTLWF9CHJMIJZ1PX4V}EHY1E?5J8QHPTLIKXX98SCRP3PMJGE4VC0NAZI19ULIZLGFYXOSO7{CKI4NWBTW1W87FO9TC1BXXDBH9G3DITY314NXG32MLTYPW1DIPFS\nsalt,38ZZR2NFQ3A4T3L5X3YTBJLC2C<RXKSVL15VVW8GIB{8CG1M1ILHSXORD1SGOIIL}OYY4FX9MWAJLL19AFJG8LC7P6XIA1TL7BSTFJEMD8R2ZABKYBNX94XT9M0WQ0PC\ncrop1,385JOQPW{5TGE2On}F2DAAPL14nQXHB3RWT0AZ7eARIKFJSS1gWJH871TZDJX8CYX8ORXPhHSHAFG2N2TC0L2rAa1CLD7TAIQ777X538LFZFON8agCMSHB5GDP2YEI8E\ncrop2,FLAG{PLACEHOLDER}\nhotdog,YTO6KWHDCJB941}RP42FVQEEFTBLGG9O3TOOAAFPSL9U7SEUHMNHZ2BVDT2CPKRS0IMAEYL4MA5AY8UTUWLVFO4QI7GL5DULZFWATL6PW1DCGSMHIKDEGSM5I8B{WOTY\nhotterdog,Q7M0WROV411IQWK4OO071T1LH6P1YDJZ9{Z1N6DNVFGWD2W7PRCDATWQVXW8JWNE}WHROV5OZOHQMSGGINUAG7LX5WGVAJYOL4OO8ODOOV1OLF98YT73IRA659G2IYFP\ndeepfake,NBG6GPZ1LQLXROC5GCUFKFXI611E9OK4EA1UZDVXOQDDBIFEXRROU8UBVFADHVD8UGMOTVX1SLGHB}YOMJLOCDZE9URC5LQCAJE50EES3SHNDZDJ6E{VLAJJW5CTL4T3\nforensics,SXPQ0TZSU0TXWLFTOLMVRIF5QG723W0UF}44KL389OBKRNBLMV0X02R9U2DB9G2DFTA82QX1JVC25VZTWD38LFFIWCRQELBXEASKFJG1845GA{ZC3_WWID8ML2SD27RL\nwifi,7L3MQ1M5NNO8EMWQFJMV1CDX7GRM9O8MKSHCQZFI4PD1CLZT42TX72J0FL2NGRLT6JSG0TCRW3KKS0J}NGXELGEWRVTW7XQB5RDYRY2WBEV{A16OQPFOSPML33ABUKJY\nleakage,5aHWsP4033rDD8nECM4o5CMHFUB8YG3YRA41KKINJ2TCYBK12BMO<ELMYCNZO8GMNAZZGIY}L1FRA4ZQc74D{BY7YBH536DG0FYS3P6<KBA07RCNQA49UXAQZZJV8W7L\nsloth,GBPEF1CFGKU3XFNDC11PICRCFRN9E6HXVFZU{7V42U35MLMTOHHTLAJA7EU1JHE7JSSERYKN}SYOC7XV2UT2F5AK06ALZD4VS92U0Z90V3QGOAYTU5UHR3R2LV6P6EFD\nmurderbots,74X2Zb3SBXWZ}SR3UOMeToAE3t6GQMaFuJSFTtWFrVLGL{MBPKG5Z5F6sYXJKS33RJD8YMFdtFP6RLALoA9GHFWdWPUWIQeQTCT768DOOIZSG5KFARBB55R6N1PZGMA8\ninference,IMTNIV6Z3PPR39OAZ06V0TIPNLJNQ8HX6YFJY4K8MZT0GL0D9B7RNRUFFJQZNGYBTJSODTTHAVAV5QZ578WWYFVGXCNZO}KUK4ATOM7FDJCO{4CFP7RMNEOERN0N9U87\n''')","metadata":{"execution":{"iopub.status.busy":"2022-09-11T23:19:51.984709Z","iopub.execute_input":"2022-09-11T23:19:51.985292Z","iopub.status.idle":"2022-09-11T23:19:51.994257Z","shell.execute_reply.started":"2022-09-11T23:19:51.985251Z","shell.execute_reply":"2022-09-11T23:19:51.993060Z"},"trusted":true},"execution_count":null,"outputs":[]}]}