Identifying scam websites

I’m writing this post after growing increasingly frustrated with the ‘tips’ that news sites put out each time a prominent scam does the rounds. I find they tend to give a bunch of general, waffly information that misses the point entirely. I’m here to tell you how than you can avoid 99{8b0b96060afa46d1ca7c90aeb24f8da085e11471ba2cd3d6bf9cf57471789b98} of scams with this ‘one simple trick’:

Look At The URL

That’s this thing (aka. the web address): 

The usual tip that gets dished out is to check for ‘https’ and the little padlock, and it’s true you should do that. If a site is asking for your credit card details and doesn’t have those two things then you should definitely get ‘outa there fast. Unfortunately any semi-sophisticated scam site will have no trouble putting those two things in place. Thus their absence is a very likely indicator of a scam but their presence is no guarantee that it isn’t one.

I’m going to use Air New Zealand as an example here, for no other reason than I’ve seen a few scams attempting to fool people into thinking they can get free flights. This same information is relevant for any website.

What you really need to be looking at is the domain and top-level domain of the URL. What is this techno-gibberish I speak of? Here’s a quick lesson:

URL Structure

A URL consists of a few parts, separated by periods:

  1. Protocol – either http or https. The ‘s’ stands for secure and tells you whether communication between your browser and the web server is encrypted.
  2. The sub-domain. This could simply be www or it could be mail in the case of It could also be blah.something.else. Usually there is one sub-domain, but there can also be none or multiple. The good news is that we don’t care about it when checking for a scam site.
  3. The domain is the unique word(s) that the site developer purchases. It’s a bit like buying a bit of land – as long as you continue paying your rates, you can keep it.
  4. The top-level domain is the top of the hierarchy and is used to segment the internet into smaller chunks. .com is probably the most well known top-level domain. Country specific top-level domains are also common eg. There’s also .govt, .net and a whole swath of more esoteric ones.
  5. The path is everything following the first slash after the top-level domain. This is just how the website developer has organised their site and is also unimportant when identifying a scam site.

A website developer purchases a combination of domain & top-level domain which must be unique across the entire internet.

What is important is the domain and top-level domain and their proximity to each other in the URL. Look closely at the periods. The hyphens don’t count!

Often a scam site will register a longer domain that includes the same word(s) as those in the legitimate site. eg. Or they’ll put the word(s) from the legitimate site into a sub-domain eg. With your new knowledge of URLs you should see that these are obvious scams. For instance, in the second example the scammer has legitimately purchased the domain and has then added a sub-domain to try and make it look like the real deal.

Here’s some other examples. The key thing is that you know what Air New Zealand’s normal/legit domain is. The best way to double check is just to do a Google search and check the first (non-ad) result:

Once you know that, see if you can identify whether these are safe sites or not. Note that I haven’t made them clickable like normal links (except for the last one).

  • The domain is airnewzealand which is what we expect.
  • not safeRegistering a domain with a slightly different spelling is a common trick among scammers.
  •– not safe. The domain here is newzealand and they have added air as a subdomain to make it appear from a quick glance that is the same site.
  •– not safe. For similiar resasons. The domain here is newzealand-online.
  •[0].originPoint=YVR&searchLegs[0].destinationPoint=&promoCode=&adults=0&children=0&tripType=return&searchType=flexible&internalRevenueSource=cms-book-book-now-button{8b0b96060afa46d1ca7c90aeb24f8da085e11471ba2cd3d6bf9cf57471789b98}7Cbook&_ga=2.147022391.1465521394.1536551535-1663654223.1536551535 safe. Don’t be put off by the fact that it looks long and scary. All you need to care about is that airnewzealand is separated by a period in front and is the last part of the URL before the top-level domain
  •[0].originPoint=YVR&searchLegs[0].destinationPoint=&promoCode=&adults=0&children=0&tripType=return&searchType=flexible&internalRevenueSource=cms-book-book-now-button{8b0b96060afa46d1ca7c90aeb24f8da085e11471ba2cd3d6bf9cf57471789b98}7Cbook&_ga=2.147022391.1465521394.1536551535-1663654223.1536551535 – not safe. Hopefully you noticed the hyphen before airnewzealand. The registered domain here is flightbookings-airnewzealand which is a completely different address.
  • – not safe. Be careful, the text you read on the page (or text, Facebook, WhatsApp…) may be pointing to a different site. Which URL did you end up on when you clicked this link? In general it’s OK if you follow a link and end up on a dodgy site, as long as you then check the URL and exit. Bad stuff only happens once you interact with the site in some way eg. download a file or enter personal information.

Hopefully this helps someone out there!

Extra for experts: The first section of this post is an awesome introduction to how DNS works

Update (22/01/2019): Google just launched a great quiz which can test your knowledge of this stuff. Check it out:


Flashing a SAM4S MCU

