# Labyrinth
* Category: Dev* 150 points* Solved by JCTF Team
## Description
Given a remote server address
## Solution
As you can guess, it is a development challenge.In this challenge we get five links for images of [Where's Wally?](https://en.wikipedia.org/wiki/Where%27s_Wally%3F) and should reply with the coordinates of wally in the image within seconds.Obviously we don't have time to find him by eyes, so let's throw ML on him!LMGTFY - we found [HereIsWally](https://github.com/tadejmagajna/HereIsWally) on GitHub.After some configuration and downloads, we managed to run [find_wally.py](https://github.com/tadejmagajna/HereIsWally/blob/master/find_wally.py) on one of the images and get the corret coordiates of Wally. Good work tadejmagajna!
Now we just had to add a little automation to get the images, run the detection function, normalize the coordinates and convert them to int, and send them back to the server.This is the full script:
```pythonimport numpy as npimport sysimport tensorflow as tffrom PIL import Imagefrom object_detection.utils import label_map_utilfrom object_detection.utils import visualization_utils as vis_util
model_path = './trained_model/frozen_inference_graph.pb'
from pwn import *import requests # to get image from the webimport shutil # to save it locally
conn = remote('labyrinth.ctf.bsidestlv.com',5000)for i in range(5):    conn.recvuntil('https', drop=True)    image_url  = 'https'+conn.recvuntil('jpg')    image_path = image_url.split("/")[-1]    print(image_path)    r = requests.get(image_url, stream = True)
    # Check if the image was retrieved successfully    if r.status_code == 200:        # Set decode_content value to True, otherwise the downloaded image file's size will be zero.        r.raw.decode_content = True
        # Open a local file with wb ( write binary ) permission.        with open(image_path,'wb') as f:            shutil.copyfileobj(r.raw, f)
        print('Image sucessfully Downloaded: ',image_path)    else:        print('Image Couldn\'t be retreived')
    detection_graph = tf.Graph()    with detection_graph.as_default():        od_graph_def = tf.GraphDef()        with tf.gfile.GFile(model_path, 'rb') as fid:            serialized_graph = fid.read()            od_graph_def.ParseFromString(serialized_graph)            tf.import_graph_def(od_graph_def, name='')
    def load_image_into_numpy_array(image):      (im_width, im_height) = image.size      return np.array(image.getdata()).reshape(          (im_height, im_width, 3)).astype(np.uint8)
    label_map = label_map_util.load_labelmap('./trained_model/labels.txt')    categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=1, use_display_name=True)    category_index = label_map_util.create_category_index(categories)
    with detection_graph.as_default():      with tf.Session(graph=detection_graph) as sess:        image_np = load_image_into_numpy_array(Image.open(image_path))        image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')        boxes = detection_graph.get_tensor_by_name('detection_boxes:0')        scores = detection_graph.get_tensor_by_name('detection_scores:0')        classes = detection_graph.get_tensor_by_name('detection_classes:0')        num_detections = detection_graph.get_tensor_by_name('num_detections:0')        # Actual detection.        (boxes, scores, classes, num_detections) = sess.run(            [boxes, scores, classes, num_detections],            feed_dict={image_tensor: np.expand_dims(image_np, axis=0)})
        if scores[0][0] < 0.1:            sys.exit('Wally not found :(')
        width, height = Image.open(image_path).size        print('Wally found')        vis_util.visualize_boxes_and_labels_on_image_array(            image_np,            np.squeeze(boxes),            np.squeeze(classes).astype(np.int32),            np.squeeze(scores),            category_index,            use_normalized_coordinates=True,            line_thickness=8)        resp = '{},{}'.format(int(round(np.squeeze(boxes)[0][1]*width)), int(round(np.squeeze(boxes)[0][0]*height)))
    print(conn.recvline())    conn.sendline(bytearray(resp, 'utf8'))print(conn.recvrepeat(timeout=2))```After five images we got:
flag: **BSidesTLV2021{Here_1s_wally_lets_throw_ML_on_him}**
#### P.S.It was also possible to solve it manually. We know of another team who downloaded all the images, and solved them "by hand" (well, by eye).