Here is a perspective that might help to put characteristic classes into a more general framework. I like to think that there are two levels of the theory. One is geometric and the other is about extracting information about the geometry through algebraic invariants.
Bear with me if this sounds to elementary and obvious at first.
The geometric side: We have some class of bundle type objects which admit a theory of classifying spaces. This allows us to swap bundles over $X$ for maps of $X$ into some fixed space, which I will call $B$ for the moment. Equivalent bundles over $X$ give equivalent maps to $B$.
The algebraic side: We study maps from $X$ to $B$ by looking at their effect on some type of cohomology theory. The point is that we push the problem of studying maps $X \to B$ forward into an algebraic category where we have a better hope of extracting information.
The passage from geometric to algebraic certainly throws some information away; this is the price for moving to a more computable setting. But in the right circumstances the information you want might still be available.
Now, a general framework for this might be the following. Bundles in the abstract are objects that are local over the base and can be glued together. This is precisely what stacks are meant to describe. So think of bundles simply as objects that are classified by maps of $X$ to some stack. This can make sense in any category where you have a notion of coverings (a Grothendieck topology), so we don't have to stick with just ordinary topological spaces here. If you know how to talk about coverings of chain complexes then you can probably make a chain level version. But more concretely, we could also be talking about principal $G$-bundles for just about any sort of a group $G$. Or we could talk about fibre bundles with fibre of some particular type (in my own work, surface bundles come up quite a lot).
As an aside, if you happen to be working with spaces and you want to get back to the usual setting of classifying spaces like grassmannians and $BO$ or $BU$ then there is a way to get there from a classifying stack. Take its homotopy type; i.e, if $B$ is a stack, then choose a space $U$ and a covering $U \to B$, then form the iterated pullbacks $U\times_B \cdots \times_B U$ which give a simplicial space - the realization of this simplicial space will be the homotopy-theoretic classifying space).
Now, we have some class of bundle objects classified by a stack $B$. To have a "useful" theory of characteristic classes we need a cohomology theory in this category for which
- We can compute enough of the cohomology of $B$ and the map induced by $X \to B$.
- Enough information is retained at the level of cohomology to tell us things we want to know about morphisms $X \to B$.
It is very much an art to make a choice of cohomology theory that helps with the problem at hand.
I just want to point out that if you are working with vector bundles, then you needn't think of characteristic classes only as living in singular cohomology classes. A vector bundle represents a K-theory class, and you can think of that class as the K-theory characteristic class of the bundle.
Addendum: Just to say something about why we work with things like $BO$ instead of $BO(n)$, let me point out that it is a matter of putting things into the same place so we can compare them. Real rank n vector bundles have classifying maps $BO(n)$, and if you want to compare a map to $BO(n)$ with a map to $BO(m)$ then a natural thing to do is map them both to $BO(n+m)$. And then, why not go all the way to $BO(\infty)=BO$? It's just a matter of not having to compare apples and oranges.