The value returned by the sexp (read "`foo") is `foo.
You are confused by the form of the printing of the read value by the
command you are using (eval-expression, bound to M-: by default). What it prints is a Lisp representation of the value. If you instead use pp-eval-expression then you see `foo, which is the (same) value printed for humans. (This is one of several reasons that I prefer to bind M-: to pp-eval-expression.)
As for the Lisp representation - in library backquote.el you see this Commentary (notice the first line):
;; When the Lisp reader sees `(...), it generates (\` (...)).
;; When it sees ,... inside such a backquote form, it generates (\, ...).
;; For ,@... it generates (\,@ ...).
That first line could have said that when it sees `... it generates (\` ...). In other words, what is says is not just for a backquoted list. In your case, when it sees `foo it generates (\` foo).
And (equal (read "`foo") '`foo) does return t. (You forgot to quote the second argument to equal. You used `foo as the second argument, but that gets evaluated - to foo, not to `foo, which is what you wanted to compare with the value of (read "`foo").)