巡風源碼閱讀與分析---view.py

巡風xunfeng----巡風源碼閱讀與分析html

巡風是一款適用於企業內網的漏洞快速應急、巡航掃描系統,經過搜索功能可清晰的瞭解內部網絡資產分佈狀況,而且可指定漏洞插件對搜索結果進行快速漏洞檢測並輸出結果報表。python

 

環境:git

巡風是基於pythonflask框架寫的,數據庫爲mongodbgithub

可安裝在Windows  OSX  Linux  Dockerweb

Python2.7  pip  mongodbmongodb

安裝:數據庫

我安裝在window,用於簡單閱讀代碼和調試。json

https://github.com/ysrc/xunfeng  flask

下載後跟着官網的window安裝教程便可。網絡

而後運行 Run.bat (得使用管理員運行,否則沒反應。。)

 

 

安裝成功。

閱讀:

使用的idepycharm
Run.bat

 

 

mogod.exe 用於啓動mongodb

Run.py 啓動web網站

Aider.py  # 輔助驗證腳本

VulScan.py  # 漏洞檢測引擎

NAScan.py  # 網絡資產信息抓取引擎

 

 

Run.py

from views.View import app

if __name__ == '__main__':
    #app.debug = True
    app.run(threaded=True, port=8888,host='')

 

去到views/View.py

 

一共有24個方法。

一個方法一個方法來看。

 

1.Search()

# 搜索頁
@app.route('/filter')
@logincheck
def Search():
    return render_template('search.html')

  

@logincheck 使用了裝飾器函數。跟過去查看views/lib/Login.py

