原標題:Django初次嘗試編寫Web漏洞掃描器挖坑記錄

Django 很適合用來寫安全小工具,因爲很多安全工具都是 Python 編寫的,所以 Django 集成的話就可以少走很多彎路,又因爲 Django 的官方文檔比較全,目前 Django 最新的版本都已經到 Django3 了,很適合新手上手使用。本文的項目暫時還沒有開源,這個只是國光初次嘗試寫的第一個版本,代碼很多地方都需要重構,功能上也有很多待完善,目前寫這篇文章只是想理一下思路,證明自己可以寫掃描器,因爲之前立過寫掃描器的 Flag ,國光建議大家也可以嘗試用 Django 之類的 Web 框架整合自己的小工具。

相關技術 Python 3.8.0

Python 3.8 支持許多高級特性,在 Web 漏掃這一塊 Python 的編寫也十分靈活。

Django 3

使用了最新的 Django 版本,Django 是 Python 語言中文檔比較全的一個 Web 框架,因爲文檔比較全,適合新手上手,所以這裏選了 Django。

MySQL

經典的關係型數據庫,實際上因爲 Django 可以完美的支持各種數據庫,一般我們不需要對數據庫進行直接操作,所以換其他的數據庫也是可以的,因爲對 MySQL 比較熟悉,就選擇了MySQL 了。

H+ 4.1

H+ 是一個功能全面的收費框架,基於 Bootstrap3.3.6 碼雲上有人開源出來了,因爲 Bootstrap 容易上手,所以國光這裏就白嫖了這個框架,然後在此基礎上進行了深度修改。

ECharts

ECharts 是百度開源的一個數據可視化的 JS 圖表插件,之前國光我使用 Django 重寫我的 Hexo 博客的時候,發現我那個主題就是使用的 ECharts 圖表插件,所以這次寫 Web 漏掃的時候也就輕車熟路的直接使用了,ECharts 很強大,對於我們這種前端一般般的開發者來說,簡直是福利。

漏洞檢測

漏洞檢測:實際上國光我一開始是不打算寫的,因爲我對漏洞檢測的算法沒有信心,另外國光也看了網上那些看上去 NB 哄哄的 Web 漏掃,發現漏洞檢測的效果也就是 just so so。但是一個掃描器還是要有漏洞檢測功能的,所以國光在寫這個功能前把 全部親自測試了一遍,然後把長亭科技的 也過了一遍。

所以這個漏洞檢測功能最終就是使用 AWVS 13 爬蟲來爬取目標資產信息,然後將獲取到的信息轉發給 xray 進行漏洞檢測,直接用輪子效率真的高,新版本的 xray 支持 webhook 方便獲取到漏洞信息,Demo 界面如下:

Django寫的對應的 xray webhook 接口,下面是這個接口簡單的實現代碼:

import json from django.shortcuts import render from django.views.generic.base import View from django.views.decorators.csrf import csrf_exempt class WebHook(View): @csrf_exempt def dispatch(self, request, *args, **kwargs): return super.dispatch(request, *args, **kwargs) def post(self, request): vul_data = json.loads(request.body) if 'detail' in str(request.body): print('漏洞插件:', vul_data['plugin']) print('漏洞位置:', vul_data['target']['url']) print('漏洞分類:', vul_data['vuln_class']) return render(request, 'test.html', { })

因爲 Django 安全機制問題,xray post 提交請求到 Django 必須填寫 CSRF Token纔可以,解決方法就是手動關掉這個類的 CSRF 檢測@csrf_exemp

點擊資產名稱的跳轉到漏洞細節:

點擊對應的漏洞 URL 會展開詳細的漏洞細節:

總的來說功能上基本可以滿足滲透測試人員的需求了。

端口掃描

端口掃描:國光我的掃描思路是先使用 masscan 進行網段粗略掃描,然後再用 nmap 進行詳細掃描。比較舒服的事情是 Python 裏面都有不錯的相應的模塊可以直接使用,這樣代碼寫起來就更加得心應手了。

python-masscan 的掃描效果圖:

IP 歸屬地查詢使用的接口如下:

ip_api_url = f'http://freeapi.ipip.net/{ip_addr}' r = requests.get(url=ip_api_url) addr_list = literal_eval(r.text) addr = ' '.join(addr_list[:3])

接着點擊網段後的跳轉頁面如下圖所示:

在這裏可以繼續發起掃描,這裏就是調用的 nmap 掃描器,上方圖標插件分別展示了端口和服務類別的餅狀圖,資產比較多的也會在右上側列出來,總體效果還是可以的。

指紋識別

指紋識別:主要使用了 做基本的指紋探測,這可以讓結果看上去不會那麼尷尬,畢竟不是每個資產都可以那麼容易識別到 CMS 的;當然傳統的指紋識別功能也集成了,這裏使用的指紋庫是:,雖然這個指紋庫比較老了,但是可以自己在這個基礎上擴充,基本上也可以滿足基本的指紋探測功能的,國光我整理出的 。

指紋識別詳情展示圖:

當然一些古老的 CMS 也是可以識別出來的,這個就歸功於 TideFinger 的功勞了:

不過這些 CMS 的名稱和描述是需要自己建庫的,然後對應的數據庫 model 註冊到 Django Admin 中:

