`kill-process` is working in your case. But `get-buffer-process` is, after killing `cat`, returning the name of a different buffer (eg *scratch*).
You can check this if you insert `(sit-for 1)` into your while-loop. Then 
you will get the debugger.

    (let ((buf
              "*Async Shell Command*"))
         (async-shell-command "cat")
         (while (get-buffer-process buf)
           (sit-for 1)
           (message "still has proc")
           (kill-process (get-buffer-process buf))))

To solve this, you should rewrite your code to something like this:

    (let ((buf
              "*Async Shell Command*"))
         (async-shell-command "cat")
         (while (not (string= (kill-process buf) buf))
    	   (sit-for 1)
    	   (message "still has proc")))