编写Django项目

Posted 南瓜__pumpkin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写Django项目相关的知识,希望对你有一定的参考价值。

当前项目分析

代码分析

需求:在原有钓鱼功能的基础上,添加钓鱼附件功能。

查看web/web/urls.py、web/app/views.py,找出对审计有用的代码文件。从 urls.py 文件中找到相关页面代码,发现钓鱼相关代码都在 app/controller/phishing_view.py 文件中。

项目分析过程,建立在对钓鱼后台代码 phishing_view.py 的分析基础之上。

from app import views as view
from app.controller import scan_view

from app.controller import phishing_view
from app.controller import assets_view

url(r'^' + path + 'task_index$', view.task_index, name="task_index"),
重要文件说明
web/web/urls.py用于配置url的映射
web/app/views.py通过 function(request) 的方式编写网页
app/controller/phishing_view.py钓鱼后台代码

功能页面

启动项目:python manage.py runserver 8001。访问 /blueteam,进入钓鱼页面,发现需要认证。

从 urls.py 文件中可以看到 from app.controller import phishing_view,打开 phishing_view.py 文件,注释掉所有的 @cookie_check(),保证钓鱼相关的网页都能够访问。

项目网页结构图

查看钓鱼相关的所有页面,作图比较大,只能使用LR才能勉强看清,下面代码是markdown的流程图代码。(图片建议新建网页,扩大页面进行局面查看)

mermaid
graph LR
A[phishing.py]
B[1.展示统计结果phishing_status]
A-->B 
C[2.钓鱼项目]
C1[phishing_project_index]
C2[phishing_project_edit]
C3[phishing_project_create]
C4[phishing_project_delete]
A-->C
C-->|展示钓鱼项目|C1
C-->|编辑钓鱼项目|C2
C-->|创建钓鱼项目|C3
C-->|删除钓鱼项目|C4

D[3.钓鱼模版]
D1[phishing_template_create]
D2[phishing_template_delete]
D3[phishing_template_edit]
D4[phishing_template_index]
A-->D
D-->|展示模版|D4
D-->|创建模版|D1
D-->|编辑模版|D3
D-->|删除模版|D2

A-->F
F[4.钓鱼任务]
F1[phishing_task_create]
F2[phishing_task_index]
F5[phishing_task_delete]
F3[phishing_task_suspend]
F4[phishing_task_run]
F-->|创建钓鱼任务|F1
F-->|展示钓鱼任务|F2
F-->|暂停钓鱼任务|F3
F-->|启动钓鱼任务|F4
F-->|删除钓鱼任务|F5



E[5.钓鱼记录]
E2[phishing_recode_delete]
E1[phishing_recode_index]
A-->E
E-->E1
E-->E2

A-->H
H[6.中招记录]
H1[phishing_visited_recode_index]
H2[phishing_visited_recode_delete]
H3[phishing_info_recode_index]
H4[phishing_info_recode_delete]
H-->|展示中招记录|H1
H-->|删除中招记录|H2
H-->|展示中招信息|H3
H-->|删除中招信息|H4

A-->G
G[7.队列帮助phishing_mq_helper]

项目流程分析

前半部分内容:模版、项目、任务。通过对三个页面数据源的测试和观察,发现创建项目、创建模版是为了分别实现 目标列表的复用钓鱼配置的复用

项目内容输入信息
创建任务项目名称、模版名称、任务名称、发送类型
创建项目项目名称、目标列表
创建模版模版名称、标题、内容、类型、备注、设置伪造邮箱地址

需求分析和简单测试

需求分析

1.附件可选

  1. 选择附件所属页面,编写前端代码,监听前端选择
  2. 为原流程函数增加一个标志位形参,另外再编写对附件的处理函数
  3. 如果选择附件,则在原流程基础上调用附件处理函数

2.接收中招的统计页面,以及附件的编写

调整需求分析

1.生成附件页面

  1. 上传正常/恶意文件
  2. 配置文件:给上传的文件加一层监听壳(适配操作系统)、指定图标、指定文档类型

2.附件中招统计页面

  1. 负责接收中招目标发来的请求,统计中招数量

3.创建模版时选择附件

创建模版页面的附件调用

