diff --git a/DownUnderCTF 2023/beginner/complementary/ape.py b/DownUnderCTF 2023/beginner/complementary/ape.py new file mode 100644 index 00000000..638bf9a2 --- /dev/null +++ b/DownUnderCTF 2023/beginner/complementary/ape.py @@ -0,0 +1,16 @@ +import math + +ctf = b"DUCTF{" + +ctf = int.from_bytes(ctf) + +# 0x44554354467b +# 0x3bd4fca9d0d3e400000000000000000000000 +# 6954494065942554678316751997792528753841173212407363342283423753536991947310058248515278 + +crypt = 6954494065942554678316751997792528753841173212407363342283423753536991947310058248515278 + +print(hex(int(math.sqrt(crypt)))) +ctf2 = 0x44554354467b0000000000000000000000000 + +print(int(crypt / ctf2)) diff --git a/DownUnderCTF 2023/beginner/complementary/complementary.py b/DownUnderCTF 2023/beginner/complementary/complementary.py new file mode 100644 index 00000000..8416d181 --- /dev/null +++ b/DownUnderCTF 2023/beginner/complementary/complementary.py @@ -0,0 +1,14 @@ +import math + +flag = open('./flag.txt', 'rb').read().strip() +m1 = int.from_bytes(flag[:len(flag)//2]) +m2 = int.from_bytes(flag[len(flag)//2:]) +print(flag[:len(flag)//2], flag[len(flag)//2:]) +print(m1, m2) +print(hex(m1), hex(m2)) +n = m1 * m2 +print(n) + +print("SOLVING!") +sq = int(math.sqrt(n)) +print(hex(sq)) diff --git a/DownUnderCTF 2023/beginner/complementary/flag.txt b/DownUnderCTF 2023/beginner/complementary/flag.txt new file mode 100644 index 00000000..03a02368 --- /dev/null +++ b/DownUnderCTF 2023/beginner/complementary/flag.txt @@ -0,0 +1 @@ +DUCTF{NOTAFLAG} \ No newline at end of file diff --git a/DownUnderCTF 2023/beginner/complementary/output.txt b/DownUnderCTF 2023/beginner/complementary/output.txt new file mode 100644 index 00000000..4ce5cd70 --- /dev/null +++ b/DownUnderCTF 2023/beginner/complementary/output.txt @@ -0,0 +1 @@ +6954494065942554678316751997792528753841173212407363342283423753536991947310058248515278 diff --git a/DownUnderCTF 2023/beginner/confusing/README.md b/DownUnderCTF 2023/beginner/confusing/README.md new file mode 100644 index 00000000..e6c63b15 --- /dev/null +++ b/DownUnderCTF 2023/beginner/confusing/README.md @@ -0,0 +1,45 @@ +# confusing + +``` +Types can be very confusing. + +Author: joseph +nc 2023.ductf.dev 30024 +``` + +## Source + +```c +#include +#include +#include + +void init() { + setvbuf(stdout, 0, 2, 0); + setvbuf(stdin, 0, 2, 0); +} + +int main() { + init(); + + short d; + double f; + char s[4]; + int z; + + printf("Give me d: "); + scanf("%lf", &d); + + printf("Give me s: "); + scanf("%d", &s); + + printf("Give me f: "); + scanf("%8s", &f); + + if(z == -1 && d == 13337 && f == 1.6180339887 && strncmp(s, "FLAG", 4) == 0) { + system("/bin/sh"); + } else { + puts("Still confused?"); + } +} +``` \ No newline at end of file diff --git a/DownUnderCTF 2023/beginner/confusing/ape.py b/DownUnderCTF 2023/beginner/confusing/ape.py new file mode 100644 index 00000000..e13f4a4c --- /dev/null +++ b/DownUnderCTF 2023/beginner/confusing/ape.py @@ -0,0 +1,34 @@ +import sys +import angr +import claripy +import time + +# compiled on ubuntu 18.04 system: +# https://github.com/b01lers/b01lers-ctf-2020/tree/master/rev/100_little_engine +success = 0x0010133c +fail = 0x00101343 + + +def main(argv): + path_to_binary = argv[1] # :string + project = angr.Project(path_to_binary) + + # Start in main() + initial_state = project.factory.entry_state() + # Start simulation + simulation = project.factory.simgr(initial_state) + + simulation.explore(find=success, avoid=fail) + + # If found a way to reach the address + if simulation.found: + solution_state = simulation.found[0] + + # Print the string that Angr wrote to stdin to follow solution_state + print(solution_state.posix.dumps(sys.stdin.fileno())) + else: + raise Exception('Could not find the solution') + + +if __name__ == '__main__': + main(sys.argv) diff --git a/DownUnderCTF 2023/beginner/confusing/confusing b/DownUnderCTF 2023/beginner/confusing/confusing new file mode 100755 index 00000000..f8ff1554 Binary files /dev/null and b/DownUnderCTF 2023/beginner/confusing/confusing differ diff --git a/DownUnderCTF 2023/beginner/confusing/confusing.c b/DownUnderCTF 2023/beginner/confusing/confusing.c new file mode 100644 index 00000000..aaa85bc7 --- /dev/null +++ b/DownUnderCTF 2023/beginner/confusing/confusing.c @@ -0,0 +1,32 @@ +#include +#include +#include + +void init() { + setvbuf(stdout, 0, 2, 0); + setvbuf(stdin, 0, 2, 0); +} + +int main() { + init(); + + short d; + double f; + char s[4]; + int z; + + printf("Give me d: "); + scanf("%lf", &d); + + printf("Give me s: "); + scanf("%d", &s); + + printf("Give me f: "); + scanf("%8s", &f); + + if(z == -1 && d == 13337 && f == 1.6180339887 && strncmp(s, "FLAG", 4) == 0) { + system("/bin/sh"); + } else { + puts("Still confused?"); + } +} diff --git a/DownUnderCTF 2023/beginner/confusing/confusing.py b/DownUnderCTF 2023/beginner/confusing/confusing.py new file mode 100644 index 00000000..f9eb0bde --- /dev/null +++ b/DownUnderCTF 2023/beginner/confusing/confusing.py @@ -0,0 +1,35 @@ +from pwn import * +import os + +os.environ["PWNLIB_DEBUG"] = "1" + +gs = ''' +unset env LINES +unset env COLUMNS +set follow-fork-mode child +# br *main+78 # first scanf +br *main+160 +br *main+170 +br *main+220 +c +''' + +elf = ELF(os.getcwd()+"/confusing") + +def start(): + if args.GDB: + return gdb.debug(elf.path, gs) + if args.REMOTE: + return remote("2023.ductf.dev", 30024) + else: + return process(elf.path) + +while True: + io = start() + print(io.recvuntil(b"Give me d: ")) + io.sendline(b"7") + print(io.recvuntil(b"Give me s: ")) + io.sendline(b"FLAG")# + b"\xff"*4) + print(io.recvuntil(b"Give me f: ")) + io.sendline(b"2") + io.interactive() \ No newline at end of file diff --git a/DownUnderCTF 2023/beginner/xxd-server/xxd_server/.htaccess b/DownUnderCTF 2023/beginner/xxd-server/xxd_server/.htaccess new file mode 100755 index 00000000..459c8c84 --- /dev/null +++ b/DownUnderCTF 2023/beginner/xxd-server/xxd_server/.htaccess @@ -0,0 +1,4 @@ +# Everything not a PHP file, should be served as text/plain + + ForceType text/plain + \ No newline at end of file diff --git a/DownUnderCTF 2023/beginner/xxd-server/xxd_server/Dockerfile b/DownUnderCTF 2023/beginner/xxd-server/xxd_server/Dockerfile new file mode 100755 index 00000000..6a7e5509 --- /dev/null +++ b/DownUnderCTF 2023/beginner/xxd-server/xxd_server/Dockerfile @@ -0,0 +1,6 @@ +FROM php:8.1-apache + +COPY index.php .htaccess /var/www/html/ +COPY flag / +RUN sed -i 's/AllowOverride None/AllowOverride All/g' /etc/apache2/apache2.conf +RUN mkdir -p /var/www/html/uploads && chmod 1333 /var/www/html/uploads diff --git a/DownUnderCTF 2023/beginner/xxd-server/xxd_server/index.php b/DownUnderCTF 2023/beginner/xxd-server/xxd_server/index.php new file mode 100755 index 00000000..903a54b6 --- /dev/null +++ b/DownUnderCTF 2023/beginner/xxd-server/xxd_server/index.php @@ -0,0 +1,110 @@ + '~' ? '.' : $c; + } + $out .= sprintf("%08x: %-40s %-16s\n", $ctr, $hex_string, $ascii_string); + $ctr += 16; + } + return $out; +} + +$message = ''; + +// Is there an upload? +if (isset($_FILES['file-upload'])) { + $upload_dir = 'uploads/' . bin2hex(random_bytes(8)); + $upload_path = $upload_dir . '/' . basename($_FILES['file-upload']['name']); + mkdir($upload_dir); + $upload_contents = xxd(file_get_contents($_FILES['file-upload']['tmp_name'])); + if (file_put_contents($upload_path, $upload_contents)) { + $message = 'Your file has been uploaded. Click here to view'; + } else { + $message = 'File upload failed.'; + } +} + +?> + + + + xxd-server + + + +
+

