# 11010010 = 0xD2 = 210 decimal = 'Ò' ASCII # bit 7 = MSB (most significant bit) # bit 0 = LSB (least significant bit) # 1 byte = 8 bits # 1 nibble = 4 bits = 1 hex digit (0-F)
| Unit | Bits | Bytes | Values |
|---|---|---|---|
| bit | 1 | — | 0 or 1 |
| nibble | 4 | ½ | 0–15 (0x0–0xF) |
| byte | 8 | 1 | 0–255 (0x00–0xFF) |
| word | 16 | 2 | 0–65535 |
| dword | 32 | 4 | 0–4,294,967,295 |
| qword | 64 | 8 | 0–2⁶⁴−1 |
| uint8 | 8 | 1 | 0–255 |
| int8 | 8 | 1 | −128–127 |
| uint32 | 32 | 4 | 0–4,294,967,295 |
| uint64 | 64 | 8 | 0–18,446,744,073,709,551,615 |
# Value: 0xDEADBEEF # Big-endian (network order): DE AD BE EF # Little-endian (x86/x64): EF BE AD DE # Python pack/unpack import struct struct.pack('>I', 0xDEADBEEF) # → b'\xde\xad\xbe\xef' big struct.pack('<I', 0xDEADBEEF) # → b'\xef\xbe\xad\xde' little struct.unpack('<I', b'\xef\xbe\xad\xde')[0] # → 3735928559 # struct format characters: # > = big-endian < = little-endian ! = network (big) # B = uint8 H = uint16 I = uint32 Q = uint64 # b = int8 h = int16 i = int32 q = int64
# Bitwise operators 0b1010 & 0b1100 # → 0b1000 AND 0b1010 | 0b1100 # → 0b1110 OR 0b1010 ^ 0b1100 # → 0b0110 XOR ~0b1010 # → -11 NOT (two's complement) 0b0001 << 3 # → 0b1000 left shift = multiply by 2 0b1000 >> 2 # → 0b0010 right shift = divide by 2 # Extract specific bits val = 0b11010110 bit3 = (val >> 3) & 1 # → bit 3 = 0 nibble_hi = (val >> 4) # → upper nibble = 0b1101 = 13 nibble_lo = val & 0x0F # → lower nibble = 0b0110 = 6 # Set/clear/toggle a bit val |= (1 << 3) # set bit 3 val &= ~(1 << 3) # clear bit 3 val ^= (1 << 3) # toggle bit 3
| Dec | Hex | Bin | ASCII | Dec | Hex | Bin | ASCII | Dec | Hex | Bin | ASCII | Dec | Hex | Bin | ASCII |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 32 | 0x20 | 00100000 | SPACE | 48 | 0x30 | 00110000 | 0 | 65 | 0x41 | 01000001 | A | 97 | 0x61 | 01100001 | a |
| 33 | 0x21 | 00100001 | ! | 49 | 0x31 | 00110001 | 1 | 66 | 0x42 | 01000010 | B | 98 | 0x62 | 01100010 | b |
| 36 | 0x24 | 00100100 | $ | 57 | 0x39 | 00111001 | 9 | 90 | 0x5A | 01011010 | Z | 122 | 0x7A | 01111010 | z |
| 10 | 0x0A | 00001010 | LF \n | 13 | 0x0D | 00001101 | CR \r | 9 | 0x09 | 00001001 | TAB \t | 0 | 0x00 | 00000000 | NULL |
| 123 | 0x7B | 01111011 | { | 125 | 0x7D | 01111101 | } | 95 | 0x5F | 01011111 | _ | 127 | 0x7F | 01111111 | DEL |
# Printable ASCII range: 32 (space) → 126 (~) # Uppercase A-Z: 0x41–0x5A (65–90) lowercase a-z: 0x61–0x7A (97–122) # Digits 0-9: 0x30–0x39 (48–57) lowercase = uppercase | 0x20 # picoCTF{ = 70 69 63 6F 43 54 46 7B (hex)
# Decimal → char printf '\x70' # → p (hex escape) printf '%b' '\x70' # → p printf '\160' # → p (octal: 160 octal = 0x70 = 112 dec) echo -e "\x70\x69\x63" # → pic # Char → decimal/hex printf '%d' "'p" # → 112 (decimal of 'p') printf '%x' "'p" # → 70 (hex of 'p') # String → hex dump echo -n "picoCTF" | xxd echo -n "picoCTF" | xxd -p # → 7069636f435446 (no spaces) echo -n "picoCTF" | od -An -tx1 # od formats: -tx1 hex bytes, -td1 decimal, -tb octal
# char → int ord('p') # → 112 ord('p') == 0x70 # → True # int → char chr(112) # → 'p' chr(0x70) # → 'p' # string → bytes → list of ints list(b'picoCTF') # → [112, 105, 99, 111, 67, 84, 70] b'picoCTF'.hex() # → '7069636f435446' # list of ints → string ''.join(chr(c) for c in [112,105,99]) # → 'pic' bytes([112,105,99]).decode() # → 'pic' # bytes ↔ string "hello".encode() # → b'hello' b'hello'.decode() # → 'hello' b'hello'.decode('latin-1') # for non-UTF8 bytes
# Dec → hex printf '%x\n' 255 # → ff printf '%X\n' 255 # → FF (uppercase) printf '%08x\n' 255 # → 000000ff (zero-padded 8 chars) echo "obase=16; 255" | bc # → FF # Hex → dec printf '%d\n' 0xff # → 255 echo "ibase=16; FF" | bc # → 255 (uppercase required for bc) $(( 16#ff )) # → 255 (bash arithmetic) # Hex string → bytes → file echo "7069636f435446" | xxd -r -p # → picoCTF echo "7069636f435446" | xxd -r -p > out.bin # Hex dump a file xxd file.bin xxd -p file.bin # plain hex, no offsets xxd -l 16 file.bin # first 16 bytes only xxd -s 0x100 file.bin # start at offset 0x100
# Int → hex string hex(255) # → '0xff' f'{255:#010x}' # → '0x000000ff' (padded) f'{255:08x}' # → '000000ff' (no prefix) f'{255:02X}' # → 'FF' # Hex string → int int('ff', 16) # → 255 int('0xff', 16) # → 255 int('0xdeadbeef', 0) # → auto-detect base # Hex string → bytes bytes.fromhex('7069636f') # → b'pico' import binascii binascii.unhexlify('7069636f') # → b'pico' # Bytes → hex string b'pico'.hex() # → '7069636f' b'pico'.hex(':') # → '70:69:63:6f' (separator) binascii.hexlify(b'pico') # → b'7069636f'
# Dec → binary echo "obase=2; 65" | bc # → 1000001 printf '%08d\n' $(echo "obase=2; 65" | bc) # → 01000001 # Binary → dec echo "ibase=2; 01000001" | bc # → 65 $(( 2#01000001 )) # → 65 (bash arithmetic) # Binary string → bytes → ASCII (your image challenge!) python3 -c " bits = open('data.txt').read().replace('\n','').replace(' ','') data = bytes(int(bits[i:i+8],2) for i in range(0,len(bits),8)) open('out.bin','wb').write(data) " file out.bin # check type # Count bits set (popcount) python3 -c "print(bin(0xFF).count('1'))" # → 8
# Int → binary string bin(65) # → '0b1000001' f'{65:08b}' # → '01000001' (8-bit, zero-padded) f'{65:b}' # → '1000001' (no padding) # Binary string → int int('01000001', 2) # → 65 int('0b01000001', 2) # → 65 # Bytes → binary string (per byte) for b in b'Hi': print(f'{b:08b}') # → 01001000 01101001 # Binary string → bytes bits = '0100100001101001' # 'Hi' data = bytes(int(bits[i:i+8],2) for i in range(0,len(bits),8)) # → b'Hi' # All formats at once n = 65 print(bin(n), oct(n), hex(n), n) # 0b1000001 0o101 0x41 65
# Base64 encode / decode echo -n "picoCTF" | base64 # → cGljb0NURg== echo "cGljb0NURg==" | base64 -d # → picoCTF # File encode / decode base64 file.bin > file.b64 base64 -d file.b64 > file.bin # Base32 echo -n "picoCTF" | base32 # → OBWGKYLTEB3W4=== echo "OBWGKYLTEB3W4===" | base32 -d # Remove newlines from base64 output base64 file.bin | tr -d '\n' # URL-safe base64 (- and _ instead of + and /) echo -n "hello" | base64 | tr '+/' '-_' | tr -d '='
import base64 # Base64 base64.b64encode(b'picoCTF') # → b'cGljb0NURg==' base64.b64decode('cGljb0NURg==') # → b'picoCTF' # URL-safe base64 base64.urlsafe_b64encode(b'data') base64.urlsafe_b64decode('ZGF0YQ==') # Base32 base64.b32encode(b'picoCTF') # → b'OBWGKYLTEB3W4===' base64.b32decode('OBWGKYLTEB3W4===') # Base16 (= hex uppercase) base64.b16encode(b'pico') # → b'7069636F' base64.b16decode('7069636F') # → b'pico' # Handle missing padding s = 'cGljb0NURg' # missing == base64.b64decode(s + '==' * (4 - len(s)%4 if len(s)%4 else 0))
# cut — extract fields/columns echo "aa:bb:cc:dd" | cut -d: -f2 # → bb echo "aa:bb:cc:dd" | cut -d: -f2-4 # → bb:cc:dd echo "abcdef" | cut -c3-5 # → cde (chars 3-5) # dd — extract raw bytes from file dd if=file.bin of=out.bin bs=1 skip=16 count=4 # bytes 16-19 dd if=file.bin of=out.bin bs=512 skip=2 count=1 # block 2 # head / tail — byte ranges head -c 16 file.bin # first 16 bytes tail -c 16 file.bin # last 16 bytes tail -c +17 file.bin # from byte 17 to end # Combine: extract bytes 10-20 head -c 20 file.bin | tail -c +11
# Bytes slicing data = b'\x00\x01\x02\x03\x04\x05\x06\x07' data[2:5] # → b'\x02\x03\x04' data[:4] # → first 4 bytes data[4:] # → from byte 4 to end data[::2] # → every other byte data[::-1] # → reversed # struct — parse binary data import struct # Unpack: big-endian uint32 at offset 0 struct.unpack_from('>I', data, offset=0) # → (66051,) # Pack multiple values struct.pack('>HHI', 1, 2, 0xdeadbeef) # → 8 bytes # Split into N-byte chunks n = 4 chunks = [data[i:i+n] for i in range(0, len(data), n)] # int.to_bytes / from_bytes (0xdeadbeef).to_bytes(4, 'big') # → b'\xde\xad\xbe\xef' int.from_bytes(b'\xde\xad\xbe\xef', 'big') # → 3735928559
# Send plain string echo "hello" | nc host 1337 # Send WITHOUT trailing newline echo -n "hello" | nc host 1337 printf "hello" | nc host 1337 # Send raw hex bytes printf '\xde\xad\xbe\xef' | nc host 1337 echo "deadbeef" | xxd -r -p | nc host 1337 # Send binary file cat payload.bin | nc host 1337 nc host 1337 < payload.bin # Interactive: keep connection open after sending (echo "input"; cat) | nc host 1337 # Send multiple lines with delay { echo "line1"; sleep 1; echo "line2"; } | nc host 1337 # Build payload inline and send python3 -c "import sys; sys.stdout.buffer.write(b'A'*40 + b'\xef\xbe\xad\xde')" \ | nc host 1337
# Raw socket import socket s = socket.socket() s.connect(('host', 1337)) s.send(b'hello\n') # send bytes s.send(bytes.fromhex('deadbeef')) print(s.recv(1024)) # receive up to 1024 bytes s.close() # pwntools (best for CTF) from pwn import * p = remote('host', 1337) # or local: p = process('./challenge') p.recvuntil(b'Enter: ') # wait for prompt p.sendline(b'answer') # send + \n p.send(b'\xde\xad\xbe\xef') # raw bytes, no \n p.sendlineafter(b'> ', b'cmd') # wait then send data = p.recvline() # read one line p.interactive() # manual shell
# Pattern: read prompt → compute answer → send python3 -c " import socket, struct s = socket.socket() s.connect(('host', 1337)) # Read challenge data = s.recv(1024) print('Got:', data) # Build response (example: send 4-byte little-endian int) answer = struct.pack(' # One-liner for simple sends python3 -c "print('A'*100)" | nc host 1337 python3 -c "import sys; sys.stdout.buffer.write(b'\x00'*8)" | nc host 1337 # ncat with ssl ncat --ssl host 1337
# Write hex bytes to file echo "deadbeef0102030405" | xxd -r -p > out.bin printf '\xde\xad\xbe\xef' > out.bin # Append bytes printf '\x00\x01' >> out.bin # Check file size in bytes wc -c < file.bin stat -c %s file.bin ls -la file.bin # Search for byte pattern in file grep -boa $'\xde\xad' file.bin # byte offset of pattern xxd file.bin | grep "dead" # Patch a byte at offset (example: offset 10, byte 0x41) printf '\x41' | dd of=file.bin bs=1 seek=10 conv=notrunc # Split file at byte boundary split -b 512 file.bin chunk_ # 512-byte chunks
# Read entire file as bytes data = open('file.bin', 'rb').read() # Write bytes open('out.bin', 'wb').write(b'\xde\xad\xbe\xef') # Patch byte at offset data = bytearray(open('file.bin','rb').read()) data[10] = 0x41 # patch offset 10 data[10:14] = b'\xde\xad\xbe\xef' # patch 4 bytes open('patched.bin','wb').write(data) # Search for pattern pos = data.find(b'\xde\xad') # → byte offset or -1 all_pos = [i for i in range(len(data)) if data[i:i+2] == b'\xde\xad'] # Hexdump (manual) for i in range(0, min(64, len(data)), 16): chunk = data[i:i+16] print(f'{i:04x}', chunk.hex(' '), '|', chunk.decode('latin-1'))
# Hex string → ASCII text echo "7069636f4354467b74657374 7d" | tr -d ' ' | xxd -r -p # → picoCTF{test} # Binary string → ASCII (like the image challenge) python3 -c " bits='0111000001101001011000110110111101000011010101000100011001111011' print(bytes(int(bits[i:i+8],2) for i in range(0,len(bits),8)).decode()) " # → picoCTF{ # Decimal list → ASCII python3 -c "print(bytes([112,105,99,111,67,84,70]).decode())" # → picoCTF # Base64 → hex echo "cGljb0NURg==" | base64 -d | xxd -p # → 7069636f435446 # Hex → base64 echo "7069636f435446" | xxd -r -p | base64 # → cGljb0NURg== # ROT13 echo "cvpbPGS{...}" | tr 'A-Za-z' 'N-ZA-Mn-za-m' # URL encode python3 -c "from urllib.parse import quote; print(quote('hello world'))" # URL decode python3 -c "from urllib.parse import unquote; print(unquote('hello%20world'))" # String → little-endian 64-bit int (for stack overflow payloads) python3 -c "import struct; print(struct.pack('<Q', 0x401234).hex())" # → 341240000000000
# Drop this at the top of any CTF solve script from pwn import * # p8/p16/p32/p64, u8/u16/u32/u64, xor, enhex, unhex import base64, struct, binascii # pwntools shortcuts p32(0xdeadbeef) # → b'\xef\xbe\xad\xde' (little-endian) p64(0xdeadbeef) # → 8 bytes LE u32(b'\xef\xbe\xad\xde') # → 0xdeadbeef xor(b'data', b'key') # → XOR bytes enhex(b'pico') # → '7069636f' unhex('7069636f') # → b'pico' # Common conversions table string → bytes : s.encode() or b'literal' bytes → string : b.decode() or b.decode('latin-1') bytes → hex : b.hex() or enhex(b) hex → bytes : bytes.fromhex(h) or unhex(h) int → bytes : n.to_bytes(length, 'little') bytes → int : int.from_bytes(b, 'little') int → b64 : base64.b64encode(n.to_bytes(...)) bits → bytes : bytes(int(bits[i:i+8],2) for i in range(0,len(bits),8))
xxd -r -p / bytes.fromhex()
· raw to nc: printf '\xde\xad' | nc host port
· binary→bytes: int(bits[i:i+8], 2) per 8-bit chunk
· endian pack: struct.pack('<I', val) little / '>I' big
· pwntools: p32/p64/u32/u64 for exploit payloads