Ulster kept alive their hopes of securing a home quarter-final in the Heineken Cup as they snatched a first ever win on French soil in the competition by edging out Castres.
Remi Lamerat's try put Castres ahead as the injury-hit visitors struggled but two Ruan Pienaar penalties cut the French team's lead to 8-6 by half-time.
Pienaar edged Ulster ahead with his third penalty in the 64th minute.
With Chris Henry outstanding, Ulster took control in the closing stages.
Ulster's lengthy injury list meant a start at full-back for Craig Gilroy with Michael Allen drafted on to the wing and Neil McComb drafted into the pack because of the absence of in-form Nick Williams.
Doubts over Paddy Jackson's fitness also led to a switch to fly-half for Pienaar with Paul Marshall handed the number nine shirt.
The visitors had a big wind advantage in the first half but it was Castres who opened the scoring in the eighth minute after a break from their own half.
The key to the try was Max Evans's break and superb inside pass to keep the ball alive and slick hands from Remi Tales and Yannick Forestier set up centre Lamerat for a simple finish.
Pienaar dropping the ball in midfield had led to Castres winning possession before the try and it was one of a number of Ulster errors in the opening period.
Rory Best was struggling with his line-out throwing in the wind with fly-half Pienaar was not looking as assured as in his recent outings in the number nine jersey.
Pienaar did open Ulster's account in the 11th minute but a Paddy Wallace indiscretion saw Rory Kockott, who had missed the conversion after Lamerat's try, putting five points between the teams again in the 19th minute.
Ulster were bossing the scrum exchanges and a penalty try looked on the cards when Castres were penalised three times in succession for pulling down the opposition front row deep in the home side's 22.
However, at the fourth time of asking referee Nigel Owens penalised Ulster for early engagement and the chance was lost.
Ulster's injury woes continued in the 27th minute as Roger Wilson was forced off with an apparent hamstring injury which led to Iain Henderson being introduced.
Needing points on the board given that Castres were to have the second-half wind advantage, Pienaar did cut the margin to two with a 36th-minute penalty but the South African missed a chance to give Ulster an undeserved interval lead as he missed from 50 metres in the last action before the break.
The match became a battle of attrition in the third quarter with neither side managing a score and opposing back rowers Pedrie Wannenburg and Henry both performing heroics.
However, with Jackson introduced to fly-half and Pienaar back in his favoured scrum-half role, Ulster began to play more with ball in hand midway through the second period.
The tactic bore dividends in the 64th minute as the South African kicked the visitors into a one-point lead after a Wallace break had yielded a penalty.
Ulster looked set to score a try in the 68th minute as Jackson charged towards the Castres line but his attempted pass was intercepted by replacement Marc Andreu whose clearance then put the visitors on the back-foot before the heroic Henry averted the danger with another thundering tackle.
Pienaar missed a chance to extend Ulster's lead as he was just short with a long-range penalty with three minutes left but the visitors ran down the clock efficiently to take the victory.
At that stage, the victory put Ulster in a position to earn a home quarter-final but that berth was by no means secure.
View from the dressing room
Ulster coach Mark Anscombe:
"We were very flat in the first half, we kept giving the ball away and couldn't get our lineout going.
"It wasn't pretty. They don't make it easy for you but the character of the guys saw us through in the end.
"I said at half-time that if we get the ball and play some rugby, work on that and be patient, opportunities would come.
"We couldn't come here and expect to score four tries, but there were opportunities and holes in Castres."
Castres: P Bernard, M Evans, S Bai, R Lamerat, M Garvey, R Tales, R Kockott; Y Forestier, M-A Rallier, A Peikrishvili, M Rolland, C Samson, M Babillot, P Faasalele, P Wannenburg.
Replacements: M Andreu for Baikeinuku 51, P Bonnefond for Lamerat 62, T Lacrampe for Kockott 55, S Taumoepeau for Forestier 45, B Mach for Rallier 61, M Lazar for Peikrishvili 53, I Tekori for Rolland (70), J Bornman for Babillot 55
Ulster: C Gilroy, A Trimble, D Cave, P Wallace, M Allen, R Pienaar, P Marshall; T Court, R Best, J Afoa, L Stevenson, N McComb, R Diack, C Henry (capt), R Wilson.
Replacements: P Jackson for Marshall 55, I Henderson for Wilson 28
Not used: R Herring, C Black, D Fitzpatrick, M McComish, M Heaney, C Cochrane
Referee: Nigel Owens (Wales)