Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

一、Django基礎(chǔ)開(kāi)發(fā)

以前搭博客用的是1.8.2,還在機(jī)子上裝著沒(méi)卸,順便拿過(guò)來(lái)用,當(dāng)然新版本會(huì)修復(fù)很多bug,盡可能還是要去學(xué)習(xí)新一些的版本,此篇權(quán)當(dāng)入門(mén)篇。

1、下載安裝與啟動(dòng)

# 下載django pip install django==1.8.2 -i https://pypi.mirrors.ustc.edu.cn/simple/ # 創(chuàng)建文件夾并啟動(dòng)虛擬環(huán)境 virtualenv django_demo cd django_demo source bin/activate # 創(chuàng)建存放django文件的文件夾 mkdir learn_django cd learn_django # 創(chuàng)建項(xiàng)目 python django-admin.py startproject django_web # 創(chuàng)建應(yīng)用 python manage.py startapp django_app # 編輯django_web中的settings.py文件,將django_app加入到apps中  

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

這樣就完成了最基礎(chǔ)的搭建

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

運(yùn)行服務(wù)看一下 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

2、Django框架中的MVC與MTV

MVC是眾所周知的模式:model(模型)、view(視圖)、controller(控制器) ? ?

用戶(hù)在頁(yè)面輸入url,轉(zhuǎn)交給url控制器,然后根據(jù)url匹配相應(yīng)的視圖函數(shù),viwe會(huì)去到models取數(shù)據(jù),然后models在數(shù)據(jù)庫(kù)中取得數(shù)據(jù)后返回給視圖,視圖把要展示的數(shù)據(jù)返回給模版,然后就輸出到頁(yè)面上。 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

Django也是一個(gè)MVC框架,但是在Django中,控制器接受用戶(hù)輸入的部分由框架自行處理,所以django更加關(guān)注的是 模型(model)、view(視圖)、templates(模版),也就是MTV模型。 ? ?

請(qǐng)求一個(gè)url后,匹配相應(yīng)的view區(qū),view去models(一個(gè)托管數(shù)據(jù)的層級(jí))查找我們要的數(shù)據(jù),然后將數(shù)據(jù)裝載到templates層,然后呈獻(xiàn)給我們。Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

兩者很像,可以說(shuō)MTV基于MVC。 ? ?

3、靜態(tài)Web開(kāi)發(fā)

創(chuàng)建模版層

當(dāng)然,要是只想讓簡(jiǎn)單的數(shù)據(jù)顯示在Web頁(yè)面中,不需要?jiǎng)?chuàng)建模版,直接在views函數(shù)中相應(yīng)回去就可以了,但是還是正規(guī)化一點(diǎn)。

在learn_django中創(chuàng)建templates文件夾(如果是IDE創(chuàng)建的django項(xiàng)目會(huì)自動(dòng)創(chuàng)建),這就是我們的模版文件夾,來(lái)添加一個(gè)可視化的模版index.html ? ?

<!DOCTYPE html> <html> <head>     <title>Django Learning</title> </head> <body>     <h2>Hellow,Django!</h2>> </body> </html>  

創(chuàng)建視圖層

視圖層通常來(lái)說(shuō)是一個(gè)視圖函數(shù),與url進(jìn)行匹配返回傳入對(duì)應(yīng)的Web頁(yè)面

from django.shortcuts import render # Create your views here. def index(request):     return render(request,'index.html')  

創(chuàng)建url層

我們可以建立一個(gè) URL 映射層來(lái)根據(jù)傳入的 URL 查找相應(yīng)的視圖函數(shù),并返回相應(yīng)的模板渲染結(jié)果

