Skip to content

Commit

Permalink
initial attempt at getting ssl virtual hosts configured while refacto…
Browse files Browse the repository at this point in the history
…ring campaign#show to use nested forms and attributes
  • Loading branch information
zeknox committed Nov 12, 2014
1 parent d099142 commit 1fba131
Show file tree
Hide file tree
Showing 22 changed files with 228 additions and 132 deletions.
54 changes: 32 additions & 22 deletions app/assets/javascripts/campaigns.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,57 @@ $( document ).ready(function() {
var myValue = $(this).val();
switch (myValue) {
case 'google':
$('#email_settings_smtp_server').val('smtp.gmail.com');
$('#email_settings_smtp_server_out').val('smtp.gmail.com');
$('#email_settings_authentication').val('plain');
$('#email_settings_domain').val('gmail.com');
$('#email_settings_enable_starttls_auto').prop('checked', true);
$('#email_settings_openssl_verify_mode').val('VERIFY_NONE');
$('#email_settings_smtp_port').val('587');
$('#campaign_email_settings_attributes_smtp_server').val('smtp.gmail.com');
$('#campaign_email_settings_attributes_smtp_server_out').val('smtp.gmail.com');
$('#campaign_email_settings_attributes_authentication').val('plain');
$('#campaign_email_settings_attributes_domain').val('gmail.com');
$('#campaign_email_settings_attributes_enable_starttls_auto').prop('checked', true);
$('#campaign_email_settings_attributes_openssl_verify_mode').val('VERIFY_NONE');
$('#campaign_email_settings_attributes_smtp_port').val('587');
break;
case 'outlook':
$('#email_settings_smtp_server').val('smtp.outlook.com');
$('#email_settings_smtp_server_out').val('smtp.outlook.com');
$('#email_settings_smtp_port').val('25');
$('#campaign_email_settings_attributes_smtp_server').val('smtp.outlook.com');
$('#campaign_email_settings_attributes_smtp_server_out').val('smtp.outlook.com');
$('#campaign_email_settings_attributes_smtp_port').val('25');
break;
case 'godaddy':
$('#email_settings_smtp_server').val('smtp.secureserver.net');
$('#email_settings_smtp_server_out').val('smtpout.secureserver.net');
$('#email_settings_smtp_port').val('3535');
$('#campaign_email_settings_attributes_smtp_server').val('smtp.secureserver.net');
$('#campaign_email_settings_attributes_smtp_server_out').val('smtpout.secureserver.net');
$('#campaign_email_settings_attributes_smtp_port').val('3535');
break;
case 'sendgrid':
$('#email_settings_email_settings_smtp_server').val('smtp.sendgrid.net');
$('#email_settings_smtp_server_out').val('smtp.sendgrid.net');
$('#email_settings_smtp_port').val('25');
$('#campaign_email_settings_attributes_smtp_server').val('smtp.sendgrid.net');
$('#campaign_email_settings_attributes_smtp_server_out').val('smtp.sendgrid.net');
$('#campaign_email_settings_attributes_smtp_port').val('25');
break;
}
});

// if use_beef checked function
function is_beef_checked() {
if ($("#campaign_settings_use_beef").is(':checked')) {
function is_stuff_checked() {
if ($("#campaign_campaign_settings_attributes_use_beef").is(':checked')) {
// enable beef_url form
$("#campaign_settings_beef_url").prop('disabled', false);
$("#campaign_campaign_settings_attributes_beef_url").prop('disabled', false);
}
else {
// disable beef_url form
$("#campaign_settings_beef_url").prop('disabled', true);
$("#campaign_campaign_settings_attributes_beef_url").prop('disabled', true);
}

if ($("#campaign_campaign_settings_attributes_ssl").is(':checked')) {
// display ssl form
$("[id=ssl-tr]").css("display", "table-row");
}
else {
// hide ssl form
$("[id=ssl-tr]").css("display", "none");
}
}

// enable beef_url if use_beef is checked on page load
is_beef_checked();
is_stuff_checked();

// click event handler to enable beef_url if use_beef is checked
$( "#campaign_settings_use_beef" ).on( "click", is_beef_checked);
$( "#campaign_campaign_settings_attributes_use_beef" ).on( "click", is_stuff_checked);
$( "#campaign_campaign_settings_attributes_ssl" ).on( "click", is_stuff_checked);
});
45 changes: 9 additions & 36 deletions app/controllers/campaigns_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ def home

