Setting Up a Proxmark3 on Windows with WSL2

I recently set up a Proxmark3 RDV4 on a Windows 11 machine and decided to document the process. My setup uses WSL2/Ubuntu for building and running the Proxmark3 client, while Windows handles the USB connection through usbipd-win.

The examples below are focused on working with tags that I own or blank test tags. The goal is to learn how different RFID technologies work rather than bypass an access-control system.

Hardware and software

My setup was:

  • Proxmark3 RDV4
  • Windows 11
  • WSL2
  • Ubuntu
  • Iceman Proxmark3 repository
  • A USB connection exposed to WSL using usbipd

The Iceman repository is available at RfidResearchGroup/proxmark3.

1. Build the client in WSL

After cloning the repository, the first problem I encountered was:

arm-none-eabi-gcc: command not found

The ARM compiler is required to build the Proxmark3 firmware. On Ubuntu, install the ARM toolchain and the host development dependencies:

sudo apt update
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi
sudo apt install liblz4-dev libbz2-dev libssl-dev
sudo apt install usbutils

Verify the ARM compiler:

arm-none-eabi-gcc --version

I also hit missing headers during compilation:

lz4frame.h: No such file or directory
bzlib.h: No such file or directory
openssl/evp.h: No such file or directory

Those were resolved by installing the corresponding development packages above.

Then build the generic target:

cd ~/proxmark3
make PLATFORM=PM3GENERIC

A successful build produces, among other files:

armsrc/obj/fullimage.elf
bootrom/obj/bootrom.elf

2. Connect the Proxmark3 to WSL

Windows sees the Proxmark3 as a USB serial device. In PowerShell:

usbipd list

Look for the Proxmark3. In my case it appeared as:

BUSID  VID:PID    DEVICE
1-11   9ac4:4b8f  USB Serial Device (COM3)

Attach it to WSL:

usbipd attach --wsl --busid 1-11

If usbipd is not installed, install usbipd-win on Windows first.

Back in Ubuntu, verify that the device is visible:

lsusb

I got:

J. Westhues ProxMark-3 RFID Instrument

Then check for the serial device:

ls -l /dev/ttyACM*

Typically it will be:

/dev/ttyACM0

If necessary, add your user to the dialout group:

sudo usermod -aG dialout $USER

Then restart the WSL session.

3. Start the Proxmark3 client

From the repository:

./client/proxmark3 /dev/ttyACM0

The client can also be started without a device:

./client/proxmark3

That starts OFFLINE mode, which is useful for looking at commands but does not communicate with the hardware.

The command-line help is useful:

./client/proxmark3 -h

4. Flashing firmware

One important lesson from the setup was that the client and firmware versions should match. The client initially reported that the ARM firmware did not match the source used to compile the client.

The build produced:

armsrc/obj/fullimage.elf
bootrom/obj/bootrom.elf

The client can flash the firmware using the generated image. The exact flashing procedure can vary by Proxmark3 hardware and firmware version, so it is worth checking the current Iceman documentation before using --unlock-bootloader.

After flashing, reconnect to the client and check:

hw version

and:

hw status

A healthy connection should return the Proxmark3 hardware information rather than a communication timeout.

5. Check the antennas

The command:

hw tune

is useful for checking the antenna characteristics.

It does not actively tune the antenna. It measures the antenna response.

For my device, both the LF and HF antennas were reported as OK. The LF antenna showed a strong response around the 125 kHz region and the HF antenna around 13.56 MHz.

6. Basic LF tag discovery

For a 125 kHz tag, the first command to try is:

lf search

This attempts to identify common LF tag technologies.

For example, a programmable LF tag may be identified as:

Chipset... T55xx

The important distinction is that a chip type and a credential format are not necessarily the same thing. For example, a T55x7 can be configured to emulate several different LF protocols.

7. T55x7 basics

T55x7 is a particularly useful tag for experimentation because its memory and RF configuration are programmable.

To detect a T55xx tag:

lf t55xx detect

For a T55x7 configured for a common 125 kHz setup, the output can look like:

Chip type......... T55x7
Modulation........ ASK
Bit rate.......... 2 - RF/32
Inverted.......... No
Offset............ 32
Seq. terminator... Yes
Block0............ 000880E8
Downlink mode..... default/fixed bit length
Password set...... No

To inspect the configuration:

lf t55xx info

And to read the tag memory:

lf t55xx dump

The T55x7 configuration is stored in block 0. The remaining blocks contain the programmable tag data.

8. Understanding block 0

One thing that initially caused confusion was treating block 0 like ordinary credential data.

For the test tag used during this setup, block 0 was:

000880E8

lf t55xx info decoded this as:

Data bit rate:       RF/32
Modulation:          Manchester
Sequence Terminator: Yes
Max block:           7
Password mode:       No

So block 0 primarily describes how the tag should transmit its data. It is not simply the tag's ID.

For that reason, don't overwrite block 0 casually. If experimenting with a blank T55x7, record its original configuration first.

9. Writing a test T55x7

For experiments on a blank tag, individual blocks can be written with:

lf t55xx write -b 1 -d 11223344
lf t55xx write -b 2 -d 55667788
lf t55xx write -b 3 -d AABBCCDD

Then read the memory back:

lf t55xx dump

This is a good way to understand the relationship between the Proxmark3 command and the physical tag memory.

Use a blank/test tag for write experiments. Don't experiment by writing arbitrary data into a live access credential.

10. AWID and other LF formats

The Proxmark3 can recognize several LF formats. One example is AWID.

A tag may be reported as something like:

AWID - len: 40

The important concept is that:

T55x7 = physical programmable tag/chip
AWID 40-bit = credential/RF format

These are different layers. A T55x7 configured for Manchester at RF/32 does not automatically contain an AWID credential simply because the correct configuration is present in block 0.

For learning, it is much easier to start with blank programmable tags and use the Proxmark3's read/detect commands to see how different formats are represented.

11. Useful command cheat sheet

Hardware

hw version
hw status
hw tune

General LF

lf search

T55xx

lf t55xx detect
lf t55xx info
lf t55xx dump
lf t55xx write -b <block> -d <8-hex-digit-value>

AWID

lf awid read

The exact command set depends on the version of the Iceman client and firmware, so use the built-in help when in doubt:

help

or, for a command family:

help lf t55xx
help lf awid

12. Troubleshooting USB communication

Running the Proxmark3 through WSL2 adds another layer between the hardware and the client. If commands start timing out, check the connection from the bottom up.

On Windows:

usbipd list

The Proxmark3 should show as Attached.

In WSL:

lsusb
ls -l /dev/ttyACM*

If the USB device disappears, detach and attach it again from PowerShell.

If the device exists but the Proxmark3 client reports communication timeouts, restarting the client and reconnecting the USB device is often a good first step.

I also found that repeatedly issuing commands while the device was already unresponsive could leave the USB transport in a bad state. In that situation, restarting the client and re-attaching the USB device was more useful than continuing to issue commands.

What's next?

The Proxmark3 supports much more than 125 kHz LF tags. Some good next experiments are:

  • EM4100/EM4102
  • EM4305/EM4469
  • Q5/T5555
  • HID Prox
  • MIFARE Classic
  • MIFARE Ultralight
  • NTAG213/215/216
  • ISO15693
  • ISO14443A/B

Starting with T5577 + EM4100 + NTAG gives a nice introduction to programmable LF, simple LF identification, and modern NFC.

The most important lesson from this setup: identify the tag technology first, understand its memory/configuration model, and experiment on tags you own or blank test tags.

Setting up AWS CLI

A guide to Setting up AWS CLI and configuring it for your AWS account.

Prerequisites

  • An AWS account. If you don't have one, you can create it here.

MAC Installation

  1. Open your terminal.
  2. Run the following command to install AWS CLI using Homebrew:
    brew install awscli
    
  3. Verify the installation by checking the version:
    aws --version
    

Get AWS Credentials

  1. Sign in to the AWS Management Console.
  2. Navigate to the IAM (Identity and Access Management) service.
  3. In the left sidebar, click on "Users."
  4. Click on your username.
  5. Go to the "Security credentials" tab.
  6. Click on "Create access key."
  7. Your Access Key ID and Secret Access Key will be displayed. Copy and save them securely.

Configure AWS CLI

  1. Open your terminal.
  2. Run the following command to configure AWS CLI:
    aws configure
    
  3. You will be prompted to enter the following details:
  4. AWS Access Key ID: Enter the Access Key ID you obtained earlier.
    • AWS Secret Access Key: Enter the Secret Access Key you obtained earlier.
    • Default region name: Enter your preferred AWS region (e.g., us-east-1).
    • Default output format: You can choose json, text, or table. For beginners, json is recommended.
  5. To verify that AWS CLI is configured correctly, run the following command to list your S3 buckets:
    aws s3 ls
    
    If everything is set up correctly, you should see a list of your S3 buckets (if any).

Deploying React Applications on AWS

A guide to deploying React applications on AWS using CloudFront and S3, using CDK Nodejs for infrastructure as code.

Prerequisites

