Miami came from behind twice to win for just the fourth time in 21 games.
The Marlins rallied from an early two-run deficit to tie it, and then fell behind in the seventh when St. Louis backup catcher Tony Cruz hit the first home run of his major league career.
Buck hit a one-out homer in the bottom half of the inning off Fernando Salas and, after Sam Freeman (0-1) relieved Salas, Morrison hit the first pitch he saw over the wall in right to give the Marlins the lead.
The shot by Morrison, who was pinch-hitting for eventual winning pitcher Anibal Sanchez, bounced off the top of the wall and struck a railing before coming back into the field of play.
Morrison stopped at second base, but came home after the umpires looked at a television replay.
Sanchez (4-6) gave up three runs on seven hits in seven innings to get the win. Heath Bell worked the ninth for his 15th save.