附件所属页面:创建模版页面,即 phishing_template_create()

修改文件修改函数
钓鱼页面 app/controller/phishing_view.pyphishing_template_create()
数据库操作 app/daos/phising_dao.pypdao.insert_new_template()

查看函数 phishing_template_create(),看到该函数首先接收前端发来的 8 个字段并使用编码 utf-8,然后通过 pdao.insert_new_project 把 8 个模版字段信息插入数据库,创建模版的工作就结束了。导入文件代码是 from app.daos import phishing_dao as pdao

前端创建模版输入的字段是 6 个,也就是说 phishing_template_create 页面只输入了 6 个字段,另外 2 个字段是从什么地方传递来的?尝试创建一个模版,使用 burp 进行抓包测试。

发现 在弹框中创建模版并提交,流量并不经过 burpsuite。 发现是向/blueteam/phishing_template_create提交了一个表单,为什么没有抓到这个表单这个表单?本地访问钓鱼项目,发现流量也不会经过burpsuite。

经过测试,应该是属于本地代理的问题。访问远程服务器,创建模版并用 burp抓包,可以抓到数据包,Post数据如下:

csrfmiddlewaretoken=Hl7WzCS9SKT91G65GSztYoZM56hHtOmyPUDguJSEUfP41CPVLYbQ6Sm6rvGSFZ2O&page=0&templateName=test5&templateTitle=test5&templateContent=&templateType=&templateFakerSender=&templateRemark=

查看模版首页 phishing_template?page=0&searchKey= 的前端代码,找到 phishing_template_create 创建模版的前端代码如下,<form action="/blueteam/phishing_template_create" method="POST"> 向后台提供一个表单。

调用附件:接下来我们需要往前端表单里添加 2 个字段:附件标志位、附件。查看前端代码 phishing_template.html,发现已经预留了附件字段,如下所示。

附件的调用很简单,发现需求出现了偏差,修改需求分析再继续编写。

<div>
	<label>
		模版附件:
	</label>
	<br>
	<textarea class="form-control" rows="1" name="templateAttachmentList"
                                          style="resize: none" ></textarea>
</div>

代码编写

编写前端

Django的模版的继承:extends用于继承母版,用法是在第一行需要写上要继承的母版,{% extends ‘母版的相对路径’ %}这样引入母版。block用于子版替换母版中被圈起来的部分。

通过编程处理报错和梳理逻辑关系,生成相关页面表格。

钓鱼附件生产页面功能文件名
首页展示附件列表phishing_attachement_index
子页面1生成附件phishing_attachement_generate
其他页面功能文件名
添加到已有页面附件中招记录添加到phishing_visited_recode
添加到已有页面附件调用添加到phishing_template_create

编写页面流程

创建页面的流程如下,以 phishing_attachement_index 为例。

1、创建前端文件 phishing_attachement.html,编辑前端代码,继承引用母版的同时保留空间。

	打开母版base.html,添加代码
<li>
<a class="sub-link" href="{% url 'phishing_attachement' %}">{% block phishingattachement %}钓鱼附件{% endblock %}</a>
</li>
	
	编辑phishing_attachement.html
{% extends "base.html" %}   <!-- 导入母版 -->

{% block phishingattachement %}<font color="#fa8919">钓鱼附件</font>{% endblock %}

{% block right %}			<!-- 自由编写部分 -->
<link rel="stylesheet" href="/blueteam/static/css/bootstrap-select.css"/>
<script src="/blueteam/static/js/bootstrap-select.js"></script>

<div class="wrapper">
    <div class="didi-form">
    </div>
</div>
    
{% endblock %}

2、urls.py文件建立页面的映射关系

url(r'^' + path + 'phishing_attachement_index$', phishing_view.phishing_attachement_index, name="phishing_attachement_index")

3、phishing_view.py添加页面处理函数,即后台代码

