---
title: 'Wireless Network Auditing'
source: 'https://academia.sh/en/courses/network-security/wireless-network-auditing'
course: 'Network Security'
language: en
updated: '2026-09-26T03:02:55+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Measures, with a path-loss calculation, the area where the signal spills outside the building boundary on a coverage map'
    - 'Calculates together what lowering transmit power gains on the outside surface and what it costs in indoor coverage'
    - 'Counts what an unauthorized-device scan finds and does not find, along with the reason code'
    - "Gathers the twenty lessons' unverified claims, verified claims, and cost of verification into a single table"
---

# Wireless Network Auditing

A fictional branch building's coverage map is calculated on a one-meter grid: the portion of the connectable area that spills outside the building is one thousand eight hundred thirty-eight square meters, the area where frames can only be heard is twenty-nine thousand six hundred twenty-two square meters, twelve times the inside area. Lowering transmit power zeroes the outside connectable area but does not close the audible area; an unauthorized-device scan finds three of six out-of-inventory sources in two hours, one of which is not found even with continuous monitoring.

The previous lesson separated out three paths that protection cannot close, and what the three
had in common was that none of them was about verifying a claim. Jamming, making the medium
appear busy, and impersonating pre-connection frames can all be done **anywhere the signal
reaches**. Every defense in this course assumed a boundary; in the wireless layer, that boundary
is not a rule, it is a surface.

This lesson calculates that surface. First it measures how far the signal spills outside the
building wall, then it counts what an unauthorized-device scan finds and does not find on that
surface. **Scanning and listening outside one's own network, without written authorization and a
defined scope, is both illegal and unprofessional**; all the measurements below are done as a
model, over a fictional inventory.

- **WS24.** The fictional branch building is sixty-two by thirty-eight meters and carries four
  access points. Positions are a model decision; no real building, real location, or real
  measurement is written.
- **WS25.** The path-loss calculation is real; the exponents, the outside-wall loss, and the
  thresholds are model values and would be derived by measurement in a real building. For points
  outside the building, a single wall crossing is assumed. The grid has a one-meter step and
  includes the building area's edges.
- **WS26.** Two thresholds are separated: the power at which a connection can be established, and
  the power at which a signal can only be heard. The second is the level at which frames can be
  received but a connection cannot be established.
- **WS27.** In the scanning model, a source is found only if it is on a scanned channel, the
  listening window is longer than the source's transmission interval, and it is on during the
  scan.

## The Physical Surface on the Coverage Map

Coverage is not a management preference, it is a path-loss calculation. The building and its
surroundings are divided into a one-meter grid, the power received from the strongest access
point is calculated in each cell, and classified against the two thresholds.

```js
// coverage.mjs — a fictional branch building's coverage map (model). No real location or real
// measurement is written; the path-loss calculation is real, the environment constants are model values.
const BUILDING = { x1: 62, y1: 38 }, AP = [[15, 10], [47, 10], [15, 28], [47, 28]];
const IN_EXP = 3.5, OUT_EXP = 2.6, WALL = 8;    // path-loss exponent and outside-wall loss (dB)
const FSPL1 = 20 * Math.log10((4 * Math.PI * 5.2e9) / 2.998e8);   // 1 m reference loss
const CONNECT = -70, HEAR = -85, LAPTOP = 210;     // dBm thresholds and laptops inside the building
const inside = (x, y) => x >= 0 && x <= BUILDING.x1 && y >= 0 && y <= BUILDING.y1;
const received = (x, y, eirp) => Math.max(...AP.map(([ax, ay]) => {
  const d = Math.max(1, Math.hypot(x - ax, y - ay));
  return eirp - (inside(x, y) ? FSPL1 + 10 * IN_EXP * Math.log10(d)
    : FSPL1 + 10 * OUT_EXP * Math.log10(d) + WALL);
}));
function coverageMap(eirp) {                    // grid: each cell counts as 1 square meter
  const h = { inside: 0, covered: 0, outConnect: 0, outHear: 0, farthest: 0 };
  for (let x = -120; x <= 182; x++) for (let y = -120; y <= 158; y++) {
    const g = received(x, y, eirp);
    if (inside(x, y)) { h.inside++; if (g > CONNECT) h.covered++; continue; }
    if (g > CONNECT) h.outConnect++;
    if (g > HEAR) { h.outHear++; h.farthest = Math.max(h.farthest, -x, x - BUILDING.x1, -y, y - BUILDING.y1); }
  }
  return h;
}
const E = [11, 13, 12, 16, 14, 11, 15];
const row = (a) => a.map((d, i) => String(d)[i ? 'padStart' : 'padEnd'](E[i])).join('');
console.log(`building ${BUILDING.x1} x ${BUILDING.y1} m, access point ${AP.length}, 1 m loss ` +
  `${FSPL1.toFixed(1)} dB, threshold ${CONNECT} / ${HEAR} dBm`);
console.log(row(['transmit', 'in covered', 'in gap', 'out connectable', 'out audible',
  'farthest m', 'devices cut']));
for (const eirp of [20, 17, 14, 11, 8]) {
  const h = coverageMap(eirp);
  console.log(row([`${eirp} dBm`, h.covered, h.inside - h.covered, h.outConnect, h.outHear, h.farthest,
    Math.round((LAPTOP * (h.inside - h.covered)) / h.inside)]));
}
const t = coverageMap(20);
console.log(`\nout audible area is ${(t.outHear / t.inside).toFixed(1)} times the inside area; at ` +
  `8 dBm out connectable 0, out audible still ${coverageMap(8).outHear} m2`);
```

