Skip to content

Commit

Permalink
Merge branch 'master' of github.com:cybermouflons/CCSC-CTF-2024
Browse files Browse the repository at this point in the history
  • Loading branch information
atsouloupas committed Apr 23, 2024
2 parents 6070a0f + 8045102 commit db13977
Show file tree
Hide file tree
Showing 24 changed files with 358 additions and 9 deletions.
11 changes: 6 additions & 5 deletions .github/actions/generate-readme/README.jinja
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
![CCSC CTF 2023](_assets/banner.png)
# Cyprus Cyber Security Challenge CTF 2024

# Cyprus Cyber Security Challenge CTF 2023

**Dates:** 01/07/2023 - 16/07/2023
**Dates:** 01/05/2024 - 12/05/2024

## Repository Structure
This is the official repository with the challenges published in Cyprus Cyber Security Challenge (CCSC) CTF 2023. Each challenge has a public, solution and setup folder (if applicable) and is accompanied with a short description. The setup folder contains all the files required to build and host the challenge and usually contains the flag and a proof of concept solution as well. The public folder contains the files that are released to the participant during the competition.

This is the official repository with the challenges published in Cyprus Cyber Security Challenge (CCSC) CTF 2024. Each challenge has a public, solution and setup folder (if applicable) and is accompanied with a short description. The setup folder contains all the files required to build and host the challenge and usually contains the flag and a proof of concept solution as well. The public folder contains the files that are released to the participant during the competition.

## Dependencies

Although some of the challenges may run as is, it is recommended that you have docker and docker-compose installed and use the provided scripts to run the challenges to ensure isolation and therefore proper environment setup.

## Challenges
Expand All @@ -20,4 +21,4 @@ Although some of the challenges may run as is, it is recommended that you have d
{% for challenge in challenges %}| [{{ challenge.name }}]({{ challenge.dir }}) | {{ challenge.author }} |
{% endfor %}

{% endfor %}
{% endfor %}
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ Although some of the challenges may run as is, it is recommended that you have d

### misc

| Name | Author |
| ------------------------------ | ----------- |
| [Placeholder](./misc/.gitkeep) | Placeholder |
| Name | Author |
| -------------------------------------------- | ------ |
| [Superguesser Part 1](./misc/superguesser) | koks |
| [Superguesser Part 2](./misc/superguesser_2) | koks |
| [Superguesser Part 3](./misc/superguesser_3) | koks |

### pwn

Expand Down
16 changes: 16 additions & 0 deletions misc/metadata-matters/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Metadata Matters

### Category: misc
### Author: YetAnotherAlt123

## Description

One of our agents has gotten a foothold on an old, isolated workstation. It looks like it might have some important information, but we need superuser privileges to get to it.

We managed to extract the password hash for the root user. We know that the password policy mandates passwords up to 13 characters long, and requires that they have capitals, numbers and letters.

```
root:$6$jM2.hLB7cxxe0Jik$ukjRJ6VORdRKdK0aBkKpjGzgId6OrR0srv.vrNlIj3gC8KTTk9nnf8bubTNUCTKo.he5CwFFs2xV9B1KHKDRt1
```

Cracking a good, long password seems impossible... unless you know something we don't?
31 changes: 31 additions & 0 deletions misc/metadata-matters/challenge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: "Metadata Matters"
author: "YetAnotherAlt123"
category: misc

description: |
One of our agents has gotten a foothold on an old, isolated workstation. It looks like it might have some important information, but we need superuser privileges to get to it.
We managed to extract the password hash for the root user. We know that the password policy mandates passwords up to 13 characters long, and requires that they have capitals, numbers and letters.
```
root:$6$jM2.hLB7cxxe0Jik$ukjRJ6VORdRKdK0aBkKpjGzgId6OrR0srv.vrNlIj3gC8KTTk9nnf8bubTNUCTKo.he5CwFFs2xV9B1KHKDRt1
```
Cracking a good, long password seems impossible... unless you know something we don't?
value: 200
type: dynamic
extra:
initial: 200
minimum: 50
decay: 25

