Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Misc - Aww

Misc/aww/writeup/writeup.livemd

> # Misc - Aww > > > Misc - 350 pts > > Aww so cute, 7 types of cats and dogs, but I can’t see the key. Can you help me? > > The flag will be the same format as this one: UiTHack23{[a-zA-z0-9]} > > Tips: Dogs are 0 and cats are 1

Mix.install(
  [
    {:nx, "~> 0.4.1"},
    {:exla, "~> 0.4.1"},
    {:axon, "~> 0.3.1"},
    {:axon_onnx, "~> 0.3.0"},
    {:kino, "~> 0.8.0"},
    {:stb_image, "~> 0.6.0"}
  ],
  config: [nx: [default_backend: EXLA.Backend]]
)

Aww

Nx.default_backend(EXLA.Backend)

The flag can be found be using an image classification model which classifies dogs and cats, which then can be saved as 0 and 1 respectivly, this will result in a binary with byte-length 7. The process is as follows:

Read Images

Read the 50 images, resize them into 244x244 (or whatever your model needs) and save them as matricies.

# Get files from the current directory
File.cd!(__DIR__)

file_names = Enum.map(1..50, fn n -> "#{n}.jpg" end)

# Resize files to 244x244
resized_images =
  Enum.map(file_names, fn file_name ->
    ("images/" <> file_name)
    |> IO.inspect(label: file_name)
    |> StbImage.read_file!()
    |> StbImage.resize(244, 244)
  end)

img_tensors =
  resized_images
  |> Enum.map(&amp;StbImage.to_nx/1)
  |> Nx.stack(name: :index, axis: 0)
  |> Nx.divide(255.0)
  |> Nx.transpose(axes: [:index, :channels, :height, :width])

Load Model

Find a model which is trained to identify cats and dog. (For example this one)

Load the chosen model and deseralize it.

path_to_onnx_file = "models/onnx/cats_v_dogs.onnx"

# Load model
cats_v_dogs = File.read!("models/axon/cats_v_dogs.axon")

# Deserialize model
{cats_v_dogs_model, cats_v_dogs_params} = Axon.deserialize(cats_v_dogs)

Run the ML model on the dataset of dogs/cats, and transform it into a string.

defmodule Predictions do
  def single_label_classification(predictions_batch, vocabulary) do
    IO.inspect(Nx.shape(predictions_batch), label: "predictions batch shape")

    for prediction_tensor <- Nx.to_batched(predictions_batch, 1) do
      {_prediction_value, prediction_label} =
        prediction_tensor
        |> Nx.to_flat_list()
        |> Enum.zip(vocabulary)
        |> Enum.max()

      prediction_label
    end
  end
end
batches = Nx.to_batched(img_tensors, 10, leftover: :discard)

# Dogs 0 and Cats 1
dog_cat_vocabulary = [0, 1]

lst =
  batches
  |> Enum.map(fn batch ->
    res = Axon.predict(cats_v_dogs_model, cats_v_dogs_params, batch, compiler: EXLA)
    Predictions.single_label_classification(res, dog_cat_vocabulary)
  end)

Enum.flat_map(lst, fn x -> x end) |> Enum.join("")

String -> Binary

Use an online string -> binary (byte-length 7) converter (e.g. CyberChef)

Flag: UiTHack23{N3tw0rk}