Ask yourself why you think it's strange that a type that is typically allocated on the stack would inherit from System.Object and I think you'll find you can't formulate a good reason.
If you think it's because an object's type defines where it is allocated, you're mistaken. What member of ValueType is responsible for defining its allocation mechanism? (What member of System.Object, for that matter?)
Type inheritance in .NET is supposed to comprise "is a" relationships: a string is an object, for example. Everything in the .NET world is an object, so an int is an object, a double is an object, etc.
You can think of this in terms of the Liskov substitution principle: if I write code that expects an object, I should be capable of dealing with any type that is an object—i.e., anything at all. My code should be equally comfortable with a string, an int, a List<int>, etc.
Also note that object guarantees certain members that all types have as a consequence of this: GetType, ToString, and GetHashCode.