Brazilian star Danny made the difference for Luciano Spalletti's victorious visitors, as the Rossoneri's Group C campaign comes to a disappointing close.
Having rested several first-team players with passage to the Champions League knockout round already secured, the hosts failed to click and were punished in the second half when the Brazilian playmaker swooped on a rebound for the only goal of the game, one that delivered the club's first victory on Italian soil.
The game began in an even fashion. Both Milan and Zenit played fluid, passing football and attempted to keep possession, although clear-cut chances were at a premium in the opening stages. The Rossoneri, though, were convinced they had earned a penalty when Giampaolo Pazzini went down under Bruno Alves' challenge, but their protests were in vain. Urby Emanuelson also went close for the hosts, flashing a venomous shot just past the post with 15 minutes on the clock.
Milan enjoyed the lion's share of possession during the first half, but it was the visitors from who took the lead. Massimo Ambrosini did well to stop Sergei Semak in his tracks with a tackle in the Italian penalty area, but his defense was painfully slow to react as the ball ran free. The first man to reach it was Danny, who artfully curled the ball past the despairing dive of Christian Abbiati to put Luciano Spalletti's men in front.
The goal served as a wake-up call for the home team, which started to commit more bodies into attack. Bojan Krkic was not far away with an ambitious overhead kick that went just wide of the post, while Mathieu Flamini called goalkeeper Viacheslav Malafeev into action with a stinging effort from outside the area that was parried by the Zenit man.
Seven minutes into the second half, Massimiliano Allegri's charges looked certain to restore parity. A well-worked counter ended with Pazzini diverting Kevin-Prince Boateng's cross into the path of Malafeev. But the keeper reacted smartly to hack the ball away with his feet. Emanuelson was in prime position to convert the rebound, but a momentary hesitation from the winger was enough for Zenit to clear their lines and keep their lead intact.
The pressure continued to build from the home team, which had almost complete control of possession as it probed for an equalizer. Krkic tried his luck from deep with a shot that flew over the bar, while Zenit began to defend in numbers in an effort to protect their slender advantage.
The deep backline was paying off for Spalletti's troops, who forced Milan out of their box and into shooting desperately from range in the absence of better alternatives. Despite close calls for substitutes Robinho and Stephan El Shaarawy, who both caused scares, the Russians were able to play out the victory.