gophish-ruby 0.2.0 → 0.4.0

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: ba7f348fc87e10ad752fe1b59ce329357ca0948dc180b5e5912210fc55a82a44
4
- data.tar.gz: bbfd2bad8612b3814f04820c9bcb3e13cf21352b2712e13c85a2cce37c3e4cf5
3
+ metadata.gz: aadeeb636e448907a3b5f3e33427c19373d903c52f8961b99b28265fe94872de
4
+ data.tar.gz: 9ef3e492ec39d8ce16327018358c0d873c70ebc20fb8064d4909d9ec66a9a3f4
5
5
  SHA512:
6
- metadata.gz: 697688a9381c1f53c4174e0d3922b4effc5d582dbd56dd0c71d40370126fb287e143ea7ee18fab7856cff52fc19d16ab6514baa04ca8759a3a8e6997cece2b97
7
- data.tar.gz: 48965fe82e77390d55df53cbc9c763edc411e055dadcd51fd7852dba49f17ac519b48a7986a021be2b7eb7ca40153a3effee4d5b999887fa400052f31a437d95
6
+ metadata.gz: a2678d8b475ef9c5c970a625f9b294ed95afde10781f5251cee81160240a80864654158887fa2df6a7b1ef17c6e7a325a4a3e051b536b72942f4f8123018ee9a
7
+ data.tar.gz: 94b1ae168de255a5e8d1154285b6b786070a1271b689965e503d5c87a6339ed959ce2df6c41a78fb5e87da245b5bc49961a29debc3a11b67b36e92722cee43ca
data/CHANGELOG.md CHANGED
@@ -7,10 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2025-01-15
11
+
10
12
  ### Added
13
+
14
+ - **Page Management System**
15
+ - `Gophish::Page` class for managing landing pages in phishing campaigns
16
+ - Full CRUD operations for pages (create, read, update, delete)
17
+ - Support for HTML content with credential capture capabilities
18
+ - Comprehensive validations requiring page name and HTML content
19
+ - Site import functionality with `Page.import_site` class method
20
+ - Option to include resources (CSS, JS, images) during site import
21
+ - Built-in methods for checking page configuration: `#captures_credentials?`, `#captures_passwords?`, `#has_redirect?`
22
+
11
23
  - **Template Management System**
12
24
  - `Gophish::Template` class for managing email templates
13
- - Full CRUD operations for templates (create, read, update, delete)
25
+ - Full CRUD operations for templates (create, read, update, delete)
14
26
  - Support for HTML and plain text email content
15
27
  - Comprehensive validations requiring template name and content
16
28
  - Email import functionality with `Template.import_email` class method
@@ -32,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
32
44
  - Enhanced README with detailed usage instructions and configuration examples
33
45
 
34
46
  ### Changed
47
+
35
48
  - **Breaking Change**: Replaced custom `@changed_attributes` system with ActiveModel::Dirty
36
49
  - Updated Base class to use `define_attribute_methods` for proper dirty tracking
37
50
  - Modified `#update_record` to include `id` in update payload for proper API calls
@@ -39,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
39
52
  - Enhanced CSV import validation with better error reporting
40
53
 
41
54
  ### Fixed
55
+
42
56
  - Console script requiring wrong file name (`gophish_ruby` → `gophish-ruby`)
43
57
  - Spec helper requiring wrong file name for consistent naming
44
58
  - Corrected require statement in main library file for Template class
@@ -46,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
46
60
  ## [0.1.0] - 2025-08-29
47
61
 
48
62
  ### Added
63
+
49
64
  - **Core SDK Foundation**
50
65
  - `Gophish::Configuration` class for managing API credentials and settings
51
66
  - `Gophish::Base` abstract class providing common CRUD operations
@@ -92,12 +107,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
92
107
  - Rake tasks for testing and quality checks
93
108
 
94
109
  ### Technical Details
110
+
95
111
  - **Dependencies**: HTTParty 0.23.1, ActiveSupport/ActiveModel/ActiveRecord 8.0+
