-
Notifications
You must be signed in to change notification settings - Fork 414
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* v8ctf setup and rules
- Loading branch information
Showing
63 changed files
with
16,158 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# v8CTF challenge | ||
|
||
This challenge is part of the v8CTF, an exploit VRP for the v8 JavaScript engine. | ||
|
||
See RULES.md for how to participate. | ||
|
||
You can reach it at `nc v8.ctfcompetition.com 1337`. | ||
|
||
It runs a `chrome --headless=new` on a user-provided URL. You can find the command line in chrome/challenge/chal and the Chrome version in chrome/challenge/Dockerfile. | ||
|
||
The flag is at /flag/flag and is in the format `v8CTF{.*}`. | ||
|
||
If you want to recreate the environment locally, check out https://google.github.io/kctf/ for tips on how to use the kCTF infrastructure. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# v8CTF Rules | ||
|
||
The v8CTF is a part of the [Google VRP](https://g.co/vrp) in which we reward successful exploitation attempts against a V8 version running on our infrastructure. | ||
This program is orthogonal to the [Chrome VRP](https://g.co/chrome/vrp), if you find a bug and exploit it, you can submit the bug to the Chrome VRP and use the exploit for the v8CTF. | ||
|
||
In the following, we will differentiate between 0-day and n-day exploits. | ||
If the bug that led to the initial memory corruption was found by you, i.e. reported from the same email address as used in the v8CTF submission, we will consider the exploit a 0-day submission. | ||
All other exploits are considered n-day submissions. | ||
|
||
## Rules | ||
|
||
The following rules apply to the eligibility of exploits: | ||
* Your exploit needs to exfiltrate the flag from our v8CTF infrastructure. | ||
* Only the first submission for a given bug that leads to the initial memory corruption is eligible. | ||
* Only the first submission per deployed V8 version in v8CTF is eligible based on the timestamp of the form submission. | ||
* 0-day submissions are exempt from this limit. | ||
* Exploits need to be reasonably fast and stable. We accept submissions with an average runtime of less than 5 minutes and at least 80% success rate. | ||
* Valid submissions get a reward of $10,000. | ||
|
||
## Submission Process | ||
|
||
1. If your exploit targets a 0-day vulnerability, make sure to report it first to the [Chrome VRP](https://g.co/chrome/vrp). | ||
1. Check [this sheet](https://docs.google.com/spreadsheets/d/e/2PACX-1vTWvO0tFNl8fJbOmTV1nwGJi4fAy5pDg-6DsHARRubj8I6c7_11RQ36Jv735zj9EQggz6AWjAOaebJh/pubhtml?gid=0&single=true) if there’s already a submission for the currently deployed V8 version. | ||
1. Exploit the bug and capture the flag from our v8CTF environment. | ||
1. Create a .tar.gz archive of your exploit and calculate its sha256, e.g. with `sha256sum exploit.tar.gz`. | ||
1. Please double check that the exploit doesn’t have any external dependencies. | ||
1. Fill out [this form](https://docs.google.com/forms/d/e/1FAIpQLScoWE5-XoF85dXMjWKTIrJGTEfCybFaktsYZMCZ86iFPrW8Ew/viewform?usp=header_link) with the flag and the exploit sha256 sum. | ||
1. For 0-day submissions, please use the same email address you reported the bug from. | ||
1. A bug in the Google Issue Tracker will be filed on your behalf. Attach the exploit matching the sha256 sum and a short write up to the bug. | ||
1. Give us a few days to validate your submission. | ||
|
||
## Setup | ||
|
||
You can find a description of our v8CTF infrastructure in the [README](https://github.com/google/security-research/blob/master/v8ctf/readme.md). | ||
|
||
## Communication | ||
|
||
We have two discord channels set up on the [Capture The Flag](https://discord.gg/hqcSdTk6vm) server: | ||
|
||
* #v8ctf-announcements: will be used for announcements such as changes to the rules. | ||
* #v8ctf: is open to all. If you have any questions, please ask here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Quickstart guide to writing a challenge | ||
|
||
The basic steps when preparing a challenge are: | ||
|
||
* A Docker image is built from the `challenge` directory. For the simplest challenges, replacing `challenge/chal.c` is sufficient. | ||
* Edit `challenge/Dockerfile` to change the commandline or the files you want to include. | ||
* To try the challenge locally, you will need to | ||
* create a a local cluster with `kctf cluster create --type kind --start $configname` | ||
* build the challenge binary with `make -C challenge` | ||
* and then deploy the challenge with `kctf chal start` | ||
* To access the challenge, create a port forward with `kctf chal debug port-forward` and connect to it via `nc localhost PORT` using the printed port. | ||
* Check out `kctf chal <tab>` for more commands. | ||
|
||
## Directory layout | ||
|
||
The following files/directories are available: | ||
|
||
### /challenge.yaml | ||
|
||
`challenge.yaml` is the main configuration file. You can use it to change | ||
settings like the name and namespace of the challenge, the exposed ports, the | ||
proof-of-work difficulty etc. | ||
For documentation on the available fields, you can run `kubectl explain challenge` and | ||
`kubectl explain challenge.spec`. | ||
|
||
### /challenge | ||
|
||
The `challenge` directory contains a Dockerfile that describes the challenge and | ||
any challenge files. This template comes with a Makefile to build the challenge, | ||
which is the recommended way for pwnables if the deployed binary matters, e.g. | ||
if you hand it out as an attachment for ROP gadgets. | ||
If the binary layout doesn't matter, you can build it using an intermediate | ||
container as part of the Dockerfile similar to how the chroot is created. | ||
|
||
### /healthcheck | ||
|
||
The `healthcheck` directory is optional. If you don't want to write a healthcheck, feel free to delete it. However, we strongly recommend that you implement a healthcheck :). | ||
|
||
We provide a basic healthcheck skeleton that uses pwntools to implement the | ||
healthcheck code. The only requirement is that the healthcheck replies to GET | ||
requests to http://$host:45281/healthz with either a success or an error status | ||
code. | ||
|
||
In most cases, you will only have to modify `healthcheck/healthcheck.py`. | ||
|
||
## API contract | ||
|
||
Ensure your setup fulfills the following requirements to ensure it works with kCTF: | ||
|
||
* Verify `kctf_setup` is used as the first command in the CMD instruction of your `challenge/Dockerfile`. | ||
* You can do pretty much whatever you want in the `challenge` directory but: | ||
* We strongly recommend using nsjail in all challenges. While nsjail is already installed, you need to configure it in `challenge/nsjail.cfg`. For more information on nsjail, see the [official website](https://nsjail.dev/). | ||
* Your challenge receives connections on port 1337. The port can be changed in `challenge.yaml`. | ||
* The healthcheck directory is optional. | ||
* If it exists, the image should run a webserver on port 45281 and respond to `/healthz` requests. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
apiVersion: kctf.dev/v1 | ||
kind: Challenge | ||
metadata: | ||
name: chrome | ||
spec: | ||
deployed: true | ||
powDifficultySeconds: 1 | ||
network: | ||
public: true | ||
healthcheck: | ||
# TIP: disable the healthcheck during development | ||
enabled: true | ||
podTemplate: | ||
template: | ||
spec: | ||
containers: | ||
- name: challenge | ||
volumeMounts: | ||
- name: flag | ||
mountPath: /chroot/flag | ||
readOnly: true | ||
volumes: | ||
- name: flag | ||
secret: | ||
defaultMode: 0555 | ||
secretName: v8ctf-flag | ||
optional: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Copyright 2020 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
FROM ubuntu:22.04 as chroot | ||
|
||
RUN /usr/sbin/useradd --no-create-home -u 1000 user | ||
|
||
RUN apt-get update && apt-get install -y gnupg2 wget | ||
|
||
# Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others) | ||
# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer installs, work. | ||
# Deps from https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix | ||
# plus libxshmfence1 which seems to be missing | ||
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ | ||
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ | ||
&& apt-get update \ | ||
&& DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \ | ||
google-chrome-stable \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
RUN apt-get update && apt-get install -y unzip | ||
|
||
RUN mkdir /home/user | ||
RUN wget 'https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2F1181205%2Fchrome-linux.zip?generation=1691535836009137&alt=media' -O /home/user/chrome-linux.zip | ||
RUN cd /home/user && unzip chrome-linux.zip && rm chrome-linux.zip | ||
|
||
COPY chal /home/user/ | ||
|
||
FROM gcr.io/kctf-docker/challenge@sha256:0f7d757bcda470c3bbc063606335b915e03795d72ba1d8fdb6f0f9ff3757364f | ||
|
||
COPY --from=chroot / /chroot | ||
RUN mkdir /chroot/dev/shm | ||
RUN touch /chroot/dev/null | ||
RUN touch /chroot/dev/zero | ||
RUN touch /chroot/dev/urandom | ||
|
||
RUN mkdir /chroot/run/dbus | ||
|
||
COPY nsjail.cfg /home/user/ | ||
|
||
CMD kctf_setup && \ | ||
kctf_drop_privs \ | ||
socat \ | ||
TCP-LISTEN:1337,reuseaddr,fork \ | ||
EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal",stderr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/usr/bin/bash | ||
|
||
CHROME=/home/user/chrome-linux/chrome | ||
|
||
echo "Version: $($CHROME --version | head -n1)" | ||
echo "Please send me a URL to open." | ||
read -r url | ||
if ! echo $url | grep -E '^https?://[A-Za-z0-9.:/?%\-_+&=]*$' -q; then | ||
echo 'url regex fail' | ||
exit 1 | ||
fi | ||
|
||
export HOME=/tmp | ||
dbus-daemon --system | ||
dbus-run-session -- $CHROME --headless=new --no-sandbox --disable-crashpad --disable-breakpad --disable-crash-reporter --user-data-dir=/tmp/chrome-userdata --enable-logging=stderr "${url}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Copyright 2020 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
# See options available at https://github.com/google/nsjail/blob/master/config.proto | ||
|
||
name: "default-nsjail-configuration" | ||
description: "Default nsjail configuration for pwnable-style CTF task." | ||
|
||
mode: ONCE | ||
uidmap {inside_id: "1000"} | ||
gidmap {inside_id: "1000"} | ||
disable_rl: true | ||
clone_newnet: false | ||
|
||
cwd: "/home/user" | ||
|
||
mount: [ | ||
{ | ||
src: "/chroot" | ||
dst: "/" | ||
is_bind: true | ||
}, | ||
{ | ||
src: "/dev/null" | ||
dst: "/dev/null" | ||
is_bind: true | ||
}, | ||
{ | ||
src: "/dev/zero" | ||
dst: "/dev/zero" | ||
is_bind: true | ||
}, | ||
{ | ||
src: "/dev/urandom" | ||
dst: "/dev/urandom" | ||
is_bind: true | ||
}, | ||
{ | ||
dst: "/tmp" | ||
fstype: "tmpfs" | ||
rw: true | ||
}, | ||
{ | ||
dst: "/run/dbus" | ||
fstype: "tmpfs" | ||
rw: true | ||
}, | ||
{ | ||
dst: "/run/user" | ||
fstype: "tmpfs" | ||
rw: true | ||
}, | ||
{ | ||
dst: "/dev/shm" | ||
fstype: "tmpfs" | ||
rw: true | ||
}, | ||
{ | ||
dst: "/proc" | ||
fstype: "proc" | ||
rw: true | ||
}, | ||
{ | ||
src: "/etc/resolv.conf" | ||
dst: "/etc/resolv.conf" | ||
is_bind: true | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Copyright 2020 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
FROM gcr.io/kctf-docker/healthcheck@sha256:6709709a8cfd6e2d743c86d58398c00ca4eb26befd3b1a0a629ab35f91e98ef0 | ||
|
||
COPY healthcheck_loop.sh healthcheck.py healthz_webserver.py /home/user/ | ||
|
||
CMD kctf_drop_privs /home/user/healthcheck_loop.sh & /home/user/healthz_webserver.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Healthcheck | ||
|
||
kCTF checks the health of challenges by accessing the healthcheck via | ||
http://host:45281/healthz which needs to return either 200 ok or an error | ||
depending on the status of the challenge. | ||
|
||
The default healthcheck consists of: | ||
* a loop that repeatedly calls a python script and writes the status to a file | ||
* a webserver that checks the file and serves /healthz | ||
* the actual healthcheck code using pwntools for convenience | ||
|
||
To modify it, you will likely only have to change the script in healthcheck.py. | ||
You can test if the challenge replies as expected or better add a full example | ||
solution that will try to get the flag from the challenge. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2020 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import socket | ||
from pwn import * | ||
|
||
r = remote('127.0.0.1', 1337) | ||
l = listen() | ||
|
||
r.readuntil(b'URL to open.', timeout=10) | ||
r.sendline(bytes('http://localhost:{}/ok'.format(l.lport), 'ascii')) | ||
|
||
_ = l.wait_for_connection() | ||
|
||
l.readuntil(b'GET /ok HTTP/1.1') | ||
l.send(b'HTTP/1.1 200 OK\nContent-Length: 0\n\n') | ||
|
||
exit (0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#!/bin/bash | ||
# Copyright 2020 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
set -Eeuo pipefail | ||
|
||
TIMEOUT=20 | ||
PERIOD=30 | ||
|
||
export TERM=linux | ||
export TERMINFO=/etc/terminfo | ||
|
||
while true; do | ||
echo -n "[$(date)] " | ||
if timeout "${TIMEOUT}" /home/user/healthcheck.py; then | ||
echo 'ok' | tee /tmp/healthz | ||
else | ||
echo -n "$? " | ||
echo 'err' | tee /tmp/healthz | ||
fi | ||
sleep "${PERIOD}" | ||
done |
Oops, something went wrong.