Skip to content

Commit

Permalink
Merge pull request #6563 from trailofbits/loverall/httpd
Browse files Browse the repository at this point in the history
Apache httpd demo
  • Loading branch information
ESultanik authored Sep 27, 2023
2 parents 7f8e497 + 0973781 commit 2ab952d
Show file tree
Hide file tree
Showing 10 changed files with 654 additions and 0 deletions.
12 changes: 12 additions & 0 deletions examples/http/faw_tdag_pairs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

if [[ -z "$1" ]]; then
echo "Error: no arguments supplied"
echo "Usage: ./example_httpd.sh /path/to/FAW/test_files/http"
exit 1
fi

FAW_DIR="$1"
./tdag_pairs.sh "$FAW_DIR"/cves
./tdag_pairs.sh "$FAW_DIR"/handcrafted
./tdag_pairs.sh "$FAW_DIR"/portswigger
3 changes: 3 additions & 0 deletions examples/http/httpd/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
httpd
example_httpd
example_httpd.o
56 changes: 56 additions & 0 deletions examples/http/httpd/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
FROM trailofbits/polytracker:latest
LABEL org.opencontainers.image.authors="[email protected]"

RUN rm -rf /polytracker/examples/http/httpd && mkdir -p /polytracker/examples/http/httpd

