源码

#! /usr/bin/env python
# #encoding=utf-8
from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
reload(sys)
sys.setdefaultencoding('latin1')
 
app = Flask(__name__)
 
secert_key = os.urandom(16)
 
class Task:
    def __init__(self, action, param, sign, ip):
        self.action = action
        self.param = param
        self.sign = sign
        self.sandbox = md5(ip)
        if(not os.path.exists(self.sandbox)):
            os.mkdir(self.sandbox)
 
    def Exec(self):
        result = {}
        result['code'] = 500
        if (self.checkSign()):
            if "scan" in self.action:
                tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
                resp = scan(self.param)
                if (resp == "Connection Timeout"):
                    result['data'] = resp
                else:
                    print resp
                    tmpfile.write(resp)
                    tmpfile.close()
                result['code'] = 200
            if "read" in self.action:
                f = open("./%s/result.txt" % self.sandbox, 'r')
                result['code'] = 200
                result['data'] = f.read()
            if result['code'] == 500:
                result['data'] = "Action Error"
        else:
            result['code'] = 500
            result['msg'] = "Sign Error"
        return result
 
    def checkSign(self):
        if (getSign(self.action, self.param) == self.sign):
            return True
        else:
            return False
 
@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():
    param = urllib.unquote(request.args.get("param", ""))   #接收参数param
    action = "scan"
    return getSign(action, param)
 
@app.route('/De1ta',methods=['GET','POST'])
def challenge():
    action = urllib.unquote(request.cookies.get("action"))      #读取cookie值
    param = urllib.unquote(request.args.get("param", ""))       #读取GET值  
    sign = urllib.unquote(request.cookies.get("sign"))          #读取cookie值
    ip = request.remote_addr
    if(waf(param)):
        return "No Hacker!!!!"
    task = Task(action, param, sign, ip)        #实例化TASK
    return json.dumps(task.Exec())      #调用函数,以json格式输出
 
@app.route('/')
def index():
    return open("code.txt","r").read()
 
def scan(param):
    socket.setdefaulttimeout(1)
    try:
        return urllib.urlopen(param).read()[:50]
    except:
        return "Connection Timeout"
 
def getSign(action, param):
    return hashlib.md5(secert_key + param + action).hexdigest()     #把密钥与传入的param和action拼接经过md5加密后返回,注意运行代码后这里密钥是唯一的,因为没有再次生成新的,所以不用管secert_key。
 
def md5(content):
    return hashlib.md5(content).hexdigest()
 
def waf(param):
    check=param.strip().lower()     #删除首尾空格并且转换小写
    if check.startswith("gopher") or check.startswith("file"):      #字符串开头,把gopher和file协议禁用
        return True
    else:
        return False
if __name__ == '__main__':
    app.debug = False
    app.run(host='0.0.0.0',port=9999)

wp

flask框架,先找到三个路由

@app.route(“/geneSign”, methods=[‘GET’, ‘POST’])

输入/geneSign会执行下面的函数geneSign(),methods表示接收的方法是GET和POST,接收参数param,返回getSign()函数。

@app.route(‘/De1ta’,methods=[‘GET’,’POST’])

输入/De1ta会执行下面的函数challenge(),methods表示接收的方法是GET和POST,获取GET的param和cookie的actionsign,waf()过滤函数,实例化Task并调用方法Exec(),返回对象的json格式。

@app.route(‘/’)

返回源代码

首先看第二个路由,接收三个主要参数,并且waf()过滤了两个伪协议。接下来实例化类并调用Exec()函数。我们来看下Exec()。

if语句中调用了checkSign(),又调用了getSign(),

getSign():将刚开始生成的随机数与param和action拼接并生成md5返回。

如果getSign()的返回值与我们需要传入的cookie里的sign相等就返回true。

接下来有两个if语句

第一个,只需’scan’在action中,然后以写入方式打开result.txt,调用scan()读取param文件(param=flag.txt)的前50个字符,然后写入result.txt文件。

第二个,只需’read’在action中,然后读取result.txt内容返回作为result字典中data的值。

从代码中来看,如果未通过第二个if的read,则输出的resp如下(即未写入之前的result.txt,此时result字典里只有code的值)

因此我们也需要获取data里的内容,这里的两个if语句中都是使用了’in’来判断,而不是通过’=’来判断,因此如果action=readscan或者scanread的话,两个if语句都会被执行。这样既可以将flag.txt写入results.txt,又能读取写入后的results.txt内容。

接下来我们回到checkSign()函数,要让它返回true我们就要得到sign的值,sign我们可以通过geneSign()来获取。由于这里的action已经是scan,而我们想要的是action='readscan'或者'action=scanread',因此需要想办法让action是我们想要的值。由于getSign()函数是使用拼接的方式(secert_key + param + action)进行md5加密,因此我们可以使 param=flag.txtread,那么此时返回的是 secert_key+'flag.txtread'+'scan'的md5加密的密文。当我们使用路由De1ta时,只需要让param=’flag.txt’,sign为geneSign()返回后的值,action=’readscan’,这样checkSign()就能够返回true,成功执行接下来的两个if语句写入后读取获得flag。

获取sign

添加Cookie到请求包,添加sign以及action,最后获取flag。

原文地址:http://www.cnblogs.com/p0n9/p/16844204.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性