NIX^:Linux & IT

macOS-ISO-to-USB

shasum -a 256 ~/Downloads/some.iso

intermediateupdated 2026-08-10Ligolo-ng

💿 Burning ISOs to USB on macOS (CLI)

[!info] TL;DR

  • Linux / BSD / macOS / most ISOs → dd just works.
  • Windows 10/11 ISOs → dd does not work. install.wim is usually >4 GB, diskutil eraseDisk can’t do FAT32, and the Windows boot chain needs a UEFI-visible FAT32 partition. Use the mount + rsync + wimlib-split method.
  • Erasing / wiping → see the diskutil erase section. Secure-erase passes are for spinning HDDs; flash/SSDs need encryption-based wipes.
  • Always diskutil list twice before writing. of= to the wrong disk destroys your Mac in seconds.

⚠️ Before You Start

  • Identify your USB drive: diskutil list — look for size, name, external, physical.
  • Never write to /dev/disk0 (internal SSD) or the disk containing /System/Volumes/Data.
  • Use the raw device (/dev/rdiskN) for dd — it’s ~10× faster than /dev/diskN.
  • Apple Silicon caveat: a Windows x64 USB will not boot an ARM Mac. You’re making this for a PC or an ARM Windows VM.

🧪 Step 0 — Verify the ISO (always do this)

# SHA-256 — compare against the vendor's published hash
shasum -a 256 ~/Downloads/some.iso

# Or if the vendor published SHA-512
shasum -a 512 ~/Downloads/some.iso

🐧 General Method — Linux / BSD / macOS / Kali / Ubuntu / etc.

Works for any hybrid ISO (isohybrid / modern Linux / Kali / Ubuntu / FreeBSD / macOS recovery). This is the dd path.

# 1. List disks, find your USB
diskutil list

# 2. Unmount the whole disk (not `eject`, not a partition)
diskutil unmountDisk /dev/disk4

# 3. Write the ISO — note `rdisk`, not `disk`
sudo dd if=~/Downloads/kali-linux-2025.iso of=/dev/rdisk4 bs=4m status=progress

# 4. Eject when done
diskutil eject /dev/disk4

[!tip] Speed & progress

  • bs=4m is a sane block size on macOS (lowercase m, not M).
  • status=progress works on recent macOS; if not, hit Ctrl+T during dd to print SIGINFO progress.

[!warning] “Resource busy” If dd refuses with Resource busy, you forgot diskutil unmountDisk. Do not reformat the drive to fix this.


🪟 Windows 10/11 ISO — The Method That Actually Works

[!danger] Why dd fails for Windows Windows ISOs since ~2017 ship sources/install.wim larger than 4 GB. A dd copy preserves the ISO’s internal filesystem (UDF/ISO9660), which most PC firmwares won’t boot as a Windows installer. The canonical fix: format USB as FAT32 + MBR, copy files, and split install.wim with wimlib so it fits FAT32’s 4 GB per-file limit. Windows Setup transparently reassembles split .swm files.

Prereqs

# Install wimlib (provides wimlib-imagex)
brew install wimlib

Full procedure

# 1. Find the USB
diskutil list
# Assume it's /dev/disk4 — a 16 GB+ stick

# 2. Format: MS-DOS (FAT32) + MBR, label WIN11
sudo diskutil eraseDisk MS-DOS "WIN11" MBR /dev/disk4

# 3. Mount the Windows ISO
hdiutil mount ~/Downloads/Win11_English_x64.iso
# Note the mount point — usually /Volumes/CCCOMA_X64FRE_EN-US_DV9
# (name varies by build/language)

# 4. Set variables for clarity
ISO_MOUNT="/Volumes/CCCOMA_X64FRE_EN-US_DV9"
USB_MOUNT="/Volumes/WIN11"

# 5. Copy everything EXCEPT install.wim (too big for FAT32)
rsync -avh --progress --exclude='sources/install.wim' "$ISO_MOUNT/" "$USB_MOUNT/"

# 6. Split install.wim into <4 GB chunks directly onto the USB
wimlib-imagex split "$ISO_MOUNT/sources/install.wim" \
    "$USB_MOUNT/sources/install.swm" 3800

# 7. Unmount cleanly (flush buffers — this takes a minute, be patient)
hdiutil unmount "$ISO_MOUNT"
diskutil eject /dev/disk4