```
building 62 x 38 m, access point 4, 1 m loss 46.8 dB, threshold -70 / -85 dBm
transmit      in covered      in gap out connectable   out audible farthest m    devices cut
20 dBm              2416          41            1838         29622         75              4
17 dBm              1998         459             612         18148         55             39
14 dBm              1554         903             124         11046         40             77
11 dBm              1158        1299               0          6558         28            111
8 dBm                740        1717               0          3702         19            147

out audible area is 12.1 times the inside area; at 8 dBm out connectable 0, out audible still 3702 m2
```

The first row gives this lesson's central number. At twenty dBm transmit power, two thousand
four hundred sixteen square meters are covered inside the building, leaving a gap of forty-one
square meters. At the same time, **outside the building**, a connection can be established over
an area of one thousand eight hundred thirty-eight square meters, and frames can be heard over an
area of twenty-nine thousand six hundred twenty-two square meters. The second number is **twelve
times** the inside area and extends seventy-five meters past the building wall.

No rule can be written at any point in this zone. All the paths measured by the third and fourth
lessons live here: an evil twin, or a source impersonating pre-connection frames, can be
positioned anywhere within the twenty-nine-thousand-square-meter area.

Lowering transmit power is the first defense that comes to mind, and the table counts its cost.
At seventeen dBm, the outside usable area drops to six hundred twelve; in exchange, the inside
coverage gap rises from forty-one to four hundred fifty-nine square meters, and thirty-nine
laptops are left outside. At eleven dBm, the outside usable area reaches **zero**, the inside gap
is one thousand two hundred ninety-nine square meters, and the number of affected devices is one
hundred eleven.

The last row gives the real conclusion. Even though the outside usable area is zero at eight dBm,
the outside audible area is still three thousand seven hundred two square meters. Since transmit
power cannot be reduced to zero, this number cannot be zeroed either: **the connectable surface
can be closed, the audible surface cannot be closed.** The physical boundary is not a defense; at
most, it is a narrowing.

Lowering power also has a side effect that does not appear in the table: since a client picks the
strongest-signaled candidate among those announcing the same name, weakening one's own access
points **makes it easier** for an evil twin to win that comparison.

## What the Scan Finds and Does Not Find

The second measurement asks who is present on the same surface. A scan listens over a list of
channels and compares the sources it hears against the inventory.

