一、前言
本文介紹了主機安全的ssh埠入侵&檢測&回應,
包括以下幾個內容
1. 熟練使用hydra、msf等平臺對ssh服務開展爆破行為
2. 能夠在服務器上找到入侵痕跡包括攻擊時間、攻擊方式、是否成功、攻擊源等有價值資訊
我們經常會用一些ssh工具直接使用默認埠22,設定記住密碼自動登錄,但這樣如果你的密碼不夠復雜很容易被攻克
下面我們就來看看ssh攻克的具體方法及解決方式,
二、實驗環境
攻擊主機ip:192.168.171.130(注:這里用kali虛擬機作為攻擊主機)
受害者主機ip:192.168.171.121
檢測主機ip:192.168.171.120
三、攻擊思路
1. 使用nmap等埠掃描工具探測目標服務器是否存在ssh服務
1)在攻擊主機的命令列下輸入nmap -sS 192.168.171.121 對目標主機進行埠掃描:

2)檢測發現目標主機存在ssh服務,嘗試登陸幾次判斷是否存在登陸次數限制或登陸地址限制情況:

經過多次嘗試登陸發現沒有存在限制次數登陸和限制登錄地址的情況,所以我們可以使用爆破工具加載字典對ssh服務進行爆破了,
2. 使用msf、hydra等工具加載字典對目標ssh服務開展爆破行為,這里使用hydra來做演示,
hydra和msf的使用方法不做過多介紹,否則篇幅無法控制,大家如果有不懂的,可以百度或者聯系我,
1)在命令列下使用hydra加載用戶名、密碼字典對目標ssh服務開展爆破行為:
hydra -L user.txt -P pass.txt ssh://192.168.171.121
2)對爆破出來的用戶名密碼嘗試登陸
ssh victim@192.168.171.121 輸入密碼后正常登陸:

3)創建SSH免密登陸
3.1)現在攻擊主機上生成公鑰資訊
ssh-keygen -t rsa
3.2)將生成的公鑰資訊傳到受害主機上

一定要注意是公鑰檔案后綴為.pub,
ssh-copy-id -i .ssh/id_rsa.pub victim@192.168.171.121

輸入受害主機的密碼后即可,
3.3)嘗試可以免密登陸
ssh victim@192.168.171.121 直接登陸不用輸入密碼,

正常情況下是需要輸入密碼的,注意標紅位置:

至此基本的SSH攻擊已經結束了,思路很簡單這個應該是基本功無壓力,下面的程序就比較有識訓了,
四、回應方法
1. 登陸目標主機關閉ssh服務、查看被爆破成功賬戶、判斷是否存在ssh免密登陸,
1)關閉ssh服務
systemctl stop sshd 或者/etc/init.d/sshd stop
2)查看被爆破成功的賬戶
兩種方案可以查看到
2.1)第一種是查看ssh日志中的關鍵字眼 Accepted password for
注意Accepted的第一個字母大寫否則匹配不到記錄:
cat /var/log/secure | grep "Accepted password for"

從日志中能夠發現victim和root賬戶均被爆破出來,
2.2)第二種是last命令查看登陸地址資訊
last 命令效果等同于 who /var/log/wtmp,

3)檢查是否存在免密登陸
因為從日志和wtmp記錄中我們看到攻擊者已經登陸了victim和root賬戶所以我們需要在這兩個賬戶下面分別查看是否存在ssh公鑰資訊,
3.1)首先查看普通賬戶victim的.ssh目錄下是否存在authorized_keys檔案
ls -l /home/victim/.ssh/

從上面可以看出victim賬戶存在免密登陸而且還記錄到了攻擊者服務器的主機名和用戶名資訊,
3.2)然后查看root賬戶的.ssh目錄是否存在authorized_keys檔案
ls -l /root/.ssh/

從結果可以看到root賬戶下不存在免密登陸,
2. 檢查系統用戶是否存在例外賬號若存在清除例外賬戶
cat /etc/passwd

