

Victim machine : 10.0.2.6
Benign machine : 10.0.2.15






We can see the username and password in plain text
username : `guest`
password : `password`
CentOS restart

This is the attacker machine:





Once the attack is started



HTTP Packet is sent from benign to victim. We can see the credentials on the attacker machine.

While the ARP Posioning is not running, the MAC Addresses are different

While the ARP poisoning is running, both MAC addresses of victim and the malicious attacker machine are the same.
# 4

Created cert with password : `mssd`

`cert.pem` and `key.pem` are sent over using scp and saved in `/data/5`
Added the changed lines:
```python=
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain('cert.pem' , 'key.pem')
...
if __name__ == '__main__':
app.run(debug=False,host='0.0.0.0',port = 443, ssl_context = context, threaded = True)
```






Wireshark does not show the creds in plain text
# 5

Hash
```
QeweCH5vn4AimWd39XzI0wJY4VibhVkfik3cUiKH5jI=
```
The file is saved as : `server_hpkp.py`
```python
from flask import Flask, url_for, request, jsonify
from flask_secure_headers.core import Secure_Headers
from functools import wraps
import json
import ssl
import socket
import os
import ssl
if socket.gethostname() == "mssd-labs":
os.chdir("/data/5/")
sh = Secure_Headers()
sh.update(({'HPKP':{'pins':[{'sha256':'QeweCH5vn4AimWd39XzI0wJY4VibhVkfik3cUiKH5jI='}],'max-age': 2592000}})
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain('cert.pem' , 'key.pem')
app = Flask(__name__)
user=''
shadow={'admin':'l4sT_L4b', 'guest':'password'}
def check_auth(username, password):
if username in shadow and shadow[username]==password:
global user
user=username
return username
else:
return False
def authenticate():
message = {'message': "Authenticate."}
resp = jsonify(message)
resp.status_code = 401
resp.headers['WWW-Authenticate'] = 'Basic realm="Example"'
return resp
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth:
return authenticate()
user=check_auth(auth.username, auth.password)
if not user:
return authenticate()
return f(*args, **kwargs)
return decorated
mdb={}
@app.route('/messages')
@requires_auth
@sh.wrapper()
def api_messages():
if user in mdb:
return jsonify(messages=mdb[user])
else:
return jsonify(messages="")
@app.route('/message/<userid>', methods=['POST'])
@requires_auth
@sh.wrapper()
def api_message(userid):
if not userid in mdb:
mdb[userid]=[]
mdb[userid].append("From %s: %s"%(user,request.json['message']))
print ("Message received from user %s for user %s: %s"%(userid,user,request.json['message']))
return "Thank you for your message\n"
if __name__ == '__main__':
app.run(debug=False,host='0.0.0.0',port = 443, ssl_context = context, threaded = True)
```




With HPKP, we can see the public key
```
Public-Key-Pins
pin-sha256=QeweCH5vn4AimWd39XzI0wJY4VibhVkfik3cUiKH5jI=; includeSubDomains; report-uri=/hpkp_report; max-age=2592000
```
# 6
Editting for `sslify`. The file is saved as `server_sslify_HTTPS.py`:
```python
from flask import Flask, url_for, request, jsonify
from flask_secure_headers.core import Secure_Headers
from functools import wraps
import json
import ssl
import socket
import os
from flask_sslify import SSLify
if socket.gethostname() == "mssd-labs":
os.chdir("/data/5/")
sh = Secure_Headers()
app = Flask(__name__)
sslify = SSLify(app) # Just add this to redirect to https
user=''
shadow={'admin':'l4sT_L4b', 'guest':'password'}
def check_auth(username, password):
if username in shadow and shadow[username]==password:
global user
user=username
return username
else:
return False
def authenticate():
message = {'message': "Authenticate."}
resp = jsonify(message)
resp.status_code = 401
resp.headers['WWW-Authenticate'] = 'Basic realm="Example"'
return resp
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth:
return authenticate()
user=check_auth(auth.username, auth.password)
if not user:
return authenticate()
return f(*args, **kwargs)
return decorated
mdb={}
@app.route('/messages')
@requires_auth
def api_messages():
if user in mdb:
return jsonify(messages=mdb[user])
else:
return jsonify(messages="")
@app.route('/message/<userid>', methods=['POST'])
@requires_auth
def api_message(userid):
if not userid in mdb:
mdb[userid]=[]
mdb[userid].append("From %s: %s"%(user,request.json['message']))
print ("Message received from user %s for user %s: %s"%(userid,user,request.json['message']))
return "Thank you for your message\n"
if __name__ == '__main__':
app.run(debug=False,host='0.0.0.0',port=80)
```


