Manual


1. Assembly

What do you get in the kit?
Raspberry Pi Zero 2/W
x2 Elechouse PN532 readers
Heat sink/screws/screwdrivers/sd card and micro USB data cable 

Step 1. Attach Pi to the board by using four hex screws (come with the heat sink)

Step 2. Stick two heat pads to the Pi chips and attach heatsink to the Pi by using four screws. You do not need to use the washers that come in the pack.

Step 3. Attach the PN532 readers to the board using the remaining screws. Please note that the board uses special spring contacts which need only to be touching the via's (holes). Attach one PN532 to the "Terminal" and one to the "Card". Set the PN532 readers in the correct modes.  As indicated on the board: the "Card" reader is in SPI mode, the "Terminal" reader is in the HSU/UART mode. Toggle the switches to match the images found on the PCB board. 

Step 4. Install the image (https://pvillage.s3.us-west-004.backblazeb2.com/badge.img) onto the SD card using dd or Win32diskimager. Modify the settings of the image if necessary (see sections 2.2 and 2.3). The SD card slot is located on the left side of the badge/Raspberry Pi:

2. Connection

There are three ways to connect to the village badge:

2.1. The data port emulates an Ethernet device:

This USB port acts as a USB ethernet device. On Linux the device should be recognised automatically. On Windows 10/11, it may be necessary to install additional drivers if the device is not recognised as an Ethernet device. Please install drivers manually or update them automatically:

Once you have connected the device, connect to it via SSH. The default settings are:
IP: 192.168.200.1
Username: pi
Password: raspberry

If you are using Linux, the IP assigned to the "wired" connection may be different. Please use "ifconfig" to confirm the IP address that has been assigned. 

Connect to the Raspberry Pi using SSH:

2.2. Connect to existing Wi-Fi

Open the SD card as storage and locate the "wpa_supplicant.bak" file (if you already have access to the Raspberry Pi, you can edit the file directly - /boot/firmware/wpa_supplicant.conf.bak)

Rename the file to "wpa_supplicant.conf" and edit the network settings if you wish to connect to an existing Wi-Fi network. Reboot the device.


If you are modifying "wifi.conf" or "wpa_supplicant.conf", please ensure one of the files is not active by appending a .bak extension to the inactive file. If you have both "wifi.conf" and "wpa_supplicant.conf" there will be a conflict.


Once the device has connectivity, ensure your PC is on the same network and connect to the Raspberry Pi using SSH.

Note: Raspberry PI is very specific about the structure of the conf files so please ensure there are no spaces in the SSID name or it will not use the file. On Windows you can create a hotspot and join that.
Modify the file on the sd card only. Do not try to modify /etc/wpa_supplicant/wpa_supplicant.conf, as our script updates the file on the file system automatically.

2.3. Create a Wi-Fi hotspot


You can connect directly to the Wi-Fi network created by the Raspberry PI. Please note this will not provide Internet access which is a requirement of solving the challenges in the CTF. Copy/rename "wifi.conf.bak" to wifi.conf.

This file contains the SSID postfix of the Raspberry Pi. You can modify the name of this by renaming the file and changing the entry in the file. The view shows the existing SSID name. Modify the name of the SSID and save the file as wifi.conf. Reboot the device and connect to the SSID of the badge and enter the passphrase by selecting the "connect using a security key instead" option:


Enter the security key "13371338". Once you have connected to the device, connect via SSH using the details:
IP: 10.42.0.1
Username: pi
Password: raspberry

3. Using the Badge

We have created an environment which allows you to fully emulate the payment process. For this you will need a village card, the village badge, an ACR122U/SCR3310 reader and the POSSim.exe or POSSim.py script.

ACR122U and SCR3310 readers can be borrowed from the Payment Village at DEF CON.

Please note, if you are using our authorisation host to simulate transactions, please do not send us your personal card data! We are not responsible for this.

You can use the badge as a standalone device to read, modify and log data between any card or terminal/ATM/reader

3.1 Payment Village Card Authorisation Architecture

If you are using our environment and the badge, the architecture looks like this:

If you are planning to solve tasks without purchasing a badge, read how to do it here.

3.2 Set up the Point of Sales Simulator

apt install swig 
apt install pcscd
(you don't need these if you run POSSim on Windows)

pip3 install requests
pip3 install pyscard

3.3 Check the PN532's are working

First check that both the readers are working and able to read cards. Place a card on top of one of the readers and run the nfc-list command on the Raspberry Pi. It will return data for either the SPI or UART NFC device. Repeat on the other side and ensure that there are no errors.

In this example, the card is being read first by the UART reader and then by the SPI reader. If you don't see the card ID identified in the output, try changing the position of the card. We found that the ideal position for the badge is as below:

Here we can see the output for the reader set in UART mode, followed by the output for the reader set in SPI mode:

To intercept communication between the Card and the Terminal, simply run
"python pn532mitm.py"

BAdge.mp4

3.4 Substituting data using the Badge

Run python pn532mitm.py -H on the Raspberry Pi. -H flag runs every request and response through a data hook function that reads the rules.json file from the current directory in the Raspberry Pi SSH console and adds/substitutes TLV tags:

    string = binascii.hexlify(data).upper()

    for key in rules:

        value = rules[key].encode().upper()

        pos = string.find(key.encode().upper()) # changing only one tag

        if (pos>=0):

            length = int(key[-2:], 16)

            if ((length*2)!=(len(value)-len(key))):

                trailen = pos+len(key)

            else:

                trailen = pos+len(value)                

            string = string[0:pos]+value+string[trailen:]                     

    print ("Data hook, send_fragmented: %s" % send_fragmented)

    print ("After: %s" % string)

In this default rules.json example, the tag 9f26 (ARQC, length 0x08) value is replaced with aabbccdd11223344, and the tag 77 (Card Template) length is extended from 0x24 to 0x28, and a new tag 9a, length 02, value ff00 is added at the beginning of the template.

Response before:
<<77249F3602004D9F260825E9C3FD004B3CD082020040570E1016434962031044D2402201807F9000
After the rules are applied:
<<77289a02ff009F3602004D9F2608aabbccdd1122334482020040570E1016434962031044D2402201807F9000

The rules indicated in the file apply to requests and responses but only once in each APDU. Feel free to modify the code on Raspberry Pi to adjust the rules and make them more complex!

Now you can launch POSsim.py, and it should receive the data from the card that's being processed by the badge

3.5 Running the Point of Sales Simulator

To access the help menu, run: POSSim.py -h

POSsim.py -h
Card Hacking Challenge / Virtual POS / Relay Emulator


options:

  -h, --help            show this help message and exit

  -H, --hook-data       Use data hook function for data processing

  -R READER_VALUE, --reader READER_VALUE

                        Reader ID

  -I {contact,cless}, --interface {contact,cless}

                        Interface type (contact or contactless)

  -A AMOUNT_VALUE, --amount AMOUNT_VALUE

                        Transaction amount without (,) E.g. for $10.01, enter 1001

  -F, --faulty          Faulty terminal, generates static UN

Check that the POSSim is working and able to see the ACR122U/SCR3310 reader:

C:\Users\yunus>"C:\Users\yunus\Documents\DC32\POSSim\POSSim DC32.py"

0: ACS ACR122 0

1: Identive SCR33xx v2.0 USB SC Reader 0

2: JAVACOS Virtual Contact Reader 0

3: JAVACOS Virtual Contactless Reader 1

4: SCM Microsystems Inc. SCR3310 USB Smart Card Reader 0

Select reader:

Run:
POSsim.py -A 100 -I cless -R 0 -F  
If everything works successfully, you will get a message showing that it has been processed in our infrastructure:

If you are using Linux and the POSSim is unable to see the ACR122U, you may need to disable the kernel NFC drivers from loading automatically. Add the following to "etc/modprobe.d/blacklist.conf":

install nfc /bin/false
install pn533 /bin/false

3.6 Summary

3.7 Understanding APDU's and TLV

Data between the card and the terminal is sent in Application Data Unit's, this takes the form of TLV (Tag Length Value).

You can use emv-bertlv.jar to decode APDU's automatically:


https://github.com/binaryfoo/emv-bertlv

Decoding a whole file of APDU's using bertlv:

cat .\output.txt | java.exe -jar .\emv-bertlv-0.1.8-shaded.jar apdu-sequence -
or for Windows: type output.txt | java -jar .\emv-bertlv-0.1.8-shaded.jar apdu-sequence -

Decode each field manually after watching this video of Dr. Stephen Murdoch explaining the structure of TLV:
https://www.youtube.com/live/IwqfR1AQwCM?si=vMbFHtda9KMjaVl1

4. Troubleshooting/Q&A

4.1. I can't connect to the Pi

4.2. My badge can't see the card or the reader!

4.3. Man-in-The-Middle script doesn't work, or you have intermittent issues with reading the card


5. DIY

All of our software and schematics are publicly available in our GitHub projects:

https://github.com/a66at/NFCMiTM

https://github.com/CardToolz/libnfc_mitm_cffi 

There is enough information in these two repositories to build your own man-in-the-middle device, should you choose to do so.