WORKDIR /polytracker/examples/http/httpd
RUN git clone --branch 2.4.13 https://github.com/apache/httpd.git
RUN apt update && apt install -y netcat curl autoconf libtool-bin && rm -rf /var/lib/apt/lists/*

WORKDIR /polytracker/examples/http/httpd/httpd
RUN mkdir -p srclib/apr srclib/apr-util srclib/pcre srclib/expat
RUN curl https://archive.apache.org/dist/apr/apr-1.7.0.tar.gz -o apr-1.7.0.tar.gz \
&& tar xfz apr-1.7.0.tar.gz -C srclib/apr --strip-components 1 \
&& rm apr-1.7.0.tar.gz
RUN curl https://archive.apache.org/dist/apr/apr-util-1.6.1.tar.gz -o apr-util-1.6.1.tar.gz \
&& tar xfz apr-util-1.6.1.tar.gz -C srclib/apr-util --strip-components 1 \
&& rm apr-util-1.6.1.tar.gz
RUN curl -L https://sourceforge.net/projects/pcre/files/pcre/8.39/pcre-8.39.tar.gz/download -o pcre-8.39.tar.gz \
&& tar xfz pcre-8.39.tar.gz -C srclib/pcre --strip-components 1 \
&& rm pcre-8.39.tar.gz
RUN curl -L https://github.com/libexpat/libexpat/releases/download/R_2_4_7/expat-2.4.7.tar.gz -o expat-2.4.7.tar.gz \
&& tar xfz expat-2.4.7.tar.gz -C srclib/expat --strip-components 1 \
&& rm expat-2.4.7.tar.gz

WORKDIR /polytracker/examples/http/httpd/httpd/srclib/pcre
RUN polytracker build ./configure --disable-shared
RUN polytracker build make

WORKDIR /polytracker/examples/http/httpd/httpd/srclib/expat
RUN polytracker build ./configure --disable-shared
RUN polytracker build make

# apr, apr-util are configured via httpd's configure script

WORKDIR /polytracker/examples/http/httpd/httpd
RUN polytracker build ./buildconf
RUN CFLAGS="-I$(pwd)/srclib/pcre -I$(pwd)/srclib/expat/lib" \
LDFLAGS="-L$(pwd)/srclib/pcre/.libs -L$(pwd)/srclib/expat/lib/.libs" \
polytracker build ./configure --disable-shared --with-mpm=prefork --with-pcre=srclib/pcre/pcre-config --with-included-apr \
--enable-mods-static='authz_core unixd'
RUN CFLAGS="-I$(pwd)/srclib/pcre -I$(pwd)/srclib/expat/lib" \
LDFLAGS="-L$(pwd)/srclib/pcre/.libs -L$(pwd)/srclib/expat/lib/.libs" \
polytracker build make -j$((`nproc`+1))

RUN polytracker instrument-targets --taint --ftrace httpd
RUN mv httpd.instrumented httpd_track
# overwrite binary to be installed with our polytracker-instrumented version
RUN cp httpd_track httpd
RUN polytracker build make install

COPY harness_httpd.sh /polytracker/examples/http/httpd/
COPY httpd.conf /usr/local/apache2/conf/

# Note, the /workdir and /testcase directories are intended to be mounted at runtime
VOLUME ["/workdir", "/testcase"]
WORKDIR /workdir
29 changes: 29 additions & 0 deletions examples/http/httpd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Polytracker demo: Apache httpd

## Quickstart
```
cd /path/to/polytracker/examples/http/httpd
./example_httpd.sh foo.txt
```
where `foo.txt` contains the raw text of an HTTP request.

## Notes on instrumentation
In order to enable polytracker instrumentation, we statically compile httpd, its dependencies, and its modules.

The default build includes the following statically compiled modules:
```
$ ./httpd -l
Compiled in modules:
core.c
mod_authz_core.c
mod_so.c
http_core.c
prefork.c
mod_unixd.c
```

In order to enable additional modules, modify the Dockerfile to include additional `--enable-MODULE=static`
or `--enable-modules-static=MODULE-LIST` directives during the final `./configure` command.
(see the [httpd configruation documenation](https://httpd.apache.org/docs/2.4/programs/configure.html) for further details).
You may also need to modify the `httpd.conf` file in this directory (which is copied to `/usr/local/apache2/conf/httpd.conf` in the container), and potentially add module configuration files to
the `/usr/local/apache2/conf/extra` directory.
47 changes: 47 additions & 0 deletions examples/http/httpd/example_httpd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash

if [[ -z "$1" ]]; then
echo "Error: no arguments supplied"
echo "Usage: ./example_httpd.sh /path/to/raw_http_request [httpd_port]"
exit 1
fi

if [[ -z "$2" ]]; then
APACHE_PORT=80
else
re='^[0-9]+$'
if ! [[ "$2" =~ $re ]] || [[ $2 -eq 0 ]] || [[ $2 -gt 65535 ]]; then
echo "Error: invalid httpd_port - must be positive integer in range 1-65535"
exit 1
else
APACHE_PORT="$2"
fi
fi

if [[ "$(docker images -q trailofbits/polytracker 2>/dev/null)" == "" ]]; then
docker build -t trailofbits/polytracker -f ../../Dockerfile ../../
fi
if [[ "$(docker images -q trailofbits/polytracker-demo-http-httpd 2>/dev/null)" == "" ]]; then
docker build -t trailofbits/polytracker-demo-http-httpd .
fi

HOST_PATH=$(realpath "$1")
BASENAME=$(basename "$HOST_PATH")
HOST_DIR=$(dirname "$HOST_PATH")

# NOTE: cannot pass --read-only because httpd needs to be able to write to /usr/local/apache2/logs/error_log

# mount the file if it's not already in /workdir
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
if [[ "$HOST_DIR" == "$SCRIPT_DIR" ]]; then
docker run -ti --rm -e POLYPATH="$1" -e POLYDB="$1.tdag" \
--mount type=bind,source="$(pwd)",target=/workdir trailofbits/polytracker-demo-http-httpd:latest \
/polytracker/examples/http/httpd/harness_httpd.sh "$1"
else
CONTAINER_PATH=/testcase/"$BASENAME"
docker run -ti --rm -e POLYPATH="$CONTAINER_PATH" -e POLYDB=/workdir/"$BASENAME".tdag -e APACHE_PORT="$APACHE_PORT" \
--mount type=bind,source="$(pwd)",target=/workdir \
--mount type=bind,source="$HOST_PATH",target="$CONTAINER_PATH" \
trailofbits/polytracker-demo-http-httpd:latest \
/polytracker/examples/http/httpd/harness_httpd.sh "$CONTAINER_PATH"
fi
28 changes: 28 additions & 0 deletions examples/http/httpd/harness_httpd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

set -e

APACHE_ROOT=/usr/local/apache2

# NB: this should be set via Docker if used with example_httpd.sh
if [[ -z "${APACHE_PORT}" ]]; then
APACHE_PORT=80
else
sed -i 's/:80/:'"$APACHE_PORT"'/g' "$APACHE_ROOT"/conf/httpd.conf
fi

$APACHE_ROOT/bin/apachectl -X &
# needed for server initialization in single-worker mode
sleep 10

# send request (from text file - first command line arg) to instrumented httpd
nc localhost "$APACHE_PORT" <"$1"

APACHE_PID=$(cat "$APACHE_ROOT"/logs/httpd.pid)
kill "$APACHE_PID"
wait

# Oddly, these cause issues with TDAG production and does not include socket fds among TDAG sources
# but only when run from the same terminal
# $APACHE_ROOT/bin/apachectl stop
# $APACHE_ROOT/bin/apachectl graceful-stop
Loading

0 comments on commit 2ab952d

Please sign in to comment.