I've always liked working in legacy code bases. It's like doing archeology. Seemingly bad code maybe didn't start out as bad code, but was made bad over time because of historical reasons (last minute product changes, time pressure, local changes without understanding the bigger picture). It can be very rewarding to make sense of it. And it makes you realize that any code you write yourself will be legacy code soon too, and someone else will need to be able to make sense of it again.
The thing about inheriting an older, undocumented codebase is that it often blows up in ways that you least expect; even drawing assumptions about how a function works based on its name can be problematic.
Or when you remove some "unused" code, only to find out that it was somehow used by reflection and your IDE can't even figure that out because the framework you're using was discontinued in 2010. Also of course, there's no test for that.
I've worked on plenty of legacy code over 37 years. It all depends on the management environment and how bad the code is. Sometimes legacy code is like being mired in quicksand.
I've grown to appreciate legacy code more than greenfield. It's real code that makes money (hopefully) and solves problems. Code is bad? Well, it's probably for good reason as real-world problems are messy. Also a lot less analysis by paralysis.