One of my final assignments in my final year of Computer Engineering is to build a ‘Wacky Racer’ car. It is a group assignment with six students in each team. The project requirements include:

  1. Be controllable from a bog-standard infrared TV remote control.
  2. Be controllable wirelessly from a mobile phone.
  3. Can capture still images and send them wirelessly to a mobile phone or laptop.
  4. Have a soft on/off switch that will power up your vehicle.
  5. Have a green LED that indicates the system is powered up.
  6. Have a red LED that indicates that the battery needs charging.
  7. Only use a single battery pack for everything.
  8. Have no trailing cables.
  9. Use almost exclusively surface mount components apart from the supplied connectors.
  10. Monitor the battery voltage and motor speed.
  11. Be dastardly!
  12. Comprise three PCBs, each with a microcontroller:
    1. Motor board: power supply/motor-control/steering/infrared comms
    2. Camera board: using the TCM8230MD image sensor.
    3. Communications board: wifi or bluetooth
  13. The boards are to communicate with an I2C bus only.
  14. Each board is to have a UART or USB debug interface.
  15. Each board needs to be able to run standalone for debugging.

We decided to use a Atmel ATSAM4S16B Microcontroller for all three boards. With our PCBs designed, manufactured and the components placed, and the voltage levels appearing to be correct we then needed to configure a toolchain to connect to our board using it’s JTAG header. The instructions below cover installing OpenOCD 0.6.1 and installing an ARM EABI toolchain. We are using a USB to JTAG converter supplied by our department (Electrical Engineering) at the University of Canterbury, however the process will be similar for commercially available adapters. Note that our adapter is based on a FTDI FT2232 chip.

Populated BoardUSB to JTAG

Ubuntu Linux (12.10) is used in this tutorial.

1). Installing OpenOCD

The FTDI drivers are required. Install these with the following command:

 sudo apt-get install libusb-dev libftdi-dev 

Now, download OpenOCD 0.6.1 from

Unzip it (I use the gui folder manager because I can never remember the command) and cd into the openocd-0.6.1 directory. Now build and install OpenOCD with the following commands:

 ./configure --enable-ft2232_libftdi
 sudo make install

Test that the install worked by running openocd and checking that something like the following appears:

Open On-Chip Debugger 0.6.1 (2013-05-17-12:52)
Licensed under GNU GPL v2
For bug reports, read
Runtime Error: embedded:startup.tcl:47: Can’t find openocd.cfg
in procedure ‘script’
at file “embedded:startup.tcl”, line 47
Error: Debug Adapter has to be specified, see “interface” command
in procedure ‘init’

2). Running OpenOCD

The next thing to do is to get the OpenOCD config files sorted for the SAM4S target and the USB to JTAG interface. Do this by creating a file called myconfig.cfg in your home directory and put the following in it:

# This section configures OpenOCD for using the university's USB-JTAG adapter.
interface ft2232
ft2232_layout usbjtag
ft2232_vid_pid 0x0403 0x6010
adapter_khz 4
adapter_nsrst_delay 200
jtag_ntrst_delay 200

# This section configures OpenOCD for working with a SAM7 chip.
source [find target/at91sam4sXX.cfg]

# Halt the MCU when GDB connects otherwise the connection fails. ($_TARGETNAME is defined in at91sam7sx.cfg)
$_TARGETNAME configure -event gdb-attach {
echo "Halting target due to gdb attach"
$_TARGETNAME configure -event gdb-detach {
echo "Resuming target due to gdb detach"

At this point, connect your board via the USB to JTAG adapter, and run OpenOCD from the same directory as your myconfig.cfg file with the following command:

 sudo openocd -f myconfig.cfg 

3). Connecting to OpenOCD

There are two approaches to connecting to OpenOCD, telnet or GDB. Use can use one of the following commands in a new terminal to connect to OpenOCD:

 telnet localhost 4444 #telnet 


 telnet localhost 3333 #gdb 

For the remainder of this tutorial we shall focus on using the GDB connection method.

4). Configuring an ARM EABI toolchain (with GDB)

We need to install a version of GDB configured for an ARM target. We might as well install our cross-compiler at the same time. This can all be achieved in one swoop by using James Snyder’s build system from

Install this as follows (alternatively, if you are used to cloning Git repos you can just follow the README on the github page):

Install git:

 sudo apt-get install git 

Install the required dependencies for the toolchain:

sudo apt-get install curl flex bison libgmp3-dev libmpfr-dev texinfo \
      libelf-dev autoconf build-essential libncurses5-dev libmpc-dev \

Clone the repo:

 git clone 

Install the toolchain:

cd arm-eabi-toolchain
sudo make install-cross

Now wait for ages while the makefile does it’s thing. When it’s done, add the stuff to your system path and clean up.

export PATH=$HOME/arm-cs-tools/bin:$PATH
sudo make clean

