pwn 0.4.935 → 0.4.937

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8851bc31c15f4b6cb9fe3f3406a98cabfbb8e10f86833a5cede850de562baf96
4
- data.tar.gz: ec4b72084fccbd0b3ec6c7f8e50fada9c3925559fcf8db37b03656bd485b803f
3
+ metadata.gz: c2517a3d98fd78417b35ed4f96be172047eb0c1cd096dde7a49cd9ecf92f5e87
4
+ data.tar.gz: 16c41a8a69d0506c3701882049ae0d13c2afd1c891ec543c9f84d2ec05197f5e
5
5
  SHA512:
6
- metadata.gz: b33fea889a8a2b88c5f0ab012b398c221e55f0cd5afb3c3f86591ef7f5b385bb1b71296a5833d9ce9b5865f56a18b42fc982a0d831115df06608384cb9b47aa5
7
- data.tar.gz: f6acb50d01107e16b36be36421411f0561e1984709c2a1b4780c1a00fd6f97152278d5d31eebd93a92372f86c6974396ed76afdf0ed1e6f4ab15f94dc57bcb89
6
+ metadata.gz: 740130b46c0370ce5ad2137a1ec91802d6e1c131d716982881ce253c7f942cbffbdfc6ce8de7c7d0290bcd27d9af89fe82b3ae26c0fa935a80e18769ed26f11d
7
+ data.tar.gz: a88a39bf547212022cde18d8e815b13e68db01082d662757704400b308f49ec52a097c97b3c1bd7c7bfc39b06f3b93cf9f2e9e75ca53b41d60fec3440995865e
data/Gemfile CHANGED
@@ -16,10 +16,10 @@ gem 'anemone', '0.7.2'
16
16
  gem 'authy', '3.0.1'
17
17
  gem 'aws-sdk', '3.2.0'
18
18
  # gem 'bettercap', '1.6.2'
19
- gem 'barby', '0.6.8'
20
- gem 'brakeman', '6.0.1'
19
+ gem 'barby', '0.6.9'
20
+ gem 'brakeman', '6.1.0'
21
21
  gem 'bson', '4.15.0'
22
- gem 'bundler', '>=2.4.22'
22
+ gem 'bundler', '>=2.5.1'
23
23
  gem 'bundler-audit', '0.9.1'
24
24
  gem 'bunny', '2.22.0'
25
25
  gem 'colorize', '1.1.0'
@@ -38,9 +38,10 @@ gem 'htmlentities', '4.3.4'
38
38
  gem 'ipaddress', '0.8.3'
39
39
  gem 'jenkins_api_client2', '1.9.0'
40
40
  gem 'js-beautify', '0.1.8'
41
- gem 'json', '2.7.0'
41
+ gem 'json', '2.7.1'
42
42
  gem 'jsonpath', '1.1.5'
43
43
  gem 'jwt', '2.7.1'
44
+ gem 'libusb', '0.6.4'
44
45
  gem 'luhn', '1.0.2'
45
46
  gem 'mail', '2.8.1'
46
47
  gem 'mongo', '2.19.3'
@@ -53,9 +54,10 @@ gem 'nexpose', '7.3.0'
53
54
  gem 'nokogiri', '1.15.5'
54
55
  gem 'nokogiri-diff', '0.2.0'
55
56
  gem 'oily_png', '1.2.1'
56
- gem 'open3', '0.2.0'
57
+ gem 'open3', '0.2.1'
57
58
  gem 'os', '1.1.4'
58
59
  gem 'packetfu', '2.0.0'
60
+ gem 'packetgen', '3.3.0'
59
61
  gem 'pdf-reader', '2.11.0'
60
62
  gem 'pg', '1.5.4'
61
63
  gem 'pry', '0.14.2'
@@ -63,14 +65,14 @@ gem 'pry-doc', '1.4.0'
63
65
  gem 'rake', '13.1.0'
64
66
  gem 'rb-readline', '0.5.5'
65
67
  gem 'rbvmomi', '3.0.0'
66
- gem 'rdoc', '6.6.0'
68
+ gem 'rdoc', '6.6.2'
67
69
  gem 'rest-client', '2.1.0'
68
70
  gem 'rex', '2.0.13'
69
71
  gem 'rmagick', '5.3.0'
70
72
  gem 'rqrcode', '2.2.0'
71
73
  gem 'rspec', '3.12.0'
72
74
  gem 'rtesseract', '3.1.3'
73
- gem 'rubocop', '1.58.0'
75
+ gem 'rubocop', '1.59.0'
74
76
  gem 'rubocop-rake', '0.6.0'