```js
// scan.mjs — what an unauthorized-device scan finds and does not find (model). The scan runs
// only over a fictional inventory; no operation targets a real network.
// [name, channel, broadcast interval (s), always on?, in inventory?]
const SOURCE = [
  ['meter endpoint', 6, 900, true, true], ['field terminal', 36, 5, true, true],
  ['branch laptop', 44, 2, true, true], ['panel display', 36, 30, true, true],
  ['barcode printer', 6, 600, true, true], ['maintenance laptop', 149, 2, true, true],
  ['personal access point', 11, 0.1, true, false],
  ['non-broadcasting access point', 157, 300, true, false],
  ['wireless bridge', 165, 1800, true, false],
  ['temporary evil twin', 44, 0.1, false, false],
  ['old-generation test access point', 1, 0.1, true, false],
  ['access point on an unscanned band', 100, 0.1, true, false],
];
const CHANNEL = [1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161, 165];
const PLAN = [['8 channels, 20 minutes', 8, 1200], ['12 channels, 20 minutes', 12, 1200],
  ['12 channels, 2 hours', 12, 7200], ['12 channels, continuous', 12, 86400]];
const seen = ([, channel, interval, always], [, channelCount, duration]) =>
  !CHANNEL.slice(0, channelCount).includes(channel) ? 'out of channel range'
    : duration / channelCount < interval ? 'listening window too short'
      : (!always && duration < 86400) ? 'off during the scan' : 'found';
const inInventory = SOURCE.filter((k) => k[4]), outInventory = SOURCE.filter((k) => !k[4]);
const E = [25, 14, 17, 18, 18];
const row = (a) => a.map((d, i) => String(d)[i ? 'padStart' : 'padEnd'](E[i])).join('');
console.log(`source ${SOURCE.length} (in inventory ${inInventory.length}, out of inventory ` +
  `${outInventory.length}), scannable channels ${CHANNEL.length}`);
console.log(row(['scan plan', 'channel/time', 'inventory item', 'out of inventory',
  'per channel (s)']));
for (const p of PLAN) {
  const b = (l) => l.filter((k) => seen(k, p) === 'found').length;
  console.log(row([p[0], `${p[1]}/${p[2]}s`, `${b(inInventory)}/${inInventory.length}`,
    `${b(outInventory)}/${outInventory.length}`, (p[2] / p[1]).toFixed(0)]));
}
const A = [35, 14, 28, 28];
const row2 = (a) => a.map((d, i) => String(d)[i ? 'padStart' : 'padEnd'](A[i])).join('');
console.log('\n' + row2(['source', 'in inventory', '2-hour scan', 'continuous monitoring']));
for (const k of SOURCE)
  console.log(row2([k[0], k[4] ? 'yes' : 'no', seen(k, PLAN[2]), seen(k, PLAN[3])]));
```

```
source 12 (in inventory 6, out of inventory 6), scannable channels 12
scan plan                  channel/time   inventory item  out of inventory   per channel (s)
8 channels, 20 minutes          8/1200s              4/6               2/6               150
12 channels, 20 minutes        12/1200s              4/6               2/6               100
12 channels, 2 hours           12/7200s              5/6               3/6               600
12 channels, continuous       12/86400s              6/6               5/6              7200

source                               in inventory                 2-hour scan       continuous monitoring
meter endpoint                                yes  listening window too short                       found
field terminal                                yes                       found                       found
branch laptop                                 yes                       found                       found
panel display                                 yes                       found                       found
barcode printer                               yes                       found                       found
maintenance laptop                            yes                       found                       found
personal access point                          no                       found                       found
non-broadcasting access point                  no                       found                       found
wireless bridge                                no  listening window too short                       found
temporary evil twin                            no         off during the scan                       found
old-generation test access point               no                       found                       found
access point on an unscanned band              no        out of channel range        out of channel range
```

The first table shows what scan duration buys. A twenty-minute scan, whether it covers eight
channels or twelve, finds four of the six inventory items and two of the six out-of-inventory
sources: increasing the channel count alone gains nothing, because with the total duration fixed,
the per-channel listening window **drops** from one hundred fifty seconds to one hundred. In two
hours, the numbers rise to five and three. What matters is the listening window: a scan that
listens for six hundred seconds per channel cannot hear a source that speaks once every nine
hundred seconds.

The first row of the second table is this lesson's real finding. **The organization's own four
thousand one hundred meter endpoints do not show up in the two-hour scan** — not an unauthorized
device, but the most populous item in the inventory. A scan reporting that it "matches the
inventory" does not mean the inventory has been verified; it only means the items the scan heard
match.

For two of the reasons a source is not found, the solution is time: continuous monitoring catches
the meter endpoint, the wireless bridge, and the temporary evil twin. The third is
different — a source that stays **out of channel range** is not found even with continuous
monitoring, because the scan's scope is the channel list, not the duration.

The same boundary ties back to the map in the first section: a scan only covers where the scanner
can hear. The two measurements give the same surface — the area where the signal spills out is
both the vulnerable zone and the scan's blind spot.

## Summary

- On the coverage map, a connection can be established over 1,838 square meters outside the
  building, and frames can be heard over 29,622 square meters: the second figure is **12.1
  times** the inside area and reaches 75 meters past the wall.
- Lowering transmit power zeroes the outside usable area at 11 dBm; the cost is a 1,299-square-
  meter coverage gap and 111 devices. The outside **audible** area never reaches zero at any
  power level: 3,702 square meters even at 8 dBm.