# @cookie_check()
def phishing_attachement_index(req):
    """
    钓鱼附件展示页
    :param req:
        page (int):当前页码
    :return:
    """
    req_page, page_size, search_key = request_parse(req, "GET", "page", "pageSize", "searchKey")

    # 参数处理
    req_page = int(req_page)
    if not page_size:
        # 默认的page_size为10
        page_size = 10
    else:
        page_size = int(page_size)
    search_key = search_key.encode("utf-8")

    page_list_num = 6
    data_list, total_count = pdao.get_template_list_by_page(req_page, search_key, page_size)
    req_page, last_page_num, page_list = fenye(total_count, req_page, page_size, page_list_num)
    return render(req, "phishing_attachement.html",
                  {"search_key": search_key, "page": req_page, "page_list": page_list, "last_page": last_page_num,
                   "data_list": data_list})

根据这个流程,可以编写出 phishing_attachement_generate.py 页面。

前端定制:phishing_attachement.html

参考 phishing_template.html 的前端代码,前端代码分为两部分。

前端功能输入变动
查询附件附件名原样参考,只需修改汉字说明
创建附件(主功能点)附件配置信息参考模态框modal,但弹框的前后端都要大改
展示已建附件格式参考,修改表名、增删字段名和汉字说明

创建附件:输入附件名、上传文件、修改文件类型、修改文件图标、选择适配的操作系统。

	添加映射关系
url(r'^' + path + 'phishing_attachement_generate$', phishing_view.phishing_attachement_generate, name="phishing_attachement_generate"),
	
	添加后台处理函数
def phishing_attachement_generate(req)

	前端代码修改比较麻烦,逐步编写 phishing_attachement.html前端文件
1.设置模态框

对比 phishing_template.html,发现是否弹出模态框要看如下代码中的 id 字段,id 字段创建模态框、data-target 字段调用模态框。

创建模态框
<div class="modal fade" tabindex="-1" role="dialog" id="attachementCreate"

引用模态框
<input type="button" data-toggle="modal" data-target="#attachementCreate"
                               class="didi-btn didi-btn-highlight" value="生成附件">
Bootstrap的事件属性说明
data-toggle指以什么事件触发常用的如modal,popover,tooltips等
data-target指事件的目标比如将某个Dom元素的内容以模态框的形式展示

目前点击 生成附件 ,会弹出模态框并输入信息。

2.定义输入信息

创建附件:输入附件名、上传文件、修改文件类型、修改文件图标、选择适配的操作系统。

在模态框添加一个输入框(组件)的代码如下所示:

<div class="modal-body">
	<div>
		<label>
			附件名称:
		 </label>
         <input type="text" name="attachementName" class="didi-input">
</div>

上传文件:

<div>
	<label>
		上传正常文件:
	</label>
	<br>
	<input type="file" name="upload_file"/>
                                
</div>
3.展示图标

生成附件的前端和后端思路,

后端定义一个处理函数,接收前端输入的附件名、源文件、文件类型、文件图标、适配OS,生成附件到指定目录。

展示页去读取指定目录下的附件。

前端目前有两种思路:第一种是上传源文件,难点是模态框上传文件需要js、而且需要美化。第二种是把源文件、图标文件作为下选框进行选择,图标文件可以展示出来,需要对下选框进行美化。综合考虑,选择第二种方案。

在模态框中展示图片,图示路径无法加载图片,URL地址也不对。

<div>
	<label>
		附件图标:
	</label>
	<br>
	<img width=320 height=240 src="../../phishing_attachement/icons/docker.jpg" name="x1">
	
	<SELECT onChange="document.x1.src=options[selectedIndex].value">
		<option value="../../phishing_attachement/icons/docker.jpg">docker</option>
		<option value="../../phishing_attachement/icons/dark.png"></option>
	</SELECT>
</div>

图片显示问题解决:查看 settings.py,发现 static 目录的路径已加载。把图片放到statci目录,方便调用。

STATICFILES_DIRS = (
          os.path.join(os.path.dirname(__file__), '../static/').replace('\\\\','/'),
)

代码如下:

<div>
	<label>
		附件图标:
	</label>
	<br>
	<img width=320 height=240 src="static/phishing_attachement/icons/docker.jpg" name="x1">
	
	<SELECT onChange="document.x1.src=options[selectedIndex].value">
		<option value="static/phishing_attachement/icons/docker.jpg">docker</option>
		<option value="static/phishing_attachement/icons/dark.png"></option>
	</SELECT>
</div>
4.指定源文件

