On a path to avenging his father, Tex Chance manufactured steam-powered robots to capture all the animals of your island to build a powerful army of fused mutated organisms using his powerful Sigma technology. You can’t let them take away your loyal doggo Julius. The robots have been trained to classify all the objects they encounter using the SigmaNet network. Can you use your laser pointer to change some of the robot’s vision pixels forcing it to misclassify your dog’s image as a non-animal object?
Category: misc
Solver: 3mb0, nh1729
Flag: HTB{0ne_tw0_thr33_p1xel_attack}
Writeup
We can download a python script with a neural network that can classify images. And when we visit the given server / port combination in a web browser, we can see the following:
With the information from the assignment, it seems that we should use our lasers to modify the image in the lower left part of the web page:
In the five input fields on the website we can enter the coordinates of one pixel and its new color that is caused by our lasers. The image’s dimensions are only 32 times 32 pixels but even if a simple bruteforce seems possible, we decide to go for a prettier solution.
We have two different approaches. The first is to understand the neural network and point our lasers based on that. The second, successful approach is to find the right spots for the lasers using a genetic algorithm.
Genetic algorithm
Our genetic algorithm runs five times, once for each laser point. In each run, it starts with a random population of 120 individuals with random position and color. Then, it calculates the fitness of the population. For the next generation, it uses the 20 individuals with the best fitness from the previous generation. Additionally, the algorithm creates five mutated individuals for each of the 20 selected individuals and includes them for the next generation to get 120 individuals again. The five different mutations change exactly one trait (x, y, r, g, b) of the individual randomly in a specific range (-50 to +50 for colors and -5 to +5 for the coordinates). We start with five generations per laser point for testing purposes but our first results show that five generations are already enough to generate sufficiently good laser points.
SigmaNet
We can get the output of the neural network for an image like this:
net = SigmaNet()
image = Image.open('dog.png')
prediction = net.predict(np.array(image)[:, :, :3])[0]
The result looks like this:
[2.1547526e-09, 6.9197569e-08, 3.2075501e-08, 1.7548517e-05, 5.4560373e-05, 9.9986970e-01, 6.3050670e-06, 5.1654850e-05, 1.4958709e-09, 4.6789701e-09]
The numbers represent the confidence of the neural network that the image fits into one of these classes:
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
As the confidence for index 5 is the largest, the neural network clearly classifies the picture as a dog.
Fitness function
Our fitness function looks like this:
for individual in population:
old_value = image.getpixel(individual[0])
image.putpixel(individual[0], individual[1])
image_array = np.array(image)[:, :, :3]
dog_confidence = self.predict(image_array)[0][5]
individual[2] = dog_confidence
image.putpixel(individual[0], old_value)
population.sort(key=lambda individual: individual[2])
We first save the original color value of the image at the position of the individual and then change it to the color of the individual. Then, we calculate the confidences of the neural network for that new image and use the confidence for the dog as our fitness value. At the end, we restore the original image and sort the individuals based on their fitness value. In the sorted array, the individuals with the lowest confidence for the dog class come first.
Results
With the fitness function that tries to minimize the confidence for the dog class, we got the following points:
14,25,252,59,0
24,11,74,213,71
1,10,204,255,255
27,11,38,36,12
24,17,127,255,12
The modified image looks like this:
This results in a confidence of the neural network that the image is a dog of about 1.185e-05
. Sadly, it didn’t work to trick the neural network:
That would have been obvious if we read the assignment more thoroughly. The assignment says that the algorithm should misclassify the dog image as something non-animal. So we adapted our fitness function to maximize the similarity to an airplane by using self.predict(image_array)[0][0]
as the fitness value and sort the individuals in reverse order (starting with the individuals with the largest fitness values). With this new fitness function, our algorithm calculates these points (x, y, r, g, b):
24,11,88,48,117
17,26,41,60,254
13,13,0,139,111
11,20,22,0,58
26,10,6,33,49
The modified image looks like this:
With this image, the neural network couldn’t identify the dog anymore, and we got the flag: