There is a difference between the static type of an object and the dynamic type of a variable.
The static type is the type known at compile time. For Object o = "Karan";, the static type is the one at the left of o, i.e. Object. Now, one could ask why that is the case since at compile-time, it can be inferred that o is a String. Well if we consider something like
Object o;
if (someCondition) {
    o = "Karam";
} else {
    o = new StringBuffer();
}
then we cannot know whether o is a String or a StringBuffer, thus its static type is Object (since o is defined as Object).
The dynamic type is the type at runtime. In the example above, after the if-statement has been executed, o is either a String or a StringBuffer, but not both and nothing else. In your example, the dynamic type of Object o = "Karan"; is String.
When variables are compared through equals(...), they must have the same dynamic type in order for the comparison to return true (notice that this property is necessary, but not sufficient). Since o in your example is, in fact, a String AND the content is equal to s, s.equals(o) == o.equals(s) == true.
As to why s == o returns true: the question is answered in this post.