# analyzing-network-traffic-with-wireshark

Captures and analyzes network packet data using Wireshark and tshark to identify malicious traffic patterns, diagnose protocol issues, extract artifacts, and support incident response investigations on authorized network segments.

- **Kind:** skill
- **Source:** https://github.com/mukul975/Anthropic-Cybersecurity-Skills
- **Page:** https://forefy.com/skills/ba0cc696-dab5-46b6-9695-4ab60f2661f5
- **API (JSON + files):** https://forefy.com/api/asr/ba0cc696-dab5-46b6-9695-4ab60f2661f5

---

## LICENSE

```

```

## SKILL.md

---
name: analyzing-network-traffic-with-wireshark
description: 'Captures and analyzes network packet data using Wireshark and tshark
  to identify malicious traffic patterns, diagnose protocol issues, extract artifacts,
  and support incident response investigations on authorized network segments.

  '
domain: cybersecurity
subdomain: network-security
tags:
- network-security
- wireshark
- packet-analysis
- traffic-analysis
- pcap
version: '1.0'
author: mahipal
license: Apache-2.0
nist_csf:
- PR.IR-01
- DE.CM-01
- ID.AM-03
- PR.DS-02
mitre_attack:
- T1040
- T1071
- T1557
- T1046
---
# Analyzing Network Traffic with Wireshark

## When to Use

- Investigating suspected network intrusions by examining packet-level evidence of command-and-control traffic, data exfiltration, or lateral movement
- Diagnosing network performance issues such as retransmissions, fragmentation, or DNS resolution failures
- Analyzing malware communication patterns by capturing traffic from sandboxed or isolated hosts
- Validating firewall and IDS rules by confirming what traffic is actually traversing network segments
- Extracting files, credentials, or indicators of compromise from captured network sessions

**Do not use** to capture traffic on networks without authorization, to intercept private communications without legal authority, or as a substitute for full-featured SIEM platforms in production monitoring.

## Prerequisites

- Wireshark 4.0+ and tshark command-line utility installed
- Root/sudo privileges or membership in the `wireshark` group for live packet capture
- Network interface access (physical NIC, span port, or network tap) to the monitored segment
- Sufficient disk space for packet capture files (estimate 1 GB per minute on busy gigabit links)
- Familiarity with TCP/IP protocols, HTTP, DNS, TLS, and SMB at the packet level

## Workflow

### Step 1: Configure Capture Environment

Set up the capture interface and filters to target relevant traffic:

```bash
# List available interfaces
tshark -D

# Start capture on eth0 with a capture filter to limit scope
tshark -i eth0 -f "host 10.10.5.23 and (port 80 or port 443 or port 445)" -w /tmp/capture.pcapng

# Capture with ring buffer to manage disk usage (10 files, 100MB each)
tshark -i eth0 -b filesize:102400 -b files:10 -w /tmp/rolling_capture.pcapng

# Capture on multiple interfaces simultaneously
tshark -i eth0 -i eth1 -w /tmp/multi_interface.pcapng
```

For Wireshark GUI, set capture filter in the Capture Options dialog before starting.

### Step 2: Apply Display Filters for Targeted Analysis

```bash
# Filter HTTP traffic containing suspicious user agents
tshark -r capture.pcapng -Y "http.user_agent contains \"curl\" or http.user_agent contains \"Wget\""

# Find DNS queries to suspicious TLDs
tshark -r capture.pcapng -Y "dns.qry.name contains \".xyz\" or dns.qry.name contains \".top\" or dns.qry.name contains \".tk\""

# Identify TCP retransmissions indicating network issues
tshark -r capture.pcapng -Y "tcp.analysis.retransmission"

# Filter SMB traffic for lateral movement detection
tshark -r capture.pcapng -Y "smb2.cmd == 5 or smb2.cmd == 3" -T fields -e ip.src -e ip.dst -e smb2.filename

# Find cleartext credential transmission
tshark -r capture.pcapng -Y "ftp.request.command == \"PASS\" or http.authbasic"

# Detect beaconing patterns (regular interval connections)
tshark -r capture.pcapng -Y "ip.dst == 203.0.113.50" -T fields -e frame.time_relative -e ip.src -e tcp.dstport
```

### Step 3: Protocol-Specific Deep Analysis

```bash
# Follow a TCP stream to reconstruct a conversation
tshark -r capture.pcapng -q -z follow,tcp,ascii,0

# Analyze HTTP request/response pairs
tshark -r capture.pcapng -Y "http" -T fields -e frame.time -e ip.src -e ip.dst -e http.request.method -e http.request.uri -e http.response.code

# Extract DNS query/response statistics
tshark -r capture.pcapng -q -z dns,tree

# Analyze TLS handshakes for weak cipher suites
tshark -r capture.pcapng -Y "tls.handshake.type == 2" -T fields -e ip.src -e ip.dst -e tls.handshake.ciphersuite

# SMB file access enumeration
tshark -r capture.pcapng -Y "smb2" -T fields -e frame.time -e ip.src -e ip.dst -e smb2.filename -e smb2.cmd
```

### Step 4: Extract Artifacts and IOCs

```bash
# Export HTTP objects (files transferred over HTTP)
tshark -r capture.pcapng --export-objects http,/tmp/http_objects/

# Export SMB objects (files transferred over SMB)
tshark -r capture.pcapng --export-objects smb,/tmp/smb_objects/

# Extract all unique destination IPs for threat intelligence lookup
tshark -r capture.pcapng -T fields -e ip.dst | sort -u > unique_dest_ips.txt

# Extract SSL/TLS certificate information
tshark -r capture.pcapng -Y "tls.handshake.type == 11" -T fields -e x509sat.uTF8String -e x509ce.dNSName

# Extract all URLs accessed
tshark -r capture.pcapng -Y "http.request" -T fields -e http.host -e http.request.uri | sort -u > urls.txt

# Hash extracted files for IOC matching
find /tmp/http_objects/ -type f -exec sha256sum {} \; > extracted_file_hashes.txt
```

### Step 5: Statistical Analysis and Anomaly Detection

```bash
# Protocol hierarchy statistics
tshark -r capture.pcapng -q -z io,phs

# Conversation statistics sorted by bytes
tshark -r capture.pcapng -q -z conv,tcp -z conv,udp

# Identify top talkers
tshark -r capture.pcapng -q -z endpoints,ip

# IO graph data (packets per second)
tshark -r capture.pcapng -q -z io,stat,1,"COUNT(frame) frame"

# Detect port scanning patterns
tshark -r capture.pcapng -Y "tcp.flags.syn == 1 and tcp.flags.ack == 0" -T fields -e ip.src -e tcp.dstport | sort | uniq -c | sort -rn | head -20
```

### Step 6: Generate Reports and Export Evidence

```bash
# Export filtered packets to a new PCAP for evidence preservation
tshark -r capture.pcapng -Y "ip.addr == 10.10.5.23 and tcp.port == 4444" -w evidence_c2_traffic.pcapng

# Generate packet summary in CSV format
tshark -r capture.pcapng -T fields -E header=y -E separator=, -e frame.number -e frame.time -e ip.src -e ip.dst -e ip.proto -e tcp.srcport -e tcp.dstport -e frame.len > traffic_summary.csv

# Create PDML (XML) output for programmatic analysis
tshark -r capture.pcapng -T pdml > capture_analysis.xml

# Calculate capture file hash for chain of custody
sha256sum capture.pcapng > capture_hash.txt
```

## Key Concepts

| Term | Definition |
|------|------------|
| **Capture Filter (BPF)** | Berkeley Packet Filter syntax applied at capture time to limit which packets are recorded, reducing file size and improving performance |
| **Display Filter** | Wireshark-specific filter syntax applied to already-captured packets for focused analysis without altering the capture file |
| **PCAPNG** | Next-generation packet capture format supporting multiple interfaces, name resolution, annotations, and metadata in a single file |
| **TCP Stream** | Reassembled sequence of TCP segments representing a complete bidirectional conversation between two endpoints |
| **Protocol Dissector** | Wireshark module that decodes a specific protocol's fields and structure, enabling deep inspection of packet contents |
| **IO Graph** | Time-series visualization of packet or byte rates over the capture duration, useful for identifying traffic spikes or beaconing |

## Tools & Systems

- **Wireshark 4.0+**: GUI-based packet analyzer with protocol dissectors for 3,000+ protocols, stream reassembly, and export capabilities
- **tshark**: Command-line version of Wireshark for headless capture, batch processing, and scripted analysis pipelines
- **tcpdump**: Lightweight packet capture tool for quick captures on remote systems without GUI dependencies
- **mergecap**: Wireshark utility for combining multiple capture files into a single PCAP for unified analysis
- **editcap**: Wireshark utility for splitting, filtering, and converting between capture file formats

## Common Scenarios

### Scenario: Investigating Suspected Data Exfiltration via DNS Tunneling

**Context**: The SOC team detected unusually high DNS query volumes from a workstation (10.10.3.45) to an external domain. The SIEM alert flagged DNS queries averaging 200 per minute compared to the baseline of 15. A packet capture was initiated from the network tap on the workstation's VLAN.

**Approach**:
1. Capture traffic from the workstation's subnet using `tshark -i eth2 -f "host 10.10.3.45 and port 53" -w dns_exfil_investigation.pcapng`
2. Analyze DNS query patterns: `tshark -r dns_exfil_investigation.pcapng -Y "dns.qry.name contains \"suspect-domain.xyz\"" -T fields -e frame.time -e dns.qry.name`
3. Examine subdomain labels for encoded data (long base64-like subdomains indicate tunneling): `tshark -r dns_exfil_investigation.pcapng -Y "dns.qry.type == 16" -T fields -e dns.qry.name -e dns.txt`
4. Calculate data volume by summing query name lengths to estimate exfiltration bandwidth
5. Extract unique query names and decode base64 subdomains to recover exfiltrated content
6. Export evidence packets to a separate PCAP and generate SHA-256 hash for chain of custody

**Pitfalls**:
- Capturing unfiltered traffic on a busy network and running out of disk space before collecting relevant data
- Using display filters instead of capture filters, resulting in massive files that are slow to process
- Overlooking encrypted DNS (DoH/DoT) traffic that bypasses traditional DNS capture on port 53
- Failing to establish packet capture hash and chain of custody documentation for forensic evidence

## Output Format

```
## Traffic Analysis Report

**Case ID**: IR-2024-0847
**Capture File**: dns_exfil_investigation.pcapng
**SHA-256**: a3f2b8c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1
**Duration**: 2024-03-15 14:00:00 to 14:45:00 UTC
**Source Interface**: eth2 (VLAN 30 span port)

### Findings

**1. DNS Tunneling Confirmed**
- Source: 10.10.3.45
- Destination DNS: 8.8.8.8 (forwarded to ns1.suspect-domain.xyz)
- Query volume: 9,247 queries in 45 minutes (205/min vs 15/min baseline)
- Average subdomain label length: 63 characters (base64-encoded data)
- Estimated data exfiltrated: ~2.3 MB via TXT record responses

**2. Indicators of Compromise**
- Domain: suspect-domain.xyz (registered 3 days prior)
- Nameserver: ns1.suspect-domain.xyz (203.0.113.50)
- Query pattern: TXT record requests with base64-encoded subdomains
- Response pattern: TXT records containing base64-encoded payloads
```

## references

```

```

## references/api-reference.md

# API Reference: Wireshark and tshark

## Live Capture
```bash
tshark -i eth0                              # Capture on interface
tshark -i eth0 -w output.pcap              # Write to file
tshark -i eth0 -a duration:60              # Capture for 60 seconds
tshark -i eth0 -f "port 80"               # BPF capture filter
tshark -D                                   # List interfaces
```

## Display Filters (Read Mode)
```bash
tshark -r capture.pcap -Y "<filter>"
```

### Common Filters
| Filter | Purpose |
|--------|---------|
| `ip.addr == 10.0.0.5` | Traffic to/from IP |
| `tcp.port == 443` | Traffic on port 443 |
| `http.request` | HTTP requests only |
| `dns.qr == 0` | DNS queries only |
| `tls.handshake.type == 1` | TLS Client Hello |
| `tcp.flags.syn == 1 && tcp.flags.ack == 0` | SYN-only |
| `frame.len > 1500` | Large frames |
| `tcp.analysis.retransmission` | Retransmissions |
| `icmp` | ICMP traffic |

## Field Extraction
```bash
tshark -r capture.pcap -T fields \
  -e frame.time -e ip.src -e ip.dst -e tcp.dstport \
  -E separator="," -E header=y
```

### Common Fields
| Field | Description |
|-------|-------------|
| `frame.time` | Packet timestamp |
| `ip.src` / `ip.dst` | Source/destination IP |
| `tcp.srcport` / `tcp.dstport` | TCP ports |
| `http.request.method` | HTTP method |
| `http.host` | HTTP Host header |
| `http.request.uri` | Request URI |
| `http.user_agent` | User-Agent |
| `dns.qry.name` | DNS query name |
| `tls.handshake.extensions_server_name` | TLS SNI |
| `tls.handshake.ja3` | JA3 fingerprint |

## Statistics
```bash
tshark -r capture.pcap -q -z conv,ip         # IP conversations
tshark -r capture.pcap -q -z endpoints,ip    # IP endpoints
tshark -r capture.pcap -q -z io,stat,60      # I/O per minute
tshark -r capture.pcap -q -z io,phs          # Protocol hierarchy
tshark -r capture.pcap -q -z http,tree       # HTTP stats
tshark -r capture.pcap -q -z dns,tree        # DNS stats
tshark -r capture.pcap -q -z expert          # Expert info
```

## Object Export
```bash
tshark -r capture.pcap --export-objects "http,/output/dir"
tshark -r capture.pcap --export-objects "smb,/output/dir"
tshark -r capture.pcap --export-objects "tftp,/output/dir"
tshark -r capture.pcap --export-objects "imf,/output/dir"
```

## Stream Following
```bash
tshark -r capture.pcap -z follow,tcp,ascii,0
tshark -r capture.pcap -z follow,http,ascii,0
tshark -r capture.pcap -z follow,tls,ascii,0
```

## Wireshark GUI Shortcuts

| Shortcut | Action |
|----------|--------|
| `Ctrl+F` | Find packet |
| `Ctrl+G` | Go to packet |
| `Ctrl+Shift+E` | Export objects |
| `Ctrl+H` | Follow stream |

## editcap - PCAP Manipulation

```bash
editcap -A "2024-01-15 09:00" -B "2024-01-15 10:00" in.pcap out.pcap  # Time filter
editcap -c 1000 large.pcap split.pcap    # Split into 1000-packet files
editcap -F pcap in.pcapng out.pcap       # Convert format
```

## mergecap - Merge PCAPs

```bash
mergecap -w merged.pcap file1.pcap file2.pcap
```

## scripts

```

```

## scripts/agent.py

```python
#!/usr/bin/env python3
"""Wireshark/tshark packet analysis agent for network security investigations."""

import subprocess
import shlex
import os
import sys


def run_tshark(pcap_path, args):
    """Execute tshark with custom arguments."""
    cmd = ["tshark", "-r", pcap_path] + shlex.split(args)
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
    return result.stdout.strip(), result.stderr.strip(), result.returncode


def capture_live(interface, output_path, duration=60, capture_filter=None):
    """Start a live packet capture using tshark."""
    cmd = ["tshark", "-i", interface, "-w", output_path, "-a", f"duration:{duration}"]
    if capture_filter:
        cmd += ["-f", capture_filter]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=duration + 10)
    return result.returncode == 0


def get_capture_summary(pcap_path):
    """Get overall PCAP capture statistics."""
    stdout, _, _ = run_tshark(pcap_path, "-q -z io,stat,0")
    return stdout


def get_protocol_hierarchy(pcap_path):
    """Get protocol hierarchy statistics."""
    stdout, _, _ = run_tshark(pcap_path, "-q -z io,phs")
    return stdout


def get_conversations(pcap_path, conv_type="ip"):
    """Get conversation statistics (ip, tcp, udp, ethernet)."""
    stdout, _, _ = run_tshark(pcap_path, f"-q -z conv,{conv_type}")
    return stdout


def get_endpoints(pcap_path, endpoint_type="ip"):
    """Get endpoint statistics."""
    stdout, _, _ = run_tshark(pcap_path, f"-q -z endpoints,{endpoint_type}")
    return stdout


def extract_http_requests(pcap_path):
    """Extract HTTP requests with key fields."""
    stdout, _, _ = run_tshark(
        pcap_path,
        '-Y "http.request" -T fields -e frame.time -e ip.src -e ip.dst '
        '-e http.request.method -e http.host -e http.request.uri -e http.user_agent '
        '-E separator="|"'
    )
    requests = []
    for line in stdout.splitlines():
        parts = line.split("|")
        if len(parts) >= 6:
            requests.append({
                "time": parts[0],
                "src": parts[1],
                "dst": parts[2],
                "method": parts[3],
                "host": parts[4],
                "uri": parts[5],
                "user_agent": parts[6] if len(parts) > 6 else "",
            })
    return requests


def extract_dns_queries(pcap_path):
    """Extract DNS queries and responses."""
    stdout, _, _ = run_tshark(
        pcap_path,
        '-Y "dns" -T fields -e frame.time -e ip.src -e ip.dst '
        '-e dns.qry.name -e dns.qry.type -e dns.flags.response '
        '-E separator="|"'
    )
    queries = []
    for line in stdout.splitlines():
        parts = line.split("|")
        if len(parts) >= 5:
            queries.append({
                "time": parts[0],
                "src": parts[1],
                "dst": parts[2],
                "query": parts[3],
                "type": parts[4],
                "is_response": parts[5] if len(parts) > 5 else "0",
            })
    return queries


def extract_tls_info(pcap_path):
    """Extract TLS handshake information including JA3 fingerprints."""
    stdout, _, _ = run_tshark(
        pcap_path,
        '-Y "tls.handshake.type==1" -T fields -e ip.src -e ip.dst '
        '-e tls.handshake.extensions_server_name -e tls.handshake.ja3 '
        '-E separator="|"'
    )
    tls_sessions = []
    for line in stdout.splitlines():
        parts = line.split("|")
        if len(parts) >= 3:
            tls_sessions.append({
                "client": parts[0],
                "server": parts[1],
                "sni": parts[2],
                "ja3": parts[3] if len(parts) > 3 else "",
            })
    return tls_sessions


def detect_suspicious_traffic(pcap_path):
    """Detect common suspicious traffic patterns."""
    findings = []

    # Large ICMP packets (possible data exfiltration)
    stdout, _, rc = run_tshark(pcap_path, '-Y "icmp && frame.len > 100" -T fields -e ip.src -e ip.dst -e frame.len')
    if stdout:
        findings.append({
            "type": "Large ICMP",
            "description": "ICMP packets with large payloads detected",
            "count": len(stdout.splitlines()),
        })

    # DNS TXT queries (possible tunneling)
    stdout, _, rc = run_tshark(pcap_path, '-Y "dns.qry.type==16" -T fields -e ip.src -e dns.qry.name')
    if stdout:
        findings.append({
            "type": "DNS TXT Queries",
            "description": "DNS TXT record queries detected",
            "count": len(stdout.splitlines()),
        })

    # Non-standard HTTP ports
    stdout, _, rc = run_tshark(
        pcap_path,
        '-Y "http && tcp.port != 80 && tcp.port != 443 && tcp.port != 8080" '
        '-T fields -e ip.src -e ip.dst -e tcp.dstport'
    )
    if stdout:
        findings.append({
            "type": "HTTP on non-standard port",
            "description": "HTTP traffic on unusual ports",
            "count": len(stdout.splitlines()),
        })

    return findings


def export_http_objects(pcap_path, output_dir):
    """Export HTTP transferred objects."""
    os.makedirs(output_dir, exist_ok=True)
    _, _, rc = run_tshark(pcap_path, f'--export-objects "http,{output_dir}"')
    files = []
    for f in os.listdir(output_dir):
        fpath = os.path.join(output_dir, f)
        files.append({"name": f, "size": os.path.getsize(fpath)})
    return files


def apply_display_filter(pcap_path, display_filter, fields):
    """Apply a custom display filter and extract specified fields."""
    field_str = " ".join(f"-e {f}" for f in fields)
    stdout, _, _ = run_tshark(
        pcap_path, f'-Y "{display_filter}" -T fields {field_str} -E separator="|"'
    )
    results = []
    for line in stdout.splitlines():
        parts = line.split("|")
        results.append(dict(zip(fields, parts)))
    return results


if __name__ == "__main__":
    print("=" * 60)
    print("Wireshark/tshark Network Analysis Agent")
    print("Packet analysis, protocol stats, artifact extraction")
    print("=" * 60)

    pcap = sys.argv[1] if len(sys.argv) > 1 else None

    if pcap and os.path.exists(pcap):
        print(f"\n[*] Analyzing: {pcap}")

        print("\n--- Capture Summary ---")
        summary = get_capture_summary(pcap)
        print(summary[:500] if summary else "  No stats available")

        print("\n--- Protocol Hierarchy ---")
        hierarchy = get_protocol_hierarchy(pcap)
        print(hierarchy[:500] if hierarchy else "  No hierarchy available")

        print("\n--- HTTP Requests ---")
        http = extract_http_requests(pcap)
        for r in http[:10]:
            print(f"  {r['method']} {r['host']}{r['uri']}")

        print("\n--- DNS Queries ---")
        dns = extract_dns_queries(pcap)
        queries_only = [d for d in dns if d["is_response"] == "0"]
        print(f"  Total DNS queries: {len(queries_only)}")

        print("\n--- TLS Sessions ---")
        tls = extract_tls_info(pcap)
        for t in tls[:10]:
            print(f"  {t['client']} -> {t['sni']} (JA3={t['ja3'][:16]}...)" if t['ja3'] else
                  f"  {t['client']} -> {t['sni']}")

        print("\n--- Suspicious Traffic ---")
        suspicious = detect_suspicious_traffic(pcap)
        for s in suspicious:
            print(f"  [!] {s['type']}: {s['description']} ({s['count']} occurrences)")
    else:
        print(f"\n[DEMO] Usage: python agent.py <capture.pcap>")
```