You can check this all went well by starting the ARM version of GDB at the command line.


You should be presented with a (gdb) prompt.

5). Using arm-none-eabi-gdb alongside OpenOCD

The following script can be used to upload a program to the SAM4S target using the GDB method:

target remote tcp:localhost:3333
monitor reset
monitor sleep 500
monitor poll
monitor soft_reset_halt
monitor reset

Save this script as program.gdb. Once you have compiled your program, and with the OpenOCD dameon running, you can invoke this script using the following command:

./arm-none-eabi-gdb -batch -x 'program.gdb myProgram.elf 

Where myProgram.elf is your compiled application.

TODO: 6). Compiling a program for the SAM4S + an example blinking LED program.


Integrating Google Forms with Mailman

Recently I was researching new email list solutions for the University of Canterbury Canoe Club. Our existing setup involves a Google Form which new members fill out, with data accessible in a Google Spreadsheet. Mailman is used for our mailing list. Currently the Webmaster is notified when a new form is submitted and manually puts the corresponding email address into the mailing system. This seemed cumbersome to me, and set me searching for a better approach.

The most promising alternative I found was MailChimp, a very popular email marketing tool. MailChimp has many options, takes steps to combat emails being wrongly detected as spam and can host a built-in signup form. However the flashy HTML emails it generates seemed overkill for our needs, and as it is designed for marketing campaigns, does not support the concept of any person on the mailing list being able to send email to it – a feature of Mailman that is utilized by the club (with emails coming to the Webmaster for moderation). Additionally, committee members wanting to send emails would have had to log into the MailChimp web application with a shared password, rather than using their personal email address and mail client. This presented two problems: non-technical committee members would have had to learn how to use a new tool, and there would not be a reply address matched to the actual person sending the email.

In light of these findings, I set about finding a way to integrate Google Forms with Mailman. I came across the answer in the form of Google Apps Scripts, a service provided by Google which allows chunks of Javascript code to be written against an API and integrate with a number of Google services – in my case Google Forms/Spreadsheets. Here I present the steps for taking the email address out of the form submit and submitting it to your Mailman server as a new subscriber.

I presume you have already created a Google Form which asks users to enter an email address. In the corresponding spread sheet, choose Tools -> Scripts Editor.

Paste in the following code, substituting the following strings with those of your setup:

  • SheetName eg. Sheet1
  • cellnumber eg. 5
  • yourdomain eg.
  • yourmailinglist eg. allsubscribers
  • yourpassword eg. password
  • webmaster@yourdomain eg.
function SubscribeEmailOfNewMemberToMailman() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName("SheetName");
  var row = sheet.getLastRow();
  var range = sheet.getRange(row,cellnumber);
  var email = range.getValue().trim();
  range.setValue(email); //Write the trimed email back to the spreadsheet.

  if (validateEmail(email)) {

UrlFetchApp.fetch(yourdomain/mailman/admin/yourmailinglist/members/add?subscribe_or_invite=0&' +

    	Logger.log("Subscribed {8b0b96060afa46d1ca7c90aeb24f8da085e11471ba2cd3d6bf9cf57471789b98}s with email {8b0b96060afa46d1ca7c90aeb24f8da085e11471ba2cd3d6bf9cf57471789b98}s.", name, email);

  } else {
      "Failed to auto-subscribe new member",
      "Email regex failed for new member '" + name + "' with email '" + email + "'.");

function validateEmail(email) {
    var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);

The behaviour of this script is as follows:

  1. The email address is pulled from the email column in the last row of the spreadsheet.
  2. The email string is trimmed in case the user accidently left some whitespace at the start or end.
  3. The email is feed into the validateEmail function which uses a regular expression to check if the email is of a valid form. It returns a Boolean.
    1. If it returns True. The email is past to the Mailman server in the URL. (Note: the mailing list password is sent in plain text in the URL which is probably not very secure). A log is made of this subscription attempt to help with any troubleshooting in the future.
    2. If it returns False an email is sent to the Webmaster with the problematic email for them to follow up on manually.

The final step is to tell the Google Spreadsheet to call the SubscribeEmailOfNewMemberToMailman function every time the form is submitted. To do this, from the scripts editor select Resources->Current script’s triggers. In that dialogue, select the function to invoke – in this case ‘SubscribeEmailOfNewMemberToMailman’, In the next two boxes, select ‘From spreadsheet’ and ‘On form submit’ respectively.

With this integration with Mailman and the club’s bank account and payment information supplied in the confirmation page of the form our signup process is now completely automated, making for a happy Webmaster!

The Google Apps Scripts platform is very well documented, and I’d encourage you to modify this script to suit your needs. One addition I made is to call a PHP function on the club website, passing through the user’s name and email address. The PHP function then creates a new username and password for the new member, and notifies them by email.

I hope you find this useful!