[!note] Why 3800 MB? FAT32’s per-file cap is 4 GiB = 4096 MB. 3800 leaves headroom; Microsoft docs suggest splitting below the limit.

[!tip] If the target PC won’t boot the USB

  • Some modern PCs want GPT, not MBR. Re-run step 2 with GPT instead of MBR and try again.
  • In BIOS/UEFI, disable CSM/Legacy and ensure Secure Boot is off for installation.
  • For Windows 7 (legacy), dd actually works fine — the .wim bloat is a modern Windows problem.

Windows ARM ISO (for Apple Silicon VMs)

Same procedure, but install.wim is often under 4 GB — try a straight rsync first with no split:

rsync -avh --progress "$ISO_MOUNT/" "$USB_MOUNT/"
# If it fails on install.wim, fall back to the wimlib-split step above.

🧹 diskutil — Erasing & Secure-Erasing Drives

[!danger] Read this first Every diskutil erase* verb is destructive and immediate — no confirmation prompt, no undo. Always run diskutil list twice and target the correct /dev/diskN. Hitting disk0 wipes your Mac’s internal SSD.

Verb cheat sheet

VerbWhat it doesScope
eraseDiskWipe entire disk, lay down new partition scheme + one volumeWhole drive
eraseVolumeWipe a single mounted volume, keep the disk’s partition schemeOne partition
partitionDiskWipe disk and create multiple partitions in one shotWhole drive
zeroDiskFill entire disk with zeros (single pass)Whole drive
randomDisk <passes>Fill entire disk with random data, N passesWhole drive
secureErase <level>Multi-pass overwrite wipe of a whole diskWhole drive
secureErase freespace <level>Overwrite only the unused space on a mounted volumeFree space only

Formats you’ll actually use

Format stringReal filesystemTypical use
APFSAPFSModern macOS-only volumes
JHFS+Mac OS Extended (Journaled)macOS legacy / Time Machine on HDD
MS-DOS or MS-DOS FAT32FAT32Windows installers, UEFI boot, BIOS flash
ExFATexFATLarge files + cross-OS (no 4 GB limit)
Free SpaceunformattedCreate a blank slot for later

Partition schemes

StringWhen to use
MBR / MBRFormatWindows installer USB (FAT32 + MBR), legacy BIOS
GPT / GPTFormatModern UEFI systems, anything >2 TB, most 2020+ PCs
APM / APMFormatPowerPC-era Macs — don’t use unless you need to

Common erase patterns

# Plain reformat a USB as exFAT + GPT (cross-OS daily-driver stick)
sudo diskutil eraseDisk ExFAT "DATA" GPT /dev/disk4

# FAT32 + MBR for a Windows installer USB
sudo diskutil eraseDisk MS-DOS "WIN11" MBR /dev/disk4

# APFS + GPT for a macOS-only stick
sudo diskutil eraseDisk APFS "MACSTICK" GPT /dev/disk4

# Wipe a single mounted volume, keep the scheme intact
sudo diskutil eraseVolume JHFS+ "Scratch" /Volumes/Scratch

# Partition a disk into two volumes in one go (exFAT + APFS, GPT)
sudo diskutil partitionDisk /dev/disk4 2 GPT \
    ExFAT "SHARED" 50% \
    APFS  "MACONLY" 0b

Secure erase — diskutil secureErase

[!warning] Secure erase on SSDs / USB flash is largely theatre Apple removed the GUI option because overwriting doesn’t reliably wipe flash. Wear-levelling, over-provisioning, and TRIM mean the controller may silently keep copies of “erased” blocks. Use it on spinning HDDs where it actually works. For SSDs/flash, prefer FileVault / encryption with a discarded key, or the drive’s own ATA Secure Erase / NVMe Sanitize (usually only accessible from Linux via hdparm / nvme-cli).

Syntax:

sudo diskutil secureErase <level> /dev/diskN
sudo diskutil secureErase freespace <level> /Volumes/VolumeName

Levels (yes, the numbering is bizarre):

LevelPassesStandardNotes
01Single-pass zeroFast. Fine for HDDs.
11Single-pass randomSlightly better than zeros on HDD
27DoE 3-pass (historic: DoD 5220.22-M 7-pass)Overkill for modern HDDs
335GutmannAlmost never justified; hours–days
43US DoD 5220.22-M (3-pass)The “sensible paranoid” option