Since flask-sslify is not installed, the following is run to install the package:
`pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org pip flask-sslify` This is done to circumvent the failing ssl certificate.

This is the commented hpkp server file (it's essentially the same as `server_https.py`)
```python=
from flask import Flask, url_for, request, jsonify
from flask_secure_headers.core import Secure_Headers
from functools import wraps
import json
import ssl
import socket
import os
import ssl
if socket.gethostname() == "mssd-labs":
os.chdir("/data/5/")
sh = Secure_Headers()
#sh.update({'HPKP':{'pins':[{'sha256':'QeweCH5vn4AimWd39XzI0wJY4VibhVkfik3cUiKH5jI='}],'max-age':2592000}})
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain('cert.pem' , 'key.pem')
app = Flask(__name__)
user=''
shadow={'admin':'l4sT_L4b', 'guest':'password'}
def check_auth(username, password):
if username in shadow and shadow[username]==password:
global user
user=username
return username
else:
return False
def authenticate():
message = {'message': "Authenticate."}
resp = jsonify(message)
resp.status_code = 401
resp.headers['WWW-Authenticate'] = 'Basic realm="Example"'
return resp
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth:
return authenticate()
user=check_auth(auth.username, auth.password)
if not user:
return authenticate()
return f(*args, **kwargs)
return decorated
mdb={}
@app.route('/messages')
@requires_auth
#@sh.wrapper()
def api_messages():
if user in mdb:
return jsonify(messages=mdb[user])
else:
return jsonify(messages="")
@app.route('/message/<userid>', methods=['POST'])
@requires_auth
#@sh.wrapper()
def api_message(userid):
if not userid in mdb:
mdb[userid]=[]
mdb[userid].append("From %s: %s"%(user,request.json['message']))
print ("Message received from user %s for user %s: %s"%(userid,user,request.json['message']))
return "Thank you for your message\n"
if __name__ == '__main__':
app.run(debug=False,host='0.0.0.0',port = 443, ssl_context = context, threaded = True)
```

Going for `http://10.0.2.6/messages`




# 6a
Executing MiTM Attack : ARP Poisoning + `sslstrip -a -l 8080`
Routing:
`iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080`





I can see victim (10.0.2.6) and sender (10.0.2.15) in wireshark, and also seeing port 80.
# 6b
After stopping the ARP Spoof:

```python
from flask import Flask, url_for, request, jsonify
from flask_secure_headers.core import Secure_Headers
from functools import wraps
import json
import ssl
import socket
import os
import ssl
if socket.gethostname() == "mssd-labs":
os.chdir("/data/5/")
sh = Secure_Headers()
sh.update({'HPKP':{'pins':[{'sha256':'QeweCH5vn4AimWd39XzI0wJY4VibhVkfik3cUiKH5jI='}],'max-age':2592000}})
sh.update({'HSTS':{'max-age': 2592000, 'includeSubDomains': True, 'preload': False}})
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain('cert.pem' , 'key.pem')
app = Flask(__name__)
user=''
shadow={'admin':'l4sT_L4b', 'guest':'password'}
def check_auth(username, password):
if username in shadow and shadow[username]==password:
global user
user=username
return username
else:
return False
def authenticate():
message = {'message': "Authenticate."}
resp = jsonify(message)
resp.status_code = 401
resp.headers['WWW-Authenticate'] = 'Basic realm="Example"'
return resp
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth:
return authenticate()
user=check_auth(auth.username, auth.password)
if not user:
return authenticate()
return f(*args, **kwargs)
return decorated
mdb={}
@app.route('/messages')
@requires_auth
@sh.wrapper()
def api_messages():
if user in mdb:
return jsonify(messages=mdb[user])
else:
return jsonify(messages="")
@app.route('/message/<userid>', methods=['POST'])
@requires_auth
@sh.wrapper()
def api_message(userid):
if not userid in mdb:
mdb[userid]=[]
mdb[userid].append("From %s: %s"%(user,request.json['message']))
print ("Message received from user %s for user %s: %s"%(userid,user,request.json['message']))
return "Thank you for your message\n"
if __name__ == '__main__':
app.run(debug=False,host='0.0.0.0',port = 443, ssl_context = context, threaded = True)
```
Create new cert and replaced the old one:

Benign

Attacker:

Running `wget --ca-certificate cert.pem --user guest --password password https://mssd-labs.com/messages`:


Content of `.wget-hsts`:

Turning on ARP Spoof:

Running `wget --ca-certificate cert.pem --user guest --password password https://mssd-labs.com/messages` again to observe in the wireshark:



We don't see any http traffic at all.