-
Notifications
You must be signed in to change notification settings - Fork 10
Sadserver instance on redis instance #459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: redis-instance
Are you sure you want to change the base?
Changes from all commits
8001230
d2034fd
b0d8f33
5983874
7014b8b
9019f96
2aff015
3208969
6ac0a5b
de3c87f
8ca25ff
966ad58
d355d5b
cd7e517
bd3ffe4
cb0ac9e
15e5f27
caea4ad
7631f90
0013eea
8a7d7c2
51e383b
de43392
8552dc3
5eb9e17
77b9cbd
864616c
695205b
ae188ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,53 @@ | ||||||
| FROM golang:1.23 AS builder | ||||||
|
|
||||||
| RUN apt-get update && apt-get install -y \ | ||||||
| make git gcc util-linux \ | ||||||
| && rm -rf /var/lib/apt/lists/* | ||||||
|
|
||||||
| WORKDIR /app | ||||||
|
|
||||||
| COPY go.mod go.sum ./ | ||||||
| RUN go mod download | ||||||
|
|
||||||
| COPY . . | ||||||
|
|
||||||
| RUN cp scripts/docker-enter /usr/bin/docker-enter && \ | ||||||
| cp scripts/docker_enter /usr/bin/docker_enter && \ | ||||||
| chmod u+s /usr/bin/docker_enter && \ | ||||||
| gcc -o /usr/bin/importenv scripts/importenv.c | ||||||
|
|
||||||
| RUN make build | ||||||
|
|
||||||
| FROM ubuntu:22.04 | ||||||
|
|
||||||
| RUN apt-get update && apt-get install -y ca-certificates curl gnupg lsb-release \ | ||||||
| && rm -rf /var/lib/apt/lists/* | ||||||
|
|
||||||
| RUN install -m 0755 -d /etc/apt/keyrings && \ | ||||||
| curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ | ||||||
| chmod a+r /etc/apt/keyrings/docker.gpg && \ | ||||||
| echo \ | ||||||
| "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ | ||||||
| $(. /etc/os-release && echo $VERSION_CODENAME) stable" \ | ||||||
| > /etc/apt/sources.list.d/docker.list && \ | ||||||
| apt-get update && \ | ||||||
| apt-get install -y \ | ||||||
| redis-tools \ | ||||||
| postgresql-client \ | ||||||
| docker-ce-cli \ | ||||||
| docker-compose-plugin \ | ||||||
| docker-buildx-plugin && \ | ||||||
| apt-get clean && rm -rf /var/lib/apt/lists/* | ||||||
|
|
||||||
| COPY --from=builder /go/bin/beast /usr/local/bin/beast | ||||||
|
|
||||||
| COPY --from=builder /usr/bin/docker-enter /usr/local/bin/docker-enter | ||||||
| COPY --from=builder /usr/bin/docker_enter /usr/local/bin/docker_enter | ||||||
| COPY --from=builder /usr/bin/importenv /usr/local/bin/importenv | ||||||
|
|
||||||
| COPY setup.sh /usr/local/bin/setup.sh | ||||||
| RUN chmod +x /usr/local/bin/setup.sh | ||||||
|
|
||||||
| EXPOSE 5005 | ||||||
|
|
||||||
| ENTRYPOINT ["setup.sh"] | ||||||
|
||||||
| ENTRYPOINT ["setup.sh"] | |
| ENTRYPOINT ["/usr/local/bin/setup.sh"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -81,3 +81,66 @@ installenv: | |
| @./scripts/installenv.sh | ||
|
|
||
| .PHONY: build format test check_format tools docs installenv | ||
|
|
||
| # ── Docker Compose Targets ──────────────────────────────────────────────────── | ||
| # Usage: make up NAME=myctf | ||
| # | ||
| # NAME (required, no spaces) — used to create a .<NAME> folder on the host which | ||
| # is mounted as /root/.beast inside the beast container. This keeps each | ||
| # deployment isolated and named. | ||
| # | ||
| # Prerequisites: | ||
| # - config.toml must exist alongside this Makefile. | ||
| # - In config.toml set psql_config.host = "postgres" (the compose service name). | ||
| # | ||
|
Comment on lines
+92
to
+95
|
||
| # Targets: | ||
| # make up NAME=<name> — set up .<name>/, copy config, start services | ||
| # make down NAME=<name> — stop and remove services | ||
| # make logs NAME=<name> — tail beast service logs | ||
|
|
||
| check-name: | ||
| @if [ -z "$(NAME)" ]; then \ | ||
| echo "Error: NAME is required. Usage: make up NAME=myctf"; \ | ||
| exit 1; \ | ||
| fi | ||
| @if echo "$(NAME)" | grep -q "[[:space:]]"; then \ | ||
| echo "Error: NAME must not contain spaces"; \ | ||
| exit 1; \ | ||
| fi | ||
|
|
||
| check-config: | ||
| @if [ ! -f "config.toml" ]; then \ | ||
| echo "Error: config.toml not found in current directory."; \ | ||
| echo "Place your config.toml here (see _examples/example.config.toml)."; \ | ||
| echo "Ensure psql_config.host = \"postgres\" for the compose network."; \ | ||
| exit 1; \ | ||
| fi | ||
|
|
||
| BEAST_DIR = $(HOME)/.$(NAME) | ||
|
|
||
| setup-beast-dir: check-name check-config | ||
| @echo "[*] Setting up $(BEAST_DIR)..." | ||
| @mkdir -p $(BEAST_DIR)/assets/logo | ||
| @mkdir -p $(BEAST_DIR)/assets/mailTemplates | ||
| @mkdir -p $(BEAST_DIR)/remote | ||
| @mkdir -p $(BEAST_DIR)/uploads | ||
| @mkdir -p $(BEAST_DIR)/secrets | ||
| @mkdir -p $(BEAST_DIR)/scripts | ||
| @mkdir -p $(BEAST_DIR)/staging | ||
| @mkdir -p $(BEAST_DIR)/cache | ||
| @mkdir -p $(BEAST_DIR)/logs | ||
| @cp config.toml $(BEAST_DIR)/config.toml | ||
| @echo "[*] $(BEAST_DIR) ready (mounted as /root/.beast in container)" | ||
|
|
||
| up: setup-beast-dir | ||
| @echo "[*] Starting beast services (project: $(NAME))..." | ||
| @BEAST_DIR=$(BEAST_DIR) docker compose --project-name $(NAME) up -d --build | ||
| @echo "[*] Beast API running at http://localhost:5005" | ||
|
|
||
| down: check-name | ||
| @docker compose --project-name $(NAME) down | ||
|
|
||
| logs: check-name | ||
| @docker compose --project-name $(NAME) logs -f beast | ||
|
|
||
| .PHONY: check-name check-config setup-beast-dir up down logs | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,17 @@ | ||
| FROM php:7.4-apache | ||
|
|
||
| # Install MySQL extension | ||
| RUN apt-get update && apt-get install -y --no-install-recommends openssh-server \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| RUN groupadd -g 1337 beast-grp \ | ||
| && useradd -u 1337 -g 1337 -ms /bin/bash beast | ||
|
|
||
| RUN docker-php-ext-install mysqli pdo pdo_mysql | ||
|
|
||
| # Copy challenge files | ||
| COPY challenge/ /var/www/html/ | ||
| COPY check.sh /challenge/check.sh | ||
|
|
||
| # Set permissions | ||
| RUN chown -R www-data:www-data /var/www/html | ||
| RUN chown -R www-data:www-data /var/www/html \ | ||
| && chmod +x /challenge/check.sh | ||
|
|
||
| EXPOSE 80 | ||
| EXPOSE 80 22 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| #!/bin/bash | ||
| # Placeholder for Beast instanced challenges (dynamic flag / checks live here in real challenges). | ||
| exit 0 |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,6 +2,7 @@ package api | |||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||
| "errors" | ||||||||||||||||||||||||||||||||||||||||
| "golang.org/x/crypto/ssh" | ||||||||||||||||||||||||||||||||||||||||
| "log" | ||||||||||||||||||||||||||||||||||||||||
| "net/http" | ||||||||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -215,10 +216,10 @@ func register(c *gin.Context) { | |||||||||||||||||||||||||||||||||||||||
| email = strings.TrimSpace(strings.ToLower(email)) | ||||||||||||||||||||||||||||||||||||||||
| sshKey = strings.TrimSpace(sshKey) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if username == "" || password == "" || email == "" { | ||||||||||||||||||||||||||||||||||||||||
| if username == "" || password == "" || email == "" || sshKey == "" { | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| c.JSON(http.StatusBadRequest, HTTPPlainResp{ | ||||||||||||||||||||||||||||||||||||||||
| Message: "Username, password and email can not be empty", | ||||||||||||||||||||||||||||||||||||||||
| Message: "Username, password, email, and sshKey can not be empty", | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -230,6 +231,15 @@ func register(c *gin.Context) { | |||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey)) | ||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| c.JSON(http.StatusBadRequest, HTTPErrorResp{ | ||||||||||||||||||||||||||||||||||||||||
| Error: "SSH Key is not valid", | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| sshKey = string(ssh.MarshalAuthorizedKey(key)) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+234
to
+242
|
||||||||||||||||||||||||||||||||||||||||
| key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey)) | |
| if err != nil { | |
| c.JSON(http.StatusBadRequest, HTTPErrorResp{ | |
| Error: "SSH Key is not valid", | |
| }) | |
| } | |
| sshKey = string(ssh.MarshalAuthorizedKey(key)) | |
| if sshKey != "" { | |
| key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey)) | |
| if err != nil { | |
| c.JSON(http.StatusBadRequest, HTTPErrorResp{ | |
| Error: "SSH Key is not valid", | |
| }) | |
| return | |
| } | |
| sshKey = string(ssh.MarshalAuthorizedKey(key)) | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The image sets the setuid bit on
/usr/bin/docker_enter. If this binary is ever executable by a non-root user inside the container, it becomes a straightforward privilege-escalation path. If setuid is not strictly required, drop it; otherwise document why it’s needed and consider restricting permissions/ownership to reduce the attack surface.