無例外賬戶
3. 檢查ssh日志是否存在短時間內大量的嘗試登陸行為,從而判斷這個登錄成功的賬戶是正常登陸還是例外登陸
查看secure日志檔案判斷是否存在大量的Invalid user 字眼
cat /var/log/secure | grep "Invalid user"
cat /var/log/secure | grep "Accepted password for victim from 192.168.171.130" 記錄登陸成功的時間點然后判斷是否跟暴力破解的時間段一致,如果一致則表示該賬戶是被爆破成功登陸,或者直接找管理員確認登陸資訊是否正常,

跟上面的secure日志中的時間點做匹配可以看到該賬戶是被暴力破解出來的,
4,檢查定時任務是否存在例外情況
1)crontab -l查看當前用戶的定時任務資訊
2)sudo crontab -u root -l 查看root賬戶的定時任務資訊
3)查看/etc/cron.d/檔案夾中是否存在檔案

能夠看到cron.d檔案夾中存在定時任務但是內容不含攻擊行為,
4)查看/etc/cron.daily/ /etc/cron.weekly/ /etc/cron.hourly/ /etc/cron.monthly/ 這些檔案夾下面是否存在定時任務

五、修復方案
1. 修改被爆破賬戶密碼增加密碼復雜度
分別執行passwd victim 和passwd root命令修改victim和root賬戶密碼,
2. 清除免密登陸資訊
洗掉.ssh/目錄下的authorized_keys檔案,
rm -rf .ssh/authorized_keys
3,清除定時任務
如果存在定時任務直接洗掉定時任務檔案或者進入到定時任務檔案中洗掉所在行資訊即可,
4,增加ssh登陸失敗次數限制
編輯sshd_config組態檔修改MaxAuthTries記錄,(sshd_config檔案路徑為 /etc/ssh/sshd_config)
![]()
保存退出后重啟sshd服務,
再次嘗試登陸且輸入密碼超過2次后會出現如下資訊,
再次使用hydra嘗試爆破ssh用戶名密碼,
查看secure日志:

為什么呢?為什么會出現這種情況呢?
我們已經在SSH的組態檔中增加次數限制了為什么還是可以爆破成功呢?
是因為我們在這里對登陸失敗次數做限制了,但是沒有鎖定賬戶,也就是說這個賬戶依然可以被暴力破解只是破解的速度會慢一點而已,
那正確的方式應該怎么做呢,
需要通過pam來鎖定超過登陸次數的賬戶編輯/etc/pam.d/sshd檔案:
vim /etc/pam.d/sshd
增加如上所示一條記錄該條記錄,表示登陸失敗超過三次后就鎖定300秒,root賬戶如果三次嘗試后也不行將被鎖定1200秒,
欄位解釋:
deny表示的是設定的最大失敗次數
unlock_time 表示的是鎖定多長時間單位是秒
deny_root 表示root賬戶也封鎖
root_unlock_time 表示的是root賬戶的鎖定時間
注:
如果限制ssh登陸則編輯sshd檔案
如果限制終端登陸則編輯login檔案
再次嘗試hydra爆破
發現無法成功爆破查看secure日志:
日志中顯示victim賬戶已經被鎖定,
查看鎖定的賬戶和登陸失敗的次數:
sudo pam_tally2 --user victim
這時候嘗試輸入正確密碼嘗試登陸:

依然無法登陸,那怎么解除封鎖呢?
只需要將pam中的記錄清除掉即可,
sudo pam_tally2 --user victim --reset
再次嘗試登陸victim賬戶:

可以發現能夠正常登陸了
5. 限制只允許特定ip地址訪問ssh
通過編輯/etc/hosts.allow和/etc/hosts.deny這兩個檔案來控制訪問源ip地址范圍,當兩個檔案同時存在策略的時候allow檔案的優先級大于deny檔案,
這里我們限制victim主機只允許171.1訪問其他全阻斷,
1)vim /etc/hosts.allow 增加如下記錄
sshd:192.168.171.1:allow
2)vim /etc/hosts.deny 增加如下記錄sshd:ALL
然后測驗從171.130 ssh訪問171.121主機如下所示可以看到通過171.130無法登陸,
查看171.1主機仍然處于登陸狀態,
![]()
6. 限制只允許特定用戶訪問ssh
通過編輯sshd組態檔增加AllowUsers和DenyUsers配置選項來控制允許登陸的用戶,
sudo vim /etc/ssh/sshd_config在檔案中追加如下配置,如果記錄存在直接修改記錄即可,如果記錄不存在需要在檔案末尾追加,
AllowUsers victim
DenyUsers root
配置完畢后重啟sshd服務然后分別嘗試以vicitm和root賬戶登陸victim主機,

可以看到victim賬戶可以直接登陸root賬戶則無法直接登陸,
這樣我們可以通過控制ip和賬戶資訊來實作完美控制限制只允許從某臺主機使用某個賬戶登陸,
但是這樣有點麻煩需要編輯hosts.allow、hosts.deny和sshd_config檔案,其實我們可以直接編輯sshd_config檔案增加如下記錄:
AllowUsers victim@192.168.171.1
這樣我們就可以限制只允許171.1通過victim賬戶登陸victim主機了,
我們在其他主機嘗試用victim賬戶登陸如下圖所示可以看到無法登陸,

7. 修改對外提供ssh服務的埠號
1)編輯sshd_config檔案增加如下配置
port 22
port 3389
增加另外一個ssh埠號3389避免修改失敗連接不上主機了
2)向防火墻添加修改的埠號
sudo firewall-cmd --zone=public --add-port=3389/tcp --permanent
多載防火墻
sudo firewall-cmd --reload
查看埠號是否添加成功
sudo firewall-cmd --zone=public --query-port=3389/tcp
提示yes表示成功添加
3)向selinux中添加修改的埠號
3.1)首先要安裝selinux的管理工具semanage
sudo yum provides semanage
sudo yum install policycoreutils-python #安裝依賴包
3.2)安裝完成后可以使用semanage命令查看ssh服務埠
sudo semanage port -l | grep ssh
![]()
向selinux添加ssh埠
sudo semanage port -a -t ssh_port_t -p tcp 3389
驗證ssh埠是否添加成功
sudo semanage port -l | grep ssh

添加后重啟ssh服務
systemctl restart sshd
重啟后我們可以嘗試用3389登陸

輸入密碼后成功登陸,
4)洗掉22埠號
4.1)編輯sshd_config檔案注釋掉22埠
4.2)firewall_cmd洗掉22埠
firewall-cmd --zone=public --remove-port=22/tcp --permanent
多載防火墻
sudo firewall-cmd --reload
4.3)selinux不用洗掉22埠或者說你也洗掉不了,但是不影響我們的需求
4.4)重啟sshd服務然后嘗試用22埠連接victim主機發現是無法連接的使用3389埠是可以的

策略正常生效
到此加固作業已經完成,后面的可忽略
附:
六、檢測方法
檢測需求如下:
1. 能夠檢測到嘗試登陸行為
2. 能夠檢測到登陸成功行為
3. 能夠檢測到登陸成功賬戶
4. 收集用戶字典
5. 記錄登錄失敗的用戶名/次數、登錄失敗用戶正確的次數、登錄成功的用戶名/次數、登陸成功的攻擊源IP地址/嘗試次數、登錄失敗的攻擊源IP地址/嘗試次數(自己可以羅列更詳細需求)
檢測方法:
我們從secure日志檔案分析來開展檢測作業,通過對secure日志檔案進行分析我們提取如下關鍵資訊,
ssh服務的默認日志記錄在/var/log/secure檔案中,關于ssh服務的日志存在五種情況,注意標黑和標紅的字眼,
1. 用戶名錯誤用戶名錯誤的日志如下所示:
Jan 14 07:37:41 victim sshd[54715]: Invalid user victim1 from 192.168.171.130 port 48550
Jan 14 07:37:41 victim sshd[54715]: input_userauth_request: invalid user victim1 [preauth]
在錯誤用戶的基礎上輸入密碼會出現如下日志
Jan 14 07:37:59 victim sshd[54715]: pam_unix(sshd:auth): check pass; user unknown
Jan 14 07:37:59 victim sshd[54715]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.171.130
Jan 14 07:38:01 victim sshd[54715]: Failed password for invalid user victim1 from 192.168.171.130 port 48550 ssh2
2. 用戶名正確但輸入錯誤密碼的日志如下所示:
Jan 14 07:37:08 victim unix_chkpwd[54691]: password check failed for user (victim)
Jan 14 07:37:08 victim sshd[54689]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.171.130 user=victim
Jan 14 07:37:10 victim sshd[54689]: Failed password for victim from 192.168.171.130 port 48548 ssh2
3. 用戶名正確且輸入正確密碼的日志如下所示:
Jan 14 07:37:30 victim sshd[54689]: Accepted password for victim from 192.168.171.130 port 48548 ssh2
Jan 14 07:37:30 victim sshd[54689]: pam_unix(sshd:session): session opened for user victim by (uid=0)
4. 客戶端主動退出ssh連接的日志如下所示
Jan 14 07:37:38 victim sshd[54694]: Received disconnect from 192.168.171.130 port 48548:11: disconnected by user
Jan 14 07:37:38 victim sshd[54694]: Disconnected from 192.168.171.130 port 48548
Jan 14 07:37:38 victim sshd[54689]: pam_unix(sshd:session): session closed for user victim
5. 客戶端強制關閉ssh連接的日志如下所示
Jan 14 07:42:25 victim sshd[54718]: Connection closed by 192.168.171.130 port 48552 [preauth]
由上所述,我們需要做的檢測策略如下:
1. 能夠檢測到嘗試登陸行為
1)這里我們設定10秒鐘內發現5條存在 invalid user 或者password check failed陳述句的記錄則表示存在嘗試登陸行為(規則可自定義:包括時間和記錄數)
2. 能夠檢測到登陸成功行為
1)檢索所有日志發現存在 accepted password for 陳述句的記錄則判定存在登陸成功情況
3. 能夠檢測到登陸成功賬戶
1)提取日志中匹配到accepted password for關鍵詞陳述句后面的一個欄位
4. 收集用戶字典
1)提取日志中匹配到Invalid user關鍵詞陳述句后面的一個欄位
5. 記錄登錄失敗的用戶名/次數、登錄失敗用戶正確的次數、登錄成功的用戶名/次數、登陸成功的攻擊源IP地址/嘗試次數、登錄失敗的攻擊源IP地址/嘗試次數
1)通過各種計算方法來統計如上資訊
檢查腳本如下:
#!/usr/bin/python
#coding:utf-8
from collections import Counter
#定義關鍵詞資訊
username_error='Invalid user'
username_correct='password check failed'
username_password_correct='Accepted password for'
user_quit='Received disconnect from'
user_forcequit='Connection closed'
#打開日志檔案
f=open('secure','r')
#定義檢測方法
def attack_detect():
#用戶名錯誤的請求次數
failed_account=0
#用戶名正確且密碼錯誤的請求次數
correct_user_account=0
#用戶名正確且密碼正確的請求次數
correct_pass_account=0
#記錄錯誤的用戶名
failed_user=[]
#記錄用戶名正確且密碼錯誤的用戶名
correct_user=[]
#記錄用戶名正確且密碼正確的用戶名
correct_pass=[]
#記錄登錄失敗的ip地址
failed_ipaddr=[]
#記錄登錄失敗&用戶名正確的ip地址
correct_ipaddr=[]
#記錄登錄成功的ip地址
correct_pass_ipaddr=[]
#標志位
alert=True
for i in f:
if username_error in i:
failed_account += 1
failed_user.append(i.split(': ')[1].split()[2])
failed_ipaddr.append(i.split(': ')[1].split()[4])
if username_correct in i:
correct_user_account += 1
correct_user.append(i.split(': ')[1].split('(')[1].strip(')'))
if username_password_correct in i:
correct_pass_account += 1
correct_pass.append(i.split(': ')[1].split()[3])
correct_pass_ipaddr.append(i.split(': ')[1].split()[5])
if failed_account > 30 and alert:
print 'exists ssh enumrate'
alert=False
#記錄登陸失敗攻擊源IP地址和嘗試次數
failed_ipaddr_count=Counter(failed_ipaddr)
failed_ipaddr_dict=dict(failed_ipaddr_count)
#記錄登陸成功攻擊源IP地址和嘗試次數
correct_pass_ipaddr_count=Counter(correct_pass_ipaddr)
correct_pass_ipaddr_dict=dict(correct_pass_ipaddr_count)
#記錄登陸失敗用戶名和次數
failed_user_count=Counter(failed_user)
failed_user_dict=dict(failed_user_count)
#記錄登陸失敗用戶名正確和次數
correct_user_count=Counter(correct_user)
correct_user_dict=dict(correct_user_count)
#記錄登陸成功用戶名和次數
correct_pass_count=Counter(correct_pass)
correct_pass_dict=dict(correct_pass_count)
#記錄所有嘗試次數
all_account=failed_account+correct_user_account+correct_pass_account
return all_account,failed_account,correct_user_account,correct_pass_account,failed_user_dict,correct_user_dict,correct_pass_dict,failed_ipaddr_dict,correct_pass_ipaddr_dict
然后執行該腳本可以得出如下結果:
從結果中可以看出該腳本能夠滿足我們的需求,但是我們需要考慮如何把這段腳本加入到spark streaming中,
八、技術實作
1. victim主機上的flume配置
注意:這里在配置channels選項的時候,增加了下面兩個條目:
a1.channels.c1.keep-alive = 60
a1.channels.c1.capacity = 1000000
這里表示增加channels中queue的大小,默認為100,如果使用默認值,當處理大量的日志時就會發生如下報錯情況,

