网页读取器

1.介绍

1.1python代码审计

1.2ssrf白名单绕过

2.步骤

2.1下载附件进行python代码审计

from flask import Flask, render_template, request, send_from_directory
import requests  # well, requests is designed for humans, and I like it.


app = Flask(__name__)
whitelist_hostname = ["example.com",
                     "www.example.com"]
whitelist_scheme = ["http://"]


def check_hostname(url):
    for i in whitelist_scheme:
        if url.startswith(i):
            url = url[len(i):]  # strip scheme
            url = url[url.find("@") + 1:]  # strip userinfo
            if not url.find("/") == -1:
                url = url[:url.find("/")]  # strip parts after authority
            if not url.find(":") == -1:
                url = url[:url.find(":")]  # strip port
            if url not in whitelist_hostname:
                return (False, "hostname {} not in whitelist".format(url))
            return (True, "ok")
    return (False, "scheme not in whitelist, only {} allowed".format(whitelist_scheme))
##
for “遍历循环” 从变量结构中逐一提取元素,放到循环变量中。

startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False。如果参数 beg 和 end 指定值,则在指定范围内检查。
len() 方法返回列表元素个数。

find() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,如果包含子字符串返回开始的索引值,否则返回-1。

python分片方法 str[i:j] 返回i-j的字符串
##


@app.route("/")
def index():
    return render_template("index.html")


@app.route("/request")
def req_route():
    url = request.args.get('url')
    status, msg = check_hostname(url)
    if status is False:
        # print(msg)
        return msg
    try:
        r = requests.get(url, timeout=2)
        if not r.status_code == 200:
            return "We tried accessing your url, but it does not return HTTP 200. Instead, it returns {}.".format(r.status_code)
        return r.text
    except requests.Timeout:
        return "We tried our best, but it just timeout."
    except requests.RequestException:
        return "While accessing your url, an exception occurred. There may be a problem with your url."
##
当需要获取前端页面表单传过来的id值的时候,我们就需要用request.args.get
##

@app.route("/source")
def get_source():
    return send_from_directory("/static/", "app.py", as_attachment=True)


if __name__ == '__main__':
    app.run("0.0.0.0", 8080, debug=False) 

首先判断url是不是以http://开头然后从这个地方截断,取后面的内容。

再判断是不是有 @取后面的内容进行判断,那我们其实可以把想访问的东西写在这里。

http://127.0.0.1/flag@example.com 这样他截断后去访问的都是后面的东西,可以通过白名单。

但是现在url是无效的,我们需要把后面的用#注释掉

最终payload:

http://127.0.0.1/flag#@example.com

2.2传入pyload,得到flag。

 

3.借鉴

Python3 startswith()方法 | 菜鸟教程 (runoob.com)

Python List len()方法 | 菜鸟教程 (runoob.com)

(17条消息) request.args.get()用法_yk 坤帝-CSDN博客_request.args

 

 Python for 循环语句 | 菜鸟教程 (runoob.com)

Python find()方法 | 菜鸟教程 (runoob.com)

(17条消息) python的字符串分片_weixin_30477293的博客-CSDN博客

https://ce.pwnthebox.com/writeup?id=104

posted @ 2021-11-26 16:44  WeQi_Blog  阅读(64)  评论(0编辑  收藏  举报