Going to robots.txt shows that admin.phps is disallowed. This indicates that the phps extension is enabled within the php configuration for this webserver. Files with the phps extension contain php code but instead of running when they are accessed, they return an HTML representation of the literal pho code.
We can store any object in the login cookie and it will be unserialized. One option is to exploit the __construct function, since this is ran immediately when the object is created. However, in both the access_log and permissions classes, there does not appear to be a valid gadget chain (see "Gadget chains" in the PortSwigger article).
We can store a serialized access_log object in the login cookie with the log_file set to ../flag. This object will be instantiated in the first line of the try block. However, the access_log class does not have an is_guest function so when the code try to run that function on the next line it will fail, thus jumping to the catch block. This catch block prints the value of $perm, which is our injected access_log object. By printing $perm, the __toString method of our access_log object is called, which displays the content of whatever filename (the value of access_log) was passed to it.
The php serialized access_log object looks like this: O:10:"access_log":1:{s:8:"log_file";s:7:"../flag";}. Fore more details about this syntax, see the aforementioned Medium article.
Let's encode that to base64 and url encode it using CyberChef to get: TzoxMDoiYWNjZXNzX2xvZyI6MTp7czo4OiJsb2dfZmlsZSI7czo3OiIuLi9mbGFnIjt9
We can use cURL to access the authentication.php file with the correct cookie set: curl mercury.picoctf.net:3449/authentication.php --cookie "login=TzoxMDoiYWNjZXNzX2xvZyI6MTp7czo4OiJsb2dfZmlsZSI7czo3OiIuLi9mbGFnIjt9". This will print the error text and the flag: Deserialization error. picoCTF{th15_vu1n_1s_5up3r_53r1ous_y4ll_b4e3f8b1}