0x01 基礎概念
ICMP(Internet control Message Protocal)Internet報文協議,是TCP/IP的一種子協議,屬于網絡層協議,其目的是用于在IP主機、路由器之間傳遞控制信息
0x02 程序
程序
# -*- coding:utf-8 -*-
from scapy.all import *
from random import randint
from optparse import OptionParserdef Scan(ip):'''Scan函數通過調用ICMP,將構造好的請求包發送到目的地址,并根據目的地址的應答數據判斷目標主機是否存活。存活的IP地址打印出“xx.xx.xx.xx--->Host is up",不存活的主機打印出"xx.xx.xx.xx--->Host is down"::param ip::return:'''ip_id = randint(1,65535)icmp_id = randint(1,65535)icmp_seq = randint(1,65535)packet = IP(dst=ip,ttl=64,id=ip_id)/ICMP(id=icmp_id,seq = icmp_seq)/b'rootkit'result = sr1(packet,timeout=1,verbose=False)if result:for rcv in result:scan_ip = rcv[IP].srcprint(scan_ip+'--->''Host is up')else:pass# print(ip+'---> host is down')def main():parser = OptionParser("usage:%prog -i <target host>")#輸出幫助信息parser.add_option("-i",type='string',dest='IP',help='specify target host')#獲取IP地址參數options,args = parser.parse_args()print("Scan report for"+options.IP+"\n")#判斷是單臺主機還是多臺主機#IP中存在-,說明是要掃描多臺主機if '-' in options.IP:#代碼舉例:192.168.1.1-120#通過'-'進行分割,把192.168.1.1和120分開#把192.168.1.1通過','進行分割,取最后一個數作為range函數的start,然后把120+1作為range函數的stop#這樣循環遍歷出需要掃描的IP地址for i in range(int(options.IP.split('-')[0].split('.')[3]),int(options.IP.split('-')[1])+1):Scan(options.IP.split('.')[0]+'.'+options.IP.split('.')[1]+'.'+options.IP.split('.')[2]+'.'+str(i))time.sleep(0.2)else:Scan(options.IP)print("\nScan finished!...\n")if __name__ == '__main__':try:main()except KeyboardInterrupt:print("interrupted by user,killing all threads...")
結果:
0x03 分析
關于optionparser的使用
- 創建parser實例
- 使用add_option添加我們要處理的命令行參數
- 得到解析sys.argv后的options對象,查看用戶的輸入
from optparse import OptionParserparser = OptionParser(...)parser.add_option(.....)
- OptionParser()不要求一定要傳遞參數
OptionParser(usage="%prog",version="%prog 1.0",description="hello")#%prog 在這里會自動替換為程序名字#usage 可以打印用法#version 在使用%prog --version的時候輸出版本信息#description 描述信息
- add_option添加命令行參數
#action 指示optparser解析參數時候該如何處理。默認是'store',表示將命令行參數值保存options 對象里 。<br>action的值有:store,store_true,store_false,store_const,append,count,callback.
#type 默認是“string",也可以是"int","float"等
#dest 如果沒有指定dest參數,將用命令行參數名來對options對象的值進行存取。
#store store可以為store_true和store_false兩種形式。用于處理命令行參數后面不帶值的情況。如-v,-q等命令行參數。
#default 設置默認值
#help 指定幫助文檔
#metavar 提示用戶期望參數
- 最后調用parse_args()解析命令行形參
(options, args) = parser.parse_args()可以傳遞一個參數列表給parse_args(),否則,默認使用命令行參數(sysargv[1:])。
parse_args()返回兩個值:options, 這是一個對象(optpars.Values),保存有命令行參數值。只要知道命令行參數名,如file,就可以訪問其對應的值:options.file。args,一個由positional arguments組成的列表。
這里要特別注意options和args,options訪問值是options.參數名
,args是一個列表
例如:
from optparse import OptionParser
#創建parser實例
parser = OptionParser()
#添加參數
parser.add_option('-s','--server',dest='server',help='server ip_address')
parser.add_option('-P','--port',type='int',dest='port',help='server port')
parser.add_option('-u','--username',dest='username',help='username info')
parser.add_option('-p','--password',dest='password',help='password info')
#獲取值
options,args=parser.parse_args()
print(options)
print(args)
#獲取特定參數
serv = options.server
user = options.username
print(serv)
print(user)
我們命令行輸入:
python test.py -s 192.168.142.145 -P 80 -u name -p 123456 111 22 333
輸出結果:
這里重點看懂:
- options獲取的是哪些值?就是我們dest值以及參數值,比如
-p 80
,options里的值是'port':80
- args獲取的是哪些值?就是除了參數和參數值以外的,這里是
['111', '22', '333']
,這個是列表類型 - 如何獲取特定參數值?使用
options.dest值
- 使用OptionParser的三步驟,創建對象—》添加參數----》獲取輸入值
雖然我們沒有添加-h,我們依然可以使用-h獲取幫助文檔
這里看明白,main函數基本就能看懂了,對于Scan函數,使用的是scapy模塊的一些知識,可以這篇文章:
https://blog.csdn.net/qq_41683305/article/details/117436197
main主要用來獲取IP地址的,并將IP地址依次傳入Scan函數進行就行判斷,是否存在該主機
0x04 參看文章
https://www.cnblogs.com/blacksunny/p/5315545.html