The attack was able to happen as a result of two separate bugs.
First, a user was able to use something as collateral with a price that could be manipulated. This allowed them to make the collateral to instantly manipulated to appear worth less than the amount borrowed, allowing it to be liquidated.
The second bug was that they had code that should not allow a user to do a series of interaction with the contract that end in bad debt for the user, however since they were able to liquidate their own bad debt from inside the series of interactions, the liquidation cleared out the bad user debt, and moved it to bad protocol debt. This made it so the whole process was checked at the end of the transaction, the user debt looked fine.
Or I could be slightly wrong - it was an usually gnarly attack.