# base64 import base64 base64.b64encode(b'data').decode() base64.b64decode('ZGF0YQ==') base64.b64decode('ZGF0YQ==' + '==') # fix padding base64.urlsafe_b64decode(s.replace('-','+').replace('_','/')) # hex bytes.fromhex('7069636f') b'pico'.hex() int('ff', 16) f'{255:02x}' # binary int('01000001', 2) f'{65:08b}' bytes(int(s[i:i+8],2) for i in range(0,len(s),8)) # URL from urllib.parse import quote, unquote quote('hello world') unquote('hello%20world') # rot13 s.translate(str.maketrans( 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'))
# Try all common decodings import base64, binascii def try_decode(s): attempts = [] try: attempts.append(('b64', base64.b64decode(s + '=='))) except: pass try: attempts.append(('hex', bytes.fromhex(s))) except: pass try: attempts.append(('b32', base64.b32decode(s))) except: pass for name, val in attempts: printable = all(32 <= b < 127 for b in val) print(f['{name}'] {val}{' ← printable' if printable else ''}) try_decode('cGljb0NURg==')
# XOR bytes bytes(a ^ b for a, b in zip(ct, key)) bytes(b ^ 0x42 for b in data) # single byte key bytes(b ^ key[i % len(key)] for i, b in enumerate(data)) # Brute XOR — find printable result for k in range(256): result = bytes(b ^ k for b in data) if all(32 <= x < 127 for x in result): print(k, result) # Reverse bytes data[::-1] # Swap endianness of 4-byte chunks import struct [struct.unpack(', data[i:i+4])[0] for i in range(0, len(data), 4)] # Pack list of ints as bytes bytes([0x70, 0x69, 0x63, 0x6f]) # Null-terminate string s.split(b'\x00')[0].decode()
# Pretty hexdump (like xxd) def hexdump(data, width=16): for i in range(0, len(data), width): chunk = data[i:i+width] hex_part = ' '.join(f'{b:02x}' for b in chunk) asc_part = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk) print(f'{i:08x} {hex_part:<{width*3}} |{asc_part}|') hexdump(b'hello world\x00\x01\x02') # Find byte pattern data.find(b'\x89PNG') [i for i in range(len(data)) if data[i:i+4] == b'\xde\xad\xbe\xef'] # Count occurrences data.count(b'\x90')
# Modular inverse pow(e, -1, phi) # Python 3.8+ built-in from Crypto.Util.number import inverse inverse(e, phi) # RSA decrypt from Crypto.Util.number import long_to_bytes, bytes_to_long p, q, e, c = ... phi = (p-1)*(q-1) d = pow(e, -1, phi) m = pow(c, d, p*q) print(long_to_bytes(m)) # GCD / extended GCD from math import gcd gcd(a, b) # Integer square root import gmpy2 root, exact = gmpy2.iroot(n, 3) # cube root root, exact = gmpy2.iroot(n, 2) # square root # CRT (Chinese Remainder Theorem) from sympy.ntheory.modular import crt n_list = [3, 5, 7] r_list = [2, 3, 2] x = crt(n_list, r_list)[1] # → 23
# Hashes import hashlib hashlib.md5(b'data').hexdigest() hashlib.sha256(b'data').hexdigest() hashlib.sha1(b'data').digest() # HMAC import hmac hmac.new(b'key', b'msg', hashlib.sha256).hexdigest() # AES CBC decrypt from Crypto.Cipher import AES cipher = AES.new(key, AES.MODE_CBC, iv) pt = cipher.decrypt(ct) # AES ECB detect (repeating blocks) ct = bytes.fromhex('...') blocks = [ct[i:i+16] for i in range(0, len(ct), 16)] print(len(blocks) != len(set(blocks))) # True = ECB # XOR two ciphertexts (CTR/OFB nonce reuse) keystream = bytes(a^b for a,b in zip(ct1, ct2))
# Read until prompt, send answer import socket s = socket.socket() s.connect(('host', 1337)) # Read challenge line line = s.recv(1024).decode().strip() n = int(line.split(': ')[1]) s.sendall((str(n * 2) + '\n').encode()) print(s.recv(1024).decode()) # flag # Read until specific string def recv_until(s, marker): buf = b'' while marker not in buf: buf += s.recv(1) return buf # pwntools is better for interactive from pwn import * p = remote('host', 1337) p.recvuntil(b'Enter n: ') p.sendline(b'42') print(p.recvline())
# requests — web challenges import requests s = requests.Session() # GET with cookies r = s.get('http://target/flag', cookies={'session': '...'}) # POST form r = s.post('http://target/login', data={'user':'admin','pass':"' OR 1=1--"}) # POST JSON r = s.post('http://target/api', json={'cmd':'cat /flag'}) # Custom headers r = s.get('http://target/', headers={'X-Admin':'true', 'User-Agent':'admin'}) # Check response print(r.status_code, r.text[:200]) import re print(re.findall(r'picoCTF\{[^}]+\}', r.text))
# Read binary data = open('file.bin', 'rb').read() # Write binary open('out.bin', 'wb').write(payload) # Patch bytes at offset data = bytearray(open('file', 'rb').read()) data[0x100] = 0x90 data[0x101:0x103] = b'\x90\x90' open('patched', 'wb').write(data) # Find all flag patterns in file import re flags = re.findall(rb'picoCTF\{[^\}]+\}', data) # Read lines, strip whitespace lines = open('data.txt').read().splitlines() # Frequency count from collections import Counter Counter(data.decode(errors='replace')).most_common(10)
# Check printable all(32 <= b < 127 for b in data) data.decode(errors='replace').isprintable() # Caesar brute force for shift in range(26): print(shift, ''.join( chr((ord(c) - 65 - shift) % 26 + 65) if c.isupper() else chr((ord(c) - 97 - shift) % 26 + 97) if c.islower() else c for c in ciphertext)) # Frequency analysis from collections import Counter Counter(c for c in text if c.isalpha()).most_common() # All combinations from itertools import product for combo in product('abcdef', repeat=4): print(''.join(combo))
import struct # Format: [endian][count][type] # Endian: < little > big ! network = native # B=uint8 H=uint16 I=uint32 Q=uint64 # b=int8 h=int16 i=int32 q=int64 # f=float d=double s=bytes x=pad byte struct.pack(', 0xdeadbeef, 0x1234, 0x5678) # → 8 bytes LE struct.unpack(' , data[:8]) # → (val1, val2, val3) struct.unpack_from(', data, offset=4) # unpack at offset struct.calcsize(' ) # → 8 (size in bytes) # Parse stream of records record_fmt = ' size = struct.calcsize(record_fmt) for i in range(0, len(data), size): a, b, c = struct.unpack(record_fmt, data[i:i+size]) print(a, b, c) # int.to_bytes / from_bytes (simpler for single values) (0xdeadbeef).to_bytes(4, 'little') int.from_bytes(b'\xef\xbe\xad\xde', 'little')
# Run command, get output import subprocess out = subprocess.check_output(['strings', 'binary']).decode() out = subprocess.check_output('strings binary | grep flag', shell=True).decode() # Run and get stdout+stderr r = subprocess.run(['./challenge'], input=b'payload\n', capture_output=True, timeout=5) print(r.stdout, r.stderr) # Environment variable import os os.environ['FLAG']
# Find flag pattern import re re.findall(r'picoCTF\{[^}]+\}', text) re.search(r'picoCTF\{.*?\}', text).group() # Extract numbers from string re.findall(r'\d+', text) re.findall(r'0x[0-9a-fA-F]+', text) # hex values # JSON parsing import json data = json.loads(response_text) json.dumps(data, indent=2) # Bit operations n = 0b11010110 bin(n) # '0b11010110' n.bit_length() # 8 bin(n).count('1') # popcount = 5 n & (n - 1) == 0 # True if power of 2
bytes(b^k for b in data) XOR
· base64.b64decode(s+'==') safe b64
· bytes.fromhex(s) hex→bytes
· re.findall(r'picoCTF\{[^}]+\}', text) find flag
· struct.unpack('<I', data[:4])[0] parse int
· Counter(data).most_common() frequency
· pow(e,-1,phi) modular inverse
· long_to_bytes(pow(c,d,n)) RSA decrypt