from django.conf.urls import include, url from django.contrib import admin from django_app.views import index urlpatterns = [     url(r'^admin/', include(admin.site.urls)), # 用正則去對(duì)url進(jìn)行匹配,然后將視圖函數(shù)匹配給相應(yīng)的url     url(r'^index/',index),  

運(yùn)行服務(wù),默認(rèn)在8000端口

python manage.py runserver

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

到這一步有一部分同學(xué)會(huì)有一些小問(wèn)題,那就是并不能返回模版,可能Windows和linux情況各不相同,linux需要把templates目錄放在app目錄下才可以找到。原因就在于settings.py中模版路徑設(shè)置問(wèn)題,如果templates目錄是放在項(xiàng)目根目錄,在settings中將templates路徑加入就可以了。

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

4、動(dòng)態(tài)web開(kāi)發(fā)

前邊是說(shuō)靜態(tài)頁(yè)面,如果需要實(shí)現(xiàn)動(dòng)態(tài),那就不得不說(shuō)與數(shù)據(jù)庫(kù)存儲(chǔ)的交互問(wèn)題,需要對(duì)models進(jìn)行對(duì)應(yīng)的編寫(xiě)來(lái)取得數(shù)據(jù)。

mysql + django

安裝對(duì)應(yīng)的數(shù)據(jù)庫(kù)接口驅(qū)動(dòng),這里大致有三種:mysqldb、pymysql、mysqlclient。

默認(rèn)使用web根目錄下的sqlite3數(shù)據(jù)庫(kù) ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

將其修改為相應(yīng)的mysql信息 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

創(chuàng)建mysql數(shù)據(jù)庫(kù),指定字符集為UTF-8 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

models層 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

創(chuàng)建模型的對(duì)象和數(shù)據(jù)庫(kù)字段的對(duì)應(yīng)關(guān)系 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

字段定義中的特殊屬性 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

from django.db import models # Create your models here. class DjangoTest(models.Model):     text = models.CharField(max_length=20)  生成遷移文件并執(zhí)行遷移 python manage.py makemigrations python manage.py migrate  

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

查看創(chuàng)建的信息 ? ?
Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

建立一些測(cè)試數(shù)據(jù) ? ?
Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

在去創(chuàng)建views層之前,我們先對(duì)models層進(jìn)行測(cè)試,看是否提取出了數(shù)據(jù) ? ?

可以用兩種方法: ? ?

1、直接在models中填寫(xiě)提取數(shù)據(jù) ? ?

也可以寫(xiě)在view層,這個(gè)無(wú)所謂

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

運(yùn)行后可能會(huì)出現(xiàn),因?yàn)樵陧?xiàng)目中單獨(dú)運(yùn)行python文件,需要搜索環(huán)境變量,而并沒(méi)有指定,所以需要進(jìn)行設(shè)置 ? ?

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS….. ? ? ? ?

pycharm解決方法:https://blog.csdn.net/u011013781/article/details/52155761

2、使用django shell ? ?

# 打開(kāi)django shell python manage.py shell import django django.setup() from django_app.models imoort DjangoTest as dj # 添加數(shù)據(jù),結(jié)果見(jiàn)下方圖片 a = dj(text="django shell test") a.save() # 查詢(xún)數(shù)據(jù),get查詢(xún)單個(gè)數(shù)據(jù),filter查詢(xún)多個(gè)模型,all查詢(xún) dj.objects.all()  

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

django admin可以幫我們快速管理后臺(tái)數(shù)據(jù) ? ?

# 創(chuàng)建管理員 python manage.py createsuperuser ``` ![](http://oxrfjovwk.bkt.clouddn.com/18-6-29/76119583.jpg)  

將我們的模型注冊(cè)到admin中,打開(kāi)admin.py

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

將我們的模型注冊(cè)到admin中,打開(kāi)admin.py ? ?

from django.contrib import admin # Register your models here. from models import DjangoTest admin.site.register(DjangoTest)  

這樣就可以在管理員界面管理模型 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

view與url層 ? ?

當(dāng)用戶(hù)請(qǐng)求django站點(diǎn)上的某個(gè)頁(yè)面時(shí),django會(huì)使用路由解析模塊來(lái)解析路由,默認(rèn)是app目錄下的urls.py。 ? ?

django加載該路由解析模塊,并尋找可用的urlpatterns,這是一個(gè)python列表,然后django依次匹配列表中每個(gè)url模式,在遇到第一個(gè)與請(qǐng)求相匹配的模式時(shí)停下來(lái),然后調(diào)用對(duì)應(yīng)的視圖,視圖是一個(gè)python函數(shù)(或者是一個(gè)基于類(lèi)的視圖)。 ? ?

