Manual
Assembly
Connection
Using the Badge
Troubleshooting/Q&A
DIY
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
Download the files from our telegram group or use this link
Install python3 and the following dependencies:
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"
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!
If the Badge successfully sends data from the card to the reader, you will hear a beep and see data passing from the card to the reader
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
Ensure that the badge readers can see the cards using the nfc-list command - SSH Raspberry Pi connection
Run python pn532mitm.py -H on the Raspberry Pi.
In a terminal window on host run POSsim.py -A 100 -I cless -R 0 -F to start the Point of Sales simulator.
Modify rules.json (on Raspberry Pi) to substitute and add TLV tags
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
Check the USB cable: it should be connected to the left USB port and your cable should allow for the transmitting data.
Check that the RNDIS driver is successfully installed (see section 2.1)
If you struggle with connecting to the badge over Wi-Fi, check the sections 2.2-2.3.
4.2. My badge can't see the card or the reader!
Check that PN532 readers are powered and the LEDs are on
Check that PN532s are in the right modes, according to the diagram on the badge, as explained in section 1, step 3
4.3. Man-in-The-Middle script doesn't work, or you have intermittent issues with reading the card
If you start receiving "libnfc.driver.pn532_spi Unable to wait for SPI data. (RX)" errors when testing the cards with the nfc-list command or when running the python script, you MUST reboot your badge. It won't work until you do so.
Don't work on metal surfaces. Despite the badge having a protective mesh, we don't advise using the badge directly on metal.
Check your set-up with another card and another card reader. For example, if you are solving the Card Challenges, check that the reader CAN read the card using POSSim without the badge first.
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.