Skip to content

Commit

Permalink
The big one. Big changes to the bash script. Big changes to Dockerfile
Browse files Browse the repository at this point in the history
  • Loading branch information
stack committed Sep 24, 2023
1 parent 53c011e commit 4356cab
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 21 deletions.
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ RUN apt -y install\
wine\
xz-utils

# Let's decide what archs we want in the container
# by default. Users can install additional ones
# as needed since the packages are relatively small
RUN apt -y install\
binutils-aarch64-linux-gnu

# Fix our locale
RUN sed -i '/^#.*en_US.UTF-8.*/s/^#//' /etc/locale.gen &&\
locale-gen en_US.UTF-8 &&\
Expand Down
47 changes: 41 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ any modern version of Docker.

If everything works as expected, you should be able to just run `./grasshopper` to get started.

If you have to build the image, this will take about 10-20 minutes even with a good internet connection.
If you have to build the image, this will take about 30 minutes even with a good internet connection.

## Quick Start

Expand All @@ -29,10 +29,14 @@ If you have to build the image, this will take about 10-20 minutes even with a g
```
Usage: ./grasshopper [OPTIONS]
OPTIONS:
-b Rebuild the container before running (don't do this)
-h Print this usage message and exit
-b Just build the container and exit (this can take 30 minutes)
-d Build the container before running (this can take 30 minutes)
-h Print this message and exit
-k Kill any containers that exist before running
-l Run and exec into a locally built container. NOTE:
This could require building the image itself, which can take
up to 30 minutes. This option should only be used for testing
-x Kill any containers and exit
Grasshopper is intended to be a temporary workbench for solving
CTF challenges. The 'workbench' is host volume mounted so you can
Expand All @@ -47,12 +51,43 @@ some of the highlights:
- gdb with gef
- hashcat
- nmap
- radare2 tool suite
- SecLists wordlists (found under /data/wordlists)
- pwntools
- python3
- qemu user emulation binaries
- radare2 tool suite
- SecLists wordlists (found under /data/wordlists)
- strace
- vim/neovim with useful plugins
- much, much more!
If you run Grasshopper with no arguments, it will either exec into
the container if it is already running, or it will first run the
container and then exec into it. If the image isn't found in your
local registry, it will first pull the image, then run it, then
exec into it.
```

## Additional Notes

It is a known problem that Docker containers that run as with the
`root` user inside of the container can lead to permissions problems.
This is particularly troublesome when we are running host-mounted
volumes, since you can just create a special file owned by root on
the host machine you are running a docker container on.

I don't have any novel ways to address this, so I am just assuming
that if you are running `grasshopper`, you are running it on a machine
you own.

Additionally, I haven't found an elegant way to create
user-who-started-the-process owned files on the host from within the
Docker image. They will appear as root, always. If I can find an elegant
solution to this, I will add it immediately, but currently the only
workaround seems to involve created a dummy user in the Dockerfile or a
bash script -- both of which would add unneeded complexity to `grasshopper`.

In the meantime, this means you will have to copy files you want inside
the docker container to the host-mounted volume path with `sudo`. This
isn't ideal, but it is the best solution I have now. Obviously, from the
host, you can make any changes to the files you want (assuming you have
`root`).
14 changes: 14 additions & 0 deletions apt_config/sources.list
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
deb [arch=i386,amd64] http://archive.ubuntu.com/ubuntu/ jammy main restricted
deb [arch=i386,amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted
deb [arch=i386,amd64] http://archive.ubuntu.com/ubuntu/ jammy universe
deb [arch=i386,amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates universe
deb [arch=i386,amd64] http://archive.ubuntu.com/ubuntu/ jammy multiverse
deb [arch=i386,amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates multiverse
deb [arch=i386,amd64] http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse
deb [arch=i386,amd64] http://security.ubuntu.com/ubuntu/ jammy-security main restricted
deb [arch=i386,amd64] http://security.ubuntu.com/ubuntu/ jammy-security universe
deb [arch=i386,amd64] http://security.ubuntu.com/ubuntu/ jammy-security multiverse

deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted universe multiverse
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted universe multiverse
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted universe multiverse
3 changes: 1 addition & 2 deletions configs/.bashrc
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,12 @@ fi

alias l="ls"
alias ..="cd .."
alias build="make clean && make && sudo make install"
alias cp="cp -i"
alias df="df -h"
alias mv="mv -i"
alias p="upower --dump | grep 'percentage\|state' | sort | uniq"
alias rm="printf 'stop using rm... use tp/tl/te instead...\n'; false"
alias search="sudo apt search"
alias search="apt search"
alias talist="~/.config/talist/src/talist"
alias te="trash-empty"
alias tl="trash-list"
Expand Down
50 changes: 37 additions & 13 deletions grasshopper
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

set -e

# Where are we?
SCRIPT_PATH="$(readlink -f $(dirname ""${BASH_SOURCE[0]}""))"

# Who are we?
DOCK_CONFIG="${SCRIPT_PATH}""/docker_config"
USER_HOME="/root"
WORKBENCH="${USER_HOME}""/workbench"
HOST_UID="$(id -u)"
HOST_GID="$(id -g)"

# Color prompts
BOLD='\033[1m'
UNBOLD='\033[0m'
Expand All @@ -11,20 +21,23 @@ RED='\033[0;31m'
YELLOW='\033[33m'

TESTED_DOCKER_VER="24.0.6"
REPO="grasshopper"
REPO="ghcr.io/vr0n/grasshopper"
NAME="grasshopper"
TAG="latest"
IMAGE="${REPO}"":""${TAG}"
WORKBENCH="/root/workbench"

usage() {
printf "Usage: %s [OPTIONS]\n" "${0}"
printf "OPTIONS:\n"
printf " -b Just build the container and exit (this can take 21 minutes)\n"
printf " -b Just build the container and exit (this can take 30 minutes)\n"
printf " -d Build the container before running (this can take 30 minutes)\n"
printf " -h Print this message and exit\n"
printf " -k Kill any containers that exist before running\n"
printf "\n\n"
printf " -l Run and exec into a locally built container. NOTE:\n"
printf " This could require building the image itself, which can take\n"
printf " up to 30 minutes. This option should only be used for testing\n"
printf " -x Kill any containers and exit\n"
printf "\n"
printf "Grasshopper is intended to be a temporary workbench for solving\n"
printf "CTF challenges. The 'workbench' is host volume mounted so you can\n"
printf "copy files from your host into it and interact with them from the\n"
Expand All @@ -38,20 +51,19 @@ usage() {
printf " - gdb with gef\n"
printf " - hashcat\n"
printf " - nmap\n"
printf " - radare2 tool suite\n"
printf " - SecLists wordlists (found under /data/wordlists)\n"
printf " - pwntools\n"
printf " - python3\n"
printf " - qemu user emulation binaries\n"
printf " - radare2 tool suite\n"
printf " - SecLists wordlists (found under /data/wordlists)\n"
printf " - strace\n"
printf " - vim/neovim with useful plugins\n"
printf " - much, much more!\n\n"
printf "If you run Grasshopper with no arguments, it will either exec into\n"
printf "the container if it is already running, or it will first run the\n"
printf "container and then exec into it. If the image isn't found in your\n"
printf "local registry, it will first build the image, then run it, then\n"
printf "exec into it. Building Grasshopper can take up to 20 minutes, so\n"
printf "make sure it is pre-built before you need it!\n"
printf "local registry, it will first pull the image, then run it, then\n"
printf "exec into it.\n"

exit 0
}
Expand Down Expand Up @@ -135,7 +147,7 @@ check_name() {
}

docker_exec() {
docker exec -it "${NAME}" /bin/bash
docker --config "${DOCK_CONFIG}" exec -it "${NAME}" /bin/bash
}

docker_kill() {
Expand All @@ -150,11 +162,19 @@ docker_build() {
log "Grab a coffee or a smoke and relax..."

docker_kill
docker build --build-arg HOME="/root" -t "${IMAGE}" .
docker build --build-arg HOME="${USER_HOME}" -t "${IMAGE}" .
}

docker_pull() {
log "Pulling the newest image!"
log "This should only take a few minutes..."

docker_kill
docker pull "${REPO}"
}

docker_run() {
LOCAL_WORKBENCH="$(pwd)""/workbench"
LOCAL_WORKBENCH="${SCRIPT_PATH}""/workbench"

if [ ! -d "${LOCAL_WORKBENCH}" ]; then
mkdir "${LOCAL_WORKBENCH}" || exit 1 # Probably a perms issue...
Expand Down Expand Up @@ -186,6 +206,10 @@ main() {
secret
exit 0
fi
if [[ "${ARG}" == *"x"* ]]; then
docker_kill
exit 0
fi
if [[ "${ARG}" == *"b"* ]]; then
docker_build
exit 0
Expand All @@ -204,7 +228,7 @@ main() {
# Any other option
check_repo
if [[ "${FOUND_REPO}" != "1" ]]; then
docker_build
docker_pull
fi

check_image
Expand Down

0 comments on commit 4356cab

Please sign in to comment.