Add API to send a text message (SMS) to mobile devices

bug/bundler_fix
wchen-r7 2017-03-02 16:47:55 -06:00
parent 4882927570
commit 6ad8afb8b3
12 changed files with 511 additions and 0 deletions

View File

@ -0,0 +1,121 @@
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 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 CELLNUMBER 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.
**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.
## Supported Carrier Gateways
The module supports the following carriers:
* AllTel
* AT&T Wireless
* Boost Mobile
* Cricket Wireless
* Sprint
* T-Mobile
* Verizon
* Virgin Mobile
## 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/
## 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
```

View File

@ -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'

View File

@ -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

View File

@ -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

4
lib/rex/proto/sms.rb Normal file
View File

@ -0,0 +1,4 @@
# -*- coding: binary -*-
require 'rex/proto/sms/exception'
require 'rex/proto/sms/model'

View File

@ -0,0 +1,77 @@
# -*- 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
smtp.send_message(message, from, recipients)
end
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

View File

@ -0,0 +1,10 @@
# -*- coding: binary -*-
module Rex
module Proto
module Sms
class Exception < ::RuntimeError
end
end
end
end

View File

@ -0,0 +1,26 @@
# -*- 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 => 'messaging.sprintpcs.com', # Sprint
:tmobile => 'tmomail.net', # T-Mobile
:verizon => 'vtext.com', # Verizon
:virgin => 'vmobl.com' # Virgin Mobile
}
end
end
end
end
require 'net/smtp'
require 'rex/proto/sms/model/smtp'
require 'rex/proto/sms/client'

View File

@ -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

View File

@ -0,0 +1,34 @@
##
# 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)...")
res = send_text(phone_numbers, datastore['SMSMESSAGE'])
print_status("Done.")
end
end

View File

@ -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

View File

@ -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