SIP REGISTER Client v7
A defensive, diagnostic SIP REGISTER client written in Go.
Designed to accurately verify SIP PBX credentials while detecting and rejecting
misconfigured, phantom, or non-SIP servers (IP cameras, GB28181 surveillance platforms, etc.).
Requirements
Go 1.18 or later
Linux / macOS / Windows
Network access to your SIP server on port 5060
Quick Start
# Build once
go build -o sip_client sip_client.go
# Run
./sip_client <user> <pass> <server> <port> [transport] [--log=yes|no]
Or run directly without building:
go run sip_client.go <user> <pass> <server> <port>
Usage
./sip_client <user> <pass> <server> <port> [transport] [--log=yes|no]
| Argument | Description | Required |
|---------------|--------------------------------------------------|----------|
| user | SIP extension / username | Yes |
| pass | SIP password | Yes |
| server | SIP server IP or hostname | Yes |
| port | SIP port (usually 5060) | Yes |
| transport | udp / tcp / auto (default: auto) | No |
| --log=yes | Write full log to sip_client.log (default) | No |
| --log=no | Console output only, no log file | No |
Transport Options
| Value | Behaviour |
|--------|--------------------------------------------------------------------|
| udp | Use UDP only |
| tcp | Use TCP only (persistent connection, Content-Length framing) |
| auto | Probe both UDP and TCP, pick best, fall back automatically |
Examples
# Auto-detect transport (recommended)
./sip_client 1010 mypassword 192.168.1.100 5060
# Force UDP only
./sip_client 1010 mypassword 192.168.1.100 5060 udp
# Force TCP only
./sip_client 1010 mypassword 192.168.1.100 5060 tcp
# Auto, no log file
./sip_client 1010 mypassword 192.168.1.100 5060 auto --log=no
# Built-in help
./sip_client --help
Output Files
| File | Contents |
|------------------|-----------------------------------------------------------------|
| results.txt | Verified successful registrations |
| rejected.txt | Phantom / misconfigured servers that were detected and discarded|
| sip_client.log | Full timestamped session log (disabled with --log=no) |
results.txt format
192.168.1.100:5060 1010:mypassword Asterisk/18.x [udp and tcp]
<server>:<port> <user>:<pass> <Server-UA> [<transport-support>]
rejected.txt format
192.168.1.200:5060 1010 REJECTED [phantom: accepts any credential (canary accepted)] 2025-01-15 10:23:44
How It Works — Full Flow
┌─────────────────────────────────────────────────────────┐
│ 1. Algorithm Self-Test │
│ Verifies MD5 / SHA-256 / SHA-512-256 locally │
│ Aborts immediately if any hash is wrong │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ 2. Protocol Probe (auto mode only) │
│ Sends REGISTER + OPTIONS on UDP and TCP │
│ Measures latency, picks best transport │
│ Runs network diagnostics (DNS, port, subnet) │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ 3. REGISTER — Round 1 (no credentials) │
│ Expects 401 Unauthorized with WWW-Authenticate │
│ If 200 OK with no challenge → REJECTED (open server) │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ 4. Challenge Sanity Checks (Section 6b) │
│ • Missing algorithm field → REJECTED │
│ • realm == username → REJECTED (circular) │
│ • Contact contains 0.0.0.0 → REJECTED │
│ • GB28181 numeric realm → REJECTED (camera) │
│ • Known non-SIP User-Agent → REJECTED │
│ • GB28181 Content-Type → REJECTED │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ 5. Digest Authentication │
│ Computes HA1 = hash(user:realm:pass) │
│ Computes HA2 = hash(method:uri) │
│ Builds Authorization header with qop / cnonce / nc │
│ Supports: MD5, SHA-256, SHA-512-256 │
│ Falls back to secondary algorithm if primary fails │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ 6. REGISTER — Round 2 (with credentials) │
│ 200 OK → registration appears successful │
│ 403 / 401 → wrong password → fail │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ 7. Canary Credential Test (Section 6c) │
│ Generates random bogus credentials │
│ e.g. user: c3f7a2b pass: ca91d4be │
│ Attempts full REGISTER cycle with them │
│ │
│ Server rejects canary (401/403) → REAL SERVER ✓ │
│ → saved to results.txt │
│ │
│ Server accepts canary (200 OK) → PHANTOM SERVER ✗ │
│ → discarded, logged to rejected.txt │
└─────────────────────────────────────────────────────────┘
Security Checks Explained
1. Open Server (no authentication)
Server returns 200 OK to a REGISTER with no credentials.
This means it accepts anyone. Credentials cannot be verified. Rejected.
2. Missing Algorithm (Section 6b)
WWW-Authenticate: Digest realm="example.com", nonce="abc123"
← no algorithm!
RFC 3261 §22.4 requires an explicit algorithm.
A server omitting it may be bypassing proper digest enforcement. Rejected.
3. Circular Hash — realm equals username (Section 6b)
Username: 3000
Realm: 3000 ← same!
HA1 = MD5("3000:3000:password")
↑ ↑
user = realm → circular input
Some broken servers accept any password in this configuration. Rejected.
4. Contact: 0.0.0.0 (Section 6b)
Contact: <sip:[email protected]:6060>
0.0.0.0 is not a routable address.
Server is misconfigured or acting as a blind proxy. Rejected.
5. GB28181 Surveillance Detection (Section 6b + Section 9)
GB28181 is a Chinese surveillance standard used by IP cameras (Hikvision, Dahua, etc.).
These devices respond to SIP REGISTER but are not SIP PBX servers.
Detected by:
Numeric-only realm 8–20 digits (e.g.
34020000001320000001)Known User-Agent strings:
hikvision,dahua,intervideo,wvp-pro, etc.Content-Type:
application/manscdp+xmlGB28181 device IDs in Contact header
Rejected.
6. Canary Credential Test (Section 6c)
After a successful registration, the tool generates random fake credentials
(e.g. c3f7a2b / ca91d4be) and attempts a full REGISTER cycle.
Server rejects canary → enforces authentication → credentials are valid ✓
Server accepts canary → accepts any input → phantom server → discarded ✗
This catches servers that accept user/user, root/root,
or literally any string as valid credentials.
Algorithm Support
| Algorithm | Standard | Notes |
|--------------|-----------------|--------------------------------|
| MD5 | RFC 3261 §22.4 | Default when none declared |
| SHA-256 | RFC 7616 | Modern standard |
| SHA-512-256 | RFC 7616 | High security variant |
The tool also handles algorithm aliases automatically:
| Declared | Resolved to |
|----------------|--------------|
| SHA256 | SHA-256 |
| SHA2 | SHA-256 |
| SHA512/256 | SHA-512-256|
| MD-5 | MD5 |
Transport Details
UDP
Connectionless, one socket per session
Standard SIP transport (RFC 3261)
Via header:
SIP/2.0/UDP
TCP
Persistent connection, Content-Length message framing
Via header:
SIP/2.0/TCPContact and Request-URI include
;transport=tcpRequired for large messages or NAT traversal
Auto Mode
Probes both UDP and TCP with REGISTER + OPTIONS
Measures response latency on each
Tries UDP first (lower overhead), falls back to TCP if UDP REGISTER fails
Reports results in a summary table
Logger Icons Reference
| Icon | Meaning |
|------|----------------------------|
| ℹ️ | General information |
| ⚠️ | Warning |
| 🆕 | New / unknown item found |
| ❌ | Error or rejection |
| 📤 | Message sent (TX) |
| 📥 | Message received (RX) |
| ✅ | Success |
| ⏭️ | Message skipped |
| 🔍 | Debug detail |
| 🔬 | Protocol probe result |
Code Structure
| Section | Name | Description |
|---------|---------------------------|-----------------------------------------------------------|
| 1 | Logger | Timestamped leveled logging to console + file |
| 2 | Transport Abstraction | Transport interface — unified API for UDP and TCP |
| 3 | Protocol Probe | Network diagnostics + UDP/TCP server detection |
| 4 | Self-Test | Hash algorithm verification on startup |
| 5 | Algorithm Detection | Parses and resolves digest algorithm declarations |
| 6 | Challenge Parser | Parses WWW-Authenticate Digest headers |
| 6b | Challenge Sanity Checks | Rejects 0.0.0.0, circular hash, missing algorithm |
| 6c | Canary Credential Test | Detects phantom servers that accept any credentials |
| 7 | Hash + Auth Builder | Computes HA1/HA2/response, builds Authorization header |
| 8 | SIP Message Builder | Builds REGISTER messages (transport-aware) |
| 9 | Server Fingerprinting | Identifies GB28181 cameras vs real SIP PBX |
| 10 | Response Code Coverage | Handles all SIP response codes (1xx–6xx) |
| 11 | SIP Response Parser | Parses raw SIP messages into structured responses |
| 12 | UDP Port Utilities | Reliable UDP socket binding with fallback strategies |
| 13 | SIP Client | Transport-agnostic client, dialog state management |
| 14 | Registration Flow | Full 2-round REGISTER + auth + canary flow |
| 15 | Auto Mode | Probe → pick transport → register with fallback |
| 16 | Results File Writer | Writes verified results to results.txt |
Signal Handling
The tool handles Ctrl+C (SIGINT) and SIGTERM cleanly:
Closes the transport connection
Writes session summary to log
Exits with code 0
Session Summary
At the end of every run, a summary is printed:
════════════════════════════════════════════════
Session Summary:
Messages sent: 4
Messages received: 4
Messages skipped: 0
Warnings: 1
Errors: 0
New/unknown items: 0
════════════════════════════════════════════════
Typical Output — Real SIP Server
╔═══════════════════════════════════════════════════════════╗
║ SIP REGISTER Client v7 — UDP + TCP + Auto-Detection ║
╚═══════════════════════════════════════════════════════════╝
Server: 192.168.1.100:5060
Username: 1010
Transport: AUTO
ℹ️ ── Algorithm self-test ────────────────────────────────
ℹ️ ✓ MD5: 5f4dcc3b5aa765d6...
ℹ️ ✓ SHA-256: 9f86d081884c7d65...
ℹ️ ✓ SHA-512-256: 3d37fe58435e0d87...
🔬 Probing server 192.168.1.100:5060 ...
🔬 UDP ✅ REGISTER responded in 12ms
🔬 TCP ✅ REGISTER responded in 15ms
🔬 🟢 Result: Server supports UDP AND TCP
╔═══════════════════════════════════════════════════════════╗
║ Protocol Probe Results ║
║ UDP: ✅ supported (12ms) ║
║ TCP: ✅ supported (15ms) ║
╚═══════════════════════════════════════════════════════════╝
📤 REGISTER sip:192.168.1.100:5060 SIP/2.0
📥 SIP/2.0 401 Unauthorized
ℹ️ Algorithm detection — declared: 'MD5'
📤 REGISTER sip:192.168.1.100:5060 SIP/2.0 (with Authorization)
📥 SIP/2.0 200 OK
✅ Registration successful [UDP]!
✅ Server/UA: Asterisk PBX 18.x
✅ Expires: 300 seconds
ℹ️ Canary Check: testing with bogus credentials
ℹ️ Canary user: c3f7a2b
ℹ️ Canary pass: ca91d4be
📤 REGISTER (canary attempt)
📥 SIP/2.0 403 Forbidden
✅ Canary Check PASSED ✓ — server rejected bogus credentials (code=403)
✅ Result saved → results.txt
✅ Done!
Typical Output — Phantom Server
📥 SIP/2.0 200 OK ← registration appears to succeed
ℹ️ Canary Check: testing with bogus credentials
ℹ️ Canary user: cb2e9a1
ℹ️ Canary pass: cd4f7b3e
📤 REGISTER (canary attempt)
📥 SIP/2.0 200 OK ← server accepts anything!
❌ PHANTOM SERVER DETECTED via Canary Check!
❌ Server accepted bogus credentials: user='cb2e9a1' pass='cd4f7b3e'
❌ This server accepts ANY username/password combination
❌ Action: result discarded, server added to rejected.txt
❌ Failed: phantom server: accepted canary user='cb2e9a1' pass='cd4f7b3e'
Notes
The tool only saves results to
results.txtafter passing all checks including the Canary Test.Each session appends to existing files — it does not overwrite previous results.
The
--logflag can appear anywhere in the argument list.Canary credentials are randomly generated each run — they will never match real extensions.