- A twenty-minute scan finds 4 of the 6 inventory items; increasing the channel count alone gains
  nothing, since it shortens the per-channel listening window, and the organization's own 4,100
  meter endpoints do not show up in a two-hour scan.
- 3 of the 6 out-of-inventory sources are found in two hours, 5 in continuous monitoring; a
  source operating on an unscanned band is not found under any plan.

## Course Wrap-Up

| Lesson | Unverified claim | What the defense verifies | Cost of verification |
|---|---|---|---|
| Layer models and attack surface | 18 claims, 0 proof | 5 layers 11 claims | 4 extra round trips, 25 manual items |
| Ports and services | 49 acceptance points, 21 unproven | narrowing brings it down to 27 points | 4 periodic flows are cut |
| Address resolution attacks | 6 poisoned records among 26 responses | three defenses rescue 6 records | 16 extra round trips, 4 rejected responses |
| Name resolution attacks | 7 poisoned names, 38 services | signed verification 3 names, 14 services | strict mode stops 47 services |
| Address assignment risks | 70 claims across 14 endpoints, 35 forged | pool and static separation 12 endpoints | 3 manual items, 2 endpoints wrong |
| Denial of service attacks | 4,096 sockets fill in 1.02 seconds | handshake proof zeroes the socket | 15% of legitimate traffic is eliminated |
| On-path attacks | 16 of 36 steps read the content | endpoint verification and root pinning 16 steps | 84-item list, 7 cut flows |
| Replay and spoofing attacks | 5 of 10 types change state via replay | three proofs 3 full, 5 partial types | 503 rejected messages, 224 state items |
| Firewall generations | 40 of 48 claims unproven | the application-aware generation 45 claims | 94,112 state records, 6 resolvers |
| Network segmentation and the DMZ | 210 transitive items | segmentation brings it down to 25 items | 15 rule lines, 2 cut flows |
| Proxy and jump servers | 99.5% of connections unrecorded | subject identity on 3,118 connections | 210,502 connections in a single outage |
| Intrusion detection and prevention | 3 of 14 classes invisible from the network | two sensors 6 of 7 classes | prevention cuts 5,214 legitimate events |
| Honeypots and sinkholes | 29.8% false positive in the signature scheme | deception 594 alerts, 1.2% wrong | 22,690 connections unrecorded at the sinkhole |
| Virtual private networks | the remote endpoint directly accesses 136 items | a separate zone brings it down to 16 items | 8 hours of proof, 97,100 unaudited connections |
| Access control lists | 2 order-sensitive pairs among 10 rules | 15 of 16 flows in the order written | in reverse order 16 flows are rejected |
| Wireless encryption generations | 10 claims, 0 proof in the old generation | the simultaneous-authentication generation 7 claims | 4,321 devices are left out |
| Authentication methods | 6 of 7 claims unproven | enterprise mode and a fixed root 7 claims | 7 infrastructure items, 4,138 devices |
| Rogue access points | 6 signals 0 proof, 4 open paths | three defenses zero out the open path | 976 manual approvals a day |
| Deauthentication | 11 of 12 frame types unproven | protection 3 frames, 3 paths | 5 paths open, protection made mandatory |
| Wireless network auditing | outside audible area is 12.1 times the inside area | at 11 dBm outside usable area 0 | 1,299 m² gap, 111 devices |

The second column writes this course's rule: **network security is not a checklist of boxes, it
is how many of the claims a message carries can be proven; every claim that cannot be proven is a
path.** No defense was measured as "installed and done"; each one was run against a set of
claims.

The third column gathers into four groups. **Extra round trips and key items** are the cost
verification writes into the protocol; **legitimate work cut off** is the cost written into the
work itself; **devices left out** is the cost written into the inventory, and in the wireless
lessons it is measured in the thousands; **manually managed items** are both a maintenance load
and a count of places that can be misconfigured.

In none of the twenty lessons did the number of open claims fall to zero, and the claims that
remained were of the same kind: who a subject is, whether a frame was sent before the connection
was established, whether a signal can be heard outside the wall. Underneath this entire
measurement, there is also an assumption that was never asked. Across the twenty lessons, calling
a claim "verifiable" meant that a proof could be tested: a signature held up, a shared secret was
known, an identity was tied to a trust root. What that proof **rested on** was never asked.
Where did the key that verifies the signature come from, who holds the shared secret, why is the
trust root trusted? **M24/K04 Identity, Access and Cryptography** begins with exactly this
question: what does a claim's provability rest on, who holds the key, and where does trust begin?