一個(gè)簡(jiǎn)單的路由選擇模塊示例: ? ?

from django.conf.urls import url from . import views urlpatterns = [     url(r'^articles/2003/$', views.special_case_2003),     url(r'^articles/([0-9]{4})/$', views.year_archive),     url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),     url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]  

與之對(duì)應(yīng)的請(qǐng)求的例子: ? ?

第三個(gè)模式將與請(qǐng)求/articles/2005/03/匹配。Django 將調(diào)用函數(shù)views.month_archive(request, ‘2005’, ’03’)。

/articles/2005/3/ 不匹配任何URL 模式,因?yàn)榱斜碇械牡谌齻€(gè)模式要求月份應(yīng)該是兩個(gè)數(shù)字。

/articles/2003/ 將匹配列表中的第一個(gè)模式不是第二個(gè),因?yàn)槟J桨错樞蚱ヅ洌谝粋€(gè)會(huì)首先測(cè)試是否匹配。請(qǐng)像這樣自由插入一些特殊的情況來(lái)探測(cè)匹配的次序。

/articles/2003 不匹配任何一個(gè)模式,因?yàn)槊總€(gè)模式要求URL 以一個(gè)斜線結(jié)尾。

最后一個(gè)模式將被匹配到/articles/2003/03/03/。Django 將調(diào)用函數(shù)views.article_detail(request, ‘2003’, ’03’, ’03’)。

根據(jù)url后邊的數(shù)值,賦予相應(yīng)的參數(shù):id

urls.py

from django.conf.urls import include, url from django.contrib import admin from django_app.views import index urlpatterns = [     url(r'^admin/', include(admin.site.urls)),     url(r'^index/(?P<id>[0-9])/$', index), ]  

將對(duì)于的id參數(shù)代入查詢(xún)獲取數(shù)據(jù)列表中指定索引的值(忽略這的一點(diǎn)小細(xì)節(jié)錯(cuò)誤) ? ?

views.py

from django.shortcuts import render from django_app.models import DjangoTest # Create your views here. def index(request,id):     text = DjangoTest.objects.all()     iden = int(id)     context = {'text':text[iden]}         return render(request,'index.html',context)  

模版層

模版層語(yǔ)法參考

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Django test</title> </head> <body>         <h2>ID: {{ text.id }}</h2>         <h2>Hello:{{ text.text }} </body> </html>  

實(shí)際運(yùn)行效果

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

二、Django開(kāi)發(fā)中的Web攻防(部分)

1、格式化字符串漏洞

修復(fù)前

from django.shortcuts import render from django.contrib.auth import authenticate, login import django django.setup() # Create your views here. def index(request):     if request.method == 'GET':         return render(request,'index.html')     else:         username = request.POST['username']         password = request.POST['password']         user = authenticate(username=username,password=password)         if user is not None:             if user.is_active:                 login(request, user)                 template = 'Hello {user}! , You can set your email is:' + request.POST.get('email')                 return render(request, 'index.html', {"value": template.format(user=request.user)})             else:                 info = "The password is valid, but the account has been disabled!"                 return render(request, 'index.html', {"value": info})         else:             info = "The username and password were incorrect."             return render(request, 'index.html', {"value": info})  

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

如果沒(méi)有添加認(rèn)證選項(xiàng),即使在原代碼上做了更改,返回的用戶(hù)也將永遠(yuǎn)是匿名用戶(hù)。 ? ?

由于我之前已經(jīng)創(chuàng)建了一個(gè)超級(jí)用戶(hù)(用戶(hù)名:admin,密碼:admin),因此可以直接使用該用戶(hù)進(jìn)行身份認(rèn)證。 ? ?

認(rèn)證之后返回登錄用戶(hù)的用戶(hù)名,我們可以自己通過(guò)post方法傳入一個(gè)郵箱地址上去作為臨時(shí)地址,如果用戶(hù)名信息出現(xiàn)任何錯(cuò)誤,返回相應(yīng)的錯(cuò)誤信息。 ? ?

