Rating:

First, explore `scramble.py`. The way it works is:
1) Sets numpy random seed.
2) Shuffles each row of the image.
3) Coverts the result shuffled image to greyscale.

**Key obervation**: `np.random.shuffle` shuffles only the first dimension, so although
all pixels in every row are shuffled, RGB parts **are not**. This means that
we can reshuffle pixels back (because random is seeded) and get original image in greyscale.

Let's do it:

1) Install OpenCV and tqdm: `pip3 install opencv-python tqdm`
2) Run the exploit:
```
% cat ransomwtf.py
import sys
import cv2
print('CV2 versin: ', cv2.__version__)
import numpy as np
from tqdm import tqdm

def decode_image(pathIn, pathOut):
# 420 EGGS !
np.random.seed(420)

# Image dimensions : 1280x720
to_hide = cv2.imread(pathIn)
to_hide_array = np.asarray(to_hide)

result = np.zeros(to_hide_array.shape, dtype=np.uint8)

for i in tqdm(range(to_hide_array.shape[0])):
arr = np.zeros(to_hide_array.shape[1:-1], dtype=np.uint32)

for j in range(arr.shape[0]):
arr[j] = j
np.random.shuffle(arr)
for j in range(arr.shape[0]):
v = arr[j]
result[i][v] = to_hide_array[i][j]

cv2.imwrite(pathOut, result)

if __name__ == '__main__':
input_name = sys.argv[1]
output_name = sys.argv[2]
decode_image(input_name, output_name)

% python3 ransomwtf.py challenge.jpg result.jpg
CV2 versin: 4.5.1
100%|████████████████████████████████| 720/720 [00:00<00:00, 820.46it/s]
```
3) Capture the flag in the `result.jpg`:
![](https://i.imgur.com/QFSKVWq.jpg)
The flag is `Hero{S3eD3d_Scr4Mbl3}`