如果没有上传文件功能,图标和源文件都必须手动上传,而且要在创建附件的前端手动指定可选择的文件。(图标肯定要这样,但源文件不能上传相对不便利)

<div>
	<label>
		选择源文件:
	</label>
	<br>
	<SELECT onChange="document.x1.src=options[selectedIndex].value">
		<option value="static/phishing_attachement/source_files/吴家豪简历.docx">吴家豪简历</option>
		<option value="static/phishing_attachement/source_files/dark.png"></option>
	</SELECT>
</div>
5.前端效果

后端文件:phishing_attachement_generate(req)

1.新建附件记录入库

打开文件 daos/phishing_dao.py ,在文件末尾追加入库代码。

def insert_new_attachement(attachement_name, source_file, attachement_type, attachement_icon, targetOS):
    """
    创建一个新的附件
    :param attachement_name: 附件名称
    :param source_file: 附件源文件
    :param attachement_type: 附件类型
    :param attachement_icon:附件图标
    :param targetOS:    附件适配操作系统
    :return:
    """

    sql_insert = 'INSERT INTO phishing_attachement(attachement_name, create_time, update_time,source_file, attachement_type, attachement_icon,' \\
                 ' targetOS) VALUES(%s, %s, %s, %s, %s, %s, %s);'
    curr_time = ntime.ntime()

    sql_val = [attachement_name, curr_time, curr_time, source_file, attachement_type, attachement_icon, targetOS]
    
    sql_helper = mysql()
    insert_result = sql_helper.insert_to_mysql(sql_insert, sql_val)

    sql_helper.commit_to_mysql()
    sql_helper.close_mysql()
    if insert_result == "exists":
        return -1
    else:
        return insert_result
2.连接数据库新建table

数据库连接配置信息:
phishing_dao.py 文件:from lib.mysql import Mysql。
lib/mysql.py 文件:import config as s
lib/config.py 文件:找到主机、端口、用户名、口令、数据库名等信息。

建立附件表格table,以及 8 个column。(参考其他项目的表格)

	查看其他表格
use	weakscan;
show tables;
select * from phishing_project limit 0,1;
| id | project_name | create_time   | update_time   | remark   | target_list  
   
	创建表格
mysql> create table phishing_attachement(
    -> id int primary key auto_increment,
    -> attachement_name varchar(50) not null,
    -> create_time varchar(20) not null,
    -> update_time varchar(20) not null,
    -> source_file varchar(50) not null,
    -> attachement_type varchar(20) not null,
    -> attachement_icon varchar(20) not null,
    -> targetOS varchar(20) not null);

接收 5 个字段,使用 .encode("utf-8") 统一编码格式,进行入库操作。

创建附件,登陆数据库发现添加成功,不过发现两个问题。
(1)源文件的路径没有截掉:source_file = source_file.split(’/’)[-1]
(2)中文字符显示错误:建表时指定字符集,例如 create table user(name varchar(11)) default charset=utf8;

	删除表格
DROP TABLE phishing_attachement;

	创建表格
create table phishing_attachement(
    -> id int primary key auto_increment,
    -> attachement_name varchar(50) not null,
    -> create_time varchar(20) not null,
    -> update_time varchar(20) not null,
    -> source_file varchar(50) not null,
    -> attachement_type varchar(20) not null,
    -> attachement_icon varchar(20) not null,
    -> targetOS varchar(20) not null) 
    -> default charset=utf8;

	创建附件,查询记录,发现仍然存在中文乱码问题,先放一放,可能是Web端问题
select * from phishing_attachement;
3.把源文件加工成附件:phishing_attachement_generate(req)

等大佬的脚本。

需求分析1.3

根据 @orleven师傅 的附件生成脚本调整了一波需求,限于文章篇幅,接下里的项目编写见《编写Django项目(二)》。

参考

Django框架中配置url路由时name的作用

Django中前后端之间的数据传送

django模板语言中的extends,block和include

js实现下拉框选择要显示图片的方法

mysql-创建表及数据类型

以上是关于编写Django项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django Summernote 中显示编程片段的代码块?

片段中ListView的setOnItemClickListener

如何使用引导程序和 for 循环在 django 中创建电影片段?

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段

PHP必用代码片段

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段