First thing: good luck, you're going to need it. This is potentially a HUGE job you've come upon. It sounds very familiar to me; I've worked on similar things in the past.
One thing to think about; before you start refactoring at all, I'd really strongly consider putting in place an extensive testing framework. The reason is this: with good unit tests and regression tests, you can begin making changes without worrying TOO much about breaking existing functionality. (That said, there's always a concern, but...)
That said: I'd look at slicing off distinct "vertical" slices of functionality, and see if you can write distinct unit and integration tests for them; once that is done, I'd jump in and start work on the refactor. While it may be very small at first, just the process of isolating the vertical slice of functionality and then writing integration and unit test code for it will get you a lot of experience with the existing code base. And if you manage to make that one little bit better initially, then you're ahead by that much.
After you've done that, start looking at potentially larger blocks of functionality to refactor. If it isn't possible to get clean blocks of functionality to refactor, I'd start looking at small chunks; if you can find a small (sometimes VERY small) chunk of code to then extract, unit test, and refactor, you're moving forward. This may seem like very very very slow progress at times, and it will, if you have a really large project, but you WILL be making a dent.
But in general, think of putting in place tests first to confirm expected functionality. Once those tests are in place, you can refactor with confidence (not perfect confidence, but better than nothing) that you aren't breaking things. Start small, and build on the techniques that reveal themselves out of the existing codebase. It's a long slog, but you'll get there eventually, and the codebase will be better for it.