Velocities are specified in the world coordinate system. So
(0, 0, moveVertical) means a velocity pointing along the world's Z axis, not the character's Z axis.
If you want to specify your velocity in local coordinates, all you have to do is convert them to world coordinates before you assign the velocity, something like this:
var localVelocity = new Vector3(0, 0, moveVertical);
var worldVelocity = transform.TransformVector(localVelocity);
// Preserve jumping/falling.
worldVelocity.y = rb.velocity.y;
rb.velocity = worldVelocity;
Though for a single axis you can take a shortcut:
worldVelocity = transform.forward * moveVertical
+ Vector3.up * rb.velocity.y;
One unrelated error here is that you're changing your position using the rigidbody's velocity, but changing your rotation using the transform. Combining physics- and non-physics movement can confuse the physics engine and cause bugs, and will disable interpolation which can make your movement look jerky. So, it's better to keep all rotation under the control of the rigidbody:
// transform.Rotate(0, moveHorizontal, 0);
var rotation = Quaternion.Euler(0, moveHorizontal, 0) * rb.rotation;
You'll probably also want to scale your rotation by
deltaTime to keep it smooth and consistent under varying framerates. (You don't need to do this with velocity since it's already a rate over time, integrated over the time step by the physics engine)