Examples:

# Single zero-pass wipe of a whole USB (HDD-era fast option)
sudo diskutil secureErase 0 /dev/disk4

# DoD 3-pass wipe of a USB stick (for pentest engagement hygiene)
sudo diskutil secureErase 4 /dev/disk4

# Scrub only the free space on a mounted volume — leaves files intact,
# tries to kill recoverable remnants of already-deleted files
sudo diskutil secureErase freespace 1 /Volumes/DATA

# Equivalent "lite" path: single-pass zero-fill of whole disk
sudo diskutil zeroDisk /dev/disk4

# Random-fill, 3 passes
sudo diskutil randomDisk 3 /dev/disk4

[!tip] Ctrl+T for progress secureErase, zeroDisk, and randomDisk are quiet. Press Ctrl+T in the terminal to send SIGINFO and get a one-line progress update.

Pentest-engagement hygiene recipe

For reusable installer/tooling USBs between clients (bearing in mind flash-memory caveats above):

# 1. Identify
diskutil list external physical

# 2. Unmount (just in case)
diskutil unmountDisk /dev/disk4

# 3. Single random-pass (good enough for flash; don't waste cycles on 7/35)
sudo diskutil randomDisk 1 /dev/disk4

# 4. Reformat ready for the next client
sudo diskutil eraseDisk ExFAT "ENGAGEMENT" GPT /dev/disk4

For genuinely sensitive data on flash, encrypt from day one (APFS encrypted volume or LUKS from Linux) and destroy the passphrase at end-of-life — that’s the only reliable “secure erase” for modern flash.


🔁 Quick Reference Table

ScenarioToolTarget filesystemPartitionNotes
Kali / Ubuntu / Linux livedd(raw write)n/abs=4m, use rdiskN
FreeBSD / OpenBSDdd(raw write)n/aSame as above
macOS installer (DMG→ISO)createinstallmediaHFS+GPTApple’s own tool, not dd
Windows 7dd(raw write)n/aLegacy — works
Windows 10 / 11 (x64)rsync + wimlibFAT32MBR (GPT fallback)Do not use dd
Windows 11 ARMrsync (+ wimlib if >4GB)FAT32MBR/GPTCheck install.wim size first

🧰 Handy One-Liners

# Identify only external physical disks (less scary than plain `diskutil list`)
diskutil list external physical

# Check install.wim size before deciding split vs direct copy
ls -lh /Volumes/CCCOMA_*/sources/install.wim

# Watch dd progress without status=progress (send SIGINFO)
# During dd, press Ctrl+T

# Unmount every partition of a disk at once
diskutil unmountDisk force /dev/disk4

# Verify what's actually on the stick after burning
diskutil info /dev/disk4

🧯 Troubleshooting

SymptomFix
dd: /dev/rdisk4: Resource busydiskutil unmountDisk /dev/disk4 first
dd: Permission deniedPrefix with sudo; on Sonoma+ grant Terminal Full Disk Access in System Settings → Privacy
Windows USB not listed in PC boot menuLikely booted ISO raw with dd — redo with the rsync+wimlib method
rsync: failed: Read-only file systemmacOS mounted the FAT32 stick read-only (seen on some Sonoma builds). Re-plug, or erase again with diskutil eraseDisk MS-DOS "WIN11" MBR /dev/disk4
Windows installer says “can’t find drivers” mid-installTry a USB 2.0 port — some Win10 media lacks USB 3.x xHCI drivers
hdiutil: mount failedISO may be corrupt — re-verify the SHA-256
Secure Boot rejects the USBDisable Secure Boot during install, re-enable after

🔐 Security-Adjacent Notes (relevant for pentest lab work)

  • Always verify ISO hashes — pre-poisoned ISOs (e.g. backdoored Kali mirrors) have happened. Cross-check against multiple sources for release signing keys.
  • For a clean evidence-grade write, follow dd with sync; sync and a hash of the source ISO vs dd if=/dev/rdisk4 bs=4m count=<iso_blocks> | shasum -a 256 (read back and compare).
  • Throwaway installer sticks for engagements: consider shred / diskutil secureErase between clients to avoid cross-contamination of tooling.

  • ligolo-ng Cheatsheet
  • Kali on Parallels M1 Setup
  • NetHydra VM Provisioning
On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.