python编程书籍1020python编程书籍_从零单排之玩转Python安全编程(II)
轉自:http://www.secpulse.com/archives/35893.html
都說Python大法好,作為一名合格的安全從業人員,不會幾門腳本語言都不好意思說自己是從事安全行業的。
而Python是最容易入門且使用最順手的腳本語言,為了不引起程序員世界大戰,我們不說Python是世界上最好的語言,沒有之一。
這是《從零單排之玩轉Python安全編程》的第二篇。第一篇參見安全脈搏
本教程繼續展示一些基本的Python腳本概念。我們把我們的代碼轉換成一個腳本、函數、類和系統模塊。
Python的腳本結構:
下面是可用于啟動Python腳本(script)。
開始 我們通過“#!/usr/bin/env python”來告訴操作系統(OS)使用哪個編譯器(interpreter) 。
然后,我們聲明一個主功能 "def main()" 和最后2行代碼來讓 main()先運行。您可以在腳本中定義的其他功能,使代碼更容易理解和修改:
#!/usr/bin/python
import ,
def myFunction():
def main():
myFunction()
if __name__=="__main__":
main()
功能Functions:
利用函數的一種常用的方法是有一段代碼執行一些動作和返回輸出。下面是一些基本的代碼演示這個概念:
# Declare function/setup logic
def MyFunction:
...do work...
return output
#Call the function from main:
def main():
output = MyFunction(input)
類(classes):
Python類(classes)一開始可能會顯得混亂,因為它是一個不同的方式來設計你的代碼。
如果你把握了定義的概念,那么你可以把類(class)當成的數據(data)和定義(definition)的邏輯分組(logical grouping)。
這樣類將具有某些屬性(attribute)和與之相關聯的方法(method)。當你定義以后可以創建該類將繼承的屬性和與之關聯的方法的對象類,這被稱為面向對象編程(object-oriented programming)。
如果這個概念對于你來說很混亂,我建議你不要太在意類(classes)。你其實并不需要利用類(classes),但它可以使你的代碼少冗余。
下面我們將使用“類”關鍵詞來定義一類新的“域”(Domain) 。
有各種方法在類代碼可供選擇( various methods within the class code are available)當你需要一個Domain類型的對象(object of type Domain)。
>>> import os
>>> class Domain:
... def __init__(self, domain, port, protocol):
# Stores the variabled passed inside two variables
... self.domain=domain
... self.port=port
... self.protocol=protocol
# Defines a method to build a URL
... def URL(self):
... if self.protocol == 'https':
... URL = 'https://'+self.domain+':'+self.port+'/'
... if self.protocol == 'http':
... URL = 'http://'+self.domain+':'+self.port+'/'
... return URL
# Sets up a method to lookup resolve domain to IP using host command via os.system
... def lookup(self):
... os.system("host "+self.domain)
...
>>>
>>> domain=Domain('google.com', '443', 'https')
>>>
>>> dir(domain)
['URL', '__doc__', '__init__', '__module__', 'ip', 'lookup', 'port', 'protocol']
>>> domain.URL()
'https://8.8.8.8:443/'
>>> domain.ip
'8.8.8.8'
>>> domain.port
'443'
>>> domain.protocol
'https'
>>> domain.lookup()
google.com has address 74.125.228.233
google.com has address 74.125.228.227
google.com has address 74.125.228.232
如上圖 你可以看到在實例化域名類的一個實例后,你能運行類中的方法。
同樣,這個概念可以在第一會造成混淆,尤其是當你剛剛掌握Python和編程的時候。
你可以嘗試在一個你已經寫好的Python腳本里實現一個新的類,我發現這可能是開始把握概念的有效途徑。
處理命令行參數“sys”:
這個介紹里的最后一個模塊觸及的是sys模塊。這使您可以在讀取 CLI 給定的參數(argument),并將其拉進變量(variable)在腳本中。
語法是非常簡單的, sys.agrv[0]就是腳本名稱,并在命令行(command line)中給定每個參數(argument)后,每個參數會被分配一個號碼。
下面是一個簡單的例子:
import sys
script = sys.argv[0]
ip = sys.argv[1]
port = sys.argv[2]
print "[+] The script name is: "+script
print "[+] The IP is: "+ip+" and the port is: "+port
當這種快速腳本調用在命令行中,加上幾個參數就產生以下的輸出:
~$ python sys.py 8.8.8.8 53
[+] The script name is: sys.py
[+] The IP is: 8.8.8.8 and the port is: 53
繼續探索更多的Python模塊和內置的功能,因為他們會允許你解決問題容易得多,你開始編寫更復雜的代碼。
-----------------------------------------------------------------------------------------
接下來的教程將介紹建立網絡連接與Python通過構建一個基本的端口掃描器的概念。
在本教程中,我們將演示如何通過建立一個基本的端口掃描(port scanner)程序,使與Python的網絡連接。
我們將做的是建立網絡套接字連接一遍又一遍的使用IP/端口組合。為了做到這一點,我們將引入一個新的概念,循環(for loop):
>>>
>>> for port in range(1000,1024):
... print "[+] The port is: "+str(port)
...
[+] The port is: 1000
[+] The port is: 1001
[+] The port is: 1002
[+] The port is: 1003
[+] The port is: 1004
[+] The port is: 1005
[+] The port is: 1006
[+] The port is: 1007
[+] The port is: 1008
[+] The port is: 1009
[+] The port is: 1010
[+] The port is: 1011
[+] The port is: 1012
[+] The port is: 1013
[+] The port is: 1014
[+] The port is: 1015
[+] The port is: 1016
[+] The port is: 1017
[+] The port is: 1018
[+] The port is: 1019
[+] The port is: 1020
[+] The port is: 1021
[+] The port is: 1022
[+] The port is: 1023
請注意,for loop以上的代碼片段有縮進。通常人們縮進2個空格或制表符,不過只要你在整個腳本一致這些都無所謂。
為了做一個簡單的端口掃描程序(port scanner),我們將更換打印語句(print statement)為一個代碼片段(code snippet)來建立套接字連接(socket connection)。
下面的代碼演示了如何使用內置的socket 模塊(built-in socket module)進行套接字連接(socket connection):
>>>
>>> import socket
>>>
>>> s = socket.socket()
>>> s.connect(('127.0.0.1', 22))
>>> s.send('Primal Security \n')
17
>>> banner = s.recv(1024)
>>> print banner
OpenSSH
上面我們導入了socket 模塊(socket module)以及調用了connect()功能(function)來連接到給定的IP地址和端口號。
這將建立一個TCP連接( SYN / SYN - ACK / ACK ),我們實際上是使用send()功能(function)來將數據發送到指定的服務,并使用recv()來打印響應(response)。
現在,如果端口未打開socket 將拋出一個異常(exception):
>>>
>>> s.connect(('127.0.0.1', 23))
Traceback (most recent call last):
File "", line 1, in ?
File "", line 1, in connect
socket.error: (111, 'Connection refused')
這可以以多種方式來解決。現在,我們將用一種非常簡單的方法,使用“嘗試(try)/除外(except)”循環(loop),并通過異常(exception)。
>>>
>>> try:
... s.connect(('127.0.0.1', 23))
... except: pass
...
>>>
請注意沒有“error!” 這是一個很好的方式來讓你的代碼看起來像是它們在工作O(∩_∩)O~。現在,讓我們使用這些概念,并做出一個快速的環路(for loop)端口(port)掃描器(scanner):
>>>
>>> for port in range(20,25):
... try:
... print "[+] Attempting to connect to 127.0.0.1:"+str(port)
... s.connect(('127.0.0.1', port))
... s.send('Primal Security \n')
... banner = s.recv(1024)
... if banner:
... print "[+] Port "+str(port)+" open: "+banner
... s.close()
... except: pass
...
17
[+] Attempting to connect to 127.0.0.1:20
[+] Attempting to connect to 127.0.0.1:21
[+] Attempting to connect to 127.0.0.1:22
[+] Port 22 open: OpenSSH
[+] Attempting to connect to 127.0.0.1:23
[+] Attempting to connect to 127.0.0.1:24
[+] Attempting to connect to 127.0.0.1:25
上面我們展示的“試(try)/除外(except)”循環(loop)的基本用法來傳遞(pass) 端口(port)關閉時被socket (socket)拋出的異常(exception)。我們還展示了如何利用一個基本的條件語句 "if" 來只嘗試打印開放的端口,如果該端口回應我們的探頭(probe)。另一種方法來創建一個端口掃描器是 定義一個列表來包括你想用數組(array)來掃描的端口,然后循環(loop)通過這個數組(array):
>>>
>>> ports = [22, 445, 80, 443, 3389]
>>> for port in ports:
... print port
...
22
445
80
443
3389
>>>
如果我們想一次性處理多個主機(hosts),我們將利用一個嵌套循環(nested for loop)。這將涉及外層(outter layer)環路(for loop)來通過主機循環然后內循環(inner for loop)通過該端口(port)循環。下面是一個基本的例子來講述如何利用嵌套for循環來建立一個稍微復雜一些的掃描器:
>>>
>>> hosts = ['127.0.0.1', '192.168.1.5', '10.0.0.1']
>>>
>>> ports = [22, 445, 80, 443, 3389]
>>>
>>> for host in hosts:
... for port in ports:
... try:
... print "[+] Connecting to "+host+":"+str(port)
... s.connect((host, port))
... s.send('Primal Security \n')
... banner = s.recv(1024)
... if banner:
... print "[+] Port "+str(port)+" open: "+banner
... s.close()
... except:pass
...
[+] Connecting to 127.0.0.1:22
[+] Port 22 open: OpenSSH
[+] Connecting to 127.0.0.1:445
[+] Connecting to 127.0.0.1:80
[+] Connecting to 127.0.0.1:443
[+] Connecting to 127.0.0.1:3389
[+] Connecting to 192.168.1.5:22
[+] Connecting to 192.168.1.5:445
[+] Connecting to 192.168.1.5:80
[+] Connecting to 192.168.1.5:443
[+] Connecting to 192.168.1.5:3389
[+] Connecting to 10.0.0.1:22
[+] Connecting to 10.0.0.1:445
[+] Connecting to 10.0.0.1:80
[+] Connecting to 10.0.0.1:443
[+] Connecting to 10.0.0.1:3389
正如你可以通過輸出看到,它循環陣列的主機(hosts array),并嘗試端口陣列(port array)中的每個端口然后再移動到下一個主機。對于最終的端口掃描器,你可能會想要要修改打印報表來只打印開放的那些端口。
在一天結束時,你會發現Nmap仍然是端口掃描一個更好的選擇,但在以后的博客帖子內 我們將建立在這些概念來完成一些更實際的使用案例。花一些時間來探索socket 模塊(socket module) "dir(socket)" 內 提供的各種功能。
總結
以上是生活随笔為你收集整理的python编程书籍1020python编程书籍_从零单排之玩转Python安全编程(II)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux的accept函数源码,acc
- 下一篇: mysql行列转置-图文详解