Dealing with scammers using Selenium and Python

Introduction

Recently got a SMS with a link to a phishing site intended to capture credit card information. The way of doing it was a billing due to a stalled international delivery, and scammers were cautious enough so the phishing site redirected to the true deliverycorporation once the credit card information with the payment were filled. I saw this as an opportunity to learn new things, so decided to write a simple bot to send fake data also known as trash, to the scammers database.

To do so gathered some simple facts:

  • No data validations where be performed over the data entered, the only requirement was for the form data to be filled. Clutther would get right into their database
  • Site worked only when accessed from a mobile browser. This is important since we are willing to access by means of a headless browser.
  • Information is gathered through simple inputs and select html elements. Piece of cake when it comes to crafting selectors.

So, to the draftboard…

We can fill their database with trash by means of filling all the fields and “clicking” the Send button.

It has a couple of interactions since the form appears after a couple of modals.

The craft process

After reading the docs of selenium and gathering the required modules using pyenv and a virtual environment, started with accessing the site,

import time

from seleniumwire import webdriver

...

firefox_options = webdriver.FirefoxOptions()
firefox_options.headless = True
driver = webdriver.Firefox(options=firefox_options)
driver.request_interceptor = interceptor
driver.set_window_rect(x=433, y=836)
print("Navigating to target...")
driver.get("https://envios.coordinadora-com.online/index.php")
time.sleep(3)

The sleep at the end allows for the first modal to load. Once is loaded we need to click a button to proceed with paying the amount due and waiting for the Credit card form to appear. Also the request required an interceptor to modify the User-Agent header so it looks like we are connecting from a mobile device.

Now, deal with the first modal,

# Catch the selector
elem = driver.find_element(by=By.CLASS_NAME, value='sarca')
time.sleep(3)
# Click-it
elem.click()
# Wait for modal to load
time.sleep(2)

After hand-picking the selectors with the aid of the Developer Tools of the web browser, i got a sequence of actions to be performed to fill the fields with random data. The intended effect is that the data is so random that clearing the database from it is not an easy task. So, using random numbers and strings with varying lenght and amount we could give a bit of a headache to whoever wants to navigate to the datase rows. So a dictionary of selectors mapped to actions, and a loop of actions would do the trick,

selectors = {
        # ID
        '#frm_payment > div > div.payment-form > div:nth-child(1) > input': lambda s: s.send_keys(random_with_N_digits(10)),
        # Name
        '#frm_payment > div > div.payment-form > div:nth-child(2) > input': lambda s: s.send_keys(random_string_N_chars(random.randint(3,10))),
        # Address
        '#frm_payment > div > div.payment-form > div:nth-child(3) > input': lambda s: s.send_keys(random_string_N_chars(random.randint(10,15))),
        # Cellphone
        '#frm_payment > div > div.payment-form > div:nth-child(4) > input': lambda s: s.send_keys(random_with_N_digits(10)),
        # City
        '#frm_payment > div > div.payment-form > div:nth-child(5) > input': lambda s: s.send_keys(random_string_N_chars(random.randint(4,10))),
        # Credit Card Number
        '#frm_payment > div > div.payment-form > div:nth-child(6) > input': lambda s: s.send_keys(random_with_N_digits(16)),
        # CCV
        '#frm_payment > div > div.payment-form > div:nth-child(7) > input': lambda s: s.send_keys(random_with_N_digits(3)),
        # Pick Month
        '#frm_payment > div > div.payment-form > div:nth-child(8) > select': lambda s: Select(s).select_by_index(random.randint(0,11)),
        # Pick Year
        '#frm_payment > div > div.payment-form > div:nth-child(9) > select': lambda s: Select(s).select_by_index(random.randint(2,8)),
        # Send
        '#frm_payment > div > div.frm_block.centered > button': lambda s: s.click(),
    }
    for selector, op in selectors.items():
        # For each selector perform the associated action
        sel = driver.find_element(by=By.CSS_SELECTOR, value=selector)
        op(sel)

And thats about the core of the task. It takes roughly about 15 seconds to complete a loop, so about 4 fakes per minute… not so fast, but hey, not to bad for a proof of concept and a first iteration. After a couple of hours managed to craft this script

In order to use it you need to install selenium to work with your python installation and Firefox using the geckodriver.

It was fun!

Random data at forms input
Random filling of fields

Four workers filling stuff Four workers filling stuff

comments powered by Disqus