For some reason net::telnet times out on the ones asking for PASSCODE
This is precisely the behaviour described in the documentation:
(the login) method performs a standard login by waiting for a login prompt and responding with $username, then waiting for the password prompt and responding with $password, and then waiting for the command interpreter prompt. If any of those prompts sent by the remote side don't match what's expected, this method will time-out, unless timeout is turned off.
The correct approach to use is also suggested by the same documentation:
Use a combination of print() and waitfor() as an alternative to login() or cmd() when they don't do what you want.