Skip to content

Commit

Permalink
cpa over http
Browse files Browse the repository at this point in the history
  • Loading branch information
zardus committed Sep 28, 2024
1 parent db8d761 commit 315ae72
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cryptography/cpa-http/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Okay, now we'll try that attack in a slightly more realistic scenario.
Can you remember your SQL to carry out the attack and recover the flag?

----
**HINT:**
Remember that you can make select return chosen plaintext by doing `SELECT 'my_plaintext'`!
62 changes: 62 additions & 0 deletions cryptography/cpa-http/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/opt/pwn.college/python

from base64 import b64encode, b64decode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes

import tempfile
import sqlite3
import random
import flask
import os

app = flask.Flask(__name__)

class TemporaryDB:
def __init__(self):
self.db_file = tempfile.NamedTemporaryFile("x", suffix=".db")

def execute(self, sql, parameters=()):
connection = sqlite3.connect(self.db_file.name)
connection.row_factory = sqlite3.Row
cursor = connection.cursor()
result = cursor.execute(sql, parameters)
connection.commit()
return result

key = get_random_bytes(16)
cipher = AES.new(key=key, mode=AES.MODE_ECB)

db = TemporaryDB()
# https://www.sqlite.org/lang_createtable.html
db.execute("""CREATE TABLE secrets AS SELECT ? AS flag""", [open("/flag").read()])

@app.route("/", methods=["GET"])
def challenge_get():
query = flask.request.args.get("query") or "'A'"

try:
sql = f'SELECT {query} FROM secrets'
print(f"DEBUG: {sql=}")
pt = db.execute(sql).fetchone()[0]
except sqlite3.Error as e:
flask.abort(500, f"Query: {query}\nError: {e}")
except TypeError:
# no records found
pt = "A"

ct = cipher.encrypt(pad(pt.encode(), cipher.block_size))

return f"""
<html><body>Welcome to pwn.secret!
<form>Query:<input type=text name=query value='{query}'><input type=submit value=Submit></form>
<hr>
<b>Query:</b> <pre>{sql}</pre><br>
<b>Results:</b><pre>{b64encode(ct).decode()}</pre>
</body></html>
"""

app.secret_key = os.urandom(8)
app.config['SERVER_NAME'] = f"challenge.localhost:80"
app.run("challenge.localhost", 80)
2 changes: 2 additions & 0 deletions cryptography/module.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ challenges:
name: AES
- id: cpa
name: Chosen-plaintext Attack
- id: cpa-http
name: CPA-over-HTTP
- id: level-5
name: level5
- id: level-6
Expand Down

0 comments on commit 315ae72

Please sign in to comment.