Digital Forensics / Intermediate: artifact-specific offline analysis / Lesson 12
Interpret offline network records without contacting targets
Use invented flow metadata to distinguish observation point, tuple, counts, duration, and identity limits.
On this page
Lesson goals
- Explain what a flow or address record can and cannot establish.
- Normalize documentation addresses locally and preserve source scope.
Name the observation point and record type
A flow summary, packet record, DNS log, proxy log, and application event see different aspects of communication. Define the collector viewpoint, direction, sampling, time semantics, and missing intervals before comparing counts. A source address at one boundary may represent a translator, proxy, shared device, or another layer rather than a person. The lesson uses invented metadata and documentation address ranges only. It captures no traffic, opens no capture file, resolves no host, and sends no packet. The examples support local interpretation, not actual connection or user attribution.
Keep tuple scope and time together
A flow-like key often includes protocol, source and destination addresses, and source and destination ports. Equal keys across distant intervals need not describe one continuous connection. The first program groups two synthetic records with the same declared key and totals their provided byte counts. It does not validate collector completeness or reconstruct a TCP stream. Counts may have source-specific meaning and direction, so record their units and policy. A destination port commonly associated with an application does not by itself prove the actual protocol content or a completed business operation.
rows = [{"protocol":"TCP","src":"192.0.2.10","sport":41000,"dst":"198.51.100.20","dport":443,"bytes":120}, {"protocol":"TCP","src":"192.0.2.10","sport":41000,"dst":"198.51.100.20","dport":443,"bytes":80}]
fields = ("protocol","src","sport","dst","dport")
keys = [tuple(row[name] for name in fields) for row in rows]
assert keys[0] == keys[1]
assert sum(row["bytes"] for row in rows) == 200
print("two declared flow records total 200 fixture bytes")
two declared flow records total 200 fixture bytes
The complete program computes a tuple and sum over two local dictionaries. It observes no actual traffic and proves no TLS session, TCP completion, data transfer, or human action. All address values are documentation examples.
Validate address syntax without a network lookup
The second program parses an IPv4 address and checks membership in the explicitly chosen documentation range. This is local numeric reasoning, not discovery, scanning, routing, or geolocation. Reserved example addresses avoid accidental interaction with a real target, but merely parsing an arbitrary address would still not establish ownership or authority to contact it. Preserve the raw source value alongside the normalized address and family. Runtime classification properties can have version-specific definitions, so the example tests explicit network membership rather than relying on a broad label such as globally trusted.
from ipaddress import ip_address, ip_network
raw = "192.0.2.10"
address = ip_address(raw)
example_range = ip_network("192.0.2.0/24")
assert address.version == 4
assert address in example_range
assert str(address) == raw
print("documentation IPv4 membership checked offline")
documentation IPv4 membership checked offline
The complete program performs address parsing and membership only. It makes no socket, DNS request, route query, or external lookup. Membership in this documentation block is not an identity, ownership, or security conclusion.
Separate transport clues from application outcomes
A recorded connection attempt may not complete, a completed transport exchange may not represent a successful application task, and encrypted content may remain unavailable. DNS resolution can precede, outlive, or occur without a later connection; cached answers complicate absence claims. Translation and proxies require time-bounded mapping evidence before linking addresses across layers. Do not infer an operator or device solely from one IP string. Seek independent authorized application or host context while explaining shared-source dependencies. This course performs no real correlation against accounts, infrastructure, or public address services.
Report exactly what the supplied record says
Include collector scope, record type, tuple, time basis, count units, parsing method, and known gaps. Distinguish observed metadata from inferred content and identify uncertainty about retransmissions, sampling, incomplete capture, and direction where relevant. Do not describe the synthetic sum as a measured exfiltration volume or a real transfer. A reproducible offline calculation is useful when its claim remains narrow. Actual packet analysis, source acquisition, endpoint attribution, and content interpretation need separate authorized material and environment-specific validation beyond these created fixtures.
Common errors and fixes
An IP address identifies a person
- Why it happens
- Observation point and translation context are ignored.
- How to fix it
- Report the address as recorded and seek time-bounded corroboration.
- Prevent it next time
- Separate network identifiers from human attribution.
Port 443 proves a successful secure transaction
- Why it happens
- A port clue becomes an application and security claim.
- How to fix it
- Distinguish protocol evidence, completion, and business outcome.
- Prevent it next time
- State payload and collector limits.
Two equal tuples become one continuous connection
- Why it happens
- Time scope and possible tuple reuse are omitted.
- How to fix it
- Keep intervals and record semantics alongside the key.
- Prevent it next time
- Review grouping assumptions before summing.
Check your understanding
1. The synthetic total is 200 bytes. Can it be called data stolen from a system?
Show worked solution
No. It is the sum of two provided counters under a declared model. There is no actual traffic, content, unauthorized action, or source measurement in the fixture. Report the arithmetic and its scope, leaving transfer purpose and real-world volume unestablished.
2. Why is a local address parser insufficient to establish destination ownership?
Show worked solution
It checks syntax and numeric relationships, not administrative control, allocation history, translation, or who used the endpoint at the relevant time. The example deliberately performs no lookup. Any actual identity or ownership conclusion requires separate authoritative and authorized contextual evidence.
Key takeaways
- Network record meaning depends on viewpoint and record type.
- Addresses and ports are clues with identity limits.
- Offline parsing and sums establish no real transfer or attribution.