I've been meaning to pick up ruby again. It's such a cool language.
This evening, after returning from todays
Shmoocon talks, I was inspired to write a bit of code. My ruby skills are still very rough, so I came up with a little project to help me to learn a few concepts.
The tool that I whipped up: a Ruby script that connects to Bank of America, and pulls down your
SiteKey image and title.
Why would something like this be useful? Were such code to be taken, improved, and hacked up a bit, one could imagine some kind of Man in the middle proxying-phishing attack, which presented itself as a legitimate financial institution to the user, connected to Bank of America, and then passed the information back and forth between the user and the legitimate financial website that she thinks she is visiting.
The user would see her Sitekey, and thus would feel safe knowing that she was indeed connecting to BoA - while in fact, she was sending her information to someone in Nigeria.
Sitekey, of course, is the technology sold by Passmark/RSA to a number of financial institutions. It's the cheaper way to do 2 factor authentication. Sitekey has been mentioned in the
press recently, after researchers found that users rarely noticed when the image was absent from their banking sessions.
I haven't developed anything like that though. This is just a simple Ruby script.
Sample output:
./boa-mechanize
Please enter your Bank Of America username: joeuser
Please enter your state 2 letter code (i.e. CA): NY
Please answer the following SiteKey Question.
What is the name of your best friend: jack valenti
Got it...
Sitekey phrase: She Sells Sea Shells On the Sea Shore
Sitekey image saved to: /tmp/sitekey.28317.0
---
And just to cover my freedom of speech bases, I'm including the text of the script here, instead of linking to a downloadable file.
----
#!/opt/local/bin/ruby
# Christopher Soghoian
# A fun little ruby script which'll login to your BoA account,
# and download your sitekey image and title, after prompting you
# for one of your sitekey questions
# Apologies for my horrible regex and ruby skills.
#I'm sure this can be done far cleaner.
# Copyleft GPL.
require 'rubygems'
require 'mechanize'
require 'tempfile'
agent = WWW::Mechanize.new
agent.user_agent_alias = 'Windows IE 6'
print "Please enter your Bank Of America username: "
username = gets.chomp
print "Please enter your state 2 letter code (i.e. CA): "
state = gets.chomp
# Make initial connection to BoA webserver. Send over our state of residence
page = agent.get("https://sitekey.bankofamerica.com/sas/signon.do?state=" + state)
boa_form = page.form('signonForm')
boa_form.onlineID = username
page = agent.submit(boa_form, boa_form.buttons.first)
# We've got a cookie that refers to our username and state. Keep going
page = agent.get('https://sitekey.bankofamerica.com/sas/signon.do?&detect=5')
# Extract the sitekey question (since our machine is unknown to BoA)
sitekey_question_html = page.search("//label[@for='sitekeyChallengeAnswer']").inner_html
sitekey_question = sitekey_question_html.scan(/\((.*)\)/)
# Prompt the user for it.
puts "Please answer the following SiteKey Question."
print sitekey_question, ": "
sitekey_answer = gets.chomp
# Submit the answer back to BoA
unknown_computer_form = page.form('challengeQandAForm')
unknown_computer_form.sitekeyChallengeAnswer = sitekey_answer
page = agent.submit(unknown_computer_form, unknown_computer_form.buttons.first)
# Neato. It worked. Grab the sitekey image, and the sitekey image title
sitekey_image_url = page.search("//html").inner_html.scan(/img src=\"(getMySiteKey.*)\" border/)
full_sitekey_image_url = "https://sitekey.bankofamerica.com/sas/#{sitekey_image_url}"
sitekey_image = agent.get(full_sitekey_image_url)
sitekey_image_title = page.search("//html").inner_html.scan(/Your SiteKey Image Title:.*nbsp;
(.*?)<\/td>/m)
tf = Tempfile.new("sitekey")
sitekey_image.save_as(tf.path)
print "\nGot it..\n"
print "Sitekey phrase: ", sitekey_image_title, "\n"
print "Sitekey image saved to: ", tf.path, "\n"
sleep 10