commit
7e19486a97
|
@ -0,0 +1,132 @@
|
|||
The ```auxiliary/client/sms/send_text``` module allows you to send a malicious text/link to a collection
|
||||
of phone numbers of the same carrier.
|
||||
|
||||
In order to use this module, you must set up your own SMTP server to deliver messages. Popular
|
||||
mail services such as Gmail, Yahoo, Live should work fine.
|
||||
|
||||
## Module Options
|
||||
|
||||
**CELLNUMBERS**
|
||||
|
||||
The 10-digit phone number (or numbers) you want to send the text to. If you wish to target against
|
||||
multiple phone numbers, ideally you want to create the list in a text file (one number per line),
|
||||
and then load the CELLNUMBERS option like this:
|
||||
|
||||
```
|
||||
set CELLNUMBERS file:///tmp/att_phone_numbers.txt
|
||||
```
|
||||
|
||||
Remember that these phone numbers must be the same carrier.
|
||||
|
||||
**SMSCARRIER**
|
||||
|
||||
The carrier that the targeted numbers use. See **Supported Carrier Gateways** to learn more about
|
||||
supported carriers.
|
||||
|
||||
**SMSMESSAGE**
|
||||
|
||||
The text message you want to send. For example, this will send a text with a link to google:
|
||||
|
||||
```
|
||||
set SMSMESSAGE "Hi, please go: google.com"
|
||||
```
|
||||
|
||||
The link should automatically be parsed on the phone and clickable.
|
||||
|
||||
**SMTPADDRESS**
|
||||
|
||||
The mail server address you wish to use to send the text messages.
|
||||
|
||||
**SMTPPORT**
|
||||
|
||||
The mail server port. By default, this is ```25```.
|
||||
|
||||
**SMTPUSERNAME**
|
||||
|
||||
The username you use to log into the SMTP server.
|
||||
|
||||
**SMTPPASSWORD**
|
||||
|
||||
The password you use to log into the SMTP server.
|
||||
|
||||
**SMTPFROM**
|
||||
|
||||
The FROM field of SMTP. In some cases, it may be used as ```SMTPUSER```.
|
||||
|
||||
## Supported Carrier Gateways
|
||||
|
||||
The module supports the following carriers:
|
||||
|
||||
* AllTel
|
||||
* AT&T Wireless
|
||||
* Boost Mobile
|
||||
* Cricket Wireless
|
||||
* Google Fi
|
||||
* T-Mobile
|
||||
* Verizon
|
||||
* Virgin Mobile
|
||||
|
||||
**Note:** During development, we could not find a valid gateway for Sprint, therefore it is currently
|
||||
not supported.
|
||||
|
||||
## Finding the Carrier for a Phone Number
|
||||
|
||||
Since you need to manually choose the carrier gateway for the phone numbers, you need to figure out
|
||||
how to identify the carrier of a phone number. There are many services that can do this, such as:
|
||||
|
||||
http://freecarrierlookup.com/
|
||||
|
||||
**Note:** If the phone is using Google Fi, then it may appear as a different carrier.
|
||||
|
||||
## Gmail SMTP Example
|
||||
|
||||
Gmail is a popular mail server, so we will use this as a demonstration.
|
||||
|
||||
Assuming you are already using two-factor authentication, you need to create an [application password](https://support.google.com/accounts/answer/185833?hl=en).
|
||||
|
||||
After creating the application password, configure auxiliary/client/sms/send_text this way:
|
||||
|
||||
* ```set cellnumbers [PHONE NUMBER]```
|
||||
* ```set smscarrier [CHOOSE A SUPPORTED CARRIER]```
|
||||
* ```set smsmessage "[TEXT MESSAGE]"```
|
||||
* ```set smtpaddress smtp.gmail.com```
|
||||
* ```set smtpport 587```
|
||||
* ```set smtpusername [USERNAME FOR GMAIL]``` (you don't need ```@gmail.com``` at the end)
|
||||
* ```set smtppassword [APPLICATION PASSWORD]```
|
||||
|
||||
And you should be ready to go.
|
||||
|
||||
## Yahoo SMTP Example
|
||||
|
||||
Yahoo is also a fairly popular mail server (although much slower to deliver comparing to Gmail),
|
||||
so we will demonstrate as well.
|
||||
|
||||
Before using the module, you must do this to your Yahoo account:
|
||||
|
||||
1. Sign in to Yahoo Mail.
|
||||
2. [Go to your "Account security" settings.](https://login.yahoo.com/account/security#less-secure-apps)
|
||||
3. Turn on Allow apps that use less secure sign in.
|
||||
|
||||
After configuring your Yahoo account, configure auxiliary/client/sms/send_text this way:
|
||||
|
||||
* ```set cellnumbers [PHONE NUMBER]```
|
||||
* ```set smscarrier [CHOOSE A SUPPORTED CARRIER]```
|
||||
* ```set smsmessage "[TEXT MESSAGE]"```
|
||||
* ```set smtpaddress smtp.mail.yahoo.com```
|
||||
* ```set smtpport 25```
|
||||
* ```set smtpusername [USERNAME FOR YAHOO]@yahoo.com```
|
||||
* ```set smtppassword [YAHOO LOGIN PASSWORD]```
|
||||
|
||||
And you're good to go.
|
||||
|
||||
## Demonstration
|
||||
|
||||
After setting up your mail server and the module, your output should look similar to this:
|
||||
|
||||
```
|
||||
msf auxiliary(send_text) > run
|
||||
|
||||
[*] Sending text (16 bytes) to 1 number(s)...
|
||||
[*] Done.
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
|
@ -28,3 +28,5 @@ require 'msf/core/auxiliary/iax2'
|
|||
require 'msf/core/auxiliary/ntp'
|
||||
require 'msf/core/auxiliary/pii'
|
||||
require 'msf/core/auxiliary/redis'
|
||||
|
||||
require 'msf/core/auxiliary/sms'
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
###
|
||||
#
|
||||
# The Msf::Auxiliary::Sms mixin allows you to send a text message to
|
||||
# multiple phones of the same carrier. A valid SMTP server is needed.
|
||||
#
|
||||
##
|
||||
|
||||
module Msf
|
||||
module Auxiliary::Sms
|
||||
|
||||
def initialize(info={})
|
||||
super
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('SMTPFROM', [false, 'The FROM field for SMTP', '']),
|
||||
OptString.new('SMTPADDRESS', [ true, 'The SMTP server to use to send the text messages']),
|
||||
OptPort.new('SMTPPORT', [true, 'The SMTP port to use to send the text messages', 25]),
|
||||
OptString.new('SMTPUSERNAME', [true, 'The SMTP account to use to send the text messages']),
|
||||
OptString.new('SMTPPASSWORD', [true, 'The SMTP password to use to send the text messages']),
|
||||
OptEnum.new('SMSCARRIER', [true, 'The targeted SMS service provider', nil,Rex::Proto::Sms::Model::GATEWAYS.keys.collect { |k| k.to_s }]),
|
||||
OptString.new('CELLNUMBERS', [true, 'The phone numbers to send to']),
|
||||
OptString.new('SMSMESSAGE', [true, 'The text message to send'])
|
||||
], Auxiliary::Sms)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptEnum.new('SmtpLoginType', [true, 'The SMTP login type', 'login', ['plain', 'login', 'cram_md5']]),
|
||||
OptString.new('HeloDdomain', [false, 'The domain to use for HELO', ''])
|
||||
], Auxiliary::Sms)
|
||||
end
|
||||
|
||||
|
||||
# Sends a text message to multiple numbers of the same service provider (carrier).
|
||||
#
|
||||
# @example This sends a text via Gmail
|
||||
# smtp = Rex::Proto::Sms::Model::Smtp.new(address: 'smtp.gmail.com', port: 587, username: user, password: pass)
|
||||
# sms = Rex::Proto::Sms::Client.new(carrier: :verizon, smtp_server: smtp)
|
||||
# numbers = ['1112223333']
|
||||
# sms.send_text_to_phones(numbers, 'Hello from Gmail')
|
||||
#
|
||||
# @param phone_numbers [<String>Array] An array of numbers of try (of the same carrier)
|
||||
# @param message [String] The text to send.
|
||||
#
|
||||
# @return [void]
|
||||
def send_text(phone_numbers, message)
|
||||
smtp = Rex::Proto::Sms::Model::Smtp.new(
|
||||
address: datastore['SMTPADDRESS'],
|
||||
port: datastore['SMTPPORT'],
|
||||
username: datastore['SMTPUSERNAME'],
|
||||
password: datastore['SMTPPASSWORD'],
|
||||
login_type: datastore['SmtpLoginType'].to_sym,
|
||||
from: datastore['SMTPFROM']
|
||||
)
|
||||
|
||||
carrier = datastore['SMSCARRIER'].to_sym
|
||||
sms = Rex::Proto::Sms::Client.new(carrier: carrier, smtp_server: smtp)
|
||||
sms.send_text_to_phones(phone_numbers, message)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -7,6 +7,7 @@ require 'rex/proto/drda'
|
|||
require 'rex/proto/iax2'
|
||||
require 'rex/proto/kerberos'
|
||||
require 'rex/proto/rmi'
|
||||
require 'rex/proto/sms'
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'rex/proto/sms/exception'
|
||||
require 'rex/proto/sms/model'
|
|
@ -0,0 +1,81 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module Sms
|
||||
class Client
|
||||
|
||||
# @!attribute carrier
|
||||
# @return [Symbol] The service provider for the phone numbers.
|
||||
attr_accessor :carrier
|
||||
|
||||
# @!attribute smtp_server
|
||||
# @return [Rex::Proto::Sms::Model::Smtp] The Smtp object with the Smtp settings.
|
||||
attr_accessor :smtp_server
|
||||
|
||||
|
||||
# Initializes the Client object.
|
||||
#
|
||||
# @param [Hash] opts
|
||||
# @option opts [Symbol] Service provider name (see Rex::Proto::Sms::Model::GATEWAYS)
|
||||
# @option opts [Rex::Proto::Sms::Model::Smtp] SMTP object
|
||||
#
|
||||
# @return [Rex::Proto::Sms::Client]
|
||||
def initialize(opts={})
|
||||
self.carrier = opts[:carrier]
|
||||
self.smtp_server = opts[:smtp_server]
|
||||
|
||||
validate_carrier!
|
||||
end
|
||||
|
||||
|
||||
# Sends a text to multiple recipients.
|
||||
#
|
||||
# @param phone_numbers [<String>Array] An array of phone numbers.
|
||||
# @param message [String] The text message to send.
|
||||
#
|
||||
# @return [void]
|
||||
def send_text_to_phones(phone_numbers, message)
|
||||
carrier = Rex::Proto::Sms::Model::GATEWAYS[self.carrier]
|
||||
recipients = phone_numbers.collect { |p| "#{p}@#{carrier}" }
|
||||
address = self.smtp_server.address
|
||||
port = self.smtp_server.port
|
||||
username = self.smtp_server.username
|
||||
password = self.smtp_server.password
|
||||
helo_domain = self.smtp_server.helo_domain
|
||||
login_type = self.smtp_server.login_type
|
||||
from = self.smtp_server.from
|
||||
|
||||
smtp = Net::SMTP.new(address, port)
|
||||
|
||||
begin
|
||||
smtp.enable_starttls_auto
|
||||
smtp.start(helo_domain, username, password, login_type) do
|
||||
recipients.each do |r|
|
||||
smtp.send_message(message, from, r)
|
||||
end
|
||||
end
|
||||
rescue Net::SMTPAuthenticationError => e
|
||||
raise Rex::Proto::Sms::Exception, e.message
|
||||
ensure
|
||||
smtp.finish if smtp && smtp.started?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
# Validates the carrier parameter.
|
||||
#
|
||||
# @raise [Rex::Proto::Sms::Exception] If an invalid service provider is used.
|
||||
def validate_carrier!
|
||||
unless Rex::Proto::Sms::Model::GATEWAYS.include?(self.carrier)
|
||||
raise Rex::Proto::Sms::Exception, 'Invalid carrier.'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module Sms
|
||||
class Exception < ::RuntimeError
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module Sms
|
||||
module Model
|
||||
|
||||
GATEWAYS = {
|
||||
:alltel => 'sms.alltelwireless.com', # Alltel
|
||||
:att => 'txt.att.net', # AT&T Wireless
|
||||
:boost => 'sms.myboostmobile.com', # Boost Mobile
|
||||
:cricket => 'sms.mycricket.com', # Cricket Wireless
|
||||
# Sprint is commented out, because the gateways don't seem to work.
|
||||
# Gateways tried for Sprint:
|
||||
# messaging.sprintpcs.com
|
||||
# pm.sprint.com
|
||||
#:sprint => 'messaging.sprintpcs.com', # Sprint
|
||||
:tmobile => 'tmomail.net', # T-Mobile
|
||||
:verizon => 'vtext.com', # Verizon
|
||||
:virgin => 'vmobl.com', # Virgin Mobile
|
||||
:google => 'msg.fi.google.com' # Google Project Fi
|
||||
}
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'net/smtp'
|
||||
require 'rex/proto/sms/model/smtp'
|
||||
require 'rex/proto/sms/client'
|
|
@ -0,0 +1,62 @@
|
|||
module Rex
|
||||
module Proto
|
||||
module Sms
|
||||
module Model
|
||||
class Smtp
|
||||
|
||||
# @!attribute address
|
||||
# @return [String] SMTP address
|
||||
attr_accessor :address
|
||||
|
||||
# @!attribute port
|
||||
# @return [Fixnum] SMTP port
|
||||
attr_accessor :port
|
||||
|
||||
# @!attribute username
|
||||
# @return [String] SMTP account/username
|
||||
attr_accessor :username
|
||||
|
||||
# @!attribute password
|
||||
# @return [String] SMTP password
|
||||
attr_accessor :password
|
||||
|
||||
# @!attribute login_type
|
||||
# @return [Symbol] SMTP login type (:login, :plain, and :cram_md5)
|
||||
attr_accessor :login_type
|
||||
|
||||
# @!attribute from
|
||||
# @return [String] Sender
|
||||
attr_accessor :from
|
||||
|
||||
# @!attribute helo_domain
|
||||
# @return [String] The domain to use for the HELO SMTP message
|
||||
attr_accessor :helo_domain
|
||||
|
||||
|
||||
# Initializes the SMTP object.
|
||||
#
|
||||
# @param [Hash] opts
|
||||
# @option opts [String] :address
|
||||
# @option opts [Fixnum] :port
|
||||
# @option opts [String] :username
|
||||
# @option opts [String] :password
|
||||
# @option opts [String] :helo_domain
|
||||
# @option opts [Symbol] :login_type
|
||||
# @option opts [String] :from
|
||||
#
|
||||
# @return [Rex::Proto::Sms::Model::Smtp]
|
||||
def initialize(opts={})
|
||||
self.address = opts[:address]
|
||||
self.port = opts[:port] || 25
|
||||
self.username = opts[:username]
|
||||
self.password = opts[:password]
|
||||
self.helo_domain = opts[:helo_domain] || 'localhost'
|
||||
self.login_type = opts[:login_type] || :login
|
||||
self.from = opts[:from] || ''
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
include Msf::Auxiliary::Sms
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'SMS Client',
|
||||
'Description' => %q{
|
||||
This module sends a text message to multiple phones of the same carrier.
|
||||
You can use it to send a malicious link to phones.
|
||||
|
||||
Please note that you do not use this module to send a media file (attachment),
|
||||
because that is MMS.
|
||||
},
|
||||
'Author' => [ 'sinn3r' ],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
end
|
||||
|
||||
def run
|
||||
phone_numbers = datastore['CELLNUMBERS'].split
|
||||
print_status("Sending text (#{datastore['SMSMESSAGE'].length} bytes) to #{phone_numbers.length} number(s)...")
|
||||
begin
|
||||
res = send_text(phone_numbers, datastore['SMSMESSAGE'])
|
||||
print_status("Done.")
|
||||
rescue Rex::Proto::Sms::Exception => e
|
||||
print_error(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'spec_helper'
|
||||
require 'rex/proto/sms/model'
|
||||
|
||||
RSpec.describe Rex::Proto::Sms::Client do
|
||||
|
||||
let(:phone_numbers) { ['1112223333'] }
|
||||
|
||||
let(:message) { 'message' }
|
||||
|
||||
let(:carrier) { :verizon }
|
||||
|
||||
let(:smtp_server) {
|
||||
Rex::Proto::Sms::Model::Smtp.new(
|
||||
address: 'example.com',
|
||||
port: 25,
|
||||
username: 'username',
|
||||
password: 'password'
|
||||
)
|
||||
}
|
||||
|
||||
subject do
|
||||
Rex::Proto::Sms::Client.new(
|
||||
carrier: carrier,
|
||||
smtp_server: smtp_server
|
||||
)
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'sets carrier' do
|
||||
expect(subject.carrier).to eq(carrier)
|
||||
end
|
||||
|
||||
it 'sets smtp server' do
|
||||
expect(subject.smtp_server).to eq(smtp_server)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_text_to_phones' do
|
||||
before(:each) do
|
||||
smtp = Net::SMTP.new(smtp_server.address, smtp_server.port)
|
||||
allow(smtp).to receive(:start).and_yield
|
||||
allow(smtp).to receive(:send_message) { |args| @sent_message = args }
|
||||
allow(Net::SMTP).to receive(:new).and_return(smtp)
|
||||
end
|
||||
|
||||
it 'sends a text message' do
|
||||
subject.send_text_to_phones(phone_numbers, message)
|
||||
expect(@sent_message).to eq(message)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'spec_helper'
|
||||
require 'rex/proto/sms/model'
|
||||
|
||||
RSpec.describe Rex::Proto::Sms::Model::Smtp do
|
||||
|
||||
let(:address) { 'example.com' }
|
||||
let(:port) { 25 }
|
||||
let(:username) { 'username' }
|
||||
let(:password) { 'password' }
|
||||
let(:login_type) { :login }
|
||||
let(:from) { 'from' }
|
||||
let(:helo_domain) { 'example.com'}
|
||||
|
||||
subject do
|
||||
Rex::Proto::Sms::Model::Smtp.new(
|
||||
address: address,
|
||||
port: port,
|
||||
username: username,
|
||||
password: password,
|
||||
login_type: login_type,
|
||||
from: from,
|
||||
helo_domain: helo_domain
|
||||
)
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'sets address' do
|
||||
expect(subject.address).to eq(address)
|
||||
end
|
||||
|
||||
it 'sets port' do
|
||||
expect(subject.port).to eq(port)
|
||||
end
|
||||
|
||||
it 'sets username' do
|
||||
expect(subject.username).to eq(username)
|
||||
end
|
||||
|
||||
it 'sets password' do
|
||||
expect(subject.password).to eq(password)
|
||||
end
|
||||
|
||||
it 'sets login_type' do
|
||||
expect(subject.login_type).to eq(login_type)
|
||||
end
|
||||
|
||||
it 'sets from' do
|
||||
expect(subject.from).to eq(from)
|
||||
end
|
||||
|
||||
it 'sets helo domain' do
|
||||
expect(subject.helo_domain).to eq(helo_domain)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue