Python 掃描探測

“腳本小子”就是會使用各種厲害的工具;“hacker”要了解工具的原理,會寫各種工具;

當然,目前我還是小白菜一棵,進修視頻學習中!

1 ARP掃描

ARP報格式:

以太網首部:

字段            長度(Byte)          默認值                 備註
接收方MAC        6                                        廣播時,爲 ff-ff-ff-ff-ff-ff
發送方MAC        6        
Ethertype        2                 0x0806                0x0806是ARP幀的類型值

ARP包:

字段            長度(Byte)         默認值                  備註
硬件類型         2                  0x1                  以太網類型值
上層協議類型     2                  0x0800               上層協議爲IP協議
MAC地址長度      1                  0x6                  以太網MAC地址長度爲 6
IP地址長度       1                  0x4                  IP地址長度爲 4
操作碼           2                                       0x1表示ARP請求包,0x2表示應答包
發送方MAC        6        
發送方IP         4        
接收方MAC        6        
接收方IP         4        
填充數據         18      因爲物理幀最小長度爲64字節,前面的42字節再加上4個CRC校驗字節,還差18個字節

來自:http://blog.csdn.net/shanzhizi

 

ARP小工具實現:

仿造ARP包構造:

# -- coding:UTF-8 --
import logging
import sys
from scapy.all import *

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)#清除報錯

def arp_request(ip_address,queue=None):
    result = srp(Ether(dst='FF:FF:FF:FF:FF:FF')
            /ARP(op=1,hwdst='00:00:00:00:00:00',pdst=ip_address),
            timeout=1,verbose=False)
    try:
        result_list = result[0].res #將響應的數據報對組成爲一組清單
        #[0]爲第一組相應的包
        if queue == None:
            return result_list[0][1].getlayer(ARP).fields['hwsrc']
            #[1]接受的包,[0]發送的包
        else:
            queue.put((ip_address,result_list[0][1].getlayer(ARP).fields['hwsrc']))
    except:
        return
if __name__ == "__main__":
    print(arp_request(sys.argv[1]))
# -- coding:UTF-8 --
import ipaddress
import logging
import sys
from arpRequest import arp_request
from multiprocessing import Process,Queue

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)#清除報錯

def arp_scan(network):
    qyt_queue = Queue()
    net = ipaddress.ip_network(network.decode('gbk'))
    for ip in net:
        ip_addr = str(ip)
        arp_one = Process(target=arp_request,args=(ip_addr,qyt_queue))
        arp_one.start()
    time.sleep(2)
    ip_mac_list =[]
    while True:
        if qyt_queue.empty():
            break
        else:
            ip,mac = qyt_queue.get()
            ip_mac_list.append((ip,mac))
    return ip_mac_list

if __name__ =="__main__":
    active_ip_mac = arp_scan(sys.argv[1])
    print("活動的IP和MAC地址如下:")
    for ip,mac in active_ip_mac:
        print(ip,mac)

 結果:

 

2 TCP端口掃描

1)全掃描

原理

掃描主機嘗試與目標主機的某個端口建立正規的三次握手的連接,連接由系統調用connect()開始。如果端口開放,則連接將建立成功;否則,返回-1,則表示端口關閉。

技術特點

    優點:實現簡單;對操作者的權限沒有嚴格要求;掃描速度快。

    缺點:掃描方式不隱蔽;很容易被檢測出來,且在日誌文件中會有大量密集的連接和錯誤記錄;容易被防火牆發現和屏蔽。

2)半掃描

原理:

掃描主機向目標主機的某個端口發送SYN數據段。如果應答是RST,那麼,說明端口是關閉的,按照設定繼續探聽其他端口;如果應答中包含SYN和ACK,說明目標端口處於監聽狀態。由於SYN掃描時,全連接尚未建立,所以,這種技術通常被稱爲“半連接”掃描。

技術特點:

    優點:日誌中對於掃描的記錄量很少。

    缺點:在大部分操作系統中,發送主機需要構造適用於這種掃描的IP包,需要超級用戶或者得到授權的用戶纔可以。

3)祕密掃描

原理:

使用FIN數據包探測端口:當一個FIN數據包到達一個關閉的端口,數據包會被丟掉,且返回一個RST數據包。當一個FIN數據包到達一個打開的端口,數據包只是簡單丟掉(不返回RST數據包)。由於這種技術不包含標準的TCP三次握手協議的任何部分,所以無法被記錄下來,所以叫祕密掃描。

技術特點:

優點:祕密掃描能躲避IDS、防火牆、包過濾器和日誌審計,從而獲取目標端口的開放或關閉的信息。

缺點:和SYN掃描類似,祕密掃描也需要構造自己的IP包,也需要權限。

 構造包的依據:

半掃描依據:

 發送標誌syn=1的包,0000 0000 0010,可以寫成flags=2或flags='S',

判斷收到的包是否爲ack+syn,0000 0001 0010,即判斷flafs==18.

# -- coding:UTF-8 --
import logging
import sys
from scapy.all import *

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)#清除報錯

def tcp_scan(hostname,lport,hport):
    result = sr(IP(dst=hostname)
                /TCP(dport=(int(lport),int(hport)),flags=2),
                timeout=1,verbose=False)
    
    result_list = result[0].res

    for i in range(len(result_list)):
        if result_list[i][1].haslayer(TCP):
            TCP_Fields = result_list[i][1].getlayer(TCP).fields

            if TCP_Fields['flags'] == 18:
                print('*端口號:'+str(TCP_Fields['sport'])+'is open!')

if __name__ == "__main__":
    print('------------------------------------------')
    if len(sys.argv)<4:
        print('格式錯誤,請按以下格式輸入:tcpScan.py IP startport endport')
	sys.exit(0)
    else:
        print('*正在掃描&'+sys.argv[1])
        print(tcp_scan(sys.argv[1],sys.argv[2],sys.argv[3]))

結果:

首先,ARP找到對方,然後發TCP包判斷

下面展示了不完整的三次握手過程!

3 NMAP Ping掃描

import nmap 
import sys

def nmap_ping(host):

    nm = nmap.PortScanner()
    result_raw = nm.scan(hosts=host,arguments ='-v -n -sn')
    host_list =[]
    for result in result_raw['scan'].values():
        if result['status']['state'] == 'up':
            host_list.append(result['addresses']['ipv4'])
    return host_list

if __name__ == "__main__":
    for host in nmap_ping(sys.argv[1]):
        print('%-20s %5s'% (host,'is up'))

 4 NMAP 全能掃描信息處理

效果:

源碼:

# -- coding:UTF-8 --
import nmap
import sys

def nmapAscan(host):
    nm = nmap.PortScanner()
    raw_result = nm.scan(hosts=host,arguments ='-v -n -A')
    for host,result in raw_result['scan'].items():
        if result['status']['state'] == 'up' :
            print('#'*17 + 'Host:' + host + '#'*17)
            print('-'*20 + '操作系統猜測' + '-'*20)
            for os in result['osmatch']:
                print('操作系統爲:'+ os['name'] + '準確度爲:' + os['accuracy'])
            idno =1
            try:
                for port in result['tcp']:
                    try :
                        print('-'*17 + 'TCP服務詳細信息' + '[' + str(idno) +']')
                        idno=idno+1
                        print('TCP端口號:' + str(port))
                        try:
                            print('狀態:'+ result['tcp'][port]['state '])
                        except :
                            pass
                        try:
                            print('原因:'+ result['tcp' ][port]['reason'])
                        except :
                            pass
                        try:
                            print('額外信息:' + result['tcp'][port]['extrainfo'])
                        except :
                            pass
                        try:
                            print('名字:'+ result['tcp'][port]['name'])
                        except :
                            pass
                        try:
                            print('版本:'+ result['tcp'][port]['version'])
                        except :
                            pass
                        try:
                            print('產品:' + result['tcp'][port]['product'])
                        except :
                            pass
                        try:
                            print('CPE:'+ result['tcp'][port]['cpe'])
                        except :
                            pass
                        try:
                            print('腳本:'+ result['tcp'][port]['script'])
                        except :
                            pass
                    except:
                        pass
            except:
                pass

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章