Flask 在debug模式下会生成PIN码
1 | root@zo1ro-ubuntu:/var/www/html/flask# python app.py |
通过PIN 码,我们可以在报错页面执行任意python代码
问题就出在了这个pin码的生成机制上,在同一台机子上多次启动同一个Flask应用时,会发现这个pin码是固定的。是由一些固定的值生成的,不如直接来看看Flask源码中是怎么写的
测试环境为:
· Ubuntu 16.04
· python 2.7
· Flask 0.10.1
主函数
1 | # -*- coding: utf-8 -*- |
Pycharm下debug断点
run 函数跟进show_server_banner
跟进run_simple
跟进DebuggedApplication
发现pin_security ,pin_logging 两个参数
直接搜索pin参数发现get_pin_and_cookie_name函数
应该就是PIN码生成的函数
1 | def get_pin_and_cookie_name(app): |
Debug后发现return的rv变量就是生成的pin码
可以看到
username就是启动这个Flask的用户
modname为flask.app
getattr(app, ‘name‘, getattr(app.class, ‘name‘))为Flask
getattr(mod, ‘file‘, None)为flask目录下的一个app.py的绝对路径
uuid.getnode()就是当前电脑的MAC地址,str(uuid.getnode())则是mac地址的十进制表达式
get_machine_id()不妨跟进去看一下
1 | def get_machine_id(): |
首先尝试读取/etc/machine-id或者 /proc/sys/kernel/random/boot_i中的值,若有就直接返回
假如是在win平台下读取不到上面两个文件,就去获取注册表中SOFTWARE\Microsoft\Cryptography的值,并返回
这里就是etc/machine-id文件下的值
这样,当这6个值我们可以获取到时,就可以推算出生成的PIN码,引发任意代码执行
Username——》root
Modname——》flask.app
getattr(app, ‘name‘, getattr(app.class, ‘name‘))——》Flask
getattr(mod, ‘file‘, None)——》/usr/local/lib/python2.7/dist-packages/flask/app.pyc
(通过debug下发现的启动位置信息)
(这里有个坑,python在运行一次文件以后会将运行内存信息存储到一个pyc文件中,在下次调用程序的时候直接调用pyc文件以加快调试速度)
str(uuid.getnode())——》52230783609
(sys/class/net/eth0/address)网卡信息位置,一般为eth0,我的虚拟机下为ens33
get_machine_id()——》340ae5fcfaaa41f69f10045a4417e24d
计算出PIN
251-181-066
调试,成功进入debug
撒花~~
附源码
1 | #!/usr/bin/env python |
参考链接