-
Notifications
You must be signed in to change notification settings - Fork 0
docs: refine cybersecurity and networking guidance #458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
441d5ed
ed25624
56fbdac
2fc7904
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,55 @@ cybersecurity and software engineering documentation. Keep entries in | |||||||||||||||||||||||||
| alphabetical order by term and use the same fields for each entry: definition, | ||||||||||||||||||||||||||
| example, security note, and references. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Contents | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - [Masquerading](#masquerading) | ||||||||||||||||||||||||||
| - [TOFU (trust on first use)](#tofu-trust-on-first-use) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Masquerading | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Definition | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Masquerading is an adversary technique that manipulates the name, location, | ||||||||||||||||||||||||||
| metadata, appearance, or other identifying features of an object so that a | ||||||||||||||||||||||||||
| malicious or suspicious artifact appears legitimate or benign to users or | ||||||||||||||||||||||||||
| security tools. MITRE ATT&CK identifies it as technique `T1036`; ATT&CK v19 and | ||||||||||||||||||||||||||
| later assign it to the Stealth tactic, while v18 and earlier classified it under | ||||||||||||||||||||||||||
| Defense Evasion. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Example | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Right-to-left override (RTLO or RLO) is sub-technique `T1036.002`. The Unicode | ||||||||||||||||||||||||||
| control character `U+202E` reverses the display order of the text that follows | ||||||||||||||||||||||||||
| it. A filename whose logical name is: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```text | ||||||||||||||||||||||||||
| photo_high_re\u202Egnp.js | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| may be displayed as `photo_high_resj.png`, causing a JavaScript file to appear | ||||||||||||||||||||||||||
| to have a `.png` extension. The backslash notation above represents the | ||||||||||||||||||||||||||
| non-printing character and is used to keep the example visible in source. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Security note | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Do not determine a file's type from its displayed name alone. Inspect the | ||||||||||||||||||||||||||
| underlying file type, signature, and complete filename, and make Unicode | ||||||||||||||||||||||||||
| formatting controls visible during triage. Detection and prevention controls | ||||||||||||||||||||||||||
| should flag or restrict unexpected `U+202E` characters in filenames, especially | ||||||||||||||||||||||||||
| when the file is downloaded, attached to an email, or about to execute. | ||||||||||||||||||||||||||
| The RTLO sub-technique can be detected by inspecting filenames for the actual | ||||||||||||||||||||||||||
| `U+202E` character and, in logs or serialized telemetry, separately accounting | ||||||||||||||||||||||||||
| for escaped (`\u202E`), labeled (`[U+202E]`), and percent-encoded (`%E2%80%AE`) | ||||||||||||||||||||||||||
| representations. These representations are not interchangeable stored values; | ||||||||||||||||||||||||||
| search each according to the field's encoding. | ||||||||||||||||||||||||||
|
Comment on lines
+45
to
+49
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ENHANCEMENT] Supersedes my sibling comment on these lines — that one had its escape sequences decoded into real U+202E characters in transit, so do not commit its suggestion. Corrected version below. The three representations are listed in one fixed case, but the hex digits in both encodings are case-insensitive and lowercase is the common emission: Python's
Suggested change
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### References | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - [MITRE ATT&CK T1036: Masquerading](https://attack.mitre.org/techniques/T1036/) | ||||||||||||||||||||||||||
| - [MITRE ATT&CK v18 T1036: Masquerading](https://attack.mitre.org/versions/v18/techniques/T1036/) | ||||||||||||||||||||||||||
| - [MITRE ATT&CK T1036.002: Right-to-Left Override](https://attack.mitre.org/techniques/T1036/002/) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## TOFU (trust on first use) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Definition | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,6 +14,15 @@ again when it activates a connection. Only the address settings conflict. | |||||||||||||||||||||||
| `linkConfig.Name` does not, and is used below to pin a name on a device whose | ||||||||||||||||||||||||
| NetworkManager policy stays `"stable"`. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| A per-profile `cloned-mac-address` is another NetworkManager owner. Use it when | ||||||||||||||||||||||||
| one network needs a fixed address; see | ||||||||||||||||||||||||
| [Set a fixed address on a connection profile](#set-a-fixed-address-on-a-connection-profile). | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| A manual `macchanger` or `ip link set address` run is a separate owner and the | ||||||||||||||||||||||||
| weakest: NetworkManager replaces the address at the next activation, so a | ||||||||||||||||||||||||
| manually set one holds only while the device is unmanaged. See [Change the | ||||||||||||||||||||||||
| address temporarily](#change-the-address-temporarily-with-macchanger). | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ## Check the interface and its current address | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| This repository sets `networking.usePredictableInterfaceNames = false` in | ||||||||||||||||||||||||
|
|
@@ -32,17 +41,31 @@ empty. | |||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||
| nmcli device status | ||||||||||||||||||||||||
| ip link show | ||||||||||||||||||||||||
| cat /sys/class/net/wlan0/address # address currently presented | ||||||||||||||||||||||||
| ip link show dev wlan0 # presented address, and permaddr when it differs | ||||||||||||||||||||||||
| ethtool -P wlan0 # permanent hardware address | ||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Read both. Once a policy other than `"preserve"` or `"permanent"` is active, | ||||||||||||||||||||||||
| `/sys/class/net/*/address` reports the address NetworkManager assigned, not the | ||||||||||||||||||||||||
| factory one, so `ethtool -P` is what identifies the existing DHCP reservation | ||||||||||||||||||||||||
| or ACL entry you are replacing. NetworkManager exposes only the presented | ||||||||||||||||||||||||
| address, as `GENERAL.HWADDR` in `nmcli device show`; it has no permanent-address | ||||||||||||||||||||||||
| field. | ||||||||||||||||||||||||
| Read both addresses. Once a policy other than `"preserve"` or `"permanent"` is | ||||||||||||||||||||||||
| active, `/sys/class/net/*/address` reports the address NetworkManager assigned, | ||||||||||||||||||||||||
| not the factory one, so the permanent address is what identifies the existing | ||||||||||||||||||||||||
| DHCP reservation or ACL entry you are replacing. Prefer `ip link show`, which | ||||||||||||||||||||||||
| prints the permanent address as a `permaddr` field whenever it differs from the | ||||||||||||||||||||||||
| presented one and so gives both in a single line. `ethtool` reaches this | ||||||||||||||||||||||||
| repository through `flake.homeManagerModules.base` in | ||||||||||||||||||||||||
| [`modules/networking/networking.nix`](../../modules/networking/networking.nix), | ||||||||||||||||||||||||
| which puts it on a user profile rather than in `/run/current-system/sw/bin`, | ||||||||||||||||||||||||
| where `ip` always is. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| `nmcli` has no permanent-address field: `nmcli device show` reports only the | ||||||||||||||||||||||||
| presented address, as `GENERAL.HWADDR`. NetworkManager itself does expose the | ||||||||||||||||||||||||
| permanent one on D-Bus as `PermHwAddress`, deprecated as of 1.56.0. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Read a Wi-Fi address only while its profile is active. This repository leaves | ||||||||||||||||||||||||
| `wifi.scan-rand-mac-address` at NetworkManager's default of `yes`, so a | ||||||||||||||||||||||||
| disconnected Wi-Fi device presents a throwaway scan address that belongs to no | ||||||||||||||||||||||||
| profile and matches neither the permanent address nor any generated one. See | ||||||||||||||||||||||||
| [Re-key services](#re-key-services-after-moving-a-host-to-stable) for reading | ||||||||||||||||||||||||
| one address per profile. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Use the actual interface name in every example below. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -89,6 +112,27 @@ breaks captive-portal state, DHCP reservations, and network allowlists | |||||||||||||||||||||||
| repeatedly. Use `"stable"` when those services need a predictable address | ||||||||||||||||||||||||
| without using the permanent hardware address. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ## Set a fixed address on a connection profile | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| To hold a chosen address on a network rather than observe one for a moment, set | ||||||||||||||||||||||||
| it on the profile instead of on the link, so NetworkManager applies it at every | ||||||||||||||||||||||||
| activation: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||
| nmcli connection modify "<profile name>" 802-3-ethernet.cloned-mac-address 02:00:00:00:00:01 | ||||||||||||||||||||||||
| nmcli connection up "<profile name>" | ||||||||||||||||||||||||
| nmcli connection modify "<profile name>" 802-3-ethernet.cloned-mac-address "" # clear the profile value | ||||||||||||||||||||||||
| nmcli connection up "<profile name>" # apply the reset to the device | ||||||||||||||||||||||||
|
Comment on lines
+122
to
+125
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ENHANCEMENT] This block is the only worked example under a heading that promises how to hold an address, but it ends by clearing the property and reactivating. A reader who copies the block — the normal way a four-line
Suggested change
|
||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| That property takes the same special values as the table above, and overrides | ||||||||||||||||||||||||
| the host-wide default that `networking.networkmanager.ethernet.macAddress` | ||||||||||||||||||||||||
| writes into `NetworkManager.conf`. Wi-Fi profiles use | ||||||||||||||||||||||||
| `802-11-wireless.cloned-mac-address`. The profile is per-host state rather than | ||||||||||||||||||||||||
| declarative repository configuration, so a re-key follows the same rules as | ||||||||||||||||||||||||
| [Re-key services](#re-key-services-after-moving-a-host-to-stable), and it is | ||||||||||||||||||||||||
| not a substitute for a declarative NetworkManager or `.link` policy. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ## Re-key services after moving a host to `"stable"` | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| `"stable"` is not the permanent hardware address either. NetworkManager hashes | ||||||||||||||||||||||||
|
|
@@ -196,8 +240,9 @@ The `.link` `MACAddressPolicy` values are `"persistent"`, `"random"`, and | |||||||||||||||||||||||
| - `"random"` generates a new random address each time the device appears, | ||||||||||||||||||||||||
| unless the kernel already assigned a random one. The result always has the | ||||||||||||||||||||||||
| unicast and locally administered bits set. | ||||||||||||||||||||||||
| - `"none"` keeps the address the kernel assigned, and is the only policy under | ||||||||||||||||||||||||
| which `MACAddress=` applies. | ||||||||||||||||||||||||
| - `"none"` keeps the address the kernel assigned. `MACAddress=` takes effect | ||||||||||||||||||||||||
| only when `MACAddressPolicy=` is unset, empty, or `"none"`, so setting the | ||||||||||||||||||||||||
| two together is one of three working forms rather than the required one. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ### Pin an interface name | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -262,34 +307,37 @@ Use `macchanger` for a one-off test instead of a persistent configuration. | |||||||||||||||||||||||
| Setting a hardware address needs `CAP_NET_ADMIN`, and the kernel rejects the | ||||||||||||||||||||||||
| change with `EBUSY` while the interface is still running. Disconnecting the | ||||||||||||||||||||||||
| NetworkManager device is not enough on its own: that deactivates the | ||||||||||||||||||||||||
| connection but leaves a Wi-Fi interface up so it can keep scanning. Release | ||||||||||||||||||||||||
| the device from NetworkManager and bring the link down first. | ||||||||||||||||||||||||
| connection but leaves a Wi-Fi interface up so it can keep scanning. Ethernet | ||||||||||||||||||||||||
| needs the same two steps for a different reason: a disconnected wired link | ||||||||||||||||||||||||
| stays `IFF_UP` for carrier detection, and the kernel rejects the change with | ||||||||||||||||||||||||
| `EBUSY` on any running interface. Release the device from NetworkManager and | ||||||||||||||||||||||||
| bring the link down first. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Both ends of the sequence matter. An unmanaged device runs no DHCP client, so | ||||||||||||||||||||||||
| stopping after `macchanger` leaves a link that has carrier and no address, | ||||||||||||||||||||||||
|
Comment on lines
+316
to
+317
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ENHANCEMENT] "address" means MAC address everywhere else on this page, and this sentence lands two lines after
Suggested change
|
||||||||||||||||||||||||
| which reads as a dead port rather than as a half-finished command. Handing the | ||||||||||||||||||||||||
| device back ends that, but it also ends the new address: the profile activates, | ||||||||||||||||||||||||
| and the `"stable"` baseline above replaces what `macchanger` set. Read the | ||||||||||||||||||||||||
| result before the final line, not after it. | ||||||||||||||||||||||||
|
Bad3r marked this conversation as resolved.
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Resolve the package as your own user and elevate only the binary. Running | ||||||||||||||||||||||||
| `nix run` under `sudo` re-evaluates the flake against root's registry, store, | ||||||||||||||||||||||||
| and caches instead: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||
| macchanger=$(nix build --no-link --print-out-paths nixpkgs#macchanger)/bin/macchanger | ||||||||||||||||||||||||
| netDev=eth0 | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| nmcli device set wlan0 managed no | ||||||||||||||||||||||||
| sudo ip link set dev wlan0 down | ||||||||||||||||||||||||
| sudo "$macchanger" -r wlan0 # -r randomizes, -p restores the permanent address | ||||||||||||||||||||||||
| sudo ip link set dev wlan0 up | ||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||
| nmcli device set "$netDev" managed no | ||||||||||||||||||||||||
| sudo ip link set dev "$netDev" down | ||||||||||||||||||||||||
| sudo "$macchanger" -r "$netDev" # -r randomizes, -p restores the permanent address | ||||||||||||||||||||||||
| sudo ip link set dev "$netDev" up | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Verify the temporary result, then hand the device back to NetworkManager: | ||||||||||||||||||||||||
| ip link show dev "$netDev" # verify here: the next line discards this address | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||
| cat /sys/class/net/wlan0/address | ||||||||||||||||||||||||
| ip link show dev wlan0 | ||||||||||||||||||||||||
| nmcli device set wlan0 managed yes | ||||||||||||||||||||||||
| nmcli device set "$netDev" managed yes | ||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| NetworkManager restores its configured address the next time it activates the | ||||||||||||||||||||||||
| connection, so do not use `macchanger` as a substitute for a declarative | ||||||||||||||||||||||||
| NetworkManager or `.link` policy. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Changing a MAC address reduces one identifier exposed to a local network. It | ||||||||||||||||||||||||
| does not prevent tracking through Wi-Fi network names, IP-level identifiers, | ||||||||||||||||||||||||
| browser fingerprints, or account activity. | ||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[ENHANCEMENT] The three representations are given in a single fixed case, but the hex digits in both encodings are case-insensitive and lowercase is the common emission: Python's
json.dumpswrites ``, andurllib.parse.quotewrites `%e2%80%ae`. An analyst who builds a literal search from this list — which is exactly what "search each according to the field's encoding" instructs — matches neither, and the miss is silent. State the case rule so the derived searches cover both.