C0deH4cker / PwnableHarness

Manage building and deploying exploitation challenges with ease
MIT License
57 stars 4 forks source link

Allow changing the base Docker image #10

Closed C0deH4cker closed 1 month ago

C0deH4cker commented 2 years ago

Especially with glibc heap exploitation challenges, it's important for CTF challenge authors to have control over which base image is used. This will also help address the issue where a challenge is linked against a newer version of glibc than is present in the container so it fails to run.

C0deH4cker commented 1 year ago

This is actively being worked on and should hopefully be merged soon!

C0deH4cker commented 1 month ago

Running pwnmake docker-start from a challenge repo root that has potentially multiple different required Ubuntu versions is tricky to deal with. Here's one idea:

  1. pwnmake will run a generic Docker container that will do something like make list-ubuntu-versions
  2. pwnmake will create and start the each of the corresponding builder images, passing along the requested make args

This means there will be multiple recursive builds, each of which will build a subset of the directory tree (only the projects with the matching Ubuntu version). The challenges with this approach is the .build directory might need to be split based on the builder image that's running, also we will need to keep track of whether a project's requested Ubuntu version matches the current builder's version. Furthermore, I'm not sure how this would handle a case like pwnmake all[SpecificProject].

An alternative approach would be to change the compile/link commands from directly running gcc to instead invoke gcc in a builder container running the right Ubuntu version. This is more likely to work cleanly with minimal changes, though builds will be slower. However, most PwnableHarness projects are relatively small, so build time isn't a big concern. I think I prefer this approach due to the simplicity and added reliability.

C0deH4cker commented 1 month ago

One tricky-ish aspect of the above decision is that any prebuild.sh script(s) might need to be run separately in each of the pwncc containers (which is the name I'm going with for the minimal compiler-only containers). For example, consider a challenge that needs libpng. The way this is supported today is that the challenge's directory will contain a prebuild.sh script that will install libpng-dev. This script is run by pwnmake as it's personalizing the pwnmake image for the workspace.

Perhaps the prebuild.sh concept can be simplified to instead only apply to the project in which it lives. Then, any projects with a prebuild.sh script will build a modified pwncc image, doing something like this:

FROM c0deh4cker/pwnableharness:pwncc-18.04-v2.1
COPY prebuild.sh /
RUN /prebuild.sh

This would then be used as the pwncc image for the current project directory (and descendents?).

C0deH4cker commented 1 month ago

I did go with the above described approach. Any project directory containing a prebuild.sh script will produce a customized pwncc image by running that script. Just note that in typical situations, when installing a shared library that the challenge needs, you'll need both a prebuild.sh script (to add the libfoo-dev package, containing headers and a linkable library) and a custom Dockerfile (which will add the libfoo package). Support has been merged into the dev branch in #27. I'll merge to master later after ensuring nothing has broken.