Skip to content

Instantly share code, notes, and snippets.

View tommilligan's full-sized avatar
🌸

Tom Milligan tommilligan

🌸
View GitHub Profile
@tommilligan
tommilligan / verify-dns.sh
Created July 18, 2025 16:32
Verify that two DNS servers behave the same for a list of records, before changing authoritative DNS servers.
#!/bin/bash
# Takes:
# - An input file with a list of hostnames to resolve
# - An old DNS server address
# - A new DNS server address
#
# Output will be a diff between the behaviour of the two DNS servers for the domains given.
set -euo pipefail
@tommilligan
tommilligan / unpad.py
Created January 25, 2024 12:58
Pad and unpad base64 strings based on length
_BASE64_PADDING = "="
def strip_base64_padding(string: str) -> str:
"""Strip padding of equals sign from base64. Required for use in urls."""
return string.rstrip(_BASE64_PADDING)
def unstrip_base64_padding(string: str) -> str:
"""Re-pad a base64 string with the right amount of padding."""
@tommilligan
tommilligan / validate.py
Created January 25, 2024 12:40
Request schema enforcement for base64 encoded bytes
def _base64_length(bytes_length: int) -> int:
"""Return the maximum length a base64 encoded string would be for the
given length of bytes.
Note that this length may change if padding is stripped.
"""
# base64 length is 33% longer, rounding up
return ceil((bytes_length / 3) * 4)
@tommilligan
tommilligan / main.rs
Created November 8, 2023 16:22
Decoding UTF16LE String from Vec<u8>
extern crate encoding_rs; // 0.8.33
fn main() {
let data: Vec<u8> = vec![46, 0, 120, 0, 108, 0, 115, 0, 120, 0];
let mut buffer: String = String::with_capacity(data.len() * 2);
let mut decoder = encoding_rs::UTF_16LE.new_decoder();
let (coder_result, read, replaced) = decoder.decode_to_string(&data, &mut buffer, true);
assert!(coder_result == encoding_rs::CoderResult::InputEmpty);
@tommilligan
tommilligan / hot_potato_panic_on_drop.rs
Created March 2, 2022 13:54
Panicking on drop is a bad idea
#[derive(Default)]
struct Potato {
cool: bool,
}
impl Potato {
fn cooldown(&mut self) {
self.cool = true;
}
@tommilligan
tommilligan / base85.rs
Created February 16, 2021 15:58
Bare-bones base85 encoding function in Rust - ended up unused for other reasons.
use std::convert::TryInto;
const RADIX: u32 = 85;
const INPUT_BLOCK_SIZE: u32 = 4;
const OUTPUT_BLOCK_SIZE: u32 = 5;
#[inline]
/// Read a block of four `u8`s in as a single big-endian u32.
fn read_u32(s: &[u8]) -> u32 {
u32::from_be_bytes(s[..4].try_into().unwrap())
@tommilligan
tommilligan / command-exists.sh
Created December 31, 2017 18:34
Function for finding if a command exists silently
#!/bin/sh
function log() {
printf "$@\n" >&2
}
function command_exists() {
command -v "$1" 2>&1 > /dev/null
return $?
}
@tommilligan
tommilligan / eggshell
Created June 17, 2017 12:05
eggshell for CTF - Intel
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80
@tommilligan
tommilligan / ImageJ TomMs Microbio Macros
Last active February 27, 2024 14:23
ImageJ Macros for uniformly cropping, adding scalebars and resizing PCM images [m] & uniformly cropping and renaming photos [s].
// This file is distributed under the terms of the GNU GPL v2
// ImageJ macros file
// To install these to your ImageJ program temporarily:
// - Plugins > Macros > Install... (Ctrl-Shift-M)
// To install these to your ImageJ program permenantly:
// - Find the "StartupMacros.txt" file on your computer
// - e.g. C:\Program Files (x86)\ImageJ\macros\StartupMacros.txt (Windows)
// - e.g. /Applications/ImageJ/macros/StartupMacros.txt (Mac)
// - Copy and paste the contents of this file at the end of StartupMacros.txt
@tommilligan
tommilligan / whatcolorisx_demo.py
Last active December 3, 2015 13:13
Demonstration of WhatColorIsX python module, using local image files to make a compound image showing: source image(s), average colour(s), bright hue colour(s)
import os
import sys
import glob
import argparse
from itertools import zip_longest
import WhatColorIsX
from PIL import Image, ImageDraw, ImageColor, ImageOps, ImageFont