75
77
  gem 'rubocop-rspec', '2.25.0'
76
78
  gem 'ruby-audio', '1.6.1'
@@ -78,7 +80,7 @@ gem 'ruby-nmap', '1.0.2'
78
80
  gem 'ruby-saml', '1.16.0'
79
81
  gem 'rvm', '1.11.3.9'
80
82
  gem 'savon', '2.14.0'
81
- gem 'selenium-devtools', '0.119.0'
83
+ gem 'selenium-devtools', '0.120.0'
82
84
  gem 'serialport', '1.3.2'
83
85
  gem 'sinatra', '3.1.0'
84
86
  gem 'slack-ruby-client', '2.2.0'
data/README.md CHANGED
@@ -37,7 +37,7 @@ $ cd /opt/pwn
37
37
  $ ./install.sh
38
38
  $ ./install.sh ruby-gem
39
39
  $ pwn
40
- pwn[v0.4.935]:001 >>> PWN.help
40
+ pwn[v0.4.937]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](https://youtu.be/G7iLUY4FzsI)
@@ -52,7 +52,7 @@ $ rvm use ruby-3.2.2@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.4.935]:001 >>> PWN.help
55
+ pwn[v0.4.937]:001 >>> PWN.help
56
56
  ```
57
57
 
58
58
  If you're using a multi-user install of RVM do:
@@ -62,7 +62,7 @@ $ rvm use ruby-3.2.2@pwn
62
62
  $ rvmsudo gem uninstall --all --executables pwn
63
63
  $ rvmsudo gem install --verbose pwn
64
64
  $ pwn
65
- pwn[v0.4.935]:001 >>> PWN.help
65
+ pwn[v0.4.937]:001 >>> PWN.help
66
66
  ```
67
67
 
68
68
 
@@ -61,6 +61,18 @@ OptionParser.new do |options|
61
61
  options.on('-g', '--create-finding-groups', '<Optional - group similar findings into one finding (defaults to false)') do |g|
62
62
  opts[:create_finding_groups] = g
63
63
  end
64
+
65
+ options.on('-c', '--close-old-findings-product-scope', '<Optional - close old findings from the engagement (defaults to false)') do |c|
66
+ opts[:close_old_findings_product_scope] = c
67
+ end
68
+
69
+ options.on('-C', '--close-old-findings', '<Optional - close old findings, regardless of engagement (defaults to false)') do |c|
70
+ opts[:close_old_findings] = c
71
+ end
72
+
73
+ options.on('-j', '--push-to-jira', '<Optional - push findings to JIRA (defaults to false)') do |j|
74
+ opts[:push_to_jira] = j
75
+ end
64
76
  end.parse!
65
77
 
66
78
  if opts.empty?
@@ -84,6 +96,9 @@ minimum_severity = opts[:minimum_severity]
84
96
  scan_date = opts[:scan_date]
85
97
  verified = opts[:verified]
86
98
  create_findings_groups = opts[:create_finding_groups]
99
+ close_old_findings_product_scope = opts[:close_old_findings_product_scope]
100
+ close_old_findings = opts[:close_old_findings]
101
+ push_to_jira = opts[:push_to_jira]
87
102
 
88
103
  begin
89
104
  dd_obj = PWN::Plugins::DefectDojo.login(
@@ -103,7 +118,10 @@ begin
103
118
  minimum_severity: minimum_severity,
104
119
  scan_date: scan_date,
105
120
  verified: verified,
106
- create_findings_groups: create_findings_groups
121
+ create_findings_groups: create_findings_groups,
122
+ close_old_findings_product_scope: close_old_findings_product_scope,
123
+ close_old_findings: close_old_findings,
124
+ push_to_jira: push_to_jira
107
125
  )
108
126
  rescue StandardError => e
109
127
  raise e
@@ -61,6 +61,18 @@ OptionParser.new do |options|
61
61
  options.on('-g', '--create-finding-groups', '<Optional - group similar findings into one finding (defaults to false)') do |g|
62
62
  opts[:create_finding_groups] = g
63
63
  end
64
+
65
+ options.on('-c', '--close-old-findings-product-scope', '<Optional - close old findings from the engagement (defaults to false)') do |c|
66
+ opts[:close_old_findings_product_scope] = c
67
+ end
68
+
69
+ options.on('-C', '--close-old-findings', '<Optional - close old findings, regardless of engagement (defaults to false)') do |c|
70
+ opts[:close_old_findings] = c
71
+ end
72
+
73
+ options.on('-j', '--push-to-jira', '<Optional - push findings to JIRA (defaults to false)') do |j|
74
+ opts[:push_to_jira] = j
75
+ end
64
76
  end.parse!