96
112
  - **Ruby Version**: Requires Ruby >= 3.1.0
97
113
  - **Architecture**: Modular design with inheritance-based API resources
98
114
  - **Security**: Built-in API key authentication for all requests
99
115
 
100
116
  ### Development Infrastructure
117
+
101
118
  - Bundler gem management with proper gemspec configuration
102
119
  - GitHub integration with proper repository URLs and metadata
103
120
  - MIT license for open source distribution
data/README.md CHANGED
@@ -13,6 +13,8 @@ A Ruby SDK for the [Gophish](https://getgophish.com/) phishing simulation platfo
13
13
  - **CSV Import Support**: Easy bulk import of targets from CSV files
14
14
  - **Email Template Management**: Create, modify, and manage email templates with attachment support
15
15
  - **Email Import**: Import existing emails and convert them to templates
16
+ - **Site Import**: Import landing pages directly from existing websites
17
+ - **Page Management**: Create, modify, and manage landing pages with credential capture
16
18
  - **SSL Configuration**: Configurable SSL verification for development environments
17
19
  - **Debug Support**: Built-in debugging capabilities for API interactions
18
20
  - **Change Tracking**: Automatic tracking of attribute changes with ActiveModel::Dirty
@@ -301,6 +303,174 @@ puts group.attribute_changed?(:name) # => true
301
303
  puts group.attribute_was(:name) # => "Original Name"
302
304
  ```
303
305
 
306
+ ### Pages Management
307
+
308
+ Pages represent landing pages that targets will see when they click on phishing links in your campaigns.
309
+
310
+ #### Creating a Page
311
+
312
+ ```ruby
313
+ # Create a simple landing page
314
+ page = Gophish::Page.new(
315
+ name: "Microsoft Login Page",
316
+ html: <<~HTML
317
+ <!DOCTYPE html>
318
+ <html>
319
+ <head>
320
+ <title>Microsoft Account Login</title>
321
+ <style>
322
+ body { font-family: Arial, sans-serif; margin: 0; padding: 40px; background-color: #f5f5f5; }
323
+ .login-container { max-width: 400px; margin: 0 auto; background: white; padding: 40px; border-radius: 8px; }
324
+ .form-group { margin-bottom: 20px; }
325
+ input { width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 4px; }
326
+ button { width: 100%; padding: 12px; background: #0078d4; color: white; border: none; border-radius: 4px; }
327
+ </style>
328
+ </head>
329
+ <body>
330
+ <div class="login-container">
331
+ <h2>Sign in to your account</h2>
332
+ <form method="post">
333
+ <div class="form-group">
334
+ <input type="email" name="email" placeholder="Email" required>
335
+ </div>
336
+ <div class="form-group">
337
+ <input type="password" name="password" placeholder="Password" required>
338
+ </div>
339
+ <button type="submit">Sign in</button>
340
+ </form>
341
+ </div>
342
+ </body>
343
+ </html>
344
+ HTML
345
+ )
346
+
347
+ # Save the page to Gophish
348
+ if page.save
349
+ puts "Page created successfully with ID: #{page.id}"
350
+ else
351
+ puts "Failed to create page: #{page.errors.full_messages}"
352
+ end
353
+ ```
354
+
355
+ #### Creating a Page with Credential Capture
356
+
357
+ ```ruby
358
+ # Create a page that captures login credentials
359
+ page = Gophish::Page.new(
360
+ name: "Banking Login - Credential Capture",
361
+ html: <<~HTML
362
+ <html>
363
+ <body>
364
+ <h1>Online Banking</h1>
365
+ <form method="post">
366
+ <input type="text" name="username" placeholder="Username" required>
367
+ <input type="password" name="password" placeholder="Password" required>
368
+ <button type="submit">Login</button>
369
+ </form>
370
+ </body>
371
+ </html>
372
+ HTML,
373
+ capture_credentials: true,
374
+ capture_passwords: true,
375
+ redirect_url: "https://www.realbank.com/login"
376
+ )
377
+
378
+ if page.save
379
+ puts "Page created with credential capture enabled"
380
+ puts "Captures credentials: #{page.captures_credentials?}"
381
+ puts "Captures passwords: #{page.captures_passwords?}"
382
+ puts "Has redirect: #{page.has_redirect?}"
383
+ end
384
+ ```
385
+
386
+ #### Importing a Website as a Landing Page
387
+
388
+ ```ruby
389
+ # Import an existing website as a landing page template
390
+ begin
391
+ imported_data = Gophish::Page.import_site(
392
+ "https://login.microsoft.com",
393
+ include_resources: true # Include CSS, JS, and images
394
+ )
395
+
396
+ # Create a page from the imported data
397
+ page = Gophish::Page.new(imported_data)
398
+ page.name = "Imported Microsoft Login Page"
399
+ page.capture_credentials = true
400
+
401
+ if page.save
402
+ puts "Successfully imported and created page from website"
403
+ end
404
+ rescue StandardError => e
405
+ puts "Failed to import site: #{e.message}"
406
+ end
407
+ ```
408
+
409
+ #### Retrieving Pages
410
+
411
+ ```ruby
412
+ # Get all pages
413
+ pages = Gophish::Page.all
414
+ puts "Found #{pages.length} pages"
415
+
416
+ # Find a specific page by ID
417
+ page = Gophish::Page.find(1)
418
+ puts "Page: #{page.name}"
419
+ puts "HTML length: #{page.html.length} characters"
420
+ ```
421
+
422
+ #### Updating a Page
423
+
424
+ ```ruby
425
+ # Update page content and settings
426
+ page = Gophish::Page.find(1)
427
+ page.name = "Updated Page Name"
428
+ page.capture_credentials = true
429
+ page.redirect_url = "https://example.com/success"
430
+
431
+ # Update HTML content
432
+ page.html = page.html.gsub("Sign in", "Login")
433
+
434
+ if page.save
435
+ puts "Page updated successfully"
436
+ end
437
+ ```
438
+
439
+ #### Deleting a Page
440
+
441
+ ```ruby
442
+ page = Gophish::Page.find(1)
443
+ if page.destroy
444
+ puts "Page deleted successfully"
445
+ end
446
+ ```
447
+
448
+ ### Validation and Error Handling
449
+
450
+ The SDK provides comprehensive validation for pages:
451
+
452
+ ```ruby
453
+ # Invalid page (missing required fields)
454
+ page = Gophish::Page.new(name: "", html: "")
455
+
456
+ unless page.valid?
457
+ puts "Validation errors:"
458
+ page.errors.full_messages.each { |msg| puts " - #{msg}" }
459
+ # => ["Name can't be blank", "Html can't be blank"]
460
+ end
461
+
462
+ # Check page configuration
463
+ page = Gophish::Page.new(
464
+ name: "Test Page",
465
+ html: "<html><body>Test</body></html>",
466
+ capture_credentials: true
467
+ )
468
+
469
+ if page.captures_credentials?
470
+ puts "This page will capture submitted credentials"
471
+ end
472
+ ```
473
+
304
474
  ## API Documentation
305
475
 
306
476
  ### Core Classes
@@ -399,6 +569,35 @@ Each attachment in the `attachments` array should have:
399
569
  - Template must have either text or HTML content (or both)
400
570
  - All attachments must have content, type, and name
401
571
 
572
+ #### `Gophish::Page`
573
+
574
+ Represents a Gophish landing page for phishing campaigns.
575
+
576
+ **Attributes:**
577
+
578
+ - `id` (Integer) - Unique page identifier
579
+ - `name` (String) - Page name (required)
580
+ - `html` (String) - HTML content of the page (required)
581
+ - `capture_credentials` (Boolean) - Whether to capture credentials (default: false)
582
+ - `capture_passwords` (Boolean) - Whether to capture passwords (default: false)
583
+ - `redirect_url` (String) - URL to redirect users after form submission
584
+ - `modified_date` (String) - Last modification timestamp
585
+
586
+ **Class Methods:**
587
+
588
+ - `.import_site(url, include_resources: false)` - Import a website as a landing page template
589
+
590
+ **Instance Methods:**
591
+
592
+ - `#captures_credentials?` - Check if page is configured to capture credentials
593
+ - `#captures_passwords?` - Check if page is configured to capture passwords
594
+ - `#has_redirect?` - Check if page has a redirect URL configured
595
+
596
+ **Validations:**
597
+
598
+ - Page must have a name
599
+ - Page must have HTML content
600
+
402
601
  ## Development
403
602
 
404
603
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -3,7 +3,7 @@
3
3
  require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
5
 
6
- RSpec::Core::RakeTask.new(:spec)
6
+ RSpec::Core::RakeTask.new :spec
7
7
 
8
8
  require "rubocop/rake_task"
9
9
 
@@ -8,6 +8,7 @@ This document provides detailed API reference for the Gophish Ruby SDK.
8
8
  - [Base Class](#base-class)
9
9
  - [Group Class](#group-class)
10
10
  - [Template Class](#template-class)
11
+ - [Page Class](#page-class)
11
12
  - [Error Handling](#error-handling)
12
13
  - [Examples](#examples)
13
14
 
@@ -624,6 +625,325 @@ unless template.valid?
624
625
  end
625
626
  ```
626
627
 
628
+ ## Page Class
629
+
630
+ The `Gophish::Page` class represents a landing page in Gophish campaigns.
631
+
632
+ ### Class: `Gophish::Page < Gophish::Base`
633
+
634
+ #### Attributes
635
+
636
+ | Attribute | Type | Required | Description |
637
+ |-----------|------|----------|-------------|
638
+ | `id` | Integer | No | Unique page identifier (set by server) |
639
+ | `name` | String | Yes | Page name |
640
+ | `html` | String | Yes | HTML content of the page |
641
+ | `capture_credentials` | Boolean | No | Whether to capture credentials (default: false) |
642
+ | `capture_passwords` | Boolean | No | Whether to capture passwords (default: false) |
643
+ | `redirect_url` | String | No | URL to redirect users after form submission |
644
+ | `modified_date` | String | No | Last modification timestamp (set by server) |
645
+
646
+ #### Validations
647
+
648
+ - `name` must be present
649
+ - `html` must be present
650
+
651
+ #### Class Methods
652
+
653
+ ##### `.import_site(url, include_resources: false)`
654
+
655
+ Import a website as a landing page template.
656
+
657
+ **Parameters:**
658
+
659
+ - `url` (String) - URL of the website to import
660
+ - `include_resources` (Boolean) - Whether to include CSS, JS, and images (default: false)
661
+
662
+ **Returns:** Hash of page attributes
663
+
664
+ **Raises:**
665
+
666
+ - `StandardError` if import fails
667
+
668
+ **Example:**
669
+
670
+ ```ruby
671
+ begin
672
+ page_data = Gophish::Page.import_site(
673
+ "https://login.microsoft.com",
674
+ include_resources: true
675
+ )
676
+
677
+ page = Gophish::Page.new(page_data)
678
+ page.name = "Imported Microsoft Login"
679
+ page.capture_credentials = true
680
+ page.save
681
+ rescue StandardError => e
682
+ puts "Import failed: #{e.message}"
683
+ end
684
+ ```
685
+
686
+ #### Instance Methods
687
+
688
+ ##### `#captures_credentials?`
689
+
690
+ Check if page is configured to capture credentials.
691
+
692
+ **Returns:** Boolean
693
+
694
+ **Example:**
695
+
696
+ ```ruby
697
+ page = Gophish::Page.new(capture_credentials: true)
698
+ puts page.captures_credentials? # => true
699
+ ```
700
+
701
+ ##### `#captures_passwords?`
702
+
703
+ Check if page is configured to capture passwords.
704
+
705
+ **Returns:** Boolean
706
+
707
+ **Example:**
708
+
709
+ ```ruby
710
+ page = Gophish::Page.new(capture_passwords: true)
711
+ puts page.captures_passwords? # => true
712
+ ```
713
+
714
+ ##### `#has_redirect?`
715
+
716
+ Check if page has a redirect URL configured.
717
+
718
+ **Returns:** Boolean
719
+
720
+ **Example:**
721
+
722
+ ```ruby
723
+ page = Gophish::Page.new(redirect_url: "https://example.com")
724
+ puts page.has_redirect? # => true
725
+
726
+ page = Gophish::Page.new
727
+ puts page.has_redirect? # => false
728
+ ```
729
+
730
+ #### Usage Examples
731
+
732
+ ##### Create a Basic Landing Page
733
+
734
+ ```ruby
735
+ page = Gophish::Page.new(
736
+ name: "Microsoft Login Clone",
737
+ html: <<~HTML
738
+ <!DOCTYPE html>
739
+ <html>
740
+ <head>
741
+ <title>Microsoft Account</title>
742
+ <style>
743
+ body {
744
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
745
+ background-color: #f5f5f5;
746
+ margin: 0;
747
+ padding: 40px;
748
+ }
749
+ .login-form {
750
+ max-width: 400px;
751
+ margin: 0 auto;
752
+ background: white;
753
+ padding: 40px;
754
+ border-radius: 8px;
755
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
756
+ }
757
+ .form-group { margin-bottom: 20px; }
758
+ input {
759
+ width: 100%;
760
+ padding: 12px;
761
+ border: 1px solid #ddd;
762
+ border-radius: 4px;
763
+ font-size: 14px;
764
+ }
765
+ button {
766
+ width: 100%;
767
+ padding: 12px;
768
+ background: #0078d4;
769
+ color: white;
770
+ border: none;
771
+ border-radius: 4px;
772
+ font-size: 14px;
773
+ cursor: pointer;
774
+ }
775
+ button:hover { background: #106ebe; }
776
+ </style>
777
+ </head>
778
+ <body>
779
+ <div class="login-form">
780
+ <h2>Sign in</h2>
781
+ <form method="post">
782
+ <div class="form-group">
783
+ <input type="email" name="username" placeholder="Email" required>
784
+ </div>
785
+ <div class="form-group">
786
+ <input type="password" name="password" placeholder="Password" required>
787
+ </div>
788
+ <button type="submit">Sign in</button>
789
+ </form>
790
+ </div>
791
+ </body>
792
+ </html>
793
+ HTML
794
+ )
795
+
796
+ if page.save
797
+ puts "Landing page created with ID: #{page.id}"
798
+ end
799
+ ```
800
+
801
+ ##### Create Page with Credential Capture
802
+
803
+ ```ruby
804
+ page = Gophish::Page.new(
805
+ name: "Banking Portal - Credential Capture",
806
+ html: <<~HTML
807
+ <html>
808
+ <head>
809
+ <title>Secure Banking Portal</title>
810
+ <style>
811
+ body { font-family: Arial, sans-serif; background: #1e3d59; color: white; }
812
+ .container { max-width: 400px; margin: 100px auto; padding: 40px; background: white; color: black; border-radius: 10px; }
813
+ input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ccc; }
814
+ button { width: 100%; padding: 12px; background: #1e3d59; color: white; border: none; border-radius: 5px; }
815
+ </style>
816
+ </head>
817
+ <body>
818
+ <div class="container">
819
+ <h2>Secure Login</h2>
820
+ <form method="post">
821
+ <input type="text" name="username" placeholder="Username" required>
822
+ <input type="password" name="password" placeholder="Password" required>
823
+ <button type="submit">Access Account</button>
824
+ </form>
825
+ </div>
826
+ </body>
827
+ </html>
828
+ HTML,
829
+ capture_credentials: true,
830
+ capture_passwords: true,
831
+ redirect_url: "https://www.realbank.com/login"
832
+ )
833
+
834
+ puts "Page captures credentials: #{page.captures_credentials?}"
835
+ puts "Page captures passwords: #{page.captures_passwords?}"
836
+ puts "Page has redirect: #{page.has_redirect?}"
837
+
838
+ page.save
839
+ ```
840
+
841
+ ##### Import Website as Landing Page
842
+
843
+ ```ruby
844
+ # Import a real website
845
+ begin
846
+ imported_data = Gophish::Page.import_site(
847
+ "https://accounts.google.com/signin",
848
+ include_resources: true # Include CSS, JS, images
849
+ )
850
+
851
+ page = Gophish::Page.new(imported_data)
852
+ page.name = "Google Login Clone"
853
+ page.capture_credentials = true
854
+
855
+ if page.save
856
+ puts "Successfully imported Google login page"
857
+ puts "Page ID: #{page.id}"
858
+ end
859
+
860
+ rescue StandardError => e
861
+ puts "Failed to import site: #{e.message}"
862
+
863
+ # Fallback to manual creation
864
+ page = Gophish::Page.new(
865
+ name: "Manual Google Login Clone",
866
+ html: "<html><body><h1>Google</h1><form method='post'><input name='email' type='email' placeholder='Email'><input name='password' type='password' placeholder='Password'><button type='submit'>Sign in</button></form></body></html>",
867
+ capture_credentials: true
868
+ )
869
+ page.save
870
+ end
871
+ ```
872
+
873
+ ##### Update Existing Page
874
+
875
+ ```ruby
876
+ page = Gophish::Page.find(1)
877
+
878
+ # Update content
879
+ page.html = page.html.gsub("Sign in", "Login")
880
+
881
+ # Enable credential capture
882
+ page.capture_credentials = true
883
+ page.capture_passwords = true
884
+
885
+ # Set redirect URL
886
+ page.redirect_url = "https://legitimate-site.com"
887
+
888
+ if page.save
889
+ puts "Page updated successfully"
890
+ puts "Now captures credentials: #{page.captures_credentials?}"
891
+ end
892
+ ```
893
+
894
+ ##### Page Validation
895
+
896
+ ```ruby
897
+ # Invalid page (missing required fields)
898
+ page = Gophish::Page.new
899
+
900
+ unless page.valid?
901
+ puts "Validation errors:"
902
+ page.errors.full_messages.each { |msg| puts " - #{msg}" }
903
+ # => ["Name can't be blank", "Html can't be blank"]
904
+ end
905
+
906
+ # Valid page
907
+ page = Gophish::Page.new(
908
+ name: "Valid Page",
909
+ html: "<html><body>Content</body></html>"
910
+ )
911
+
912
+ puts page.valid? # => true
913
+ ```
914
+
915
+ ##### Checking Page Configuration
916
+
917
+ ```ruby
918
+ page = Gophish::Page.find(1)
919
+
920
+ # Check capabilities
921
+ if page.captures_credentials?
922
+ puts "⚠️ This page will capture user credentials"
923
+ end
924
+
925
+ if page.captures_passwords?
926
+ puts "🔐 This page will capture passwords in plain text"
927
+ end
928
+
929
+ if page.has_redirect?
930
+ puts "🔄 Users will be redirected to: #{page.redirect_url}"
931
+ else
932
+ puts "🛑 Users will see a generic success message"
933
+ end
934
+ ```
935
+
936
+ ##### Delete Page
937
+
938
+ ```ruby
939
+ page = Gophish::Page.find(1)
940
+
941
+ if page.destroy
942
+ puts "Page deleted successfully"
943
+ puts "Page frozen: #{page.frozen?}" # => true
944
+ end
945
+ ```
946
+
627
947
  ## Error Handling
628
948
 
629
949
  ### Validation Errors