Skip to content

melrosenetworks/S1APAnonymise

Repository files navigation

S1AP PCAP Anonymiser and Stats

Utilities for processing LTE S1AP PCAP/PCAPNG captures:

  • anonymise_s1ap.py: Anonymise IMSIs inside S1AP traffic, optionally strip or anonymise NAS payloads, and filter by S1AP procedure codes.
  • run_anonymise.sh: Convenience wrapper to run the anonymiser with sensible defaults and verification.
  • s1ap_stats.py: Generate quick statistics (procedure codes, IPs, cell IDs, time range) from S1AP captures.

Published by Melrose Networks. Repository will be hosted under the organisation: https://github.com/melrosenetworks

Requirements

  • Python 3.9+ (tested on recent Python 3 versions)
  • Wireshark/Tshark installed and on $PATH (required by pyshark)
  • Python packages (from requirements.txt):
    • pyshark
    • scapy
    • pycrate (provides pycrate_mobile.NAS; used for best-effort NAS handling)

Install (macOS)

  1. Install Wireshark (for tshark):
brew install wireshark
  1. Create a virtual environment and install Python deps:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
  1. Verify tshark is available:
tshark -v

Install (Linux - Debian/Ubuntu)

sudo apt update
sudo apt install -y tshark python3-venv
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Note: This tool reads from capture files; live-capture permissions are not needed. Only the tshark binary is required by pyshark for dissection.

Quick start

source .venv/bin/activate
python anonymise_s1ap.py \
  -i input.pcap \
  -o output.pcap \
  -m output.imsi_map.txt \
  --include 9 11 12 13 18 21 23

Script overview

  • anonymise_s1ap.py

    • Reads PCAP/PCAPNG, scans S1AP frames using Tshark/PyShark, and writes a new capture containing only S1AP frames that pass filtering.
    • For each frame, attempts best‑effort IMSI anonymisation by replacing:
      • TBCD-encoded IMSIs (both nibble orders)
      • ASCII decimal IMSI representations
      • NAS-PDU bytes can be anonymised length‑preserving or zeroed if --strip-nas is used.
    • Generates an IMSI mapping file: original digits to anonymised digits (same length), with configurable anonymised MCC/MNC prefix.
    • Supports pcapng input if your Scapy version provides PcapNgReader.
    • Additional options:
      • --drop-encrypted-nas: Drop frames that carry security‑protected NAS (cannot be anonymised without keys).
      • --no-prefilter: Disable Tshark prefilter step (S1AP‑only fast path); enabled by default.
      • --s1ap-port: Decode S1AP on a specific SCTP port for tshark/pyshark (default 36412).
      • --fast-raw-mode (default) / --no-fast-raw-mode: Toggle fast raw‑byte replacement path vs Scapy‑based processing.
      • --experimental-workers, --experimental-inflight: Experimental concurrency knobs for NAS anonymisation.
  • run_anonymise.sh

    • Wrapper for the Python anonymiser with:
      • Default --include of common S1AP procedures (9, 11, 12, 13, 18, 21, 23)
      • Optional --strip-nas (uncomment in the script)
      • Forwards additional flags to the Python script (e.g., --drop-encrypted-nas, --s1ap-port 38412)
      • Post‑run verification using Tshark:
        • IMSI counts before/after and by field name
        • MCC‑MNC table (input vs output)
        • Procedure code distribution (input vs output)
        • Pass/fail checks:
          • When --strip-nas is enabled, fails if any IMSIs remain in output.
          • Otherwise, fails if output IMSIs are not anonymised or equal to originals.
    • Usage:
      ./run_anonymise.sh -i INPUT.pcapng -o out/anonymised.pcap
    • The IMSI map will be created alongside the output (e.g., out/anonymised.imsi_map.txt).
  • s1ap_stats.py

    • Computes quick S1AP stats using Tshark fields dynamically detected on your Wireshark version:
      • Count of S1AP packets
      • Time range (epoch seconds)
      • Procedure code histogram
      • IP addresses sent/received
      • Detected cell identifiers (various field variants)
    • Usage:
      python s1ap_stats.py -i input.pcap --top 20

anonymise_s1ap.py usage

python anonymise_s1ap.py [-h] -i INPUT [-o OUTPUT] [-m MAP]
                         [--mcc MCC] [--mnc MNC]
                         [--include INCLUDE [INCLUDE ...]]
                         [--exclude EXCLUDE [EXCLUDE ...]]
                         [--strip-nas]
                         [--anonymise-nas | --no-anonymise-nas]
                         [--drop-encrypted-nas]
                         [--no-prefilter]
                         [--s1ap-port S1AP_PORT]
                         [--experimental-workers N]
                         [--experimental-inflight N]
                         [--fast-raw-mode | --no-fast-raw-mode]
  • -i/--input: Input PCAP/PCAPNG file (required)
  • -o/--output: Output PCAP (default: output.pcap)
  • -m/--map: IMSI mapping output (default: imsi_map.txt)
  • --mcc/--mnc: MCC/MNC to prefix anonymised IMSIs (defaults: 999/99)
  • --include: Only include these S1AP procedure codes (space‑separated)
  • --exclude: Exclude these S1AP procedure codes (space‑separated)
  • --anonymise-nas (default) | --no-anonymise-nas: Best‑effort IMSI anonymisation within NAS PDUs (unencrypted NAS only)
  • --strip-nas: Zero out NAS PDUs; if an IMSI is still detected and cannot be safely replaced, the frame may be dropped
  • --drop-encrypted-nas: Drop frames carrying security‑protected NAS (cannot be anonymised without keys)
  • --no-prefilter: Disable Tshark S1AP‑only prefiltering (enabled by default for speed)
  • --s1ap-port: SCTP port to decode as S1AP for tshark/pyshark (default: 36412). Use this if your S1AP runs on a non‑standard port so that procedure codes and NAS PDUs are decoded correctly.
  • --experimental-workers: Experimental number of worker processes for NAS anonymisation
  • --experimental-inflight: Experimental max in‑flight frame queue (default: workers*16)
  • --fast-raw-mode (default) | --no-fast-raw-mode: Use fast raw‑byte replacement path (no checksum fixups) or Scapy‑based processing

Examples:

# Basic anonymisation with common procedures
python anonymise_s1ap.py -i input.pcap -o output.pcap -m output.imsi_map.txt \
  --include 9 11 12 13 18 21 23

# Strip NAS payloads (best-effort zeroing) and drop frames where IMSI remains
python anonymise_s1ap.py -i input.pcap -o output.pcap --strip-nas

# Use a specific anonymised MCC/MNC prefix (length preserved)
python anonymise_s1ap.py -i input.pcap -o output.pcap --mcc 234 --mnc 30

# Disable NAS anonymisation (only do direct TBCD/ASCII replacements when found)
python anonymise_s1ap.py -i input.pcap --no-anonymise-nas

# Decode S1AP on a non-standard SCTP port (e.g., 38412)
python anonymise_s1ap.py -i input.pcap -o output.pcap --s1ap-port 38412

# Drop frames with security-protected NAS that cannot be anonymised
python anonymise_s1ap.py -i input.pcap -o output.pcap --drop-encrypted-nas

Outputs:

  • output.pcap: New capture containing only allowed S1AP frames (others are dropped)
  • output.imsi_map.txt: Lines of original -> anonymised IMSIs actually encountered

run_anonymise.sh usage

./run_anonymise.sh -i INPUT.pcap(,pcapng) -o OUTPUT.pcap

Notes:

  • The script activates .venv automatically if present.
  • Defaults include procedure codes 9 11 12 13 18 21 23.
  • To enable NAS stripping, open the script and uncomment the line that adds --strip-nas.
  • After running, it prints:
    • IMSI counts before/after (via e212.imsi)
    • IMSI field occurrences by field name
    • MCC‑MNC counts (input vs output)
    • Procedure code distribution (input vs output)
    • Pass/fail status:
      • With --strip-nas, fails if any IMSIs remain in output
      • Otherwise, fails if any output IMSIs are not anonymised or equal to originals

s1ap_stats.py usage

python s1ap_stats.py -i INPUT.pcapng --top 20

Typical output (truncated):

=== S1AP Statistics ===
- Number of S1AP packets: 12345
- Time period: 2025-01-01T12:00:00+00:00 to 2025-01-01T12:05:00+00:00 (duration 300.00s)
- Procedure codes (code=count):
  9=120
  11=85
  ...
- IP addresses sent (ip=count):
  10.0.0.1=500
  ...
- IP addresses received (ip=count):
  10.0.0.2=480
  ...
- Cell IDs (id=count):
  0123ABCD=200
  ...

Verifying results with Tshark

Count IMSIs before/after:

tshark -r input.pcap  -Y "s1ap && e212.imsi" -T fields -e e212.imsi | wc -l
tshark -r output.pcap -Y "s1ap && e212.imsi" -T fields -e e212.imsi | wc -l

List sample frames with IMSIs:

tshark -r output.pcap -Y "s1ap && e212.imsi" -T fields -e frame.number -e e212.imsi | head

Check NAS-PDU zeroing (when --strip-nas is used):

tshark -r output.pcap -Y "s1ap" -T fields -e s1ap.nas_pdu 2>/dev/null \
  | sed 's/[^0-9a-fA-F]//g' | grep -E -m1 '[1-9a-fA-F]' || echo "NAS-PDUs appear zeroed or absent"

Important notes and limitations

  • Output contains only S1AP frames that pass filtering; non‑S1AP frames are not copied to the output capture.
  • IMSI anonymisation is best‑effort:
    • Works by replacing known TBCD encodings (both nibble orders) and ASCII occurrences when found.
    • NAS anonymisation is attempted only for unencrypted NAS. Encrypted NAS cannot be decoded/anonymised.
    • With --strip-nas, NAS payloads are zeroed and frames with remaining detectable IMSIs may be dropped.
  • Fast path is enabled by default (--fast-raw-mode): raw‑byte replacements without Scapy checksum fixups. Disable with --no-fast-raw-mode to use Scapy‑based processing if you need protocol‑aware fixups (slower).
  • A Tshark prefilter step (S1AP‑only) is enabled by default for performance; disable it with --no-prefilter if it causes issues in your environment.
  • Use --drop-encrypted-nas to remove frames with security‑protected NAS that cannot be anonymised.
  • Depending on capture link‑types and Scapy/Wireshark versions, some tools may show decoding quirks.
  • For protocol‑correct full re‑encoding, extend with ASN.1/PER aware handling (e.g., pycrate) and ensure length‑preserving updates of SCTP DATA segments.

Repository

This code is provided by Melrose Networks and will be published under the organisation on GitHub: https://github.com/melrosenetworks

About

Anonymisation of LTE S1AP PCAP/PCAPNG captures for evaluation use with the Melrose Networks LTE S1 Analyser.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors