Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7a4c746

Browse files
author
Carl Svensson
committed
2024 challenges
1 parent369663c commit7a4c746

File tree

2,448 files changed

+143670
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,448 files changed

+143670
-2
lines changed

‎2024/README.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
Sources from the 2024 Google CTF will be uploaded here shortly after the event
2-
finishes
1+
#Google CTF 2024
2+
3+
*[Qualifiers](quals/)
4+
* Hackceler8 (released after the finals)
5+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#Quickstart guide to writing a challenge
2+
3+
The basic steps when preparing a challenge are:
4+
5+
* A Docker image is built from the`challenge` directory. For the simplest challenges, replacing`challenge/chal.c` is sufficient.
6+
* Edit`challenge/Dockerfile` to change the commandline or the files you want to include.
7+
* To try the challenge locally, you will need to
8+
* create a a local cluster with`kctf cluster create --type kind --start $configname`
9+
* build the challenge binary with`make -C challenge`
10+
* and then deploy the challenge with`kctf chal start`
11+
* 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.
12+
* Check out`kctf chal <tab>` for more commands.
13+
14+
##Directory layout
15+
16+
The following files/directories are available:
17+
18+
###/challenge.yaml
19+
20+
`challenge.yaml` is the main configuration file. You can use it to change
21+
settings like the name and namespace of the challenge, the exposed ports, the
22+
proof-of-work difficulty etc.
23+
For documentation on the available fields, you can run`kubectl explain challenge` and
24+
`kubectl explain challenge.spec`.
25+
26+
###/challenge
27+
28+
The`challenge` directory contains a Dockerfile that describes the challenge and
29+
any challenge files. This template comes with a Makefile to build the challenge,
30+
which is the recommended way for pwnables if the deployed binary matters, e.g.
31+
if you hand it out as an attachment for ROP gadgets.
32+
If the binary layout doesn't matter, you can build it using an intermediate
33+
container as part of the Dockerfile similar to how the chroot is created.
34+
35+
###/healthcheck
36+
37+
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 :).
38+
39+
We provide a basic healthcheck skeleton that uses pwntools to implement the
40+
healthcheck code. The only requirement is that the healthcheck replies to GET
41+
requests to http://$host:45281/healthz with either a success or an error status
42+
code.
43+
44+
In most cases, you will only have to modify`healthcheck/healthcheck.py`.
45+
46+
##API contract
47+
48+
Ensure your setup fulfills the following requirements to ensure it works with kCTF:
49+
50+
* Verify`kctf_setup` is used as the first command in the CMD instruction of your`challenge/Dockerfile`.
51+
* You can do pretty much whatever you want in the`challenge` directory but:
52+
* 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/).
53+
* Your challenge receives connections on port 1337. The port can be changed in`challenge.yaml`.
54+
* The healthcheck directory is optional.
55+
* If it exists, the image should run a webserver on port 45281 and respond to`/healthz` requests.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
fromecdsa.curvesimportNIST256p
16+
fromecdsa.numbertheoryimportjacobi,square_root_mod_prime
17+
fromecdsa.ellipticcurveimportPoint
18+
fromCrypto.Randomimportrandom
19+
importhashlib
20+
21+
curve=NIST256p.curve
22+
23+
defH(id):
24+
a,b,p=curve.a(),curve.b(),curve.p()
25+
26+
hash=hashlib.sha256(f'id={id}'.encode()).digest()
27+
x=int.from_bytes(hash,'big')
28+
29+
whileTrue:
30+
y2= (x**3+a*x+b)%p
31+
ifjacobi(y2,p)==1:break
32+
x+=1
33+
34+
y=square_root_mod_prime(y2,p)
35+
returnPoint(curve,x,y)
36+
37+
# Implements Blinders, a private set membership protocol.
38+
classBlindersServer:
39+
def__init__(self,S):
40+
self.S=S
41+
42+
defhandle(self,client_eid):
43+
# 2.1. Generate a random secret key k
44+
k=random.randrange(0,NIST256p.order)
45+
# Compute eid1 = H(id1)^K, ..., eidn = H(idn)^K
46+
eids= [H(id)*kforidinself.S]
47+
# Compute doubly-encrypted identifier deid = eid^K
48+
deid=client_eid*k
49+
# Return (eid1, ..., eidn) and deid to P1
50+
returneids,deid
51+
52+
defchallenge():
53+
# S = {0, 1, ..., 255} \ {x} for some 0 <= x < 256
54+
S=list(range(256))
55+
S.remove(random.getrandbits(8))
56+
server=BlindersServer(S)
57+
58+
for_inrange(3):
59+
operation,*params=input().split()
60+
ifoperation=='handle':
61+
client_eid=Point(curve,int(params[0]),int(params[1]))
62+
eids,deid=server.handle(client_eid)
63+
print([(eid.x(),eid.y())foreidineids])
64+
print((deid.x(),deid.y()))
65+
elifoperation=='submit':
66+
client_S_hash=bytes.fromhex(params[0])
67+
S_hash=hashlib.sha256(','.join(map(str,server.S)).encode()).digest()
68+
returnclient_S_hash==S_hash
69+
else:
70+
returnFalse
71+
72+
if__name__=='__main__':
73+
withopen('/flag.txt','r')asf:
74+
FLAG=f.read().strip()
75+
76+
# Convince me 16 times and I will give you the flag :)
77+
for_inrange(16):
78+
ifchallenge():
79+
print('OK!')
80+
else:
81+
print('Nope.')
82+
break
83+
else:
84+
print(FLAG)
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
importast
16+
importsocket
17+
fromCrypto.Randomimportrandom
18+
fromrich.progressimporttrack
19+
importhashlib
20+
fromecdsa.curvesimportNIST256p
21+
fromecdsa.numbertheoryimportjacobi,square_root_mod_prime
22+
fromecdsa.ellipticcurveimportPoint
23+
24+
curve=NIST256p.curve
25+
26+
defH(id):
27+
a,b,p=curve.a(),curve.b(),curve.p()
28+
29+
hash=hashlib.sha256(f'id={id}'.encode()).digest()
30+
x=int.from_bytes(hash,'big')
31+
32+
whileTrue:
33+
y2= (x**3+a*x+b)%p
34+
ifjacobi(y2,p)==1:break
35+
x+=1
36+
37+
y=square_root_mod_prime(y2,p)
38+
returnPoint(curve,x,y)
39+
40+
classBlindersAPI:
41+
def__init__(self,host,port):
42+
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
43+
s.connect((host,port))
44+
s.settimeout(10)
45+
self.s=s
46+
self.recvline()
47+
48+
defrecvline(self):
49+
output= []
50+
whileTrue:
51+
c=self.s.recv(1)
52+
ifc==b''orc==b'\n':break
53+
output.append(c)
54+
returnb''.join(output)
55+
56+
defhandle(self,eid):
57+
self.s.send(f'handle{eid.x()}{eid.y()}\n'.encode())
58+
eids=ast.literal_eval(self.recvline().decode())
59+
deid=ast.literal_eval(self.recvline().decode())
60+
return [Point(curve,*eid)foreidineids],Point(curve,*deid)
61+
62+
defsubmit(self,S):
63+
hash=hashlib.sha256(','.join(map(str,S)).encode()).hexdigest()
64+
self.s.send(f'submit{hash}\n'.encode())
65+
returnself.recvline().decode()
66+
67+
deffinal(self):
68+
returnself.recvline().decode()
69+
70+
71+
# Implements the client side of Blinders
72+
classBlindersClient:
73+
def__init__(self,api):
74+
self.api=api
75+
76+
defquery(self,id):
77+
# 1.1. Generate a random key R
78+
r=random.randrange(0,NIST256p.order)
79+
r_inverse=int(pow(r,-1,NIST256p.order))
80+
# 1.2. Compute encrypted identified eid = H(id)^R
81+
eid=H(id)*r
82+
# 1.3. Send eid to P2
83+
server_eids,deid=self.api.handle(eid)
84+
85+
# 3.1. Compute eid' = deid^(1/R)
86+
new_eid=deid*r_inverse
87+
# If eid' = eidi for any i = 1, ..., n, return S = {id}
88+
# Otherwise return S = {}.
89+
returnnew_eidinserver_eids
90+
91+
defsubmit(self,S):
92+
returnself.api.submit(S)
93+
94+
deffinal(self):
95+
returnself.api.final()
96+
97+
98+
defmain():
99+
api=BlindersAPI('localhost',1337)
100+
client=BlindersClient(api)
101+
102+
for_inrange(16):
103+
S= [xforxintrack(range(2))ifclient.query(x)]
104+
print(f'{S=}')
105+
res=client.submit(S)
106+
print(f'{res=}')
107+
ifres=='Nope.':return
108+
109+
print(client.final())# sweet flag <3
110+
111+
112+
if__name__=='__main__':
113+
main()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
apiVersion:kctf.dev/v1
2+
kind:Challenge
3+
metadata:
4+
name:blinders
5+
spec:
6+
deployed:true
7+
powDifficultySeconds:0
8+
network:
9+
public:true
10+
healthcheck:
11+
# TIP: disable the healthcheck during development
12+
enabled:true
13+
image:europe-west4-docker.pkg.dev/gctf-2024/kctf-cluster-challenges/blinders-healthcheck:b74f235ef533a30577b1202ed6fa1a265600cffade05289023cf5aef98125693
14+
image:europe-west4-docker.pkg.dev/gctf-2024/kctf-cluster-challenges/blinders-challenge:3741ad9168e282c09b34af5a75f5ec8bd57ba71b41697b61718a0ee2add53469
15+
horizontalPodAutoscalerSpec:
16+
maxReplicas:20
17+
minReplicas:1
18+
targetCPUUtilizationPercentage:80
19+
podTemplate:
20+
template:
21+
spec:
22+
containers:
23+
-name:challenge
24+
resources:
25+
requests:
26+
memory:"2Gi"
27+
cpu:"1"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
FROM ubuntu:22.04 as chroot
15+
16+
RUN /usr/sbin/useradd --no-create-home -u 1000 user
17+
18+
ARG DEBIAN_FRONTEND=noninteractive
19+
RUN apt update
20+
RUN apt install -y software-properties-common
21+
RUN add-apt-repository ppa:deadsnakes/ppa
22+
RUN apt update
23+
RUN apt install -y python3.12
24+
RUN apt install -y curl
25+
RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.12
26+
RUN python3.12 -m pip install ecdsa pycryptodome
27+
28+
COPY flag.txt /
29+
COPY chall.py /home/user/
30+
31+
FROM gcr.io/kctf-docker/challenge@sha256:0f7d757bcda470c3bbc063606335b915e03795d72ba1d8fdb6f0f9ff3757364f
32+
33+
COPY --from=chroot / /chroot
34+
35+
COPY nsjail.cfg /home/user/
36+
37+
CMD kctf_setup && \
38+
kctf_drop_privs \
39+
socat \
40+
TCP-LISTEN:1337,reuseaddr,fork \
41+
EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /usr/bin/python3.12 /home/user/chall.py"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp