HackTheBox - Ellingson

You have to call setuid(0) because of a bash security feature. The setuid flag of the garbage file only sets the effective uid to 0. The real uid stays the one of the user calling bash. When bash detects that the effective and the real uid do not match, it drops the privileges.

To prevent this you can call setuid(0) before calling bash. So if you want to run bash from a setuid binary, you have to run it through a setuid wrapper. In the ellingson exploit the setuid() call is directly included in the ROP chain.

See here for details on the bash security mechanism: