CLI tool to change the network key of PCAP files#53
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new standalone CLI utility (pcap-rekey) under the new ziggurat-tools crate to help sanitize Zigbee packet captures for sharing by re-encrypting NWK-secured traffic under a replacement network key and rewriting APS Transport-Key commands that leak the old key. The tool also optionally injects a synthetic Transport-Key command so Wireshark can learn the new key automatically.
Changes:
- Introduce
pcap-rekeyCLI that reads/writes pcapng and rekeys NWK-secured frames while leaving foreign networks untouched. - Add new
ziggurat-toolscrate definition and dependencies (clap/anyhow/pcap-file). - Update
Cargo.lockfor the new crate/dependencies.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| crates/ziggurat-tools/src/bin/pcap_rekey.rs | Implements the pcapng rekeying CLI, including NWK decrypt/re-encrypt, APS Transport-Key rewrite, and optional key injection for Wireshark. |
| crates/ziggurat-tools/Cargo.toml | Defines the new ziggurat-tools crate and registers the pcap-rekey binary with required dependencies. |
| Cargo.lock | Adds lockfile entries for ziggurat-tools and new transitive dependencies (e.g., pcap-file). |
Comments suppressed due to low confidence (1)
crates/ziggurat-tools/src/bin/pcap_rekey.rs:56
- Similarly,
--new-keyhelp text should state it expects hex, sinceparse_keyrejects non-hex input.
/// The network key to re-encrypt the capture with.
#[arg(long, value_parser = parse_key)]
new_key: Key,
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| fn main() -> Result<()> { | ||
| let args = Args::parse(); | ||
|
|
| Block::EnhancedPacket(EnhancedPacketBlock { | ||
| interface_id: original.interface_id, | ||
| timestamp: original.timestamp, | ||
| original_len: new_data.len() as u32, | ||
| data: Cow::Owned(new_data), | ||
| options: original | ||
| .options | ||
| .iter() | ||
| .map(|option| option.clone().into_owned()) | ||
| .collect(), | ||
| }) |
| // Unsecured join frame: rewrite a cleartext Transport-Key command if it carries the key. | ||
| if encrypted.nwk_header.frame_control.frame_type != NwkFrameType::Data { | ||
| return None; | ||
| } | ||
| let new_aps = | ||
| rewrite_transport_key(&encrypted.ciphertext, old_key, new_key, aps_transport_key)?; | ||
| *aps_rewrites += 1; |
| /// The current network key protecting the capture. | ||
| #[arg(long, value_parser = parse_key)] | ||
| old_key: Key, |
| fn rekey_packet( | ||
| link_type: LinkType, | ||
| data: &[u8], | ||
| old_key: &Key, | ||
| new_key: &Key, | ||
| aps_transport_key: &Key, | ||
| aps_rewrites: &mut u64, | ||
| ) -> Option<Vec<u8>> { | ||
| match link_type { | ||
| LinkType::Raw => rekey_phy(data, old_key, new_key, aps_transport_key, aps_rewrites), | ||
| LinkType::Tap => { | ||
| let header_len = tap_header_len(data)?; | ||
| let new_phy = rekey_phy( | ||
| &data[header_len..], | ||
| old_key, | ||
| new_key, | ||
| aps_transport_key, | ||
| aps_rewrites, | ||
| )?; | ||
|
|
||
| let mut out = data[..header_len].to_vec(); | ||
| out.extend(new_phy); | ||
| Some(out) | ||
| } | ||
| } | ||
| } |
|
I think its not deleting / masking the network key then joining new or old devices ?? GWDP !!!! |
It replaces the network key within the APS Transport Key command so joining should be covered too! |
This is a small utility to make it easier to publicly share PCAP files captured from production networks. It decrypts traffic with a provided network key and then re-encrypts that same traffic with a different key. It also rewrites APS "Transport-Key" commands that directly emit the old key. For ease of use, the second key is injected as a fake "Transport Key" command at the top of the capture so that Wireshark automatically uses it.
Note: this tool won't anonymize packet captures. IEEE addresses, NWK addresses, device-specific unique link key traffic, extended PAN IDs, nearby 802.15.4 network traffic (including non-Zigbee networks), etc. will still be present.
cargo run -p ziggurat-tools --bin pcap-rekey \ capture.pcap rekeyed.pcap --old-key AA:BB:... --new-key 11:22:...