2. observer主機上的flume配置
3. observer上的kafka、zookeeper配置
kafka和zookeeper的配置保持不變即可
4. spark streaming配置
#!/usr/bin/python
#coding:utf-8
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
from pyspark.streaming.kafka import KafkaUtils
from collections import Counter
import datetime
import json
#定義保存的檔案名
destname="result.json"
#定義讀取檔案方法
def readjson(file_name):
with open (file_name,"r") as file_obj:
numbers = json.load(file_obj)
print "讀取json檔案:",numbers
return numbers
#定義寫入檔案方法
def writejson(file_name,nums):
with open (file_name,"w") as file_obj:
json.dump(nums,file_obj)
print "寫入json檔案:",nums
#第一步:創建一個本地的StreamingContext,并設定批處理周期為1s
sc=SparkContext("local[2]","flumeWordCount")
ssc=StreamingContext(sc,1)
#第二步:創建一個kafka連接
topic="streamingtopic"
brokers="hadoop0:9092"
#引數分別表示ssc連接名,串列形式顯示的topic名稱,brokers串列
directkafkaStream = KafkaUtils.createDirectStream(ssc,[topic],{"metadata.broker.list":brokers})
#第三步:資料處理&轉換
#0,提取kafka資料的第一個欄位為訊息正文欄位
lines = directkafkaStream.map(lambda x: x[1])
#1,定義檢測方法
def attack_detect(i):
username_error='Invalid user'
username_correct='password check failed'
username_password_correct='Accepted password for'
user_quit='Received disconnect from'
user_forcequit='Connection closed'
failed_account=0
correct_user_account=0
correct_pass_account=0
failed_user=[]
correct_user=[]
correct_pass=[]
failed_ipaddr=[]
correct_ipaddr=[]
correct_pass_ipaddr=[]
alert=True
if username_error in i:
print username_error
failed_account += 1
failed_user.append(i.split(': ')[1].split()[2])
failed_ipaddr.append(i.split(': ')[1].split()[4])
#print failed_account
if username_correct in i:
#print username_correct
correct_user_account += 1
correct_user.append(i.split(': ')[1].split('(')[1].strip(')').strip(')\n'))
if username_password_correct in i:
#print username_password_correct
correct_pass_account += 1
correct_pass.append(i.split(': ')[1].split()[3])
correct_pass_ipaddr.append(i.split(': ')[1].split()[5])
if failed_account > 5 and alert:
#print 'exists ssh enumrate'
alert=False
total_count=failed_account+correct_user_account+correct_pass_account
#記錄登陸失敗攻擊源IP地址和嘗試次數
failed_ipaddr_count=Counter(failed_ipaddr)
failed_ipaddr_dict=dict(failed_ipaddr_count)
#記錄登陸成功攻擊源IP地址和嘗試次數
correct_pass_ipaddr_count=Counter(correct_pass_ipaddr)
correct_pass_ipaddr_dict=dict(correct_pass_ipaddr_count)
#記錄登陸失敗用戶名和次數
failed_user_count=Counter(failed_user)
failed_user_dict=dict(failed_user_count)
#記錄登陸失敗用戶名正確和次數
correct_user_count=Counter(correct_user)
correct_user_dict=dict(correct_user_count)
#記錄登陸成功用戶名和次數
correct_pass_count=Counter(correct_pass)
correct_pass_dict=dict(correct_pass_count)
#這里將處理的資料以字典的形式保存到json檔案中,每次從json檔案中讀取變數值并跟處理的結果進行累加
nums=[{"total_count":total_count,"failed_account":failed_account,"correct_user_account":correct_user_account,"correct_pass_account":correct_pass_account,"failed_ipaddr_count":failed_ipaddr_count,"failed_ipaddr_dict":failed_ipaddr_dict,"correct_pass_ipadd_count":correct_pass_ipaddr_count,"correct_pass_dict":correct_pass_dict,"correct_pass_ipaddr_dict":correct_pass_ipaddr_dict,"failed_user_count":failed_user_count,"failed_user_dict":failed_user_dict,"correct_user_count":correct_user_count,"correct_user_dict":correct_user_dict}]
rs_old = readjson(destname)
for i in nums:
for j in rs_old:
for k,v in j.items():
if isinstance(v,dict):
for m,n in v.items():
try:
i[k][m] = i[k][m] + j[k][m]
except KeyError as e:
i[k][m] = j[k][m]
else:
i[k] = i[k] + j[k]
writejson(destname,nums)
#第四步:資料輸出,這里選擇列印出去
pairs=lines.map(lambda x:attack_detect(x))
pairs.pprint()
#第五步:開始sparkstreaming
ssc.start()
ssc.awaitTermination()
5. 啟動各個組件
1)先啟動zookeeper和kafka
./zkServer.sh start
./bin/kafka-server-start.sh $KAFKA_HOME/config/server.properties
2)然后啟動flume-server端(先監聽,后發送)
./bin/flume-ng agent --name a1 --conf $FLUME_HOME/conf --conf-file $FLUME_HOME/conf/collect-ssh-kafka.conf -Dflume.root.logger=INFO,console
3)啟動flume-client端(監聽檔案,發送資料到server端)
sudo ./flume-ng agent --name a1 --conf $FLUME_HOME/conf --conf-file $FLUME_HOME/conf/send-ssh.conf -Dflume.root.logger=INFO,console
4)啟動spark-streaming
./bin/spark-submit --packages org.apache.spark:spark-streaming-kafka-0-8_2.11:2.2.0 examples/src/main/python/streaming/sshdirect.py
6. 模擬攻擊者向victim發起ssh爆破行為
hydra -L user -P pass ssh://192.168.171.121:3389
然后我們查看result.json檔案中的內容不斷實時更新,攻擊完成后的最終結果如下:
![]()
由上所述我們能夠看到檔案記錄了ssh總攻擊次數、用戶名錯誤嘗試次數、用戶名正確登陸次數以及登陸源ip地址等資訊,
注:
1. 這里我使用的是以檔案形式進行存盤的,沒有使用mysql資料庫,理論上方法是一樣的,這里我就不演示了,有興趣的小伙伴可以自己搞
2. 這里的result.json檔案內容是固定的,必須要跟spark streaming腳本中的變數格式一致,否則可能會出現問題,后面附錄中我會把格式檔案貼上來
九、圖形頁面展示
這里我就以一個例子來展示吧,以條形圖的形式展示登陸失敗的用戶情況,
1,django環境安裝
注:已安裝django環境的自動忽略
1)使用virtualenv環境
virtualenv -p /usr/bin/python3 myechart
source myechart/bin/activate
pip install django==1.11.4
pip install pyecharts
2)新建django專案和app程式
django-admin startproject myechart
cd sshechart
python manage.py startapp sshechart
編輯myechart/settings.py檔案,注冊應用程式:
編輯sshechart的urls檔案,該檔案默認不存在,需要創建,內容如下:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
編輯myechart的urls檔案,更新內容如下:
2. 資料處理
1)編輯views.py檔案內容如下:
from __future__ import unicode_literals
import math
from django.http import HttpResponse
from django.template import loader
from pyecharts import Line
from django.shortcuts import render
import json
# Create your views here.
#加載echart.js檔案
REMOTE_HOST = "https://pyecharts.github.io/assets/js"
def index(request):
#指定模板檔案
template = loader.get_template('sshechart/index.html')
attack_line=line1()
context = dict(
myechart=attack_line.render_embed(),
host=REMOTE_HOST,
script_list=attack_line.get_js_dependencies()
)
return HttpResponse(template.render(context, request))
def line1():
#Line圖需要指定x軸和y軸資料
x_raw=[]
y_raw=[]
with open('result.json') as f:
numbers = json.load(f)
for i in numbers:
dic=i["failed_user_dict"]
print (dic)
for k,v in dic.items():
x_raw.append(k)
y_raw.append(v)
line_attack=Line("登陸失敗用戶",title_pos="45%")
line_attack.add("",x_raw,y_raw,mark_point=["max","min"],is_datazoom_show=True,datazoom_type="inside")
return line_attack
2)創建模板index.html檔案
在sshechart目錄下創建templates/sshechart目錄,

并編輯index.html檔案,內容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Proudly presented by PycCharts</title>
{% for jsfile_name in script_list %}
<script src="{{ host }}/{{ jsfile_name }}.js"></script>
{% endfor %}
</head>
<body>
{{ myechart|safe }}
</body>
</html>
3. 運行程式
運行程式后,在瀏覽器中打開目標網站,如下所示:
同樣的,還可以多添加幾個echart圖,增加分析維度,
也可以將這個里面的源代碼拷貝下來集成到其他web程式中,
至此,這個課題就此結束,期間也是碰到各種問題,拖延了不少時間,好在最終是搞定了,希望大家能夠在這里有所識訓,也希望大家能夠指出文章的不足之處,共勉之,
附錄:
1. result.json檔案格式
[{"failed_account": 0, "correct_user_dict": {}, "correct_pass_ipaddr_count": {}, "correct_pass_account": 0, "failed_ipaddr_dict": {}, "failed_user_dict": {}, "correct_pass_ipaddr_dict": {}, "correct_pass_dict":{},"total_count": 0, "correct_pass_ipadd_count": {}, "correct_user_count": {}, "correct_user_account": 0, "failed_user_count": {}, "failed_ipaddr_count": {}}]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291790.html
標籤:其他
