My setup for solving pwn challenges in CTFs consists of a docker image that is handled using some aliases that are described further down.

# Dockerfile

FROM ubuntu:19.10

ENV DEBIAN_FRONTEND=noninteractive

RUN dpkg --add-architecture i386 && \
apt-get update && \
apt-get install -y golang build-essential jq strace ltrace curl wget rubygems && \
gcc dnsutils netcat gcc-multilib net-tools vim gdb gdb-multiarch python python3 && \
python3-pip python3-dev libssl-dev libffi-dev wget git make procps libpcre3-dev && \
libdb-dev libxt-dev libxaw7-dev python-pip libc6:i386 libncurses5:i386 && \
libstdc++6:i386 sqlmap tmux && \
pip install capstone requests pwntools r2pipe huepy && \
pip3 install pwntools keystone-engine unicorn capstone ropper angr && \
mkdir tools && cd tools && \
git clone https://github.com/JonathanSalwan/ROPgadget && \
git clone https://github.com/radare/radare2 && cd radare2 && sys/install.sh && \
cd .. && git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh && \
cd .. && git clone https://github.com/niklasb/libc-database && cd libc-database && \
./get && gem install one_gadget
# aliases.txt

# make (pmk <name>)
alias pmk='function _dockermk(){docker run --rm -v "(pwd):/pwn" \
--cap-add=SYS_PTRACE --security-opt seccomp=unconfined -d --name 1 -i \
ctf:ubuntu19.10;};_dockermk'

# change directory into the /pwn folder of the container (pcd <name>)
alias pcd='function _dockercd(){docker exec -it --workdir /pwn 1 bash;};_dockercd'

# delete the container with the given name (prm <name>)
alias prm='function _dockerrm(){docker stop 1;};_dockerrm'