《Violent Python》第一章Introduction(3)中文版(乌云python,英文爱好者翻译)
介绍信息:http://zone.wooyun.org/content/23138
解释型python VS 交互型python
与其他脚本语言类似,Python是一种解释型语言。在运行时,解释器处理代码并执行他,为了演示python解释器的使用,我们写一个.py文件来打印“Hello World”。
为了解释这个程序,我们调用python解释器创建一个新的脚本。
programmer# echo print \"Hello World\" > hello.py
programmer# python hello.py
Hello World
此外,python具有交互能力,程序设计师可以调用python解释器,并直接与解释器“交流”。要启动解释器,程序开发者要先不带参数的执行python,接着解释器会呈现一个>>>来提示程序设计师,他可以接收命令了。在这里,程序设计师输入print “Hello World”。按下回车后,python交互解释器会立即执行该语句
programmer# python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
>>>
>>> print "Hello World"
Hello World
为了初步了解语言背后的含义,本章偶尔会用到python解释器的交互能力。你可以通过找寻>>>提示,来发现样例中对解释器的操作。
因为我们要解释下面章节中的样例,所以我们将通过数个被称为方法或函数的、有一定功能的代码块,来建立我们的脚本。每当我们完成一个脚本,我们将展示如何重新组合这些方法(函数)来让他们在main()中被调用。试图运行一个只有孤立的函数定义而不去调用他们的脚本是毫无意义的。大多数情况下,你都可以认出完整的脚本,因为他们都有定义好的main()函数。
在我们开始写我们的第一个程序前,我们将说明一些python标准库的重要组成部分。
Python语言
在下面的内容中,我们会讲解变量,数据类型,字符串,复杂的数据结构,网络,选择,循环,文件处理,异常处理,与操作系统进行交互。为了显示这一点,我们将构建一个简单的TCP类型的漏洞扫描器,读取来自服务的提示消息,并把他们与已知的存在漏洞的服务版本做比较,作为一个有经验的程序设计师,你可能会发现一些最初的示例代码的设计非常难看,事实上,我们希望你能在我们的代码基础上进行发展,使他变得优雅。
那么,让我们从任何编程语言的基础——变量开始吧!
变量
在python中,变量对应的数据存储在内存中,这种在内存中的位置可以存储不同的值,如整型,实数,布尔值,字符串,或更复杂的数据结构,例如列表或字典。在下面的代码中,我们定义一个存储整形的变量和一个存储字符串的提示消息,为了把这两个变量连接到一个字符串中,我们必须用str()函数。
>>> port = 21
>>> banner = "FreeFloat FTP Server"
>>> print "[+] Checking for "+banner+" on port "+str(port)
[+] Checking for FreeFloat FTP Server on port 21
当程序设计师声明变量后,python为这些变量保存了内存空间。程序设计师不必声明变量的类型,相反,python解释器决定了变量类型何在内存中为他保留的空间的大小。思考下面的例子,我们正确的声明了一个字符串,一个整数,一个列表和一个布尔值,解释器都自动的正确的识别了每个变量的类型。
>>> banner = "FreeFloat FTP Server" # A string
>>> type(banner)
<type 'str'>
>>> port = 21 # An integer
>>> type(port)
<type 'int'>
>>> portList=[21,22,80,110] # A list
>>> type(portList)
<type 'list'>
>>> portOpen = True # A boolean
>>> type(portOpen)
<type 'bool'>
字符串
在python中字符串模块提供了一系列非常强大的字符串操作方法。阅读http://docs.python.org/library/string.html上的用法列表的python文档。
让我们来看几个常用的函数。思考下面这些函数的用法,upper() 方法将字符串中的小写字母转为大写字母,lower()方法转换字符串中所有大写字母为小写,replace(old,new)方法把字符串中的old(旧字符串) 替换成 new(新字符串),find()方法检测字符串中是否包含指定的子字符串。
>>> banner = "FreeFloat FTP Server"
>>> print banner.upper()
FREEFLOAT FTP SERVER
>>> print banner.lower()
freefloat ftp server
>>> print banner.replace('FreeFloat','Ability')
Ability FTP Server
>>> print banner.find('FTP')
10
列表
Python的数据结构——列表,提供了一种存储一组数据的方式。程序设计师可以构建任何数据类型的列表。另外,有一些内置的操作列表的方法,例如添加,删除,插入,弹出,获取索引,排序,计数,排序和反转。请看下面的例子,一个程序通过使用append()添加元素来建立一个列表,打印项目,然后在再次输出前给他们排序。程序设计师可以找到特殊元素的索引(例如样例中的80),此外,指定的元素也可以被移动。(例如样例中的443)
>>> portList = []
>>> portList.append(21)
>>> portList.append(80)
>>> portList.append(443)
>>> portList.append(25)
>>> print portList
[21, 80, 443, 25]
>>> portList.sort()
>>> print portList
[21, 25, 80, 443]
>>> pos = portList.index(80)
>>> print "[+] There are "+str(pos)+" ports to scan before 80."
[+] There are 2 ports to scan before 80.
>>> portList.remove(443)
>>> print portList
[21, 25, 80]
>>> cnt = len(portList)
>>> print "[+] Scanning "+str(cnt)+" Total Ports."
[+] Scanning 3 Total Ports.
字典
Python的数据结构——字典,提供了一个可以存储任何数量python对象的哈希表。字典的元素由键和值组成,让我们继续用我们的漏洞扫描器的例子来讲解python的字典。当扫描指定的TCP端口是,用字典包含每个端口对应的常见的服务名会很有用。建立一个字典,我们能查找像ftp这样的键并返回端口关联的值21。
当我们建立一个字典时,每一个键和他的用被冒号隔开,同时,我们用逗号分隔元素。注意,.keys()这个方法将返回字典的所有键的列表,.items()这个方法将返回字典的元素的一系列列表。接下来,我们验证字典是否包含了指定的键(ftp)。
>>> services = {'ftp':21,'ssh':22,'smtp':25,'http':80}
>>> services.keys()
['ftp', 'smtp', 'ssh', 'http']
>>> services.items()
[('ftp', 21), ('smtp', 25), ('ssh', 22), ('http', 80)]
>>> services.has_key('ftp')
True
>>> services['ftp']
21
>>> print "[+] Found vuln with FTP on port "+str(services['ftp'])
[+] Found vuln with FTP on port 21