flags:
- CCSC{M4skFtW}

tags:
- misc
- easy

state: visible
version: "0.1"
File renamed without changes.
Empty file.
9 changes: 9 additions & 0 deletions misc/metadata-matters/solution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
The password is the flag. This means that the attacker knows the beginning and the end, and the only part of the password that they actually need to guess is the middle. The middle being only 7 characters means that it's straightforward to crack on a relatively modern cpu/gpu.

Start up hashcat, give it the right mask, and get the flag.

```
hashcat -m 1800 pw -a 3 "CCSC{?a?a?a?a?a?a?a}"
```

Flag: CCSC{M4skFtW}
27 changes: 27 additions & 0 deletions misc/superguesser/challenge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Superguesser Part 1"
author: "koks"
category: misc

description: |
The machines seem to live and breathe in binary. Use that against them and capture the flag.
value: 500
type: dynamic_docker
extra:
initial: 500
minimum: 100
decay: 25
redirect_type: direct
compose_stack: !filecontents docker-compose.yml

flags:
- CCSC{part1_sec0nds_and_s33ds_d0nt_m1x_t0gether}

tags:
- misc
- easy
- medium
- hard

state: visible
version: "0.1"
7 changes: 7 additions & 0 deletions misc/superguesser/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: '3'
services:
superguesser:
image: ghcr.io/cybermouflons/ccsc2024/superguesser:latest
build: ./setup/
ports:
- 9745:9745
Binary file added misc/superguesser/public/superguesser.zip
Binary file not shown.
20 changes: 20 additions & 0 deletions misc/superguesser/setup/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM golang:1.22.1-alpine3.19 as builder

RUN mkdir -p /temp/builder
COPY main.go /temp/builder
RUN cd /temp/builder && go build -o superguesser main.go

FROM alpine:3.19

RUN mkdir /challenge
WORKDIR /challenge
COPY --from=builder /temp/builder/superguesser .

RUN addgroup -S challenge && adduser -S challenge -G challenge
USER challenge

ENV FLAG_ONE="CCSC{part1_sec0nds_and_s33ds_d0nt_m1x_t0gether}"
ENV FLAG_TWO="CCSC{part2_m1lli5_n33d_som3_brains_and_s0me_luck}"
ENV FLAG_THREE="CCSC{part3_nan0s_d0nt_c4re_bis3ct_is_1n_the_a1r}"

ENTRYPOINT [ "./superguesser" ]
169 changes: 169 additions & 0 deletions misc/superguesser/setup/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package main

import (
"bufio"
"fmt"
"math"
"math/rand"
"net"
"os"
"strconv"
"strings"
"time"
)

var flags []string

func init() {
flag_one := os.Getenv("FLAG_ONE")
if flag_one == "" {
flag_one = "CCSC{fake_dummy_flag_1}"
}

flag_two := os.Getenv("FLAG_TWO")
if flag_two == "" {
flag_two = "CCSC{fake_dummy_flag_2}"
}

flag_three := os.Getenv("FLAG_THREE")
if flag_three == "" {
flag_three = "CCSC{fake_dummy_flag_3}"
}

flags = []string{flag_one, flag_two, flag_three}
}

func main() {
port := os.Getenv("PORT")
if port == "" {
port = "7945"
}
listener, err := net.Listen("tcp", ":"+port)
if err != nil {
fmt.Println("Error listening:", err.Error())
return
}
defer listener.Close()

fmt.Println("Listening on port " + port)

for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting connection:", err.Error())
return
}

fmt.Println("Client connected")

go handleConnection(conn)
}
}

