2013-06-19 428 views
1

我一直在研究一個Python程序,它搜索多個IP地址範圍並檢查SSL證書/讀取某些信息,然後將其寫入CSV文件。在Python中獲取服務器/服務器名稱指示

現在我遇到的麻煩是,我要通過搜索的一些IP地址可能在同一個IP地址上有多個域名。我一直在尋找嘗試,併爲此提出一些類型的解決方案,但似乎沒有太多關於使用OpenSSL中的SNI檢查IP地址的文檔

另外,我遇​​到的另一個問題是我想從證書中獲取服務器類型(例如,apache,nginx等),但是OpenSSL似乎沒有提供該信息。另一方面,Curl確實使用curl來確定是否在IP地址上找到了證書 - 我只是不知道如何從curl的輸出中獲取這些信息。

如果任何人都可以給我一些輸入以我如何實施上述兩個特點,我會很感激

這裏是我到目前爲止(藉口很長的硬編碼線程的代碼 - 我還沒有機會把它清理乾淨):

from subprocess import * 
import time 
import ssl 
import OpenSSL 
import threading 
import sys 
import csv 

def main(): 
    global IP_list 
    IP_list = [] 

    global certInfoHolder 
    certInfoHolder = [] 

    getRanges() 


def getRanges(): 
    print 'Enter a range(ex. From: 192.168.1.0 , To: 192.168.1.10)' 
    starting_IP = raw_input('From: ') 
    ending_IP = raw_input('To: ') 


    ip_ranges = ipRange(starting_IP, ending_IP) 
    addMore = raw_input('Do you want to add another IP range?Y/N') 
    addmore = addMore.lower() 
    if addMore == 'y' or addMore == 'yes': 
     getRanges() 

    elif addMore == 'n' or addMore =='no': 
     print 'Done gathering IP Addresses' 
     createdThreads = 0 
     threadSplit = len(IP_list)/10 

     #Splitting the work up between the threads 
     thread_1_list = IP_list[0:threadSplit] 
     thread_2_list = IP_list[threadSplit:(threadSplit*2)] 
     thread_3_list = IP_list[(threadSplit*2):(threadSplit*3)] 
     thread_4_list = IP_list[(threadSplit*3):(threadSplit*4)] 
     thread_5_list = IP_list[(threadSplit*4):(threadSplit*5)] 
     thread_6_list = IP_list[(threadSplit*5):(threadSplit*6)] 
     thread_7_list = IP_list[(threadSplit*6):(threadSplit*7)] 
     thread_8_list = IP_list[(threadSplit*7):(threadSplit*8)] 
     thread_9_list = IP_list[(threadSplit*8):(threadSplit*9)] 
     thread_10_list = IP_list[(threadSplit*9):(threadSplit*10)] 


     print '5 Threads..Splitting the work up to: ' , threadSplit 
     for address in range(threadSplit): 
      print address 
      thread_1 = getCertInfo(thread_1_list[address]) 
      thread_2 = getCertInfo(thread_2_list[address]) 
      thread_3 = getCertInfo(thread_3_list[address]) 
      thread_4 = getCertInfo(thread_4_list[address]) 
      thread_5 = getCertInfo(thread_5_list[address]) 
      thread_6 = getCertInfo(thread_6_list[address]) 
      thread_7 = getCertInfo(thread_7_list[address]) 
      thread_8 = getCertInfo(thread_8_list[address]) 
      thread_9 = getCertInfo(thread_9_list[address]) 
      thread_10 = getCertInfo(thread_10_list[address]) 
      thread_1.start() 
      thread_2.start() 
      thread_3.start() 
      thread_4.start() 
      thread_5.start() 
      thread_6.start() 
      thread_7.start() 
      thread_8.start() 
      thread_9.start() 
      thread_10.start() 
      thread_1.join() 
      thread_2.join() 
      thread_3.join() 
      thread_4.join() 
      thread_5.join() 
      thread_6.join() 
      thread_7.join() 
      thread_8.join() 
      thread_9.join() 
      thread_10.join() 
      if address == threadSplit-1: 
       for address in range(threadSplit,len(thread_5_list)): 
        thread_10 = getCertInfo(thread_10_list[address]) 
        thread_10.start() 
        thread_10.join() 

     c = csv.writer(open("AInfo.csv", "a")) 
     CIH = certInfoHolder 

     for info in CIH: 
      c.writerow([info[0], info[1], info[2], info[3], info[4]]) 

     print 'DONE' 



def ipRange(start_ip, end_ip): 
    start = list(map(int, start_ip.split("."))) 
    end = list(map(int, end_ip.split("."))) 
    temp = start 

    IP_list.append(start_ip) 
    while temp != end: 
     start[3] += 1 
     for i in (3, 2, 1): 
      if temp[i] == 256: 
       temp[i] = 0 
       temp[i-1] += 1   
     IP = ".".join(map(str, temp)) 
     IP_list.append(IP) 
    print 'IP_List size', len(IP_list) 


class getCertInfo(threading.Thread): 
    def __init__(self,IP): 
     threading.Thread.__init__(self) 
     self.IP_check=IP 

    def run(self): 
     try: 
      #Using curl to check for a timeout 
      self.getCert = check_output('curl --max-time 2 '+self.IP_check, 
      stderr=STDOUT, 
      shell=True) 
      #OpenSSL get server certificate 
      self.server_certificate = ssl.get_server_certificate((self.IP_check, 443)) 
      self.x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, self.server_certificate) 

      #Formatting expiration date and time 
      self.eDateT = str(self.x509.get_notAfter()) 
      #173.252.110.27 
      self.certInfo = self.x509.get_subject() 
      self.commonName = self.certInfo.commonName 
      self.companyName = self.certInfo.O 
      self.serialNumber = self.x509.get_serial_number() 
      self.x = [str(self.IP_check),str(self.companyName),str(self.eDateT), 
         str(self.commonName),str(self.serialNumber)] 
      certInfoHolder.append(self.x) 

     except CalledProcessError as detail: 
      print str(detail) + ' ' + self.IP_check +'\n' 
      pass 
+0

['subprocess.check_output()'](http://docs.python.org/2/library/subprocess.html#subprocess.check_output)將允許您更容易地刮擦curl調用的結果。 – Droogans

+0

['socket.gethostbyaddr()'](http://stackoverflow.com/a/2575779/881224)*可能*是你正在尋找與DNS查找。 – Droogans

回答

1

SNI

你應該能夠與Python 3.x系列到那裏,3.2+如果我理解正確。

如果您遇到了Python 2,請查看python請求對兩個可選依賴關係ndg-httpsclientpyasn1的處理方式。

我的理解是,你真的不能做與普通的Python < = 2.7.8由於開發者令人困惑的觀點,即SNI is somehow a feature of Python

編輯

由於PEP466,Python的2.7.9包含從Python 3.4反向移植的ssl模塊,並且您擁有所有OpenSSL功能。

其他項目

也許sslyze (github)可以做你想做什麼已經?