CTFs and solutions

This commit is contained in:
emln
2025-04-27 19:24:27 +02:00
commit aa0fe54b3b
426 changed files with 2756 additions and 0 deletions

71
back-to-the-future/2 Normal file
View File

@ -0,0 +1,71 @@
#!/usr/bin/env python3
from Cryptodome.Cipher import ChaCha20
from Cryptodome.Random import get_random_bytes
from Cryptodome.Util.number import long_to_bytes, bytes_to_long
import time
from random import randint
from pwn import *
import base64
import requests
import time
from requests.utils import cookiejar_from_dict
LOGIN ="http://130.192.5.212:6522/login"
FLAG = "http://130.192.5.212:6522/flag"
username='aa'
admin=0
expire_date=int(time.time()) + 30 * 24 * 60 * 60
cookie = f"username={username}&expires={expire_date}&admin={admin}"
print(f"Cookie len:{len(cookie.encode())}")
LOGIN="http://127.0.0.1:5000/login"
FLAG="http://127.0.0.1:5000/flag"
# expire = 1.748.345.396
PARAMS = {"username":'aa','admin':1}
s = requests.Session()
r = s.get(url=LOGIN,params=PARAMS)
cookie= r.json()['cookie']
print(f"Cookie encrypted len:{len(long_to_bytes(cookie))}")
#sleep(1000)
nonce = r.json()['nonce']
cookie = bytearray(long_to_bytes(cookie))
for i in range(1,256):
cookie[-1]= cookie[-1] ^ i
COOKIES = {'cookie':bytes_to_long(cookie), 'nonce': nonce}
f = s.get(url=FLAG,params=COOKIES)
print(f.text)
"""if(f.text == "You have expired!"):
print(f"Guessed byte:{i}")
cookie[20] = 2 ^ i
COOKIES['cookie'] = bytes_to_long(cookie)
f = s.get(url=FLAG,params=COOKIES)
print(f.text)"""
#break
"""decCookie = cipher.decrypt(encCookie)
print(decCookie)
sleep(10000)
r = s.get(url=LOGIN,params=PARAMS)
for cookie in s.cookies:
print(cookie)
keyEncoded = cookie.value
key = base64.urlsafe_b64decode(keyEncoded+'=')
print(f"LEN:{len(key)}")
LOG_PARAMS = {"username":'aaaaaaaaa','admin':1}
r = s.get(url=LOGIN,params=LOG_PARAMS)
print(f"login:{r.json()}")
cookie=long_to_bytes(r.json()['cookie'])
nonce=long_to_bytes(r.json()['nonce'])
print(f"Nonce:{bytes_to_long(nonce)}")
cipher = ChaCha20.new(key=key, nonce=nonce)
decrypt=cipher.decrypt(cookie)
print(len(decrypt))
sleep(1000)
nonce = bytes_to_long(nonce)
cookie = bytes_to_long(cipher.encrypt(testCookie.encode()))
PARAMS = {'cookie':cookie, 'nonce':nonce }
f = s.get(url=FLAG, params=PARAMS)
print(f.text)"""

Binary file not shown.

View File

@ -0,0 +1,50 @@
#!/usr/bin/env python3
from Cryptodome.Cipher import ChaCha20
from Cryptodome.Random import get_random_bytes
from Cryptodome.Util.number import long_to_bytes, bytes_to_long
import time
from random import randint
from pwn import *
import base64
import requests
import time
from requests.utils import cookiejar_from_dict
LOGIN ="http://130.192.5.212:6522/login"
FLAG = "http://130.192.5.212:6522/flag"
#LOGIN="http://127.0.0.1:5000/login"
#FLAG="http://127.0.0.1:5000/flag"
# expire = 1.748.345.396
PARAMS = {"username":'aa','admin':1}
givenTime = int(time.time())
minAdminDate = givenTime - 10 * 24 * 60 * 60
maxAdminDate = givenTime - 259 * 24 * 60 * 60
avgAdminDate = int((minAdminDate + maxAdminDate)/2)
expire_date = givenTime + 30 * 24 * 60 * 60
eMin = expire_date - minAdminDate
eMax = expire_date - maxAdminDate
eAvg = (eMin+eMax) / 2
plaintext = f"username={PARAMS['username']}&expires={expire_date}&admin={PARAMS['admin']}"
plaintext = plaintext.encode()
s = requests.Session()
r = s.get(url=LOGIN,params=PARAMS)
cookie= r.json()['cookie']
cookie = long_to_bytes(cookie)
print(f"Cookie encrypted len:{len(cookie)}, Plaintext len:{len(plaintext)}")
nonce = r.json()['nonce']
ks = bytes([c ^ p for c,p in zip(cookie, plaintext)])
print(f"Keystream len:{len(ks)}")
for i in range(1):
payload = f"username={PARAMS['username']}&expires={maxAdminDate + 295 * 24 * 60 * 60}&admin={1}".encode()
cookie = bytes([p ^ k for p,k in zip(payload,ks)])
print(f"Malicious cookie len:{len(cookie)}")
COOKIES = {'cookie':bytes_to_long(cookie),'nonce':nonce}
f = s.get(url=FLAG,params=COOKIES)
print(f.text)
##########

View File

@ -0,0 +1,99 @@
from Crypto.Cipher import ChaCha20
from Crypto.Random import get_random_bytes
from Crypto.Util.number import long_to_bytes, bytes_to_long
import time
from random import randint
#from secret import flag
from flask import Flask, session, jsonify, request
from flask_session import Session
import sys
flag="PuppaFlag"
app = Flask(__name__)
app.secret_key = get_random_bytes(16).hex()
app.config['SESSION_TYPE'] = 'filesystem'
sess = Session()
sess.init_app(app)
def make_cipher():
key = get_random_bytes(32)
nonce = get_random_bytes(12)
cipher = ChaCha20.new(key=key, nonce=nonce)
return nonce, key, cipher
def sanitize_field(field: str):
return field \
.replace(" ", "_") \
.replace("/", "_") \
.replace("&", "") \
.replace(":", "") \
.replace(";", "") \
.replace("<", "") \
.replace(">", "") \
.replace('"', "") \
.replace("'", "") \
.replace("(", "") \
.replace(")", "") \
.replace("[", "") \
.replace("]", "") \
.replace("{", "") \
.replace("}", "") \
.replace("=", "")
def parse_cookie(cookie: str) -> dict:
parsed = {}
for field in cookie.split("&"):
key, value = field.split("=")
key = sanitize_field(key)
value = sanitize_field(value)
parsed[key] = value
return parsed
@app.route("/login", methods=["GET"])
def login():
username = request.args.get("username")
admin = int(request.args.get("admin"))
nonce, key, cipher = make_cipher()
session['key'] = key
username = sanitize_field(username)
if admin != 1:
admin = 0
else:
#MAX = 22.377.600
#MIN = 864.000
session['admin_expire_date'] = int(time.time()) - randint(10, 259) * 24 * 60 * 60
#ADD = 2.592.000
expire_date = int(time.time()) + 30 * 24 * 60 * 60
cookie = f"username={username}&expires={expire_date}&admin={admin}"
return jsonify({
"nonce": bytes_to_long(nonce),
"cookie": bytes_to_long(cipher.encrypt(cookie.encode()))
})
@app.route("/flag", methods=["GET"])
def get_flag():
nonce = int(request.args.get("nonce"))
cookie = int(request.args.get("cookie"))
cipher = ChaCha20.new(nonce=long_to_bytes(nonce), key=session['key'])
try:
dec_cookie = cipher.decrypt(long_to_bytes(cookie)).decode()
token = parse_cookie(dec_cookie)
if int(token["admin"]) != 1:
return f"Admin value:{token['admin']}"
#25.056.000 < value < 25.920.000
#
if 290 * 24 * 60 * 60 < abs(int(token["expires"]) - session['admin_expire_date']) < 300 * 24 * 60 * 60:
return f"OK! Your flag: {flag}"
else:
return f"You have expired! with expiration: {token['expires']} and {session['admin_expire_date']}"
except:
return f"Something didn't work :C"

158
back-to-the-future/des.py Normal file
View File