使用django認(rèn)證系統(tǒng) ? ?

User對(duì)象是認(rèn)證系統(tǒng)的核心,默認(rèn)user的基本屬性有username、password、email….. ? ? ? ?

代碼中郵箱信息直接通過(guò)format拼接在了字符串中,然后展示在頁(yè)面里,我們可以通過(guò)以下payload來(lái)獲取敏感數(shù)據(jù),將user變量中的password屬性 作為變量信息進(jìn)行拼接,從而進(jìn)行獲取 ? ?

payload:? {user.password} ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

修復(fù)后

index.html

將其他的文本信息直接存放在模版中 ? ?

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Django test</title> </head> <body>     <h2>Hello, Django!</h2>     <h3>hello {{ user }}, You can set your email is:{{ value }}</h3> </body> </html>  views.py ..... email = request.POST.get('email') return render(request, 'index.html', {"value": email}) ...

2、XSS

測(cè)試與修復(fù)前

只是簡(jiǎn)單的接收post參數(shù)值,然后讓其顯示在頁(yè)面上?

views.py  def index(request):     if request.method == 'GET':         return render(request,'index.html')     else:         info = request.POST.get('info')         return render(request,'index.html',{"value":info})  index.html       <h2>Hello, Django!</h2>     <h3>{{ value }}</h3>

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的當(dāng)鍵入payload時(shí),并沒(méi)有預(yù)想的彈窗,因?yàn)閐jango自動(dòng)為開(kāi)發(fā)者提供了escape功能,讓html代碼在render之前先進(jìn)行轉(zhuǎn)義,然后再顯示出來(lái)。 ? ?

除了自動(dòng)開(kāi)啟的escape,還有safe、autoescape、make_Safe等 ? ?

autoescape測(cè)試 ? ?

    {% autoescape off %}     <h3>{{ value }}</h3>     {% endautoescape %}  

當(dāng)其值為off時(shí),即存在xss漏洞 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

safe測(cè)試 ? ?

    <h2>Hello, Django!</h2>     <h3>{{ value | safe }}</h3>

通過(guò)safe關(guān)閉了模版的安全機(jī)制,出現(xiàn)XSS漏洞 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

還有幾種情況也可能存在XSS: ? ?

1、var mystr = “{ { value | escapejs } }”

2、safe、make_safe、autoescape

3、DOM型XSS

4、HttpResponse返回動(dòng)態(tài)內(nèi)容

修復(fù)后 ? ?

import cgi # Create your views here. def index(request):     if request.method == 'GET':         return render(request,'index.html')     else:         info = request.POST.get('info')         info = cgi.escape(info)         return render(request,'index.html',{"value":info})  

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

使用cgi模塊需要注意: ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

設(shè)為T(mén)rue,讓其轉(zhuǎn)義盡可能多的導(dǎo)致逃逸的字符。

3、SQL注入

Django QuerySet ? ?

查看django queryset執(zhí)行的SQL ? ?

from django_app.models import DjangoTest as dj print dj.objects.all().query  得到 SELECT `django_app_djangotest`.`id`, `django_app_djangotest`.`text` FROM `django_app_djangotest`  簡(jiǎn)化之后就是 SELECT id,text FROM django_app_djangotest;   

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

extra實(shí)現(xiàn)別名、條件、排序等 ? ?

以select為例: ? ?

tag = dj.objects.all().extra(select={“tag_id”:’id’}) ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

以where為例:

在extra中,可以使用原生SQL語(yǔ)句作為當(dāng)前的where參數(shù)進(jìn)行查詢(xún)。 ? ?

條件為id=1,結(jié)果即查詢(xún)出了一條數(shù)據(jù) ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

raw方法實(shí)現(xiàn)原生的SQL語(yǔ)句查詢(xún) ? ?

a = dj.objects.raw(‘SELECT id,text FROM django_app_djangotest ‘)

raw()方法支持索引訪問(wèn)(a[0])

