By sending a hash of the password, instead of the password itself, all you are protecting is the cleartext of the password. This has some merit, but it does nothing to protect against replay attacks - this is known as pass-the-hash.
By combining the users password with a single-use salt (challenge) supplied by the server, you can protect against such an attack - but in order to validate the token presented (h(p+c)), the service needs to recreate the same hashed value - i.e. it needs to store the plain text of the password. That's not good.
Conventionally, an authentication service will store a hash of the password with a randomly generated salt (h(s+p)), along with the cleartext of the salt. The clear text of the salt is not considered to be particularly secret - the effectiveness of the mechanism is not greatly weakened by revealing this. So, in principal, the server could send both a challenge and the client would send back:
h(h(s+p)+c)
Sadly, this does not solve the pass-the-hash problem as a knowledge of the data (h(s+p)) stored on the server is sufficient to be able to authenticate.
The only practical way to avoid the problem is to use an authentication service trusted by both the client and the application service - e.g. using kerberos or openid - that just moves the problem to the authentication service, but this separates and decouples the responsibilities.