65
77
 
66
78
  if opts.empty?
@@ -84,6 +96,9 @@ minimum_severity = opts[:minimum_severity]
84
96
  scan_date = opts[:scan_date]
85
97
  verified = opts[:verified]
86
98
  create_finding_groups = opts[:create_finding_groups]
99
+ close_old_findings_product_scope = opts[:close_old_findings_product_scope]
100
+ close_old_findings = opts[:close_old_findings]
101
+ push_to_jira = opts[:push_to_jira]
87
102
 
88
103
  begin
89
104
  dd_obj = PWN::Plugins::DefectDojo.login(
@@ -103,7 +118,10 @@ begin
103
118
  minimum_severity: minimum_severity,
104
119
  scan_date: scan_date,
105
120
  verified: verified,
106
- create_finding_groups: create_finding_groups
121
+ create_finding_groups: create_finding_groups,
122
+ close_old_findings_product_scope: close_old_findings_product_scope,
123
+ close_old_findings: close_old_findings,
124
+ push_to_jira: push_to_jira
107
125
  )
108
126
  rescue StandardError => e
109
127
  raise e
@@ -388,6 +388,9 @@ module PWN
388
388
  # scan_date: 'optional - date in which scan was kicked off (defaults to now)',
389
389
  # verified: 'optional - flag finding as verified by a tester (defaults to false)',
390
390
  # create_finding_groups: 'optional - flag to create finding groups (defaults to false)'
391
+ # close_old_findings_product_scope: 'optional - flag to close old findings from engagement (defaults to false)',
392
+ # close_old_findings: 'optional - flag to close old findings, regardless of engagement (defaults to false)',
393
+ # push_to_jira: 'optional - flag to push findings to JIRA (defaults to false)'
391
394
  # )
392
395
 
393
396
  public_class_method def self.importscan(opts = {})
@@ -446,7 +449,7 @@ module PWN
446
449
  http_body[:lead] = user_by_username_object.first[:id]
447
450
  end
448
451
 
449
- http_body[:tags] = opts[:tags].to_s.strip.chomp.scrub
452
+ http_body[:tags] = opts[:tags].to_s.strip.chomp.scrub.gsub("\s,\s", ',').split(',') if opts[:tags]
450
453
 
451
454
  minimum_severity = opts[:minimum_severity].to_s.strip.chomp.scrub.downcase.capitalize
452
455
  case minimum_severity
@@ -465,6 +468,12 @@ module PWN
465
468
 
466
469
  opts[:create_finding_groups] ? (http_body[:create_finding_groups_for_all_findings] = true) : (http_body[:create_finding_groups_for_all_findings] = false)
467
470
 
471
+ opts[:close_old_findings_product_scope] ? (http_body[:close_old_findings_product_scope] = true) : (http_body[:close_old_findings_product_scope] = false)
472
+
473
+ opts[:close_old_findings] ? (http_body[:close_old_findings] = true) : (http_body[:close_old_findings] = false)
474
+
475
+ opts[:push_to_jira] ? (http_body[:push_to_jira] = true) : (http_body[:push_to_jira] = false)
476
+
468
477
  api_path = 'import-scan/'
469
478
  api_path = 'importscan/' if api_version == 'v1'
470
479
 
@@ -489,7 +498,10 @@ module PWN
489
498
  # minimum_severity: 'optional - minimum finding severity Info||Low||Medium||High||Critical (Defaults to Info)',
490
499
  # scan_date: 'optional - date in which scan was kicked off (defaults to now)',
491
500
  # verified: 'optional - flag finding as verified by a tester (defaults to false)',
492
- # create_finding_groups: 'optional - flag to create finding groups (defaults to false)'
501
+ # create_finding_groups: 'optional - flag to create finding groups (defaults to false)',
502
+ # close_old_findings_product_scope: 'optional - flag to close old findings from engagement (defaults to false)',
503
+ # close_old_findings: 'optional - flag to close old findings, regardless of engagement (defaults to false)',
504
+ # push_to_jira: 'optional - flag to push findings to JIRA (defaults to false)'
493
505
  # )
494
506
 
495
507
  public_class_method def self.reimportscan(opts = {})
@@ -543,13 +555,11 @@ module PWN
543
555
  end
544
556
  end
545
557
 
546
- tags = opts[:tags].to_s.strip.chomp.scrub
547
558
  # TODO: wait for solution to:
548
559
  # https://github.com/DefectDojo/django-DefectDojo/issues/457
549
560
  # in order to obtain the unique test resource_uri
550
561
  # by searching tags for unique identifier (would be better to have a unique test names)
551
-
552
- http_body[:tags] = tags
562
+ http_body[:tags] = opts[:tags].to_s.strip.chomp.scrub.gsub("\s,\s", ',').split(',') if opts[:tags]
553
563
 
554
564
  http_body[:test] = opts[:test_resource_uri] if opts[:test_resource_uri]
555
565
 
@@ -570,6 +580,12 @@ module PWN
570
580
 
571
581
  opts[:create_finding_groups] ? (http_body[:create_finding_groups_for_all_findings] = true) : (http_body[:create_finding_groups_for_all_findings] = false)
572
582
 
583
+ opts[:close_old_findings_product_scope] ? (http_body[:close_old_findings_product_scope] = true) : (http_body[:close_old_findings_product_scope] = false)
584
+
585
+ opts[:close_old_findings] ? (http_body[:close_old_findings] = true) : (http_body[:close_old_findings] = false)
586
+
587
+ opts[:push_to_jira] ? (http_body[:push_to_jira] = true) : (http_body[:push_to_jira] = false)
588
+
573
589
  api_path = 'reimport-scan/'
574
590
  api_path = 'reimportscan/' if api_version == 'v1'
575
591
 
@@ -726,7 +742,10 @@ module PWN
726
742
  minimum_severity: 'optional - minimum finding severity Info||Low||Medium||High||Critical (Defaults to Info)',
727
743
  scan_date: 'optional - date in which scan was kicked off (defaults to now)',
728
744
  verified: 'optional - flag finding as verified by a tester (defaults to false)',
729
- create_finding_groups: 'optional - flag to create finding groups (defaults to false)'
745
+ create_finding_groups: 'optional - flag to create finding groups (defaults to false)',
746
+ close_old_findings_product_scope: 'optional - flag to close old findings from engagement (defaults to false)',
747
+ close_old_findings: 'optional - flag to close old findings, regardless of engagement (defaults to false)',
748
+ push_to_jira: 'optional - flag to push findings to JIRA (defaults to false)'
730
749
  )
731
750
 
732
751
  reimportscan_response = #{self}.reimportscan(
@@ -739,7 +758,10 @@ module PWN
739
758
  minimum_severity: 'optional - minimum finding severity Info||Low||Medium||High||Critical (Defaults to Info)',
740
759
  scan_date: 'optional - date in which scan was kicked off (defaults to now)',
741
760
  verified: 'optional - flag finding as verified by a tester (defaults to false)',
742
- create_finding_groups: 'optional - flag to create finding groups (defaults to false)'
761
+ create_finding_groups: 'optional - flag to create finding groups (defaults to false)',
762
+ close_old_findings_product_scope: 'optional - flag to close old findings from engagement (defaults to false)',
763
+ close_old_findings: 'optional - flag to close old findings, regardless of engagement (defaults to false)',
764
+ push_to_jira: 'optional - flag to push findings to JIRA (defaults to false)'
743
765
  )
744
766
 
745
767
  finding_list = #{self}.finding_list(
data/lib/pwn/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.4.935'
4
+ VERSION = '0.4.937'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.935
4
+ version: 0.4.937
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-01 00:00:00.000000000 Z
11
+ date: 2023-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -72,28 +72,28 @@ dependencies:
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 0.6.8
75
+ version: 0.6.9
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 0.6.8
82
+ version: 0.6.9
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: brakeman
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 6.0.1
89
+ version: 6.1.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 6.0.1
96
+ version: 6.1.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: bson
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: 2.4.22
117
+ version: 2.5.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: 2.4.22
124
+ version: 2.5.1
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: bundler-audit
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -380,14 +380,14 @@ dependencies:
380
380
  requirements:
381
381
  - - '='
382
382
  - !ruby/object:Gem::Version
383
- version: 2.7.0
383
+ version: 2.7.1
384
384
  type: :runtime
385
385
  prerelease: false
386
386
  version_requirements: !ruby/object:Gem::Requirement
387
387
  requirements:
388
388
  - - '='
389
389
  - !ruby/object:Gem::Version
390
- version: 2.7.0
390
+ version: 2.7.1
391
391
  - !ruby/object:Gem::Dependency
392
392
  name: jsonpath
393
393
  requirement: !ruby/object:Gem::Requirement
@@ -416,6 +416,20 @@ dependencies:
416
416
  - - '='
417
417
  - !ruby/object:Gem::Version