@ -0,0 +1,158 @@
#!/usr/bin/env python3
# encoding: utf-8
"""
Flask session cookie toolkit.
Decode, verify or generate a signed Flask session cookie.
Credits to Terry Vogelsang for the original script (https://terryvogelsang.tech/MITRECTF2018-my-flask-app/)
which I just slightly modified for my personal use.
"""
from hashlib import sha512
from flask.sessions import session_json_serializer
from itsdangerous import URLSafeTimedSerializer, BadTimeSignature
import argparse
import base64
from zlib import decompress
import sys
import json
# GENERAL FUNCTIONS.
def debug(msg):
if VERBOSE_OUTPUT:
print("[DEBUG] " + msg)
def pretty_print_json_data(json_data):
json_pretty_str = json.dumps(json_data, indent=4)
print(json_pretty_str)
# COOKIE DECODER.
def decode_cookie_payload(cookie):
debug(f"Cookie:\n{cookie}")
# If the cookie starts with a dot the paylod is base64 encoded and GZIP compressed.
if cookie[0] == ".":
b64_gzip_payload = cookie[1:].split(".")[0]
# Python needs the padding which is stripped in the base64_URLsafe version (see https://stackoverflow.com/questions/2941995/python-ignore-incorrect-padding-error-when-base64-decoding#comment12174484_2942039)
b64_gzip_payload += "=" * (-len(b64_gzip_payload) % 4)
debug(f"Encoded and compressed payload:\n{b64_gzip_payload}")
gzip_payload = base64.urlsafe_b64decode(b64_gzip_payload)
payload = decompress(gzip_payload)
debug(f"Decoded and decompressed payload:\n{payload}")
else:
# If the cookie does not start with a dot the payload is just base64 encoded.
b64_payload = cookie.split(".")[0]
# Python needs the padding which is stripped in the base64_URLsafe version (see https://stackoverflow.com/questions/2941995/python-ignore-incorrect-padding-error-when-base64-decoding#comment12174484_2942039)
b64_payload += "=" * (-len(b64_payload) % 4)
debug(f"Encoded payload:\n{b64_payload}")
payload = base64.urlsafe_b64decode(b64_payload)
debug(f"Decoded payload:\n{payload}")
return payload
def output_decoded_payload(payload, json_pretty, str_encoding):
str_payload = payload.decode(str_encoding)
if json_pretty:
# Pretty print the JSON data.
try:
debug(f"Payload string (encoding=\"{str_encoding}\"):\n{str_payload}")
pretty_print_json_data(json.loads(str_payload))
except:
print("The payload is not valid JSON!", file=sys.stderr)
sys.exit(1)
else:
# Do not pretty print the JSON data.
print(str_payload)
sys.exit(0)
# COOKIE VERIFIER.
def readAndVerifyCookie(cookie, secret_key):
debug(f"Cookie:\n{cookie}")
signer = URLSafeTimedSerializer(
secret_key, salt="cookie-session",
serializer=session_json_serializer,
signer_kwargs={"key_derivation": "hmac", "digest_method": sha512}
)
try:
session_data = signer.loads(cookie)
print("The signature is correct!")
return session_data
except BadTimeSignature:
print(f"The signature is not correct!")
sys.exit(1)
# COOKIE GENERATOR.
def generate_cookie(json_str_payload, key):
try:
payload = json.loads(json_str_payload)
except:
print("Your payload is not a valid JSON string!")
sys.exit(1)
signer = URLSafeTimedSerializer(
key, salt="cookie-session",
serializer=session_json_serializer,
signer_kwargs={"key_derivation": "hmac", "digest_method": sha512}
)
cookie = signer.dumps(payload)
return cookie
# MAIN.
if __name__ == "__main__":
# Argparse setup.
argparser = argparse.ArgumentParser(description="Pefroma various actions regarding a Flask session COOKIE.")
argparser.add_argument("command", metavar="COMMAND", choices=["decode", "verify", "generate"], help="the command to execute")
argparser.add_argument("-c", "--cookie", metavar="COOKIE", help="the COOKIE to decode or verify")
argparser.add_argument("-k", "--key", metavar="SECRET_KEY", help="the SECRET_KEY to sign or verify the cookie with")
argparser.add_argument("-p", "--payload", metavar="PAYLOAD", help="the PAYLOAD to encode in teh cookie")
argparser.add_argument("-v", "--verbose", action="store_true", help="enable verbose output")
argparser.add_argument("--pretty-json", action="store_true", help="whether to pretty print the JSON data")
argparser.add_argument("--encoding", default="UTF-8", help="the ENCODING to use when parsing data as a string")
# Parse arguments.
args = argparser.parse_args()
command = args.command
VERBOSE_OUTPUT = args.verbose
# Choose command.
if command == "decode":
# Check arguments.
if args.cookie is None:
argparser.error("The 'decode' command requires the --cookie argument.")
cookie = args.cookie
json_pretty = args.pretty_json
str_encoding = args.encoding
# Decode.
payload = decode_cookie_payload(cookie)
# Output.
output_decoded_payload(payload, json_pretty, str_encoding)
elif command == "verify":
# Check arguments.
if args.cookie is None or args.key is None:
argparser.error("The 'verify' command requires both the --cookie and the --key arguments.")
cookie = args.cookie
key = args.key
pretty_json = args.pretty_json
# Verify.
session_data = readAndVerifyCookie(cookie, key)
# Output.
print('')
if pretty_json:
debug(f"Session data:\n{session_data}")
pretty_print_json_data(session_data)
else:
print(json.dumps(session_data))
elif command == "generate":
# Check arguments.
if args.payload is None or args.key is None:
argparser.error("The 'generate' command requires both the --payload and the --key arguments.")
payload = args.payload
key = args.key
# Generate.
cookie = generate_cookie(payload, key)
# Output.
print(cookie)

Some files were not shown because too many files have changed in this diff Show More