func handleConnection(conn net.Conn) {
defer conn.Close()

gen := func(part int) (randomNumber int64, maxTries int) {
switch part {
case 1:
seed := time.Now().Unix()
random := rand.New(rand.NewSource(seed))
randomNumber, maxTries = random.Int63(), 5
return
case 2:
seed := time.Now().UnixMilli()
random := rand.New(rand.NewSource(seed))
randomNumber, maxTries = random.Int63(), 50
return
case 3:
seed := time.Now().UnixNano()
random := rand.New(rand.NewSource(seed))
randomNumber, maxTries = random.Int63(), 500
return
}
return 0, 0
}

reader := bufio.NewReader(conn)
writer := bufio.NewWriter(conn)

writer.WriteString("v1.1\n")
writer.WriteString("=======================================================\n")
writer.WriteString("ReverseCAPTCHA commencing... Prove you are not a human!\n")
writer.WriteString("=======================================================\n\n")
writer.Flush()

var optionSelected = -1

for {
writer.WriteString("Options:\n--------\n(1) Part One\n(2) Part Two\n(3) Part Three\n\nSolve part: ")
writer.Flush()

input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error reading input:", err.Error())
return
}

input = strings.TrimSpace(input)
option, err := strconv.Atoi(input)
if err != nil || option > 3 || option < 1 {
writer.WriteString("\n[x] Invalid input.\n\n")
writer.Flush()
continue
}

optionSelected = option
break
}

randomNumber, maxTries := gen(optionSelected)
if randomNumber == 0 {
fmt.Println("Something's wrong, terminate")
return
}

triesLeft := maxTries

writer.WriteString("\n")
writer.WriteString(fmt.Sprintf("I've hallucinated a number between 0 and %d. Can you guess it?\n\n", math.MaxInt64))
writer.WriteString(fmt.Sprintf("You have %d tries.\n\n", maxTries))
writer.Flush()

for {
writer.WriteString(fmt.Sprintf("[%d]: ", triesLeft))
writer.Flush()

input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error reading input:", err.Error())
return
}

input = strings.TrimSpace(input)
guess, err := strconv.ParseInt(input, 10, 64)
if err != nil {
writer.WriteString("Invalid input.\n")
writer.Flush()
continue
}

triesLeft--

if triesLeft <= 0 {
writer.WriteString("\nBye.\n")
writer.Flush()
return
} else if guess < randomNumber {
writer.WriteString("++ Higher\n")
writer.Flush()
} else if guess > randomNumber {
writer.WriteString("-- Lower\n")
writer.Flush()
} else {
writer.WriteString(fmt.Sprintf("Superior computational brain power detected.\n%s\n", flags[optionSelected-1]))
writer.Flush()
return
}
}
}
Empty file.
27 changes: 27 additions & 0 deletions misc/superguesser_2/challenge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Superguesser Part 2"
author: "koks"
category: misc

description: |
The machines seem to live and breathe in binary. Use that against them and capture the flag.
value: 500
type: dynamic_docker
extra:
initial: 500
minimum: 100
decay: 25
redirect_type: direct
compose_stack: !filecontents docker-compose.yml

flags:
- CCSC{part2_m1lli5_n33d_som3_brains_and_s0me_luck}

tags:
- misc
- easy
- medium
- hard

state: visible
version: "0.1"
7 changes: 7 additions & 0 deletions misc/superguesser_2/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: '3'
services:
superguesser:
image: ghcr.io/cybermouflons/ccsc2024/superguesser:latest
build: ../superguesser/setup/
ports:
- 9745:9745
Binary file added misc/superguesser_2/public/superguesser.zip
Binary file not shown.
Empty file.
Empty file.
27 changes: 27 additions & 0 deletions misc/superguesser_3/challenge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Superguesser Part 3"
author: "koks"
category: misc

description: |
The machines seem to live and breathe in binary. Use that against them and capture the flag.
value: 500
type: dynamic_docker
extra:
initial: 500
minimum: 100
decay: 25
redirect_type: direct
compose_stack: !filecontents docker-compose.yml

flags:
- CCSC{part3_nan0s_d0nt_c4re_bis3ct_is_1n_the_a1r}

tags:
- misc
- easy
- medium
- hard

state: visible
version: "0.1"
Loading

0 comments on commit db13977

Please sign in to comment.