Closed C0deH4cker closed 1 month ago
This is actively being worked on and should hopefully be merged soon!
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:
pwnmake
will run a generic Docker container that will do something like make list-ubuntu-versions
pwnmake
will create and start the each of the corresponding builder images, passing along the requested make
argsThis 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.
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?).
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.
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.