pwn 0.5.418 → 0.5.421
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 +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile +7 -7
- data/README.md +3 -3
- data/bin/pwn_sast +5 -5
- data/etc/pwn.yaml.EXAMPLE +3 -1
- data/lib/pwn/ai/grok.rb +14 -5
- data/lib/pwn/ai/ollama.rb +13 -13
- data/lib/pwn/ai/open_ai.rb +64 -5
- data/lib/pwn/plugins/burp_suite.rb +150 -2
- data/lib/pwn/plugins/repl.rb +109 -80
- data/lib/pwn/plugins/vault.rb +3 -0
- data/lib/pwn/plugins/zaproxy.rb +11 -18
- data/lib/pwn/reports/sast.rb +8 -6
- data/lib/pwn/version.rb +1 -1
- data/third_party/pwn_rdoc.jsonl +2 -2
- metadata +15 -15
data/lib/pwn/ai/open_ai.rb
CHANGED
@@ -16,6 +16,7 @@ module PWN
|
|
16
16
|
# open_ai_rest_call(
|
17
17
|
# token: 'required - open_ai bearer token',
|
18
18
|
# http_method: 'optional HTTP method (defaults to GET)
|
19
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
19
20
|
# rest_call: 'required rest call to make per the schema',
|
20
21
|
# params: 'optional params passed in the URI or HTTP Headers',
|
21
22
|
# http_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST',
|
@@ -30,6 +31,8 @@ module PWN
|
|
30
31
|
else
|
31
32
|
opts[:http_method].to_s.scrub.to_sym
|
32
33
|
end
|
34
|
+
|
35
|
+
base_uri = opts[:base_uri] ||= 'https://api.openai.com/v1'
|
33
36
|
rest_call = opts[:rest_call].to_s.scrub
|
34
37
|
params = opts[:params]
|
35
38
|
headers = {
|
@@ -45,8 +48,6 @@ module PWN
|
|
45
48
|
|
46
49
|
spinner = opts[:spinner] || false
|
47
50
|
|
48
|
-
base_open_ai_api_uri = 'https://api.openai.com/v1'
|
49
|
-
|
50
51
|
browser_obj = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
|
51
52
|
rest_client = browser_obj[:browser]::Request
|
52
53
|
|
@@ -60,7 +61,7 @@ module PWN
|
|
60
61
|
headers[:params] = params
|
61
62
|
response = rest_client.execute(
|
62
63
|
method: http_method,
|
63
|
-
url: "#{
|
64
|
+
url: "#{base_uri}/#{rest_call}",
|
64
65
|
headers: headers,
|
65
66
|
verify_ssl: false,
|
66
67
|
timeout: timeout
|
@@ -72,7 +73,7 @@ module PWN
|
|
72
73
|
|
73
74
|
response = rest_client.execute(
|
74
75
|
method: http_method,
|
75
|
-
url: "#{
|
76
|
+
url: "#{base_uri}/#{rest_call}",
|
76
77
|
headers: headers,
|
77
78
|
payload: http_body,
|
78
79
|
verify_ssl: false,
|
@@ -81,7 +82,7 @@ module PWN
|
|
81
82
|
else
|
82
83
|
response = rest_client.execute(
|
83
84
|
method: http_method,
|
84
|
-
url: "#{
|
85
|
+
url: "#{base_uri}/#{rest_call}",
|
85
86
|
headers: headers,
|
86
87
|
payload: http_body.to_json,
|
87
88
|
verify_ssl: false,
|
@@ -108,15 +109,18 @@ module PWN
|
|
108
109
|
|
109
110
|
# Supported Method Parameters::
|
110
111
|
# response = PWN::AI::OpenAI.get_models(
|
112
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
111
113
|
# token: 'required - Bearer token',
|
112
114
|
# timeout: 'optional timeout in seconds (defaults to 180)'
|
113
115
|
# )
|
114
116
|
|
115
117
|
public_class_method def self.get_models(opts = {})
|
118
|
+
base_uri = opts[:base_uri]
|
116
119
|
token = opts[:token]
|
117
120
|
timeout = opts[:timeout]
|
118
121
|
|
119
122
|
response = open_ai_rest_call(
|
123
|
+
base_uri: base_uri,
|
120
124
|
token: token,
|
121
125
|
rest_call: 'models'
|
122
126
|
)
|
@@ -128,6 +132,7 @@ module PWN
|
|
128
132
|
|
129
133
|
# Supported Method Parameters::
|
130
134
|
# response = PWN::AI::OpenAI.chat(
|
135
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
131
136
|
# token: 'required - Bearer token',
|
132
137
|
# request: 'required - message to ChatGPT'
|
133
138
|
# model: 'optional - model to use for text generation (defaults to gpt-5-chat-latest)',
|
@@ -140,6 +145,7 @@ module PWN
|
|
140
145
|
# )
|
141
146
|
|
142
147
|
public_class_method def self.chat(opts = {})
|
148
|
+
base_uri = opts[:base_uri]
|
143
149
|
token = opts[:token]
|
144
150
|
request = opts[:request]
|
145
151
|
|
@@ -224,6 +230,7 @@ module PWN
|
|
224
230
|
spinner = opts[:spinner]
|
225
231
|
|
226
232
|
response = open_ai_rest_call(
|
233
|
+
base_uri: base_uri,
|
227
234
|
http_method: :post,
|
228
235
|
token: token,
|
229
236
|
rest_call: rest_call,
|
@@ -282,6 +289,7 @@ module PWN
|
|
282
289
|
|
283
290
|
# Supported Method Parameters::
|
284
291
|
# response = PWN::AI::OpenAI.img_gen(
|
292
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
285
293
|
# token: 'required - Bearer token',
|
286
294
|
# request: 'required - message to ChatGPT',
|
287
295
|
# n: 'optional - number of images to generate (defaults to 1)',
|
@@ -290,6 +298,7 @@ module PWN
|
|
290
298
|
# )
|
291
299
|
|
292
300
|
public_class_method def self.img_gen(opts = {})
|
301
|
+
base_uri = opts[:base_uri]
|
293
302
|
token = opts[:token]
|
294
303
|
request = opts[:request]
|
295
304
|
n = opts[:n]
|
@@ -307,6 +316,7 @@ module PWN
|
|
307
316
|
}
|
308
317
|
|
309
318
|
response = open_ai_rest_call(
|
319
|
+
base_uri: base_uri,
|
310
320
|
http_method: :post,
|
311
321
|
token: token,
|
312
322
|
rest_call: rest_call,
|
@@ -321,6 +331,7 @@ module PWN
|
|
321
331
|
|
322
332
|
# Supported Method Parameters::
|
323
333
|
# response = PWN::AI::OpenAI.vision(
|
334
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
324
335
|
# token: 'required - Bearer token',
|
325
336
|
# img_path: 'required - path or URI of image to analyze',
|
326
337
|
# request: 'optional - message to ChatGPT (defaults to, "what is in this image?")',
|
@@ -332,6 +343,7 @@ module PWN
|
|
332
343
|
# )
|
333
344
|
|
334
345
|
public_class_method def self.vision(opts = {})
|
346
|
+
base_uri = opts[:base_uri]
|
335
347
|
token = opts[:token]
|
336
348
|
img_path = opts[:img_path]
|
337
349
|
|
@@ -399,6 +411,7 @@ module PWN
|
|
399
411
|
timeout = opts[:timeout]
|
400
412
|
|
401
413
|
response = open_ai_rest_call(
|
414
|
+
base_uri: base_uri,
|
402
415
|
http_method: :post,
|
403
416
|
token: token,
|
404
417
|
rest_call: rest_call,
|
@@ -429,6 +442,7 @@ module PWN
|
|
429
442
|
|
430
443
|
# Supported Method Parameters::
|
431
444
|
# response = PWN::AI::OpenAI.create_fine_tune(
|
445
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
432
446
|
# token: 'required - Bearer token',
|
433
447
|
# training_file: 'required - JSONL that contains OpenAI training data'
|
434
448
|
# validation_file: 'optional - JSONL that contains OpenAI validation data'
|
@@ -445,6 +459,7 @@ module PWN
|
|
445
459
|
# )
|
446
460
|
|
447
461
|
public_class_method def self.create_fine_tune(opts = {})
|
462
|
+
base_uri = opts[:base_uri]
|
448
463
|
token = opts[:token]
|
449
464
|
training_file = opts[:training_file]
|
450
465
|
validation_file = opts[:validation_file]
|
@@ -462,6 +477,7 @@ module PWN
|
|
462
477
|
timeout = opts[:timeout]
|
463
478
|
|
464
479
|
response = upload_file(
|
480
|
+
base_uri: base_uri,
|
465
481
|
token: token,
|
466
482
|
file: training_file
|
467
483
|
)
|
@@ -469,6 +485,7 @@ module PWN
|
|
469
485
|
|
470
486
|
if validation_file
|
471
487
|
response = upload_file(
|
488
|
+
base_uri: base_uri,
|
472
489
|
token: token,
|
473
490
|
file: validation_file
|
474
491
|
)
|
@@ -492,6 +509,7 @@ module PWN
|
|
492
509
|
http_body[:suffix] = suffix if suffix
|
493
510
|
|
494
511
|
response = open_ai_rest_call(
|
512
|
+
base_uri: base_uri,
|
495
513
|
http_method: :post,
|
496
514
|
token: token,
|
497
515
|
rest_call: 'fine_tuning/jobs',
|
@@ -506,15 +524,18 @@ module PWN
|
|
506
524
|
|
507
525
|
# Supported Method Parameters::
|
508
526
|
# response = PWN::AI::OpenAI.list_fine_tunes(
|
527
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
509
528
|
# token: 'required - Bearer token',
|
510
529
|
# timeout: 'optional - timeout in seconds (defaults to 180)'
|
511
530
|
# )
|
512
531
|
|
513
532
|
public_class_method def self.list_fine_tunes(opts = {})
|
533
|
+
base_uri = opts[:base_uri]
|
514
534
|
token = opts[:token]
|
515
535
|
timeout = opts[:timeout]
|
516
536
|
|
517
537
|
response = open_ai_rest_call(
|
538
|
+
base_uri: base_uri,
|
518
539
|
token: token,
|
519
540
|
rest_call: 'fine_tuning/jobs',
|
520
541
|
timeout: timeout
|
@@ -527,12 +548,14 @@ module PWN
|
|
527
548
|
|
528
549
|
# Supported Method Parameters::
|
529
550
|
# response = PWN::AI::OpenAI.get_fine_tune_status(
|
551
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
530
552
|
# token: 'required - Bearer token',
|
531
553
|
# fine_tune_id: 'required - respective :id value returned from #list_fine_tunes',
|
532
554
|
# timeout: 'optional - timeout in seconds (defaults to 180)'
|
533
555
|
# )
|
534
556
|
|
535
557
|
public_class_method def self.get_fine_tune_status(opts = {})
|
558
|
+
base_uri = opts[:base_uri]
|
536
559
|
token = opts[:token]
|
537
560
|
fine_tune_id = opts[:fine_tune_id]
|
538
561
|
timeout = opts[:timeout]
|
@@ -540,6 +563,7 @@ module PWN
|
|
540
563
|
rest_call = "fine_tuning/jobs/#{fine_tune_id}"
|
541
564
|
|
542
565
|
response = open_ai_rest_call(
|
566
|
+
base_uri: base_uri,
|
543
567
|
token: token,
|
544
568
|
rest_call: rest_call,
|
545
569
|
timeout: timeout
|
@@ -552,12 +576,14 @@ module PWN
|
|
552
576
|
|
553
577
|
# Supported Method Parameters::
|
554
578
|
# response = PWN::AI::OpenAI.cancel_fine_tune(
|
579
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
555
580
|
# token: 'required - Bearer token',
|
556
581
|
# fine_tune_id: 'required - respective :id value returned from #list_fine_tunes',
|
557
582
|
# timeout: 'optional - timeout in seconds (defaults to 180)'
|
558
583
|
# )
|
559
584
|
|
560
585
|
public_class_method def self.cancel_fine_tune(opts = {})
|
586
|
+
base_uri = opts[:base_uri]
|
561
587
|
token = opts[:token]
|
562
588
|
fine_tune_id = opts[:fine_tune_id]
|
563
589
|
timeout = opts[:timeout]
|
@@ -565,6 +591,7 @@ module PWN
|
|
565
591
|
rest_call = "fine_tuning/jobs/#{fine_tune_id}/cancel"
|
566
592
|
|
567
593
|
response = open_ai_rest_call(
|
594
|
+
base_uri: base_uri,
|
568
595
|
http_method: :post,
|
569
596
|
token: token,
|
570
597
|
rest_call: rest_call,
|
@@ -578,12 +605,14 @@ module PWN
|
|
578
605
|
|
579
606
|
# Supported Method Parameters::
|
580
607
|
# response = PWN::AI::OpenAI.get_fine_tune_events(
|
608
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
581
609
|
# token: 'required - Bearer token',
|
582
610
|
# fine_tune_id: 'required - respective :id value returned from #list_fine_tunes',
|
583
611
|
# timeout: 'optional - timeout in seconds (defaults to 180)'
|
584
612
|
# )
|
585
613
|
|
586
614
|
public_class_method def self.get_fine_tune_events(opts = {})
|
615
|
+
base_uri = opts[:base_uri]
|
587
616
|
token = opts[:token]
|
588
617
|
fine_tune_id = opts[:fine_tune_id]
|
589
618
|
timeout = opts[:timeout]
|
@@ -591,6 +620,7 @@ module PWN
|
|
591
620
|
rest_call = "fine_tuning/jobs/#{fine_tune_id}/events"
|
592
621
|
|
593
622
|
response = open_ai_rest_call(
|
623
|
+
base_uri: base_uri,
|
594
624
|
token: token,
|
595
625
|
rest_call: rest_call,
|
596
626
|
timeout: timeout
|
@@ -603,12 +633,14 @@ module PWN
|
|
603
633
|
|
604
634
|
# Supported Method Parameters::
|
605
635
|
# response = PWN::AI::OpenAI.delete_fine_tune_model(
|
636
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
606
637
|
# token: 'required - Bearer token',
|
607
638
|
# model: 'required - model to delete',
|
608
639
|
# timeout: 'optional - timeout in seconds (defaults to 180)'
|
609
640
|
# )
|
610
641
|
|
611
642
|
public_class_method def self.delete_fine_tune_model(opts = {})
|
643
|
+
base_uri = opts[:base_uri]
|
612
644
|
token = opts[:token]
|
613
645
|
model = opts[:model]
|
614
646
|
timeout = opts[:timeout]
|
@@ -616,6 +648,7 @@ module PWN
|
|
616
648
|
rest_call = "models/#{model}"
|
617
649
|
|
618
650
|
response = open_ai_rest_call(
|
651
|
+
base_uri: base_uri,
|
619
652
|
http_method: :delete,
|
620
653
|
token: token,
|
621
654
|
rest_call: rest_call,
|
@@ -629,15 +662,18 @@ module PWN
|
|
629
662
|
|
630
663
|
# Supported Method Parameters::
|
631
664
|
# response = PWN::AI::OpenAI.list_files(
|
665
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
632
666
|
# token: 'required - Bearer token',
|
633
667
|
# timeout: 'optional - timeout in seconds (defaults to 180)'
|
634
668
|
# )
|
635
669
|
|
636
670
|
public_class_method def self.list_files(opts = {})
|
671
|
+
base_uri = opts[:base_uri]
|
637
672
|
token = opts[:token]
|
638
673
|
timeout = opts[:timeout]
|
639
674
|
|
640
675
|
response = open_ai_rest_call(
|
676
|
+
base_uri: base_uri,
|
641
677
|
token: token,
|
642
678
|
rest_call: 'files',
|
643
679
|
timeout: timeout
|
@@ -650,6 +686,7 @@ module PWN
|
|
650
686
|
|
651
687
|
# Supported Method Parameters::
|
652
688
|
# response = PWN::AI::OpenAI.upload_file(
|
689
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
653
690
|
# token: 'required - Bearer token',
|
654
691
|
# file: 'required - file to upload',
|
655
692
|
# purpose: 'optional - intended purpose of the uploaded documents (defaults to fine-tune',
|
@@ -657,6 +694,7 @@ module PWN
|
|
657
694
|
# )
|
658
695
|
|
659
696
|
public_class_method def self.upload_file(opts = {})
|
697
|
+
base_uri = opts[:base_uri]
|
660
698
|
token = opts[:token]
|
661
699
|
file = opts[:file]
|
662
700
|
raise "ERROR: #{file} not found." unless File.exist?(file)
|
@@ -672,6 +710,7 @@ module PWN
|
|
672
710
|
}
|
673
711
|
|
674
712
|
response = open_ai_rest_call(
|
713
|
+
base_uri: base_uri,
|
675
714
|
http_method: :post,
|
676
715
|
token: token,
|
677
716
|
rest_call: 'files',
|
@@ -686,12 +725,14 @@ module PWN
|
|
686
725
|
|
687
726
|
# Supported Method Parameters::
|
688
727
|
# response = PWN::AI::OpenAI.delete_file(
|
728
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
689
729
|
# token: 'required - Bearer token',
|
690
730
|
# file: 'required - file to delete',
|
691
731
|
# timeout: 'optional - timeout in seconds (defaults to 180)'
|
692
732
|
# )
|
693
733
|
|
694
734
|
public_class_method def self.delete_file(opts = {})
|
735
|
+
base_uri = opts[:base_uri]
|
695
736
|
token = opts[:token]
|
696
737
|
file = opts[:file]
|
697
738
|
timeout = opts[:timeout]
|
@@ -702,6 +743,7 @@ module PWN
|
|
702
743
|
rest_call = "files/#{file_id}"
|
703
744
|
|
704
745
|
response = open_ai_rest_call(
|
746
|
+
base_uri: base_uri,
|
705
747
|
http_method: :delete,
|
706
748
|
token: token,
|
707
749
|
rest_call: rest_call,
|
@@ -715,12 +757,14 @@ module PWN
|
|
715
757
|
|
716
758
|
# Supported Method Parameters::
|
717
759
|
# response = PWN::AI::OpenAI.get_file(
|
760
|
+
# base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
718
761
|
# token: 'required - Bearer token',
|
719
762
|
# file: 'required - file to delete',
|
720
763
|
# timeout: 'optional - timeout in seconds (defaults to 180)'
|
721
764
|
# )
|
722
765
|
|
723
766
|
public_class_method def self.get_file(opts = {})
|
767
|
+
base_uri = opts[:base_uri]
|
724
768
|
token = opts[:token]
|
725
769
|
file = opts[:file]
|
726
770
|
raise "ERROR: #{file} not found." unless File.exist?(file)
|
@@ -733,6 +777,7 @@ module PWN
|
|
733
777
|
rest_call = "files/#{file_id}"
|
734
778
|
|
735
779
|
response = open_ai_rest_call(
|
780
|
+
base_uri: base_uri,
|
736
781
|
token: token,
|
737
782
|
rest_call: rest_call,
|
738
783
|
timeout: timeout
|
@@ -756,11 +801,13 @@ module PWN
|
|
756
801
|
public_class_method def self.help
|
757
802
|
puts "USAGE:
|
758
803
|
response = #{self}.get_models(
|
804
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
759
805
|
token: 'required - Bearer token',
|
760
806
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
761
807
|
)
|
762
808
|
|
763
809
|
response = #{self}.chat(
|
810
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
764
811
|
token: 'required - Bearer token',
|
765
812
|
request: 'required - message to ChatGPT',
|
766
813
|
model: 'optional - model to use for text generation (defaults to gpt-5-chat-latest)',
|
@@ -773,6 +820,7 @@ module PWN
|
|
773
820
|
)
|
774
821
|
|
775
822
|
response = #{self}.img_gen(
|
823
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
776
824
|
token: 'required - Bearer token',
|
777
825
|
request: 'required - message to ChatGPT',
|
778
826
|
n: 'optional - number of images to generate (defaults to 1)',
|
@@ -781,6 +829,7 @@ module PWN
|
|
781
829
|
)
|
782
830
|
|
783
831
|
response = #{self}.vision(
|
832
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
784
833
|
token: 'required - Bearer token',
|
785
834
|
img_path: 'required - path or URI of image to analyze',
|
786
835
|
request: 'optional - message to ChatGPT (defaults to, \"what is in this image?\")',
|
@@ -792,6 +841,7 @@ module PWN
|
|
792
841
|
)
|
793
842
|
|
794
843
|
response = #{self}.create_fine_tune(
|
844
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
795
845
|
token: 'required - Bearer token',
|
796
846
|
training_file: 'required - JSONL that contains OpenAI training data'
|
797
847
|
validation_file: 'optional - JSONL that contains OpenAI validation data'
|
@@ -808,52 +858,61 @@ module PWN
|
|
808
858
|
)
|
809
859
|
|
810
860
|
response = #{self}.list_fine_tunes(
|
861
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
811
862
|
token: 'required - Bearer token',
|
812
863
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
813
864
|
)
|
814
865
|
|
815
866
|
response = #{self}.get_fine_tune_status(
|
867
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
816
868
|
token: 'required - Bearer token',
|
817
869
|
fine_tune_id: 'required - respective :id value returned from #list_fine_tunes',
|
818
870
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
819
871
|
)
|
820
872
|
|
821
873
|
response = #{self}.cancel_fine_tune(
|
874
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
822
875
|
token: 'required - Bearer token',
|
823
876
|
fine_tune_id: 'required - respective :id value returned from #list_fine_tunes',
|
824
877
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
825
878
|
)
|
826
879
|
|
827
880
|
response = #{self}.get_fine_tune_events(
|
881
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
828
882
|
token: 'required - Bearer token',
|
829
883
|
fine_tune_id: 'required - respective :id value returned from #list_fine_tunes',
|
830
884
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
831
885
|
)
|
832
886
|
|
833
887
|
response = #{self}.delete_fine_tune_model(
|
888
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
834
889
|
token: 'required - Bearer token',
|
835
890
|
model: 'required - model to delete',
|
836
891
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
837
892
|
)
|
838
893
|
|
839
894
|
response = #{self}.list_files(
|
895
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
840
896
|
token: 'required - Bearer token',
|
841
897
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
842
898
|
)
|
843
899
|
|
844
900
|
response = #{self}.upload_file(
|
901
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
845
902
|
token: 'required - Bearer token',
|
846
903
|
file: 'required - file to upload',
|
847
904
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
848
905
|
)
|
849
906
|
|
850
907
|
response = #{self}.delete_file(
|
908
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
851
909
|
token: 'required - Bearer token',
|
852
910
|
file: 'required - file to delete',
|
853
911
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
854
912
|
)
|
855
913
|
|
856
914
|
response = #{self}.get_file(
|
915
|
+
base_uri: 'optional - base OpenAI API URI (defaults to https://api.openai.com/v1)',
|
857
916
|
token: 'required - Bearer token',
|
858
917
|
file: 'required - file to delete',
|
859
918
|
timeout: 'optional - timeout in seconds (defaults to 180)'
|
@@ -360,7 +360,8 @@ module PWN
|
|
360
360
|
# Supported Method Parameters::
|
361
361
|
# json_sitemap = PWN::Plugins::BurpSuite.get_sitemap(
|
362
362
|
# burp_obj: 'required - burp_obj returned by #start method',
|
363
|
-
# keyword: 'optional - keyword to filter sitemap entries (default: nil)'
|
363
|
+
# keyword: 'optional - keyword to filter sitemap entries (default: nil)',
|
364
|
+
# return_as: 'optional - :base64 or :har (defaults to :base64)'
|
364
365
|
# )
|
365
366
|
|
366
367
|
public_class_method def self.get_sitemap(opts = {})
|
@@ -368,6 +369,7 @@ module PWN
|
|
368
369
|
rest_browser = burp_obj[:rest_browser]
|
369
370
|
mitm_rest_api = burp_obj[:mitm_rest_api]
|
370
371
|
keyword = opts[:keyword]
|
372
|
+
return_as = opts[:return_as] ||= :base64
|
371
373
|
|
372
374
|
rest_call = "http://#{mitm_rest_api}/sitemap"
|
373
375
|
|
@@ -385,6 +387,151 @@ module PWN
|
|
385
387
|
end
|
386
388
|
end
|
387
389
|
|
390
|
+
if return_as == :har
|
391
|
+
# Convert to HAR format
|
392
|
+
har_entries = sitemap_arr.map do |site|
|
393
|
+
decoded_request = Base64.strict_decode64(site[:request])
|
394
|
+
|
395
|
+
# Parse request head and body
|
396
|
+
if decoded_request.include?("\r\n\r\n")
|
397
|
+
request_head, request_body = decoded_request.split("\r\n\r\n", 2)
|
398
|
+
else
|
399
|
+
request_head = decoded_request
|
400
|
+
request_body = ''
|
401
|
+
end
|
402
|
+
request_lines = request_head.split("\r\n")
|
403
|
+
request_line = request_lines.shift
|
404
|
+
method, full_path, http_version = request_line.split(' ', 3)
|
405
|
+
headers = {}
|
406
|
+
request_lines.each do |line|
|
407
|
+
next if line.empty?
|
408
|
+
|
409
|
+
key, value = line.split(': ', 2)
|
410
|
+
headers[key] = value if key && value
|
411
|
+
end
|
412
|
+
|
413
|
+
host = headers['Host'] || raise('No Host header found in request')
|
414
|
+
scheme = 'http' # Hardcoded as protocol is not available; consider enhancing if available in site
|
415
|
+
url = "#{scheme}://#{host}#{full_path}"
|
416
|
+
uri = URI.parse(url)
|
417
|
+
query_string = uri.query ? URI.decode_www_form(uri.query).map { |k, v| { name: k, value: v.to_s } } : []
|
418
|
+
|
419
|
+
request_headers_size = request_head.bytesize + 4 # Account for \r\n\r\n
|
420
|
+
request_body_size = request_body.bytesize
|
421
|
+
|
422
|
+
request_obj = {
|
423
|
+
method: method,
|
424
|
+
url: uri.to_s,
|
425
|
+
httpVersion: http_version,
|
426
|
+
headers: headers.map { |k, v| { name: k, value: v } },
|
427
|
+
queryString: query_string,
|
428
|
+
headersSize: request_headers_size,
|
429
|
+
bodySize: request_body_size
|
430
|
+
}
|
431
|
+
|
432
|
+
if request_body_size.positive?
|
433
|
+
mime_type = headers['Content-Type'] || 'application/octet-stream'
|
434
|
+
post_data = {
|
435
|
+
mimeType: mime_type,
|
436
|
+
text: request_body
|
437
|
+
}
|
438
|
+
post_data[:params] = URI.decode_www_form(request_body).map { |k, v| { name: k, value: v.to_s } } if mime_type.include?('x-www-form-urlencoded')
|
439
|
+
request_obj[:postData] = post_data
|
440
|
+
end
|
441
|
+
|
442
|
+
if site[:response]
|
443
|
+
decoded_response = Base64.strict_decode64(site[:response])
|
444
|
+
|
445
|
+
# Parse response head and body
|
446
|
+
if decoded_response.include?("\r\n\r\n")
|
447
|
+
response_head, response_body = decoded_response.split("\r\n\r\n", 2)
|
448
|
+
else
|
449
|
+
response_head = decoded_response
|
450
|
+
response_body = ''
|
451
|
+
end
|
452
|
+
response_lines = response_head.split("\r\n")
|
453
|
+
status_line = response_lines.shift
|
454
|
+
version, status_str, status_text = status_line.split(' ', 3)
|
455
|
+
status = status_str.to_i
|
456
|
+
status_text ||= ''
|
457
|
+
response_headers = {}
|
458
|
+
response_lines.each do |line|
|
459
|
+
next if line.empty?
|
460
|
+
|
461
|
+
key, value = line.split(': ', 2)
|
462
|
+
response_headers[key] = value if key && value
|
463
|
+
end
|
464
|
+
|
465
|
+
response_headers_size = response_head.bytesize + 4 # Account for \r\n\r\n
|
466
|
+
response_body_size = response_body.bytesize
|
467
|
+
mime_type = response_headers['Content-Type'] || 'text/plain'
|
468
|
+
|
469
|
+
response_obj = {
|
470
|
+
status: status,
|
471
|
+
statusText: status_text,
|
472
|
+
httpVersion: version,
|
473
|
+
headers: response_headers.map { |k, v| { name: k, value: v } },
|
474
|
+
content: {
|
475
|
+
size: response_body_size,
|
476
|
+
mimeType: mime_type,
|
477
|
+
text: response_body
|
478
|
+
},
|
479
|
+
redirectURL: response_headers['Location'] || '',
|
480
|
+
headersSize: response_headers_size,
|
481
|
+
bodySize: response_body_size
|
482
|
+
}
|
483
|
+
else
|
484
|
+
response_obj = {
|
485
|
+
status: 0,
|
486
|
+
statusText: 'No response',
|
487
|
+
httpVersion: 'unknown',
|
488
|
+
headers: [],
|
489
|
+
content: {
|
490
|
+
size: 0,
|
491
|
+
mimeType: 'text/plain',
|
492
|
+
text: ''
|
493
|
+
},
|
494
|
+
redirectURL: '',
|
495
|
+
headersSize: -1,
|
496
|
+
bodySize: 0
|
497
|
+
}
|
498
|
+
end
|
499
|
+
|
500
|
+
{
|
501
|
+
startedDateTime: Time.now.iso8601,
|
502
|
+
time: 0,
|
503
|
+
request: request_obj,
|
504
|
+
response: response_obj,
|
505
|
+
cache: {},
|
506
|
+
timings: {
|
507
|
+
send: 0,
|
508
|
+
wait: 0,
|
509
|
+
receive: 0
|
510
|
+
},
|
511
|
+
pageref: 'page_1'
|
512
|
+
}
|
513
|
+
end
|
514
|
+
|
515
|
+
har_log = {
|
516
|
+
log: {
|
517
|
+
version: '1.2',
|
518
|
+
creator: {
|
519
|
+
name: 'BurpSuite via PWN::Plugins::BurpSuite',
|
520
|
+
version: '1.0'
|
521
|
+
},
|
522
|
+
pages: [{
|
523
|
+
startedDateTime: Time.now.iso8601,
|
524
|
+
id: 'page_1',
|
525
|
+
title: 'Sitemap Export',
|
526
|
+
pageTimings: {}
|
527
|
+
}],
|
528
|
+
entries: har_entries
|
529
|
+
}
|
530
|
+
}
|
531
|
+
|
532
|
+
sitemap_arr = har_log
|
533
|
+
end
|
534
|
+
|
388
535
|
sitemap_arr.uniq
|
389
536
|
rescue StandardError => e
|
390
537
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -1357,7 +1504,8 @@ module PWN
|
|
1357
1504
|
|
1358
1505
|
json_sitemap = #{self}.get_sitemap(
|
1359
1506
|
burp_obj: 'required - burp_obj returned by #start method',
|
1360
|
-
keyword: 'optional - keyword to filter sitemap results (default: nil)'
|
1507
|
+
keyword: 'optional - keyword to filter sitemap results (default: nil)',
|
1508
|
+
return_as: 'optional - :base64 or :har (defaults to :base64)'
|
1361
1509
|
)
|
1362
1510
|
|
1363
1511
|
json_sitemap = #{self}.add_to_sitemap(
|