Categories
Hacking

How hackers are finding creative ways to steal gift cards using artificial intelligence.

The black hat hacker’s premise is a story as old as time: find things, break things, make money. Over the years, there have been many creative attacks that have pioneered the industry and made groundbreaking changes in our digital infrastructure. While some may argue that attacks have become monolithic over the years, I would say that this isn’t necessarily true. Some people fail to realize that the best and most creative attacks are the ones we don’t see. This summer, I set off on an adventure of sorts to see what black-hat hackers were doing to circumvent systems. I started on a couple of internet forums, including nulled and cracked and was surprised to find many services that had thousands of page views. These forums often had 15k people on at one time browsing the marketplace and lively sharing sections. However, the one that caught my eye was an online store selling Starbucks gift cards. I was genuinely curious how someone could obtain stolen gift cards for different stores. It was fascinating because the seller was selling these gift cards without a PIN attached. Thus came an exciting experience.

I started by posing (not really) as a developer and sent a message to the seller asking how I could check these gift cards for balance if I were to buy. I was met by a prompt dm telling me I could check them using the store’s gift card phone line. My initial reaction was confusion; why would I use a phone line? Was he somehow exploiting their phone line? Did he have access? I decided to put down the thought of figuring out how it worked for a couple of days and spent the next week without thinking about it. However, one day, while searching for an SMS provider, it finally clicked. He was somehow obtaining a vast list of cards and checking their balance on the phone line using a phone provider. I immediately got back onto the forum and quickly searched for a gift card bot. The site then returned a thread for a newly created program called easycards.io. While reading the thread, I found what I was looking for:

Image for post
The “Phone bot”

It all clicked when I read the information; the bot called using a phone provider (in this case, Twilio) and then got back the balance using a speech to text service (Assembly). With this in mind, I decided to grab an old forgotten Starbucks gift card that I had received for a birthday present and check the balance via the phone line for myself. I typed in the gift card via the phone DTMF system and was then prompted for something I never expected, a captcha. At that moment, I realized that this was actually much more complex than I had originally thought.

The bots must find a way to call the gift card line, input the card, get the captcha, send the captcha, record the balance, transcribe the balance, and send it back to the user, all with great accuracy. I was truly baffled at the sophistication and granularity of this task, and I decided to experiment for myself. I re-called the gift card hotline and decided to see how long it would wait for me to input this captcha. Once again, I went through the motions of inputting the extensions and the card until I was prompted with the captcha, and a short 7 seconds later, I was greeted again with “Sorry, that’s incorrect.” These programs had a measly 7 seconds to get this captcha, record it, transcribe it, and send it. It was truly baffling to me that these sellers were somehow able to obtain 1500 gift cards with balances over $5 using this methodology. In shock with the complexity, I did what any good programmer does, make one myself.

The first day or two, I did some digging through Twilio’s documentation on how these calls were made programmatically. Twilio has helper/wrapper function libraries in just about every language imaginable, so this was a fairly easy task. The bot would first start off by making a call and sending the extension and card number by posting to the create call route. This methodology requires something called Twiml (just a corporate name for XML) to do call actions. The Twiml would look something like this:

<Response>
<Pause length="70"/>
</Response>

And the python code would look something like this:

# Download the helper library from https://www.twilio.com/docs/python/install
import os
from twilio.rest import Client


# Your Account Sid and Auth Token from twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ['TWILIO_ACCOUNT_SID']
auth_token = os.environ['TWILIO_AUTH_TOKEN']
client = Client(account_sid, auth_token)

call = client.calls.create(
url='http://demo.twilio.com/docs/voice.xml',
to=gift_card_hotline_phone_number,
from_=bought_phone_number
send_digits=extension + card_number
)

print(call.sid)

Within the send digits parameter, you can wait seconds and half seconds, which is nearly perfect for this use case because often times you have to wait before putting in the extension digits. For example, if you wanted to wait 3 seconds, dial the extension number 1, and then wait another 3 seconds, you would put the following:

"WWW1WWW"

Once this call is placed, one can wait the amount of time it takes for the captcha (I am not going to put the times for Starbucks to prevent malicious use) to appear to start recording the call. Recording the call returns an endpoint where you can reach this recording. This recording function is called with the call sid (The call’s unique identifier), which is returned from the create call function. The code would look something like this:

recording = client.calls(sid)
.recordings
.create()

After about 5 seconds, one would need to stop this call from recording (using the same Twilio API) and then pass the URL to a transcription service such as Assembly.

import requests

endpoint = "https://api.assemblyai.com/v2/transcript"

json = {
"audio_url": recording url from twilio
}

headers = {
"authorization": "YOUR-API-TOKEN",
"content-type": "application/json"
}

response = requests.post(endpoint, json=json, headers=headers)

print(response.json())

Finally, you can use regex to parse through the transcription, and send the digits back via the Twilio API. Here’s some pseudocode:

x = [3-9]\d\dsend_digits(x)

As soon as you send these digits, you want to start recording again, and then at a certain point (once the Pause element on your Twiml is over), transcribe what was returned back and give it to the client. Before it is sent back to the client, you probably want to sanitize the input down to simple VALID or INVALID return values to make things easier on the eyes. You also probably want to save your newly stolen loot in a text file. Once all is said and done, you have spent a grand total of $0.015 on this one check. A minuscule amount compared to what you could make stealing people’s gift cards from the perspective of the black hat. I think this project taught me more than anything that our systems are always under attack by bad actors. This method of attack proves more than anything that attacks are becoming more and more complex, despite some people’s arguments that many attacks are now very similar. I think a lot about the security world can be learned by just taking a look under the hood, deep on the inside. And I hope this article encourages some of you to find your own “phone bot” type of attack. The security of the future relies on the willingness of security researchers to spend more time on the inside than time with each other.