By default, each time a new hash is generated (e.g.
wp_hash_password()) WordPress salts it with random bytes, producing a unique hash for each call. The string returned from
wp_hash_password() consists of four parts concatenated in order - the hashing algorithm ID, the exponent of hash iterations, the randomly generated salt, and finally the salted and hashed password.
For example, given the default hashing configuration, in the string
$P$ is the algorithm identifier
B indicates the number of hashing iterations
I17Hnqif is the random salt
i2CHQsPi5z/nVbEInNjl21 is the salted and hashed password
When checking a plaintext password against the hash of a stored user password, instead of simply querying the database for a matching user/password hash, WordPress retrieves the stored hash for the user and passes it into
wp_check_password() alongside the plaintext password. The checking algorithm extracts the salt and iteration count from the stored hash, and uses them to generate a hash of the plaintext password before checking the two against one another.
This mechanism adds a layer of protection against rainbow table attacks as it makes precomputing/using a dictionary of hashes to passwords more expensive - instead of a single hash for a single input, in WordPress' case there are octillions of possible hashes for a single input.
A brief overview of the general technique can be found here. The source of the
PasswordHash class can be scoured for the specifics as they relate to WordPress.