418
418
  version: 2.7.1
419
+ - !ruby/object:Gem::Dependency
420
+ name: libusb
421
+ requirement: !ruby/object:Gem::Requirement
422
+ requirements:
423
+ - - '='
424
+ - !ruby/object:Gem::Version
425
+ version: 0.6.4
426
+ type: :runtime
427
+ prerelease: false
428
+ version_requirements: !ruby/object:Gem::Requirement
429
+ requirements:
430
+ - - '='
431
+ - !ruby/object:Gem::Version
432
+ version: 0.6.4
419
433
  - !ruby/object:Gem::Dependency
420
434
  name: luhn
421
435
  requirement: !ruby/object:Gem::Requirement
@@ -590,14 +604,14 @@ dependencies:
590
604
  requirements:
591
605
  - - '='
592
606
  - !ruby/object:Gem::Version
593
- version: 0.2.0
607
+ version: 0.2.1
594
608
  type: :runtime
595
609
  prerelease: false
596
610
  version_requirements: !ruby/object:Gem::Requirement
597
611
  requirements:
598
612
  - - '='
599
613
  - !ruby/object:Gem::Version
600
- version: 0.2.0
614
+ version: 0.2.1
601
615
  - !ruby/object:Gem::Dependency
602
616
  name: os
603
617
  requirement: !ruby/object:Gem::Requirement
@@ -626,6 +640,20 @@ dependencies:
626
640
  - - '='
627
641
  - !ruby/object:Gem::Version
628
642
  version: 2.0.0
643
+ - !ruby/object:Gem::Dependency
644
+ name: packetgen
645
+ requirement: !ruby/object:Gem::Requirement
646
+ requirements:
647
+ - - '='
648
+ - !ruby/object:Gem::Version
649
+ version: 3.3.0
650
+ type: :runtime
651
+ prerelease: false
652
+ version_requirements: !ruby/object:Gem::Requirement
653
+ requirements:
654
+ - - '='
655
+ - !ruby/object:Gem::Version
656
+ version: 3.3.0
629
657
  - !ruby/object:Gem::Dependency
630
658
  name: pdf-reader
631
659
  requirement: !ruby/object:Gem::Requirement
@@ -730,14 +758,14 @@ dependencies:
730
758
  requirements:
731
759
  - - '='
732
760
  - !ruby/object:Gem::Version
733
- version: 6.6.0
761
+ version: 6.6.2
734
762
  type: :development
735
763
  prerelease: false
736
764
  version_requirements: !ruby/object:Gem::Requirement
737
765
  requirements:
738
766
  - - '='
739
767
  - !ruby/object:Gem::Version
740
- version: 6.6.0
768
+ version: 6.6.2
741
769
  - !ruby/object:Gem::Dependency
742
770
  name: rest-client
743
771
  requirement: !ruby/object:Gem::Requirement
@@ -828,14 +856,14 @@ dependencies:
828
856
  requirements:
829
857
  - - '='
830
858
  - !ruby/object:Gem::Version
831
- version: 1.58.0
859
+ version: 1.59.0
832
860
  type: :runtime
833
861
  prerelease: false
834
862
  version_requirements: !ruby/object:Gem::Requirement
835
863
  requirements:
836
864
  - - '='
837
865
  - !ruby/object:Gem::Version
838
- version: 1.58.0
866
+ version: 1.59.0
839
867
  - !ruby/object:Gem::Dependency
840
868
  name: rubocop-rake
841
869
  requirement: !ruby/object:Gem::Requirement
@@ -940,14 +968,14 @@ dependencies:
940
968
  requirements:
941
969
  - - '='
942
970
  - !ruby/object:Gem::Version
943
- version: 0.119.0
971
+ version: 0.120.0
944
972
  type: :runtime
945
973
  prerelease: false
946
974
  version_requirements: !ruby/object:Gem::Requirement
947
975
  requirements:
948
976
  - - '='
949
977
  - !ruby/object:Gem::Version
950
- version: 0.119.0
978
+ version: 0.120.0
951
979
  - !ruby/object:Gem::Dependency
952
980
  name: serialport
953
981
  requirement: !ruby/object:Gem::Requirement
@@ -2198,7 +2226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
2198
2226
  - !ruby/object:Gem::Version
2199
2227
  version: '0'
2200
2228
  requirements: []
2201
- rubygems_version: 3.4.22
2229
+ rubygems_version: 3.5.1
2202
2230
  signing_key:
2203
2231
  specification_version: 4
2204
2232
  summary: Automated Security Testing for CI/CD Pipelines & Beyond