@admin.register(Component) class ComponentAdmin(admin.ModelAdmin): list_display = ('name', 'desc', 'category', 'icon_data') search_fields = ('name', 'desc') readonly_fields = ('icon_data',) list_per_page = 20 fieldsets = ( ('編輯組件', { 'fields': ('name', 'desc', 'category', 'icon', 'icon_data') }), ) formfield_overrides = { models.CharField: {'widget': TextInput(attrs={'size': '59'})}, }

其中 icon 是圖片,這裏需要我們在對應的 Model 裏面編寫好對應的 HTML:

class Component(models.Model): name = models.CharField(max_length=200, verbose_name='組件名稱') desc = models.CharField(max_length=200, verbose_name='組件描述') icon = models.FileField(upload_to='icons/', verbose_name='組件logo', max_length=100) category = models.CharField(max_length=100, verbose_name='組件類別', blank=True) def icon_data(self): return format_html( '', self.icon, ) icon_data.short_deion = 'Logo'

實際上在 Django Admin中添加編輯起來的話效率也比較高,國光這裏使用的是目前比較流行的 Django Admin:Simple Ui ,下圖是具體的效果:

這裏國光我打包了對應的數據庫以及 icon 素材,方便大家直接使用:CMS組件描述-藍奏雲

域名深測

域名探測:功能國光我發現比較流行的子域名探測功能 one for all 用的也是很多 API 接口,於是國光我也打算使用第三方服務來獲取子域名,這樣獲取的速度會很快。

爲什麼不用傳統的暴力破解子域名呢?因爲現在很多 SRC 的子域名都已經到 3 級甚至 4 級了,這個時候用暴力破解子域名的話效率是及其低下的,要等到天荒地老。接口的話,國光我篩選了 6 個還算不錯和穩定接口,基本上覆蓋面是有的了:

因爲這些子域名是存入數據庫的,所以也就順便增加了域名監控功能,每次掃描可以統計出新增的域名數量。域名探測所使用的 6 個接口分別如下,大家也可以直接拿去使用,做好對應的數據提取就可以了:

# 愛站 https://baidurank.aizhan.com/baidu/{domain}/ # 百度雲觀測 http://ce.baidu.com/index/getRelatedSites?site_address={domain} # hackertarget https://api.hackertarget.com/hostsearch/?q={domain} # IP138 https://site.ip138.com/{domain}/domain.htm # crt.sh SSL 證書反查 https://crt.sh/?q=%25.{domain} # 千尋 url = 'https://www.dnsscan.cn/dns.html' datas = {"ecmsfrom": '8.8.8.8', "show": 'none', "keywords": domain}

域名探測細節效果圖:

域名訪問超時直接丟棄結果的,然後再獲取網頁標題,這個在實際的信息收集中比較實用的,一些 404 403資產的可以跳過,減少無意義的浪費時間。

目錄掃描

目錄掃描:國光這裏直接強行把 Dirsearch 給集成到 Django 中了,附上羅永浩那句話:“又不是不能用”

爲什麼是強行呢,因爲代碼實在不優雅,等後面正式開源這裏再好好重寫一下。又因爲前端比較菜,所以 Web 目錄掃描這一塊和之前的模板外觀看上去是差不多的:

點擊目錄掃描細節可以看到詳細的目錄掃描結果:

這裏沒有啥亮點,Dirsearch 本身就很強大,後期打算集成 top 1000 字典,每次目錄命中的話,計數 + 1,然後把高命中的字典保存下載下來,這樣實戰中應該會更實用。

小工具

目前小工具集成的功能如下:IP 提取、文本對比、批量獲取網頁標題、SSH批量爆破驗證……這些都是比較常用的小功能,寫起來也比較簡單:

這些小工具實際上就是一些小腳本的整合,建議大家也嘗試使用 Django 去集成一些,這樣平時使用的時候就會更加方便了,不需要翻來覆去地導出找腳本了。

SSH 批量爆破驗證

衆所周知,SSH 可能開啓公私鑰登錄,這個時候如果直接丟到類似 超級弱口令爆破工具 理論批量爆破的話,就會很浪費時間。所以最好爆破之前批量檢測一下是否支持密碼爆破。下面是簡單的 Python Demo:

import os import pexpect import progressbar with open('22.txt') as f: lines = f.readlines attack_ips = [] p = progressbar.ProgressBar for line in p(lines): ssh = pexpect.spawn('ssh root@{ip}'.format(ip=line)) try: flag = ssh.expect(['continue', 'password:'], timeout=3) if str(flag).isnumeric: attack_ips.append(line) except pexpect.EOF: ssh.close except pexpect.TIMEOUT: ssh.close for ip in attack_ips: with open('ssh.txt','a') as f: f.write(ip)

類似的還可以寫 MySQL 批量爆破驗證,因爲 MySQL 不一定都是開啓外連的,所以爆破前的檢測是很有必要的,這樣可以在後面的爆破節省大量的時間。

總結

總的來說,使用 Django 寫一個漏掃雖然難度不高(用了輪子了,讓我寫一個 xray 這種強大的掃描器還差的很遠呢…羞愧地低下了頭),但是要做的細緻好用的話難度還是很高的。這裏給自己挖個坑,待以後有精力了重寫這個掃描器:

Redis 緩存加速

WebSocket 通信

Django 配合 React、Vue 等技術實現前後端分離

代碼變量、數據庫結構優化

實用功能完善

總之不論是開發還是安全都有很長的路要走,路漫漫其修遠兮,吾將上下而求索,共勉 !

相關文章