Before starting, ensure you have the following prerequisites:

  • AWS Account: Sign up for an AWS account if you don't have one.
  • AWS CLI: Install and configure the AWS Command Line Interface (CLI) with your credentials. You can follow the guide here.
  • Node.js and yarn: Ensure you have Node.js and yarn installed on your machine.
  • React Application: Have a React application ready for deployment.

Step 1: Set Up IaC project

  1. Navigate to your react application directory in the terminal.
  2. Create a new directory for your IaC project and navigate into it:
    mkdir iac
    cd iac
    
  3. Initialize a new CDK project using Node.js:

    npx aws-cdk init app --language=typescript
    

  4. Install the necessary AWS CDK packages:

    yarn add @aws-cdk/aws-s3 @aws-cdk/aws-cloudfront @aws-cdk/aws-s3-deployment
    

Step 2: Update the IaC code to create an S3 bucket.

  1. Open the lib/iac-stack.ts file in your IaC project directory.
  2. Replace the contents with the following code to create an S3 bucket and a CloudFront distribution
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';

export class IacStack extends cdk.Stack {
   constructor(scope: Construct, id: string, props?: cdk.StackProps) {
      super(scope, id, props);

      // Create an S3 bucket
      const bucket = new s3.Bucket(this, 'MyReactAppBucket', {
         websiteIndexDocument: 'index.html',
         websiteErrorDocument: 'index.html',
         publicReadAccess: true,
      });

      // Create a CloudFront distribution
      const distribution = new cloudfront.CloudFrontWebDistribution(this, 'MyReactAppDistribution', {
         originConfigs: [
            {
               s3OriginSource: {
                  s3BucketSource: bucket,
               },
               behaviors: [{ isDefaultBehavior: true }],
            },
         ],
      });
   }
}

Step 3: Build and Deploy the React Application

  1. Navigate back to your React application directory.
  2. Build your React application:
    yarn build
    
  3. Navigate back to your IaC project directory.
  4. Deploy the CDK stack to create the S3 bucket and CloudFront distribution:
    npx cdk deploy
    
  5. After the stack is deployed, note the S3 bucket name and CloudFront distribution domain name from the output.
  6. Deploy the built React application to the S3 bucket:
    aws s3 sync ../build s3://<Your-Bucket-Name> --delete
    
  7. Invalidate the CloudFront cache to ensure the latest version of your application is served:
    aws cloudfront create-invalidation --distribution-id <Your-Distribution-ID> --paths "/*"
    
  8. Access your React application using the CloudFront distribution domain name.

Step 4: Clean Up

To avoid incurring unnecessary charges, remember to delete the resources created during this process when they are no longer needed. You can do this by destroying the CDK stack:

npx cdk destroy

AI and Coding

Gemini CLI

The Gemini CLI is a powerful tool for AI assisted coding, it provides a generous daily usage quota for free.

Installation

To install the Gemini CLI, simply run the following command:

npm install -g @google/gemini-cli

API Key

Get the API Key from here

Set it as an environment variable:

Bash

export GEMINI_API_KEY=your_api_key_here

Windows PowerShell

$env:GEMINI_API_KEY = "AIs**********od"

Usage

Navigate to your project directory and run:

gemini

Monitor token usage

You can monitor your token usage by navigating to https://aistudio.google.com/usage

Usage Ideas

  • Documentation: Talk to the agent and build your documentation like this.

  • Boilerplate: Generate boilerplate code for your project using tools like for react use npx create-react-app my-app and then engage with the agent to customize it.

Blog support just landed

Hey there! You're looking at our new blog, built with the brand new built-in blog plugin. With this plugin, you can easily build a blog alongside your documentation or standalone.

Proper support for blogging, as requested by many users over the past few years, was something that was desperately missing from Material for MkDocs' feature set. While everybody agreed that blogging support was a blind spot, it was not obvious whether MkDocs could be extended in a way to allow for blogging as we know it from Jekyll and friends. The built-in blog plugin proves that it is, after all, possible to build a blogging engine on top of MkDocs, in order to create a technical blog alongside your documentation, or as the main thing.

Synology NAS Setup Guide

A comprehensive guide covering external access configuration and media management services for your Synology NAS.

This guide will walk you through setting up your Synology NAS for external access and configuring the popular *arr stack for automated media management.

Access outside home

There are several methods to access your Synology NAS from outside your home network:

Synology Quickconnect

The easiest method provided by Synology for remote access without complex network configuration.

Cloudflare

Using Cloudflare's services for secure remote access with additional features like DNS management and security.

Tailscale

A modern VPN solution that creates a secure mesh network between your devices.

Port forwarding

Traditional method of opening specific ports on your router to allow external access.

*arr Services

The *arr services (Sonarr, Radarr, Lidarr, etc.) provide automated downloading and organization of media content.

