Lesson 09 / 22
Other Channels
Measuring text-message- and voice-call-based phishing in terms of verifiability: the strength of ten verification items across four channels, the fact that the number of strong items in a voice call is zero, the number of breakable links per channel, and the link a callback verification procedure gains in only one channel versus the cost it pays across four channels.
Published Updated
In this lesson
- Maps verification items to a per-channel strength value and derives the per-channel total
- Runs the same chain across four channels and compares the number of breakable links
- Measures the link a callback verification procedure gains together with the legitimate work it cuts
Contents
Every indicator in the previous lesson belonged to a single channel, and that channel had a defining property: the message is stored. Headers can be read, the domain can be queried, the link target can be compared with the text — and all of this can be done before the message is opened. In a text message, part of these items is missing; in a voice call, nearly all of them are.
This lesson compares channels not by tone but by a single measure: how many verification items can be applied per channel. An item is in one of three states — applicable in the channel, present in the channel but spoofable, absent from the channel entirely. The same five-step chain is run across four channels, and the number of links broken in each channel is counted. What emerges is a channel in which the chain breaks at no link at all; which procedure can break that channel, and what that procedure costs, is the lesson’s closing section.
- SE13. The channel list, verification items, and strength values belong to the field crews and
the subscriber services desk of the fictional regional measurement network. What is measured is the
model built with
node. - SE14. The strength value has three tiers (2, 1, 0). Real verifiability is continuous; three tiers preserve the ranking across channels and erase the fine differences within a channel.
- SE15. An item counted as “spoofable” means that the shown source cannot be verified against an independent record as being the source itself. Under what conditions the channel’s infrastructure provides this was not modeled.
- SE16. The chain was taken as identical across the four channels. In reality the channel also changes the chain’s length; a fixed chain makes cross-channel comparison possible.
- SE17. Traffic counts are daily and fictional. A request that is in scope is one requesting authorization or payment; a request that does not fit the window is one that must pass before the callback completes.
- SE18. A step is either broken or it is not. Partial breaking — slowing the request, asking a second question — was not modeled.
Verifiability Per Channel
// channels.mjs — per-channel verification-item strength, the chain, and legitimate traffic; model export const CHANNEL = ['email', 'text message', 'voice call', 'instant message']; // item: strength per channel in channel order (2 applicable, 1 weak/spoofable, 0 absent) export const ITEM = { 'sender domain lookup': [2, 0, 0, 1], 'sender verification record': [2, 0, 0, 0], 'link target comparison': [2, 2, 0, 2], 'inspection without opening the message': [2, 2, 0, 2], 'lookup in a saved directory': [2, 1, 1, 1], 'later re-reading': [2, 2, 0, 2], 'matching against past correspondence': [2, 1, 0, 2], 'verifying the source against an independent record': [1, 1, 1, 1], 'window to consult a second person': [2, 2, 0, 2], 'retaining a record for audit': [2, 2, 0, 1], }; // [step, precondition, item that breaks the step (needs strength 2), item dropped once the step completes] export const CHAIN = [ ['channel selection and preparation', 'a reachable channel address', null, 0], ['contact', 'the recipient responding', 'lookup in a saved directory', 1], ['building trust', 'an internal detail that cannot be verified', 'matching against past correspondence', 1], ['conveying the request', "the recipient's interest", 'inspection without opening the message', 3], ['action', 'the decision-maker being alone', 'window to consult a second person', 6], ]; export const CALLBACK_TIME = 180; // seconds // [channel, daily legitimate requests, in procedure scope, in scope but does not fit the callback window] export const TRAFFIC = [['email', 240, 36, 1], ['text message', 60, 15, 3], ['voice call', 45, 18, 7], ['instant message', 120, 24, 2]]; export const strength = (item, k) => ITEM[item][k]; export function breakable(k, procedure = false) { const d = CHAIN.map((a, i) => (a[2] && strength(a[2], k) === 2 ? i : -1)).filter((i) => i >= 0); return procedure && !d.includes(4) ? [...d, 4] : d; }
// run1.mjs — number of verification items per channel and total verifiability strength import { CHANNEL, ITEM } from './channels.mjs'; console.log(`${Object.keys(ITEM).length} verification items, ${CHANNEL.length} channels ` + `(2 applicable, 1 weak, 0 absent)\n`); console.log(`${'item'.padEnd(52)} ${CHANNEL.map((k) => k.padStart(16)).join('')}`); for (const [name, v] of Object.entries(ITEM)) console.log(`${name.padEnd(52)} ${v.map((g) => String(g).padStart(16)).join('')}`); console.log(`\n${'channel'.padEnd(16)} ${'strong items'.padStart(12)} ${'weak items'.padStart(11)} ` + `${'absent'.padStart(7)} ${'total strength'.padStart(14)} ${'% of email'.padStart(18)}`); const strong = CHANNEL.map((_, k) => Object.values(ITEM).filter((v) => v[k] === 2).length); const total = CHANNEL.map((_, k) => Object.values(ITEM).reduce((a, v) => a + v[k], 0)); CHANNEL.forEach((name, k) => console.log(`${name.padEnd(16)} ${String(strong[k]).padStart(12)} ` + `${String(Object.values(ITEM).filter((v) => v[k] === 1).length).padStart(11)} ` + `${String(Object.values(ITEM).filter((v) => v[k] === 0).length).padStart(7)} ${String(total[k]).padStart(14)} ` + `${`${Math.round((total[k] / total[0]) * 100)}%`.padStart(18)}`)); const inAll = Object.entries(ITEM).filter(([, v]) => v.every((g) => g >= 1)); console.log(`\nitems present in all 4 channels ${inAll.length}: ${inAll.map(([a, v]) => `${a} (strength ${v.join('/')})`).join('; ')}`); console.log(`strong items in voice call: ${strong[2]}`);
10 verification items, 4 channels (2 applicable, 1 weak, 0 absent) item email text message voice call instant message sender domain lookup 2 0 0 1 sender verification record 2 0 0 0 link target comparison 2 2 0 2 inspection without opening the message 2 2 0 2 lookup in a saved directory 2 1 1 1 later re-reading 2 2 0 2 matching against past correspondence 2 1 0 2 verifying the source against an independent record 1 1 1 1 window to consult a second person 2 2 0 2 retaining a record for audit 2 2 0 1 channel strong items weak items absent total strength % of email email 9 1 0 19 100% text message 5 3 2 13 68% voice call 0 2 8 2 11% instant message 5 4 1 14 74% items present in all 4 channels 2: lookup in a saved directory (strength 2/1/1/1); verifying the source against an independent record (strength 1/1/1/1) strong items in voice call: 0
The channel table converges on a single line: the number of strong verification items in a voice call is zero. Eight of the ten items are entirely absent in this channel, two are present but spoofable. Total strength is two, against email’s nineteen — eleven percent. This is not because the channel is badly designed; it is that a live, unstored channel has no object left to examine: the conversation cannot be looked at before it opens, cannot be re-read afterward, cannot be retained for audit.
The difference between a text message and an instant message is also instructive. Both have five strong items, but the distribution differs: in an instant message, matching against past correspondence is strong while in a text message it is weak; in a text message, retaining a record for audit is strong while in an instant message it is weak. Even though total strength is close, which link of the chain they break at will differ, because links depend not on a sum but on specific items.
The percentage in the total-strength column ranks channels with a single number, but it can mislead: a text message appears as sixty-eight percent of email, yet email’s two strongest items — the domain lookup and the sender verification record — are entirely absent from this channel. The percentage does not say which item is missing; its counterpart in the chain will be counted separately in the next section.
Of the two items present in all four channels, the first is strong in only one channel — email; the second is not strong in any channel. No verification item works across every channel; a channel- independent verification procedure can only be added from outside.
Where the Chain Breaks by Channel
// run2.mjs — breakable links per channel, and the gain and cost of the callback verification procedure import { CHANNEL, CHAIN, TRAFFIC, CALLBACK_TIME, breakable } from './channels.mjs'; let s = 0; const cumul = CHAIN.map((a) => (s += a[3])); console.log(`${'#'.padStart(2)} ${'step'.padEnd(35)} ${'precondition'.padEnd(44)} ${'item that breaks the step'.padEnd(40)} cumulative`); CHAIN.forEach((a, i) => console.log(`${String(i + 1).padStart(2)} ${a[0].padEnd(35)} ${a[1].padEnd(44)} ` + `${(a[2] ?? '-').padEnd(40)} ${cumul[i]}`)); const FULL = cumul[CHAIN.length - 1]; const row = (name, d) => { const e = d.length ? (d[0] ? cumul[d[0] - 1] : 0) : FULL, g = d.length ? cumul[d[d.length - 1] - 1] : FULL; return `${name.padEnd(16)} ${String(d.length).padStart(6)} ${(d.length ? String(d[0] + 1) : '-').padStart(10)} ` + `${String(e).padStart(11)} ${String(g).padStart(10)} ${String(g - e).padStart(6)}`; }; console.log(`\n${'channel'.padEnd(16)} ${'links'.padStart(6)} ${'earliest'.padStart(10)} ${'early items'.padStart(11)} ` + `${'late items'.padStart(10)} ${'gain'.padStart(6)} (if never broken ${FULL})`); CHANNEL.forEach((name, k) => console.log(row(name, breakable(k)))); console.log(`\nafter adding the callback verification procedure (callback to the recorded channel, ${CALLBACK_TIME} s):`); CHANNEL.forEach((name, k) => console.log(row(name, breakable(k, true)))); console.log(`\n${'channel'.padEnd(16)} ${'legitimate requests'.padStart(20)} ${'in scope'.padStart(8)} ${'added time (s)'.padStart(14)} ` + `${'delayed jobs'.padStart(12)} ${'link gain +'.padStart(15)}`); let scope = 0, delayed = 0; for (const [name, t, k, a] of TRAFFIC) { scope += k; delayed += a; const i = CHANNEL.indexOf(name), diff = breakable(i, true).length - breakable(i).length; console.log(`${name.padEnd(16)} ${String(t).padStart(20)} ${String(k).padStart(8)} ${String(k * CALLBACK_TIME).padStart(14)} ` + `${String(a).padStart(12)} ${String(diff).padStart(15)}`); } console.log(`total: in scope ${scope} requests, ${scope * CALLBACK_TIME} s (${(scope * CALLBACK_TIME / 3600).toFixed(2)} hours), delayed jobs ${delayed}`); console.log(`voice call: items dropped before the procedure ${FULL}, after ${cumul[3]}; gain ${FULL - cumul[3]} items, cost 7 delayed jobs`); const only = TRAFFIC.find((t) => t[0] === 'voice call'); console.log(`if the procedure is applied only to voice call: in scope ${only[2]} requests, ${only[2] * CALLBACK_TIME} s, ` + `delayed jobs ${only[3]}; the link-gain is the same (1)`);
# step precondition item that breaks the step cumulative 1 channel selection and preparation a reachable channel address - 0 2 contact the recipient responding lookup in a saved directory 1 3 building trust an internal detail that cannot be verified matching against past correspondence 2 4 conveying the request the recipient's interest inspection without opening the message 5 5 action the decision-maker being alone window to consult a second person 11 channel links earliest early items late items gain (if never broken 11) email 4 2 0 5 5 text message 2 4 2 5 3 voice call 0 - 11 11 0 instant message 3 3 1 5 4 after adding the callback verification procedure (callback to the recorded channel, 180 s): email 4 2 0 5 5 text message 2 4 2 5 3 voice call 1 5 5 5 0 instant message 3 3 1 5 4 channel legitimate requests in scope added time (s) delayed jobs link gain + email 240 36 6480 1 0 text message 60 15 2700 3 0 voice call 45 18 3240 7 1 instant message 120 24 4320 2 0 total: in scope 93 requests, 16740 s (4.65 hours), delayed jobs 13 voice call: items dropped before the procedure 11, after 5; gain 6 items, cost 7 delayed jobs if the procedure is applied only to voice call: in scope 18 requests, 3240 s, delayed jobs 7; the link-gain is the same (1)
The channel table shows how the chain changes by channel. In email, four links are breakable and the earliest is the second step: no item has dropped there yet. In a text message the number of breakable links falls to two, and the earliest is the fourth step — by that point two items have already dropped. In an instant message there are three links, and the earliest is the third step. In a voice call the number of breakable links is zero, and the table’s “late items” column reads eleven: the number of items dropped when the chain never breaks at all.
This is the course’s second encounter with the same situation: when a chain has no control at any link, the measure shifts from breaking to detection. In a voice call, detection comes not from the call itself but from what follows it — from the record of the item where the request was carried out. The chain not breaking does not mean what happened goes unseen; it only means that seeing it happens afterward.
The callback verification procedure changes this table in exactly one place. In a voice call, the fifth link becomes breakable, and dropped items fall from eleven to five: the gain is six items. The other three channels see no change at all, because the fifth link was already breakable there. Every gain from the procedure is confined to a single channel.
The cost table writes the counterpart. If the procedure is applied across all four channels at once, it covers ninety-three requests, adds 16,740 seconds a day — more than four and a half hours — of verification time, and delays thirteen legitimate jobs. Its contribution to the breakable-link count is one, and only in the voice call; in the other three channels it is zero. If the procedure is applied only to the voice call, scope falls to eighteen requests, added time to 3,240 seconds, and delayed jobs to seven; the link gained stays the same. The cost of the same gain drops to a fifth, and the only thing that makes the difference is where the procedure is applied.
The seven delayed jobs are the highest in this channel, and that is not a coincidence. A voice call is also the channel of urgent legitimate work; seven of the eighteen in-scope requests do not fit the callback window. The chain’s weakest channel is also the channel where the procedure is most expensive.
The Measure of Switching Channels
The tables measure a chain that runs in a single channel, yet a chain’s steps can be spread across different channels. The effect can be read directly from the output. In email the breakable links are the second and third steps; in a voice call, neither the fourth nor the fifth step is breakable. When the first three steps pass through email and the last two through a voice call, only two breakable links remain, and both sit at values one and two of the cumulative column.
The numeric result is this: on the same chain, the early-break gain falls from five items to one, and the nine-item gap carried by the last two links stays behind no control at all. Switching channels does not add a new step to the chain; it only moves existing steps to a channel with fewer verification items. The defense-side counterpart is measured the same way — what matters is not which channel a request begins in, but which items are present in the channel it completes in. In the previous section, applying the procedure only to voice calls looked cheap; switching channels makes this choice necessary in addition, because the chain’s final link can deliberately be moved to that channel. Per-channel measurement is therefore not enough on its own; the sequence of channels a request follows must also be recorded as an item.
Summary
- The total strength of 10 verification items across the four channels is 19, 13, 2, and 14 respectively. The number of strong items in a voice call is 0; 8 items are entirely absent, 2 are spoofable.
- Only 2 items are present in all four channels, and neither is strong in more than one channel. Channel-independent verification can only be added by an external procedure.
- The same 5-step chain breaks at 4 links in email, 3 in an instant message, 2 in a text message, and 0 in a voice call. In a voice call the chain never breaks, and dropped items stay at 11.
- In an unbreakable chain the measure shifts to detection: in a voice call, seeing happens not during the call but in the record of the item where the request was carried out.
- The callback verification procedure gains one link only in a voice call; dropped items fall from 11 to 5, a gain of 6 items. The other three channels gain 0.
- Applied across all four channels, the procedure costs 16,740 seconds and 13 delayed jobs a day; applied only to voice calls, 3,240 seconds and 7 delayed jobs. The link gained is the same in both cases.
Next Step
All four channels in this lesson worked remotely, and all of them shared one precondition: an address — an email address, a number, or an account. A person entering a building needs none of these preconditions. Going through a door, spoofing a card, looking at a screen left unlocked, or collecting a discarded document draws on a different set of resources: doors, cards, and visual verification. That is the next lesson’s question: how many access items exist in a building model, how many of them have a control, which chain breaks at which item, and how many steps an escort procedure breaks in exchange for how many legitimate passages it slows down.
To keep your progress and take notes, Log in
My notes
Log in to take notes.