Tags: bit-flipping-attack 

Rating: 4.0

# ▼▼▼Secure Logon - Points: 500▼▼▼
**This writeup is written by [@kazkiti_ctf](https://twitter.com/kazkiti_ctf)**

```
Uh oh, the login page is more secure... I think. http://2018shell2.picoctf.com:56265
Source(https://2018shell2.picoctf.com/static/a39b448f70e7523eb03516bb9c211c1a/server_noflag.py).
```

Hint:There are versions of AES that really aren't secure.

---

## 【Understanding of functions】

Login with id=`test_id`&password=`test_pass`

The following is displayed

`Cookie: {'admin': 0, 'password': 'test_pass', 'username': 'test_id'}`

I should do it to admin: `1`

---

## 【View source code & Identify the vulnerability】

source

```
from flask import Flask, render_template, request, url_for, redirect, make_response, flash
import json
from hashlib import md5
from base64 import b64decode
from base64 import b64encode
from Crypto import Random
from Crypto.Cipher import AES

app = Flask(__name__)
app.secret_key = 'seed removed'
flag_value = 'flag removed'

BLOCK_SIZE = 16 # Bytes
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

@app.route("/")
def main():
return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.form['user'] == 'admin':
message = "I'm sorry the admin password is super secure. You're not getting in that way."
category = 'danger'
flash(message, category)
return render_template('index.html')
resp = make_response(redirect("/flag"))

cookie = {}
cookie['password'] = request.form['password']
cookie['username'] = request.form['user']
cookie['admin'] = 0
print(cookie)
cookie_data = json.dumps(cookie, sort_keys=True)
encrypted = AESCipher(app.secret_key).encrypt(cookie_data)
print(encrypted)
resp.set_cookie('cookie', encrypted)
return resp

@app.route('/logout')
def logout():
resp = make_response(redirect("/"))
resp.set_cookie('cookie', '', expires=0)
return resp

@app.route('/flag', methods=['GET'])
def flag():
try:
encrypted = request.cookies['cookie']
except KeyError:
flash("Error: Please log-in again.")
return redirect(url_for('main'))
data = AESCipher(app.secret_key).decrypt(encrypted)
data = json.loads(data)

try:
check = data['admin']
except KeyError:
check = 0
if check == 1:
return render_template('flag.html', value=flag_value)
flash("Success: You logged in! Not sure you'll be able to see the flag though.", "success")
return render_template('not-flag.html', cookie=data)

class AESCipher:
"""
Usage:
c = AESCipher('password').encrypt('message')
m = AESCipher('password').decrypt(c)
Tested under Python 3 and PyCrypto 2.6.1.
"""

def __init__(self, key):
self.key = md5(key.encode('utf8')).hexdigest()

def encrypt(self, raw):
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return b64encode(iv + cipher.encrypt(raw))

def decrypt(self, enc):
enc = b64decode(enc)
iv = enc[:16]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:])).decode('utf8')

if __name__ == "__main__":
app.run()
```

BLOCK_SIZE = 16 # Bytes

The data in the JSON format displayed after logging in shows that the cookie is encrypted with `AES-CBC`

There is a vulnerability of `Bit-flipping attack`

---

## 【Bit-flipping attack against AES-CBC】

Login with `user=&password=`

display `Cookie: {'admin': 0, 'password': '', 'username': ''}`

and

cookie= `Ftj1cxomO+7uA+9LknJgDG5MsSeuJAiiudLTwLG2AwOzVWPkuqrJsazTpvRPNjbHGSlTvI4QqkBM4Snbj8JAIA==`

↓ base64 decode & ASCII hex encode

`16d8f5731a263beeee03ef4b9272600c6e4cb127ae2408a2b9d2d3c0b1b60303b35563e4baaac9b1acd3a6f44f3636c7192953bc8e10aa404ce129db8fc24020`

I used BurpSuite Intruder

![](https://raw.githubusercontent.com/kazkiti/CTF-image/master/picoctf_Intruder1.png)

![](https://raw.githubusercontent.com/kazkiti/CTF-image/master/picoctf_Intruder4.png)

↓ Start Attack

![](https://raw.githubusercontent.com/kazkiti/CTF-image/master/picoctf_Intruder3.png)

`picoCTF{fl1p_4ll_th3_bit3_2efa4bf8}`