Django基础知识

Django是基于python的一个web框架,我们学习Django的时候需要一定的python基础知识,以及HTML、CSS、JavaScript、socket的一些简单知识

什么是Django

Django是一个开源的高级Python web框架,使用M(模型)T(视图)V(模板)模式,本质上和MVC的模式是一样的,使用Django能够简便、快速的开发数据库驱动的网站。

相比与java程序,Django的程序组成会简单一些,一般来说Django(python web)程序会由两部分组成:服务器程序和应用程序,服务器程序通常会对socket服务器进行封装,对请求数据进行整理。而应用程序负责逻辑处理。

image-20220926142551797

Django项目组成

image-20220926144624063

Django的基本配置文件

数据库配置

1
2
3
4
5
6
7
8
9
10
DATABASES = {
'default': {
'ENGINE': 'mysql',
'NAME':'root',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
'PORT': 'XXXX',
}
}

模板配置,模板是一个文本,用于分离文档的表现形式和内容

1
2
3
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'templates'),
)

静态文件,主要用于Django项目所需要的静态文件,比如JavaScript、CSS一类

1
2
3
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)

路由系统

分为静态路由,动态路由和二级路由

在Django中,它的路由系统和其它语言的框架有所区别,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

ORM数据库的简单使用

ORM可以做什么
  • 对数据库中的表进行增删改查操作
  • 对数据进行操作
ORM不能做什么
  • 不能创建数据库
ORM数据库创建

create database name DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

ORM数据库连接

image-20220926161831717

orm修改表结构

image-20220926161902105

Django的漏洞

在Django的ORM历史漏洞中,我们可以看到几乎一半以上的漏洞都是和SQL注入有关联的,ORM使我们在操作数据库的时候更加简单易行,但是也带来了一些缺点,例如安全性问题

image-20220926150052704

CVE-2022-28346

漏洞描述

攻击者使用精心编制的字典, 通过**kwargs传递给QuerySet.annotate()、aggregate()和extra()这些方法,可导致这些方法在列别名中受到SQL注入攻击

影响版本

Django Django >=2.2,<2.2.28
Django Django >=3.2,<3.2.13
Django Django >=4.0,<4.0.4

漏洞靶场搭建

使用docker拉取镜像并启动

1
2
docker pull s0cke3t/cve-2022-28346
docker run -d -p 8000:8000 s0cke3t/cve-2022-28346

启动后访问以下url,可以访问到则启动成功

1
http://127.0.0.1:8000/demo?field=admin

image-20220926150803861

漏洞源码分析

下载靶场代码

CVE-2022-28346

首先可以看到requirement.txt,此项目基于Django3.2.11

image-20220926151439821

初始化数据库

image-20220926151639763

查看一下数据表,可以看到只有两个字段,分别是id和name

image-20220926151924688

寻找到漏洞的触发点,也是官方给出的测试用例

image-20220926152357627

首先我们先了解一下QuerySte类中的annotate()函数的作用

image-20220926153122301

从官方文档可知,QuerySte类中的annotate()函数就是从数据库获取全部分类,相当于使用了 all 方法,帮我们为每一个分类添加属性,这样我们在模板中就可以调用这个属性,而QuerySet.all()方法是通过链式调用获取这个ORM模型的所有QuerySet对象。

再回到我们搭建好的环境中去,可以看到页面的显示效果。

image-20220926150803861

漏洞验证

SQL注入EXP

http://127.0.0.1:8000/demo?field=demo.name" FROM “demo_user” union SELECT “1”,sqlite_version(),”3” –

image-20220926155012800

漏洞修复

官方已经给出了修复建议

image-20220926164152763