xxd-server

+

Our patented hex technology™ allows you to view the binary data of any file. Try it here!

+
+ + +
+ +
+ ' . $message . '

' : ''; ?> +
+ + + + + diff --git a/DownUnderCTF 2023/web/actually-proxed/actually-proxed/Dockerfile b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/Dockerfile new file mode 100644 index 00000000..387f7b84 --- /dev/null +++ b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/Dockerfile @@ -0,0 +1,11 @@ +FROM golang:1.20-alpine3.17 + +WORKDIR /app + +COPY . ./ + +RUN go build -o out/ ./... +USER 1000:1000 +EXPOSE 8080 + +ENTRYPOINT [ "./docker-entrypoint.sh" ] diff --git a/DownUnderCTF 2023/web/actually-proxed/actually-proxed/cmd/proxy/main.go b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/cmd/proxy/main.go new file mode 100644 index 00000000..ef4e646e --- /dev/null +++ b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/cmd/proxy/main.go @@ -0,0 +1,131 @@ +package main + +import ( + "bufio" + "bytes" + "flag" + "fmt" + "io" + "log" + "net" + "net/http" + "net/url" + "strings" +) + +func main() { + targetUrlFlag := flag.String("target", "http://localhost:8081", "Target URL") + port := flag.Int("port", 8080, "The port to listen on") + flag.Parse() + + targetUrl, err := url.Parse(*targetUrlFlag) + if err != nil { + log.Fatalf("Error parsing target URL: %s", err) + } + + ln, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) + log.Printf("Listening on port %d\n", *port) + if err != nil { + log.Fatalf("Error listening: %s", err) + } + defer ln.Close() + + for { + conn, err := ln.Accept() + if err != nil { + log.Printf("Error accepting connection: %s", err) + continue + } + + go func() { + defer conn.Close() + + scanner := bufio.NewScanner(conn) + var rawRequest bytes.Buffer + for scanner.Scan() { + line := scanner.Text() + if line == "" { + break + } + fmt.Fprintf(&rawRequest, "%s\r\n", line) + } + if err := scanner.Err(); err != nil { + log.Printf("Error reading request: %s", err) + return + } + + clientIP := strings.Split(conn.RemoteAddr().String(), ":")[0] + + request, err := parseRequest(rawRequest.Bytes(), clientIP, targetUrl.Host) + if err != nil { + log.Printf("Error parsing request: %s", err) + return + } + + client := http.Client{} + resp, err := client.Do(request) + if err != nil { + log.Printf("Error proxying request: %s", err) + return + } + defer resp.Body.Close() + + // Write the response to the connection + writer := bufio.NewWriter(conn) + resp.Write(writer) + writer.Flush() + }() + } +} + +func parseRequest(raw []byte, clientIP, targetHost string) (*http.Request, error) { + var method, path, version string + headers := make([][]string, 0) + reader := bytes.NewReader(raw) + scanner := bufio.NewScanner(reader) + scanner.Scan() + fmt.Sscanf(scanner.Text(), "%s %s %s", &method, &path, &version) + + for scanner.Scan() { + line := scanner.Text() + if line == "" { + break + } + parts := strings.SplitN(line, ":", 2) + if len(parts) == 2 { + headers = append(headers, []string{strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])}) + } + } + + for i, v := range headers { + if strings.ToLower(v[0]) == "x-forwarded-for" { + headers[i][1] = fmt.Sprintf("%s, %s", v[1], clientIP) + break + } + } + + headerMap := make(map[string][]string) + for _, v := range headers { + value := headerMap[v[0]] + + if value != nil { + value = append(value, v[1]) + } else { + value = []string{v[1]} + } + + headerMap[v[0]] = value + } + + request := &http.Request{ + Method: method, + URL: &url.URL{Scheme: "http", Host: targetHost, Path: path}, + Proto: version, + ProtoMajor: 1, + ProtoMinor: 1, + Header: headerMap, + Body: io.NopCloser(reader), + ContentLength: int64(reader.Len()), + } + return request, nil +} diff --git a/DownUnderCTF 2023/web/actually-proxed/actually-proxed/cmd/secret_server/main.go b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/cmd/secret_server/main.go new file mode 100644 index 00000000..3d37ec4b --- /dev/null +++ b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/cmd/secret_server/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" + "os" + "strings" +) + +var ( + port = flag.Int("port", 8081, "port to listen on") +) + +func main() { + + flag.Parse() + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + xff := r.Header.Values("X-Forwarded-For") + + ip := strings.Split(r.RemoteAddr, ":")[0] + + if xff != nil { + ips := strings.Split(xff[len(xff)-1], ", ") + ip = ips[len(ips)-1] + ip = strings.TrimSpace(ip) + } + + // 1337 hax0rz 0nly! + if ip != "31.33.33.7" { + message := fmt.Sprintf("untrusted IP: %s", ip) + http.Error(w, message, http.StatusForbidden) + return + } else { + w.Write([]byte(os.Getenv("FLAG"))) + } + }) + + log.Printf("Listening on port %d", *port) + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)) +} diff --git a/DownUnderCTF 2023/web/actually-proxed/actually-proxed/docker-entrypoint.sh b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/docker-entrypoint.sh new file mode 100755 index 00000000..dc5e905c --- /dev/null +++ b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/docker-entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# https://docs.docker.com/config/containers/multi-service_container/ + +cd /app/out + +# Start the proxy +./proxy & + +# Start the web server +./secret_server & + +# Wait for any process to exit +wait -n + +# Exit with status of process that exited first +exit $? diff --git a/DownUnderCTF 2023/web/actually-proxed/actually-proxed/go.mod b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/go.mod new file mode 100644 index 00000000..1f3029fe --- /dev/null +++ b/DownUnderCTF 2023/web/actually-proxed/actually-proxed/go.mod @@ -0,0 +1,3 @@ +module github.com/DownUnderCTF/actually-proxed + +go 1.20