也可以打印當(dāng)前賦予的這個(gè)變量a都有哪些方法 ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

直接利用API來(lái)查詢(xún)數(shù)據(jù) ? ?

django.connection ? ?

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

MySQL API ? ?

諸如mysqldb、pymysql、mysqlclient,在views層寫(xiě)好sql語(yǔ)句,根據(jù)傳入的參數(shù)值來(lái)查詢(xún),得出結(jié)果后返回給模版就可以了 ? ?

修復(fù)前

views.py

from django.shortcuts import render from django_app.models import DjangoTest as dj # Create your views here. def index(request):     if request.method == 'GET':         return render(request,'index.html')     else:         id = request.POST.get('id')         tag = dj.objects.extra(where={'id={}'.format(id)})[0].text         return render(request,'index.html',{"value":tag})  

接下來(lái)就可以進(jìn)行愉快的測(cè)試了

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

測(cè)試篇

a = dj.objects.extra(where={‘id=1’})

SELECT `django_app_djangotest`.`id`, `django_app_djangotest`.`text` FROM `django_app_djangotest` WHERE (id=1asdasdad)

先輸入payload查看django傳遞回?cái)?shù)據(jù)庫(kù)的sql語(yǔ)句是什么

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

更改后的payload

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的Django開(kāi)發(fā)與攻防測(cè)試是怎樣的后邊又構(gòu)造測(cè)試了幾個(gè),SQL語(yǔ)句是正確,但是django傳入SQL語(yǔ)句時(shí)會(huì)提示里邊的語(yǔ)法問(wèn)題,并且就算語(yǔ)法正確,也返回不了數(shù)據(jù)。(這其實(shí)有點(diǎn)問(wèn)題,后邊做完一想,沒(méi)拿到mysql shell里邊去測(cè),終端里邊測(cè)對(duì)了,再拿過(guò)來(lái),這里有點(diǎn)懶沒(méi)再弄)

又因?yàn)閕d的值,從而在頁(yè)面中顯示不出來(lái),所以這時(shí)候想到了延時(shí)注入

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

在這里調(diào)用a的時(shí)候會(huì)延時(shí)3秒

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

我們?cè)赪eb頁(yè)面中進(jìn)行測(cè)試

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

關(guān)于這里的秒數(shù)是成倍關(guān)系,以前看到過(guò)一篇帖子,說(shuō)是當(dāng)時(shí)間滿(mǎn)足出現(xiàn)成倍的關(guān)系時(shí),應(yīng)該是查詢(xún)出了多條數(shù)據(jù),每一個(gè)row執(zhí)行一次延時(shí)。

接下來(lái)就好辦了

x = dj.objects.extra(where={“id=1 and if(substr((select user()),1,1)=’r’,sleep(3),1)”})

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

后邊的步驟跟著盲注的流程走就OJBK了。

有時(shí)候不要直接在django shell中執(zhí)行,先去mysql命令行把命令敲對(duì)了,也確實(shí)可以執(zhí)行payload時(shí)候再回來(lái)測(cè)試,確保第一步先正確。

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

剛剛提到的是extra模塊中的where子句,其他類(lèi)型的數(shù)據(jù)提取方法已經(jīng)在前面討論過(guò)了,需要具體問(wèn)題具體分析

修復(fù)后

views.py

from django.shortcuts import render from django_app.models import DjangoTest as dj # Create your views here. def index(request):     if request.method == 'GET':         return render(request,'index.html')     else:         id = request.POST.get('id')         tag = dj.objects.extra(where=['id=%s'],params=id)         info = tag[0].text         return render(request,'index.html',{"value":info})  

用戶(hù)發(fā)送的請(qǐng)求再匹配到視圖函數(shù)進(jìn)行處理時(shí),視圖函數(shù)的相關(guān)機(jī)制會(huì)對(duì)敏感信息進(jìn)行處理,導(dǎo)致一些惡意語(yǔ)句被過(guò)濾

現(xiàn)在測(cè)試就不會(huì)了

Django開(kāi)發(fā)與攻防測(cè)試是怎樣的

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊9 分享