def show
@templates = Template.all
@campaign = Campaign.find_by_id(params[:id], :include => [:campaign_settings, :email_settings])
@blasts = @campaign.blasts.order('created_at DESC').limit(10)
@campaign = Campaign.find(params[:id], :include => [:campaign_settings, :email_settings])
@victims = Victim.where("campaign_id = ? and archive = ?", params[:id], false)
@template = @campaign.template
unless @template
Expand All @@ -38,8 +37,7 @@ def create
@campaign_settings = CampaignSettings.new(:campaign_id => @campaign.id, :fqdn => '')
@email_settings = EmailSettings.new(:campaign_id => @campaign.id)
if @campaign_settings.save and @email_settings.save
flash[:notice] = "Campaign Created"
redirect_to @campaign
redirect_to @campaign, notice: "Campaign Created"
else
render('new')
end
Expand All @@ -49,12 +47,7 @@ def create
end

def edit
# find existing id
@campaign = Campaign.find_by_id(params[:id])
if @campaign.nil?
list
render('list')
end
@campaign = Campaign.find(params[:id])
end

def update
Expand All @@ -65,37 +58,17 @@ def update
end

@campaign = Campaign.find(params[:id])
if @campaign.update_attributes(params[:campaign])
flash[:notice] = "Campaign Updated"
redirect_to @campaign
else
render('edit')
end
end

def update_settings
# ensure we have write access to sites-enabled
unless File.writable?(GlobalSettings.first.sites_enabled_path)
redirect_to campaign_path, notice: "File Permission Issue: chmod #{GlobalSettings.first.sites_enabled_path}"
errors = @campaign.update_deps(params).messages.values.join(', ')
if errors.present?
redirect_to @campaign, notice: "Error: #{errors}"
return
end

@campaign = Campaign.find_by_id(params[:id], :include => [:campaign_settings, :email_settings])

# ensure we have required dependencies to go active
if params[:campaign][:active] == "1"
if params[:campaign_settings][:fqdn] == ""
redirect_to campaign_path(params[:id]), notice: "FQDN cannot be blank when active"
return false
end
end

if @campaign.update_attributes(params[:campaign]) and @campaign.email_settings.update_attributes(params[:email_settings]) and @campaign.campaign_settings.update_attributes(params[:campaign_settings])
flash[:notice] = "Campaign Updated"
redirect_to @campaign
if @campaign.update_attributes(params[:campaign])
redirect_to @campaign, notice: "Campaign Updated"
else
@templates = Template.all
render('form')
render('show')
end
end

Expand Down
26 changes: 2 additions & 24 deletions app/controllers/templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ def list

def show
@template = Template.find_by_id(params[:id])
if @template.nil?
list
render('list')
end

@images = @template.images
end

Expand All @@ -35,29 +30,12 @@ def create
end

def edit
@template = Template.find_by_id(params[:id])
if @template.nil?
list
render('list')
end
@template = Template.find(params[:id])
end

def update
binding.pry
@template = Template.find(params[:id])
attachments = params[:template][:attachments_attributes]
unless attachments.nil?
attachments.each do |a|
if a[1]["_destroy"].eql? "1"
begin
@template.attachments.destroy(a[1]["id"])
params[:template][:attachments_attributes].delete(a[0])
rescue
next
end
end
end
end

if @template.update_attributes(params[:template])
redirect_to edit_template_path, notice: "Template Updated"
else
Expand Down
12 changes: 12 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,16 @@ module ApplicationHelper
def error_messages_for( object )
render(:partial => 'shared/error_messages', :locals => {:object => object})
end

def link_to_remove_fields(name, f)
f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
end

def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")
end
end
53 changes: 41 additions & 12 deletions app/models/campaign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ class Campaign < ActiveRecord::Base
belongs_to :template
has_one :campaign_settings, dependent: :destroy
has_one :email_settings, dependent: :destroy
has_many :ssl, dependent: :destroy
has_many :victims, dependent: :destroy
has_many :blasts, dependent: :destroy
has_many :statistics
has_many :smtp_communications
has_many :baits, through: :blasts
has_many :visits, through: :victims

accepts_nested_attributes_for :email_settings, allow_destroy: true
accepts_nested_attributes_for :campaign_settings, allow_destroy: true
accepts_nested_attributes_for :ssl, allow_destroy: true#, :reject_if => proc {|attributes| attributes['filename'].blank?}

# allow mass asignment
attr_accessible :name, :description, :active, :emails, :scope, :template_id, :test_email
attr_accessible :name, :description, :active, :emails, :scope, :template_id, :test_email, :ssl_attributes, :email_settings_attributes, :campaign_settings_attributes

# named scopes
scope :active, where(:active => true)
Expand All @@ -23,6 +28,7 @@ class Campaign < ActiveRecord::Base
before_save :parse_email_addresses
after_update :devops, :if => :active_changed?
after_destroy :cleanup_apache
after_create :create_deps

# validate form before saving
validates :name, :presence => true,
Expand All @@ -34,6 +40,21 @@ class Campaign < ActiveRecord::Base
validates :scope, :numericality => {:greater_than_or_equal_to => 0},
:length => {:maximum => 4}, :allow_nil => true

def create_deps
Ssl.functions.each do |function|
newSSL = ssl.new
newSSL.function = function[0]
newSSL.save(validate: false)
end
end

def update_deps(params)
if params[:campaign][:active] == "1"
errors.add(:fqdn, "FQDN cannot be nil when activating") unless campaign_settings.fqdn.present?
end
return errors
end

def self.clicks(campaign)
campaign.visits.where('extra is null OR extra not LIKE ?', "%EMAIL%").pluck(:victim_id).uniq.size
end
Expand All @@ -56,6 +77,7 @@ def self.logfile(campaign)
end

def get_binding
@ssl = ssl
@campaign_id = id
@campaign_settings = campaign_settings
@fqdn = campaign_settings.fqdn
Expand Down Expand Up @@ -137,8 +159,8 @@ def parse_triple_csv
end
end

def vhost_text(campaign)
template = ERB.new File.read(File.join(Rails.root, "app/views/campaigns/virtual_host.txt.erb",))
def vhost_text(campaign, virtual_host_type)
template = ERB.new File.read(File.join(Rails.root, "app/views/campaigns/#{virtual_host_type}.txt.erb",))
template.result(campaign.get_binding)
end

Expand Down Expand Up @@ -166,16 +188,11 @@ def undeploy
end

def deploy
# add vhost file to sites-enabled
File.open(vhost_file, "w") do |f|
template = Template.find_by_id(self.template_id)
if template.nil?
raise 'Template #{self.template_id} not found'
else
f.write(vhost_text(self))
end
end
# determine if SSL is enabled on campaign
virtual_host_type = self.campaign_settings.ssl ? "virtual_host_ssl" : "virtual_host"

# write vhost config and restart apache
write_vhost(virtual_host_type)
reload_apache

# deploy phishing website files
Expand All @@ -202,6 +219,18 @@ def deploy
end
end

def write_vhost(vhost_type)
# add vhost file to sites-enabled
File.open(vhost_file, "w") do |f|
template = Template.find_by_id(self.template_id)
if template.nil?
raise 'Template #{self.template_id} not found'
else
f.write(vhost_text(self, vhost_type))
end
end
end

def tag_beef(tags)
beef = ERB.new File.read(File.join(Rails.root, "app/views/reports/beef.txt.erb"))
return beef.result(self.beef_binding(select_beef_url)) + tags.result
Expand Down
2 changes: 1 addition & 1 deletion app/models/campaign_settings.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class CampaignSettings < ActiveRecord::Base
belongs_to :campaign

attr_accessible :track_uniq_visitors, :track_hits, :iptable_restrictions, :schedule_campaign, :use_beef, :beef_url, :campaign_id, :fqdn, :smtp_delay
attr_accessible :track_uniq_visitors, :track_hits, :iptable_restrictions, :schedule_campaign, :use_beef, :beef_url, :campaign_id, :fqdn, :smtp_delay, :ssl

def smtp_delays
[0,5,10,15,30,60].map { |s| ["%d seconds" % s, s]}
Expand Down
15 changes: 15 additions & 0 deletions app/models/ssl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Ssl < ActiveRecord::Base
belongs_to :campaign

#validates_presence_of :filename
validates :function, uniqueness: true

attr_accessible :filename, :function
mount_uploader :filename, FileUploader

def self.functions
[['SSLCertificateFile', 'SSLCertificateFile'],
['SSLCertificateKeyFile','SSLCertificateKeyFile'],
['SSLCertificateChainFile','SSLCertificateChainFile']]
end
end
2 changes: 1 addition & 1 deletion app/models/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Template < ActiveRecord::Base

has_many :attachments, as: :attachable, dependent: :destroy

accepts_nested_attributes_for :attachments
accepts_nested_attributes_for :attachments, :allow_destroy => true , :reject_if => proc {|attributes| attributes['file'].blank?}

def email_directory
File.dirname(email_files.first.file.current_path)
Expand Down
6 changes: 3 additions & 3 deletions app/views/campaigns/_campaign_settings.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@
</td>
<td>
<%= f.text_area(:emails, :size => "31x2",
placeholder: 'firstname, lastname, [email protected]',
value: '',
class: 'form-control') %>
placeholder: 'firstname, lastname, [email protected]',
value: '',
class: 'form-control') %>
</td>
</tr>
</table>
Expand Down
Loading

0 comments on commit 1fba131

Please sign in to comment.