Prerequisites

Before setting up the *arr services, ensure you have:

  • Docker Container Manager installed: Container Manager supports docker compose projects
  • Docker user created: Make a note of the UID and GID for proper permissions
  • Shared folders created:
  • docker-compose - for your docker compose projects
  • media - for your media files
  • downloads - for downloaded content
  • Protocol understanding: Familiarity with Torrent and Usenet protocols
  • Private trackers knowledge (Optional): Understanding of private trackers and their usage

Docker Compose Configuration

Here's a complete docker-compose setup for the full *arr stack:

version: '3.5'
services:
  jackett:
    image: linuxserver/jackett:latest
    container_name: jackett
    restart: unless-stopped
    volumes:
      - ./jackett:/config
      - ../../../media/torr:/downloads
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    ports:
      - 9117:9117
    network_mode: bridge

  sonarr:
    image: linuxserver/sonarr:latest
    container_name: sonarr
    restart: unless-stopped
    volumes:
      - ./sonarr:/config
      - ../../../media/torr:/downloads
      - ../../../media/tv:/tv
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    ports:
      - 8989:8989
    network_mode: bridge

  radarr:
    image: linuxserver/radarr:latest
    container_name: radarr
    restart: unless-stopped
    volumes:
      - ./radarr:/config
      - ../../../media/torr:/downloads
      - ../../../media/English Movies:/movies
      - ../../../media/torr:/data
      - ../../../../volumeUSB1/usbshare:/14tb
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    ports:
      - 7878:7878
    network_mode: bridge

  lidarr:
    image: linuxserver/lidarr:latest
    container_name: lidarr
    restart: unless-stopped
    volumes:
      - ./lidarr:/config
      - ../../../media/torr:/downloads
      - ../../../media/English Music:/en-music
      - ../../../media/HindiMusic:/hi-music
      - ../../../media/torr:/data
      - ../../../../volumeUSB1/usbshare:/14tb
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    ports:
      - 8686:8686
    network_mode: bridge

  prowlarr:
    image: linuxserver/prowlarr:latest
    container_name: prowlarr
    restart: unless-stopped
    volumes:
      - ./prowlarr:/config
      - ../../../media/torr:/downloads
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    ports:
      - 9696:9696
    network_mode: bridge

  flaresolverr:
    image: ghcr.io/flaresolverr/flaresolverr:latest
    container_name: flaresolverr
    restart: unless-stopped
    volumes:
      - ./flaresolverr:/config
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    ports:
      - 8191:8191
    network_mode: bridge

  overseerr:
    image: sctx/overseerr:latest
    container_name: overseerr
    restart: unless-stopped
    volumes:
      - ./overseerr:/app/config
      - ../../../media/torr:/downloads
      - ../../../media/English Tv:/tv
      - ../../../media/English Movies:/movies
      - ../../../media/torr:/data
      - ../../../../volumeUSB1/usbshare:/14tb
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    ports:
      - 5055:5055
    network_mode: bridge

  nzbget:
    image: linuxserver/nzbget:latest
    container_name: nzbget
    restart: unless-stopped
    volumes:
      - ./nzbget:/config
      - ../../../media/torr:/downloads
      - ../../../media/torr:/data
      - ../../../../volumeUSB1/usbshare:/14tb
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    ports:
      - 6789:6789
    network_mode: bridge

  maintainerr:
    image: ghcr.io/jorenn92/maintainerr:latest
    container_name: maintainerr
    restart: unless-stopped
    user: 1032:100
    volumes:
      - ./maintainerr:/opt/data
    environment:
      - TZ=America/Los_Angeles
    ports:
      - 6246:6246
    network_mode: bridge

  calibre-web-automated:
    image: crocodilestick/calibre-web-automated:latest
    container_name: calibre-web-automated
    restart: unless-stopped
    environment:
      - PUID=1032
      - PGID=100
      - TZ=America/Los_Angeles
    volumes:
      - ./calibre-web-automated:/config
      - ../../../media/eBooks:/books
      - ../../../homes/amit/Drive/Books/ingest:/cwa-book-ingest
    ports:
      - 8083:8083
    network_mode: bridge

Service Overview

  • Jackett: Torrent indexer proxy
  • Sonarr: TV show management
  • Radarr: Movie management
  • Lidarr: Music management
  • Prowlarr: Indexer manager for *arr applications
  • FlareSolverr: CloudFlare bypass proxy
  • Overseerr: Request management for media
  • NZBGet: Usenet downloader
  • Maintainerr: Media cleanup and maintenance
  • Calibre-Web-Automated: eBook management

Remember to adjust the PUID, PGID, timezone, and volume paths according to your specific Synology setup.