# 登陸狀態檢查
def logincheck(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        try:
            if session.has_key('login'):
                if session['login'] == 'loginsuccess':
                    return f(*args, **kwargs)
                else:
                    return redirect(url_for('Login'))
            else:
                return redirect(url_for('Login'))
        except Exception, e:
            print e
            return redirect(url_for('Error'))

    return wrapper

  

若是seesion中的login等於loginsuccess 就繼續執行view.py下的函數。不然跳轉掉Error模板。就是檢測是否有登陸。

 

回到Search() 加載search.html模板

 

 

2.Deleteall()

 

# 刪除全部
@app.route('/deleteall', methods=['post'])
@logincheck
@anticsrf
def Deleteall():
    Mongo.coll['Task'].remove({})
    return 'success'

  

 

先判斷了登陸狀態,多了一個@anticsrf 裝飾器函數。跟過去查看views/lib/AntiCSRF.py

# 檢查referer
def anticsrf(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        try:
            if request.referrer and request.referrer.replace('http://', '').split('/')[0] == request.host:
                return f(*args, **kwargs)
            else:
                return redirect(url_for('NotFound'))
        except Exception, e:
            print e
            return redirect(url_for('Error'))

    return wrapper

  

 

判斷是否有referrer頭,並且將http://替換成空 再分割取第一部分,也就是取出網站的host,而後與本站host相比較。看是否一致。不同的話,跳轉404頁面。不然就繼續執行。

@anticsrf 就是防止CSRF漏洞的。

 

回到Deleteall()

Mongo 跟過去發現是鏈接mongoDB。選擇Task這個數據表,移除全部數據。

就是將任務總數所有刪除。

 

 

 

3.Main()

# 搜索結果頁
@app.route('/')
@logincheck
def Main():
    q = request.args.get('q', '')
    page = int(request.args.get('page', '1'))
    plugin = Mongo.coll['Plugin'].find()  # 插件列表
    plugin_type = plugin.distinct('type')  # 插件類型列表
    if q:  # 基於搜索條件顯示結果
        result = q.strip().split(';')
        query = querylogic(result)
        cursor = Mongo.coll['Info'].find(query).sort('time', -1).limit(page_size).skip((page - 1) * page_size)
        return render_template('main.html', item=cursor, plugin=plugin, itemcount=cursor.count(),
                               plugin_type=plugin_type, query=q)
    else:  # 自定義,無任何結果,用戶手工添加
        return render_template('main.html', item=[], plugin=plugin, itemcount=0, plugin_type=plugin_type)

  

判斷是否登陸(下同)

先獲取傳入的q page

plugin = Mongo.coll['Plugin'].find()  #鏈接數據庫,列出Plugin中全部清單。

plugin_type = plugin.distinct('type') #從查詢的全部清單裏面獲取名字是 type的數據。

  

而後將q進行分割「;」主要是分割相似這種的 q= 127.0.0.1;127.8.8.1  

分紅列表傳入querylogic()函數。 跟過去看看views/lib/QueryLogic.py(詳細:http://www.javashuo.com/article/p-xzajjajg-es.html

將搜索的值q轉成mongoDB能查詢的語句。

cursor = Mongo.coll['Info'].find(query).sort('time', -1).limit(page_size).skip((page - 1) * page_size)

info表裏把條件代入查詢sort()排序 limit()分頁

最後傳給視圖

 

 

4.Getplugin()

# 獲取插件信息異步
@app.route('/getplugin', methods=['get', 'post'])
@logincheck
def Getplugin():
    type = request.form.get('type', '')
    risk = request.form.get('risk', '')
    search = request.form.get('search', '')
    query = {}
    if type:
        query['type'] = type
    if risk:
        query['level'] = risk
    if search:
        search = unquote(search)
        query['name'] = {"$regex": search, '$options': 'i'}
    cursor = Mongo.coll['Plugin'].find(query)
    rsp = []
    for i in cursor:
        result = {'name': i['name'], 'info': i['info']}
        rsp.append(result)
    return json.dumps(rsp)

  

 

獲取了type risk search 是否有值

沒有的話,就所有查詢。有的話 Plugin表代入條件查詢。而後將插件名字和信息轉json格式返回。

 

5.Addtask()

# 新增任務異步
@app.route('/addtask', methods=['get', 'post'])
@logincheck
@anticsrf
def Addtask():
    title = request.form.get('title', '')
    plugin = request.form.get('plugin', '')
    condition = unquote(request.form.get('condition', ''))
    plan = request.form.get('plan', 0)
    ids = request.form.get('ids', '')
    isupdate = request.form.get('isupdate', '0')
    resultcheck = request.form.get('resultcheck', '0')
    result = 'fail'
    if plugin:
        targets = []
        if resultcheck == 'true':  # 結果集全選
            list = condition.strip().split(';')
            query = querylogic(list)
            cursor = Mongo.coll['Info'].find(query)
            for i in cursor:
                tar = [i['ip'], i['port']]
                targets.append(tar)
        else:  # 當前頁結果選擇
            for i in ids.split(','):
                tar = [i.split(':')[0], int(i.split(':')[1])]
                targets.append(tar)
        temp_result = True
        for p in plugin.split(','):
            query = querylogic(condition.strip().split(';'))
            item = {'status': 0, 'title': title, 'plugin': p, 'condition': condition, 'time': datetime.now(),
                    'target': targets, 'plan': int(plan), 'isupdate': int(isupdate), 'query': dumps(query)}
            insert_reuslt = Mongo.coll['Task'].insert(item)
            if not insert_reuslt:
                temp_result = False
        if temp_result:
            result = 'success'
    return result

  

 

先獲取了頁面傳了的值 先默認resultfail

沒有plugin的話直接返回fail

有的話,先判斷結果集是否全選,將結果集的ipport都加入列表,不然將當前頁的ip將入列表。 而後執行插入。成功返回success

 

6.Task()

# 任務列表頁面
@app.route('/task')
@logincheck
def Task():
    page = int(request.args.get('page', '1'))
    cursor = Mongo.coll['Task'].find().sort('time', -1).limit(page_size).skip((page - 1) * page_size)
    return render_template('task.html', item=cursor)

查詢出任務信息,展現。

 

 

7.Recheck()

# 複測任務異步
@app.route('/taskrecheck')
@logincheck
@anticsrf
def Recheck():
    tid = request.args.get('taskid', '')
    task = Mongo.coll['Task'].find_one({'_id': ObjectId(tid)})
    result = 'fail'
    if task and task['plan'] == 0 and task['status'] == 2:  # 一次性任務,而且已經掃描完成
        result = Mongo.coll['Task'].update({'_id': ObjectId(tid)}, {'$set': {'status': 0}})
        if result:
            result = 'success'
    return result

  

找到任務後,判斷掃描完成後,更新數據庫。返回success

 

8.TaskDetail()

# 任務詳情頁面
@app.route('/taskdetail')
@logincheck
def TaskDetail():
    id = request.args.get('taskid', '')
    page = int(request.args.get('page', '1'))
    taskdate = request.args.get('taskdate', "")
    plugin_name = ''
    task_info = Mongo.coll['Task'].find_one({'_id': ObjectId(id)})
    if task_info:
        plugin_name = task_info['plugin']
    vulcount = 0
    lastscan = Mongo.coll["Result"].distinct('task_date', {'task_id': ObjectId(id)})
    result_list = []
    if len(lastscan) > 0:
        lastscan.sort(reverse=True)
        if taskdate:  # 根據掃描批次查看結果
            cursor = Mongo.coll['Result'].find(
                {'task_id': ObjectId(id), 'task_date': datetime.strptime(taskdate, "%Y-%m-%d %H:%M:%S.%f")}).sort(
                'time', -1).limit(page_size).skip((page - 1) * page_size)
        else:  # 查看最新批次結果
            taskdate = lastscan[0].strftime("%Y-%m-%d %H:%M:%S.%f")
            cursor = Mongo.coll['Result'].find(
                {'task_id': ObjectId(id), 'task_date': lastscan[0]}).sort('time', -1).limit(page_size).skip(
                (page - 1) * page_size)
        vulcount = cursor.count()
        for _ in cursor:
            result_list.append(
                {'ip': _['ip'], 'port': _['port'], 'info': _['info'], 'vul_level': _['vul_info']['vul_level'],
                 'time': _['time']})

        # 速度優化,數據量多采起不一樣的方式查詢
        if len(result_list) > 100:
            ip_hostname = {}
            hostname = Mongo.coll['Info'].aggregate(
                [{'$match': {'hostname': {'$ne': None}}}, {'$project': {'_id': 0, 'ip': 1, 'hostname': 1}}])
            for _ in hostname:
                if 'hostname' in hostname:
                    ip_hostname[_["ip"]] = _["hostname"]
            for _ in result_list:
                if 'ip' in ip_hostname:
                    _['hostname'] = ip_hostname[_["ip"]]
                else:
                    _['hostname'] = ''
        else:
            for _ in result_list:
                hostname = Mongo.coll['Info'].find_one({'ip': _['ip']})
                if hostname and 'hostname' in hostname:
                    _['hostname'] = hostname['hostname']
                else:
                    _['hostname'] = ''
    return render_template('detail.html', item=result_list, count=vulcount, id=id, taskdate=taskdate,
                           plugin_name=plugin_name, scanlist=lastscan)

 

  

經過id找到任務詳情,而後將詳情展現出來。有taskdate就是能夠查詢指定的日期。沒有這個參數就是查詢最新日期。當結果大於100,使用優化的查詢語句。

 

 

9.DeleteTask()

# 刪除任務異步
@app.route('/deletetask', methods=['get', 'post'])
@logincheck
@anticsrf
def DeleteTask():
    oid = request.form.get('oid', '')
    if oid:
        result = Mongo.coll['Task'].delete_one({'_id': ObjectId(oid)})
        if result.deleted_count > 0:
            result = Mongo.coll['Result'].delete_many({'task_id': ObjectId(oid)})
            if result:
                return 'success'
    return 'fail'

  

 

刪除任務操做

 

10.Downloadxls()

# 下載excel報表異步
@app.route('/downloadxls', methods=['get', 'post'])
@logincheck
@anticsrf
def DownloadXls():
    tid = request.args.get('taskid', '')
    taskdate = request.args.get('taskdate', '')
    result_list = []
    if tid:  # 有任務id
        if taskdate:  # 從任務中拉取指定批次掃描結果
            taskdate = datetime.strptime(taskdate, "%Y-%m-%d %H:%M:%S.%f")
            cursor = Mongo.coll['Result'].find({'task_id': ObjectId(tid), 'task_date': taskdate}).sort(
                'time', -1)
        else:  # 從任務中直接取該任務最新一次掃描結果
            lastscan = Mongo.coll["Result"].distinct('task_date', {'task_id': ObjectId(tid)})
            if len(lastscan) == 0:
                cursor = []
                taskdate = datetime.now()
            else:
                lastscan.sort(reverse=True)
                taskdate = lastscan[0]
                cursor = Mongo.coll['Result'].find({'task_id': ObjectId(tid), 'task_date': taskdate}).sort(
                    'time', -1)
        title = Mongo.coll['Task'].find_one({'_id': ObjectId(tid)})['title']
        for _ in cursor:
            hostname = ''
            result = Mongo.coll['Info'].find_one({'ip': _['ip']})
            if result and 'hostname' in result:
                hostname = result['hostname']
            result_list.append(
                {'ip': _['ip'], 'port': _['port'], 'info': _['info'], 'vul_level': _['vul_info']['vul_level'],
                 'time': _['time'], 'vul_name': _['vul_info']['vul_name'], 'lastscan': taskdate, 'title': title,
                 'hostname': hostname})
        response = make_response(CreateTable(result_list, taskdate.strftime("%Y%m%d-%H%M%S")))
        if taskdate == '':
            response.headers["Content-Disposition"] = "attachment; filename=nodata.xls;"
        else:
            response.headers["Content-Disposition"] = "attachment; filename=" + quote(
                title.encode('utf-8')) + taskdate.strftime(
                "%Y-%m-%d-%H-%M-%S") + ".xls;"
    else:  # 下載綜合報表
        tasks = Mongo.coll['Task'].find({})
        t_list = []
        for t in tasks:
            name = t['title']
            lastscan = Mongo.coll["Result"].distinct('task_date', {'task_id': t['_id']})
            if len(lastscan) == 0:
                cursor = Mongo.coll['Result'].find({'task_id': t['_id']})
                taskdate = None
            else:
                lastscan.sort(reverse=True)
                taskdate = lastscan[0]
                cursor = Mongo.coll['Result'].find({'task_id': t['_id'], 'task_date': taskdate})
            for _ in cursor:  # 單任務詳情
                hostname = Mongo.coll['Info'].find_one({'ip': _['ip']})
                if hostname:
                    _['hostname'] = hostname['hostname']
                else:
                    _['hostname'] = None
                _['title'] = name
                _['vul_level'] = _['vul_info']['vul_level']
                _['vul_name'] = _['vul_info']['vul_name']
                _['lastscan'] = taskdate
                t_list.append(_)
        response = make_response(CreateTable(t_list, 'all_data'))
        response.headers["Content-Disposition"] = "attachment; filename=all_data.xls;"
    response.headers["Content-Type"] = "application/x-xls"
    return response

  

 

216-243行 將掃描結果查詢出來後加到result_list

response = make_response(CreateTable(result_list, taskdate.strftime("%Y%m%d-%H%M%S")))

  

CreateTable()函數  View/lib/CreateExcel.py

def CreateTable(cursor, id):
    item = []
    item.append(['IP', '端口', '主機名', '風險等級', '漏洞描述', '插件類型', '任務名稱', '時間', '掃描批次'])
    for i in cursor:
        if i['lastscan']:
            _ = [i['ip'], i['port'], i['hostname'], i['vul_level'], i['info'],
                 i['vul_name'], i['title'], i['time'].strftime('%Y-%m-%d %H:%M:%S'),
                 i['lastscan'].strftime('%Y-%m-%d %H:%M:%S')]
        else:
            _ = [i['ip'], i['port'], i['hostname'], i['vul_level'], i['info'],
                 i['vul_name'], i['title'], i['time'].strftime('%Y-%m-%d %H:%M:%S'), '']
        item.append(_)
    file = write_data(item, id)
    return file.getvalue()

  

建立個列表,將數據加入列表和描述對應起來。write_data()函數

def write_data(data, tname):
    file = xlwt.Workbook(encoding='utf-8')
    table = file.add_sheet(tname, cell_overwrite_ok=True)
    l = 0
    for line in data:
        c = 0
        for _ in line:
            table.write(l, c, line[c])
            c += 1
        l += 1
    sio = StringIO.StringIO()
    file.save(sio)
    return sio

 

經過xlwt包,將數據一行行寫到文件裏, 而後保存,文件名爲時間格式。

 

回到view/view.py

make_response()返回文件名。 245-250行設置了http頭和下載文件名字。後面返回下載。

251-277行同上。

 

 

11.search_result_xls()

# 搜索結果報表下載接口
@app.route('/searchxls', methods=['get'])
@logincheck
@anticsrf
def search_result_xls():
    query = request.args.get('query', '')
    if query:
        result = query.strip().split(';')
        filter_ = querylogic(result)
        cursor = Mongo.coll['Info'].find(filter_).sort('time', -1)
        title_tup = ('IP', '端口號', '主機名', '服務類型')
        xls = [title_tup, ]
        for info in cursor:
            item = (
                info.get('ip'), info.get('port'),
                info.get('hostname'), info.get('server')
            )
            xls.append(item)
        file = write_data(xls, 'search_result')
        resp = make_response(file.getvalue())
        resp.headers["Content-Disposition"] = "attachment; filename=search_result.xls;"
        resp.headers["Content-Type"] = "application/x-xls"
        resp.headers["X-Content-Type-Options"] = "nosniff"
        return resp
    else:
        redirect(url_for('NotFound'))

 

搜索結果有個話,寫入文件下載。沒有的話NotFound

 

12.Plugin()

# 插件列表頁
@app.route('/plugin')
@logincheck
def Plugin():
    page = int(request.args.get('page', '1'))
    cursor = Mongo.coll['Plugin'].find().limit(page_size).skip((page - 1) * page_size)
    return render_template('plugin.html', cursor=cursor, vultype=cursor.distinct('type'), count=cursor.count())

  

 

查詢-展現

 

13.AddPlugin()

單獨分析 http://www.javashuo.com/article/p-aogwousg-em.html

 

14.DeletePlugin()

# 刪除插件異步
@app.route('/deleteplugin', methods=['get', 'post'])
@logincheck
@anticsrf
def DeletePlugin():
    oid = request.form.get('oid', '')
    if oid:
        result = Mongo.coll['Plugin'].find_one_and_delete({'_id': ObjectId(oid)}, remove=True)
        if not result['filename'].find('.') > -1:
            result['filename'] = result['filename'] + '.py'
        if os.path.exists(file_path + result['filename']):
            os.remove(file_path + result['filename'])
            return 'success'
    return 'fail'

  

 

刪除插件,從數據庫中刪除而且刪除文件

 

 

15.Analysis

# 統計頁面
@app.route('/analysis')
@logincheck
def Analysis():
    ip = len(Mongo.coll['Info'].distinct('ip'))
    record = Mongo.coll['Info'].find().count()
    task = Mongo.coll['Task'].find().count()
    vul = int(Mongo.coll['Plugin'].group([], {}, {'count': 0},'function(doc,prev){prev.count = prev.count + doc.count}')[0]['count'])
    plugin = Mongo.coll['Plugin'].find().count()
    vultype = Mongo.coll['Plugin'].group(['type'], {"count":{"$ne":0}}, {'count': 0},'function(doc,prev){prev.count = prev.count + doc.count}')
    cur = Mongo.coll['Statistics'].find().sort('date', -1).limit(30)
    trend = []
    for i in cur:
        trend.append(
            {'time': i['date'], 'add': i['info']['add'], 'update': i['info']['update'], 'delete': i['info']['delete']})
    vulbeat = Mongo.coll['Heartbeat'].find_one({'name': 'load'})
    scanbeat = Mongo.coll['Heartbeat'].find_one({'name': 'heartbeat'})
    if vulbeat == None or scanbeat == None:
        taskpercent = 0
        taskalive = False
        scanalive = False
    else:
        taskpercent = vulbeat['value'] * 100
        taskalive = (datetime.now() - vulbeat['up_time']).seconds
        scanalive = (datetime.now() - scanbeat['up_time']).seconds
        taskalive = True if taskalive < 120 else False
        scanalive = True if scanalive < 120 else False
    server_type = Mongo.coll['Info'].aggregate(
        [{'$group': {'_id': '$server', 'count': {'$sum': 1}}}, {'$sort': {'count': -1}}])
    web_type = Mongo.coll['Info'].aggregate([{'$match': {'server': 'web'}}, {'$unwind': '$webinfo.tag'},
                                             {'$group': {'_id': '$webinfo.tag', 'count': {'$sum': 1}}},
                                             {'$sort': {'count': -1}}])
    return render_template('analysis.html', ip=ip, record=record, task=task, vul=vul, plugin=plugin, vultype=vultype,
                           trend=sorted(trend, key=lambda x: x['time']), taskpercent=taskpercent, taskalive=taskalive,
                           scanalive=scanalive, server_type=server_type, web_type=web_type)

  

看了頁面回來看代碼,這個方法就是將數據庫中的值查詢出來而後顯示,不具體分析語句。

 

 

16.Config()

# 配置頁面
@app.route('/config')
@logincheck
def Config():
    val = []
    table = request.args.get('config', '')
    if table in ("vulscan", "nascan"):
        dict = Mongo.coll['Config'].find_one({'type': table})
        if dict and 'config' in dict:
            dict = dict['config']
            for _ in dict:
                if _.find('_') > 0:
                    item_type = "list"
                else:
                    item_type = "word"
                val.append({"show": item_type, "type": _, "info": dict[_]["info"], "help": dict[_]["help"],
                            "value": dict[_]["value"]})
    val = sorted(val, key=lambda x: x["show"], reverse=True)
    return render_template('config.html', values=val)

  

 

判斷是爬蟲引擎仍是掃描引擎,而後分別查詢出數據。

 

17.UpdateConfig()

# 配置更新異步
@app.route('/updateconfig', methods=['get', 'post'])
@logincheck
@anticsrf
def UpdateConfig():
    rsp = 'fail'
    name = request.form.get('name', 'default')
    value = request.form.get('value', '')
    conftype = request.form.get('conftype', '')
    if name and value and conftype:
        if name == 'Masscan' or name == 'Port_list':
            origin_value = Mongo.coll['Config'].find_one({'type': 'nascan'})["config"][name]["value"]
            value = origin_value.split('|')[0] + '|' + value
        elif name == 'Port_list_Flag':
            name = 'Port_list'
            origin_value = Mongo.coll['Config'].find_one({'type': 'nascan'})["config"]['Port_list']["value"]
            value = value + '|' + origin_value.split('|')[1]
        elif name == 'Masscan_Flag':
            name = 'Masscan'
            path = Mongo.coll['Config'].find_one({'type': 'nascan'})["config"]["Masscan"]["value"]
            if len(path.split('|')) == 3:
                path = path.split('|')[1] + "|" + path.split('|')[2]
            else:
                path = path.split('|')[1]
            if value == '1':
                value = '1|' + path
            else:
                value = '0|' + path
        result = Mongo.coll['Config'].update({"type": conftype}, {'$set': {'config.' + name + '.value': value}})
        if result:
            rsp = 'success'
    return rsp

   

先判斷是更新哪個配置。

 

根據name來判斷是哪一個配置,就從數據庫去取對應的值,而後把提交過來的value加上去更新。

 

18.PullUpdate()

19.checkupdate()

20.installplugin()

# 拉取線上最新插件異步
@app.route('/pullupdate')
@logincheck
@anticsrf
def PullUpdate():
    rsp = 'err'
    f = urlopen('https://sec.ly.com/xunfeng/getlist')
    j = f.read().strip()
    if j:
        try:
            remotelist = json.loads(j)
            #remotelist_temp = copy.deepcopy(remotelist)
            plugin = Mongo.coll['Plugin'].find({'source': 1})
            for p in plugin:
                for remote in remotelist:
                    if p['name'] == remote['name'] and remote['coverage'] == 0:
                        remotelist.remove(remote)
            locallist = Mongo.coll['Update'].aggregate([{'$project': {'_id': 0, 'unicode': 1}}])
            local = []
            for i in locallist:
                local.append(i['unicode'])
            ret = [i for i in remotelist if i['unicode'] not in local]
            for i in ret:
                i['isInstall'] = 0
                Mongo.coll['Update'].insert(i)
            rsp = 'true'
        except:
            pass
    return rsp


# 檢查本地已知的線上插件列表異步
@app.route('/checkupdate')
@logincheck
@anticsrf
def CheckUpdate():
    json = []
    notinstall = Mongo.coll['Update'].find({'isInstall': 0}).sort('unicode', -1)
    for _ in notinstall:
        json.append({'unicode': _['unicode'], 'name': _['name'], 'info': _['info'], 'time': _['pushtime'],
                     'author': _['author']})
    return dumps(json)


# 安裝/下載插件異步
@app.route('/installplugin')
@logincheck
@anticsrf
def installplugin():
    rsp = 'fail'
    unicode = request.args.get('unicode', '')
    item = Mongo.coll['Update'].find_one({'unicode': unicode})
    json_string = {'add_time': datetime.now(), 'count': 0, 'source': 1}
    file_name = secure_filename(item['location'].split('/')[-1])
    if os.path.exists(file_path + file_name):
        if ".py" in file_name:
            db_record = Mongo.coll['Plugin'].find_one({'filename': file_name.split('.')[0]})
        else:
            db_record = Mongo.coll['Plugin'].find_one({'filename': file_name})
        if not db_record or not db_record['source'] == 1:
            file_name = file_name.split('.')[0] + '_' + str(datetime.now().second) + '.' + \
                        file_name.split('.')[-1]
        else:
            db_record = Mongo.coll['Plugin'].delete_one({'filename': file_name.split('.')[0]})
    if item['location'].find('/') == -1:
        urlretrieve('https://sec.ly.com/xunfeng/getplugin?name=' + item['location'], file_path + file_name)
    else:
        urlretrieve(item['location'], file_path + file_name)  # 兼容舊的插件源
    if os.path.exists(file_path + file_name):
        try:
            if file_name.split('.')[-1] == 'py':
                module = __import__(file_name.split('.')[0])
                mark_json = module.get_plugin_info()
                json_string['filename'] = file_name.split('.')[0]
            else:
                json_text = open(file_path + file_name, 'r').read()
                mark_json = json.loads(json_text)
                json_string['filename'] = file_name
                mark_json.pop('plugin')
            json_string.update(mark_json)
            Mongo.coll['Plugin'].insert(json_string)
            Mongo.coll['Update'].update_one({'unicode': unicode}, {'$set': {'isInstall': 1}})
            rsp = 'success'
        except:
            pass
    return rsp

  

 

均爲更新插件的,不細分析。

https://sec.ly.com/xunfeng/getlist 查詢出最新插件,而後與數據庫比較。

查看是否本地有安裝。

https://sec.ly.com/xunfeng/getplugin?name= 在這裏實現下載。

 

21.Login()

22.Loginout()

# 登陸
@app.route('/login', methods=['get', 'post'])
def Login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        account = request.form.get('account')
        password = request.form.get('password')
        if account == app.config.get('ACCOUNT') and password == app.config.get('PASSWORD'):
            session['login'] = 'loginsuccess'
            return redirect(url_for('Search'))
        else:
            return redirect(url_for('Login'))


# 登出異步
@app.route('/loginout')
@logincheck
def LoginOut():
    session['login'] = ''
    return redirect(url_for('Login'))

  

 

一個登錄一個登出。

 

 

23.NotFound()

24.Error()

@app.route('/404')
def NotFound():
    return render_template('404.html')


@app.route('/500')
def Error():
    return render_template('500.html')

  

顯示404 500

 

閱讀了view.py 裏的每一個方法具體都是幹嗎的,對巡風掃描器總體有一個大概瞭解。

感謝ysrc開源。

相關文章
相關標籤/搜索