Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions docs/csec/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown
Contributor

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.dumps writes ``, and urllib.parse.quote writes `%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.

Suggested change
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.
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 (``), labeled (`[U+202E]`), and percent-encoded (`%E2%80%AE`)
representations. The hex digits in the escaped and percent-encoded forms are
case-insensitive, and lowercase is what most serializers emit, so match
`` and `%e2%80%ae` as well. These representations are not interchangeable
stored values; search each according to the field's encoding.

Comment on lines +45 to +49

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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 json.dumps writes `` and urllib.parse.quote writes `%e2%80%ae`. An analyst who builds a literal search from this list — exactly what "search each according to the field's encoding" instructs — matches neither, and the miss is silent.

Suggested change
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.
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 (``), labeled (`[U+202E]`), and percent-encoded (`%E2%80%AE`)
representations. The hex digits in the escaped and percent-encoded forms are
case-insensitive, and lowercase is what most serializers emit, so search for
`` and `%e2%80%ae` as well. These representations are not interchangeable
stored values; search each according to the field's encoding.


### 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
Expand Down
100 changes: 74 additions & 26 deletions docs/networking/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.

Expand Down Expand Up @@ -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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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 nmcli recipe gets used — ends with the profile back on the host-wide "stable" default and no fixed address, which is the opposite of what the section set out to do. The revert steps belong to the undo path, not the setup path; separate them so the setup sequence stands alone.

Suggested change
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
nmcli connection modify "<profile name>" 802-3-ethernet.cloned-mac-address 02:00:00:00:00:01
nmcli connection up "<profile name>"
# Undo path, run only when reverting: `modify` rewrites the saved profile, so
# the device keeps the address until this second activation.
nmcli connection modify "<profile name>" 802-3-ethernet.cloned-mac-address ""
nmcli connection up "<profile name>"

```

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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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 macchanger has just written one. "carrier and no address" reads as "the MAC assignment did not stick," which is the failure a reader running this procedure is already primed to look for; the intended meaning is that no DHCP lease exists. Name the layer.

Suggested change
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,
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 IP address,

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.
Comment thread
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.
Loading