转自:http://www.secpulse.com/archives/35893.html

都说Python大法好,作为一名合格的安全从业人员,不会几门脚本语言都不好意思说自己是从事安全行业的。

而Python是最容易入门且使用最顺手的脚本语言,为了不引起程序员世界大战,我们不说Python是世界上最好的语言,没有之一。

这是《从零单排之玩转Python安全编程》的第二篇。第一篇参见安全脉搏<从零单排之玩转Python安全编程(I)>


本教程继续展示一些基本的Python脚本概念。我们把我们的代码转换成一个脚本、函数、类和系统模块。

Python的脚本结构:

下面是可用于启动Python脚本(script)。

开始 我们通过“#!/usr/bin/env python”来告诉操作系统(OS)使用哪个编译器(interpreter) 。
然后,我们声明一个主功能 "def main()" 和最后2行代码来让 main()先运行。您可以在脚本中定义的其他功能,使代码更容易理解和修改:

#!/usr/bin/python
import <module1>,<module2> 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)" 内 提供的各种功能。

【原文:0x0-python-tutorials-getting-started-pt2 && 0×1 – Port Scanner 翻译:安全脉搏Dim7 转载请注明来自安全脉搏 分享技术 悦享品质

从零单排之玩转Python安全编程(II)的更多相关文章

  1. JAVA从零单排之前因

    本人,男,21岁,普通院校本科,计算机专业.大学之前对计算机编程没有一点涉及.大学学计算机专业也是个偶然.因为当初高考的成绩不好,结果都是我父亲帮我报的学校和专业. 上了大学之后,大一都是在新奇中度过 ...

  2. Unity3D游戏开发从零单排(四) - 制作一个iOS游戏

    提要 此篇是一个国外教程的翻译,尽管有点老,可是适合新手入门. 自己去写代码.debug,布置场景,能够收获到非常多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一 ...

  3. Web开发从零单排之一:在新浪云平台SAE上开发一个html5电子喜帖

    需求描述: 本人大婚将至,女朋友说“现在都流行在微信上发电子请帖了,你不是技(cheng)术(xu)宅(yuan)嘛,不会连这个都搞不定吧” 本人嘴上说这等小事何足挂齿,但心里还是七上八下的,虽然自认 ...

  4. HDU4870_Rating_双号从零单排_高斯消元求期望

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Other ...

  5. 从零单排Linux – 3 – 目录结构

    从零单排Linux – 3 – 目录结构 1.FHS标准(filesystem hierarchy standard) why? –> 为了规范,还有为了linux的发展 重点 –> 规范 ...

  6. 从零单排Linux – 2 – 目录权限

    从零单排Linux – 2 – 目录权限 1.sync 讲内存数据跟新到硬盘中 2.执行等级init a: run level 0:关机 b: run level 3:纯命令模式 c:run leve ...

  7. 从零单排Linux – 1 – 简单命令

    从零单排Linux – 1 – 简单命令 Posted in: Linux 从零单排Linux – 1 一.Linux的简单命令: 1.忘记root密码: 读秒时按任意键进入 – e – ↓选择第二个 ...

  8. 从零单排学Redis【铂金二】

    前言 只有光头才能变强 好的,今天我们要上[铂金二]了,如果还没有上铂金的,赶紧先去蹭蹭经验再回来(不然不带你上分了): 从零单排学Redis[青铜] 从零单排学Redis[白银] 从零单排学Redi ...

  9. 从零单排学Redis【铂金一】

    前言 只有光头才能变强 好的,今天我们要上铂金段位了,如果还没经历过青铜和白银和黄金阶段的,可以先去蹭蹭经验再回来: 从零单排学Redis[青铜] 从零单排学Redis[白银] 从零单排学Redis[ ...

随机推荐

  1. JS省份联级下拉框

    <script type="text/javascript"> var china=new Object();china['北京市']=new Array('北京市区' ...

  2. Windows下MySQL安装配置与使用

    1.下载. 下载地址: http://downloads.mysql.com/archives/get/file/mysql-5.7.11-winx64.zip. NavicatforMySQL:ht ...

  3. mybatis之<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim>的含义

    转自:http://blog.csdn.net/qq_33054511/article/details/70490046   <trim prefix="" suffix=& ...

  4. python--bs4

  5. 关于python浮点数的精度问题。

    若想严格按照四舍五入进行,可使用Decimal,代码如下: from decimal import Decimal, ROUND_HALF_UP def round(x, n): return Dec ...

  6. Flask的上下文管理机制

    前引 在了解flask上下文管理机制之前,先来一波必知必会的知识点. 面向对象双下方法 首先,先来聊一聊面向对象中的一些特殊的双下划线方法,比如__call__.__getattr__系列.__get ...

  7. CF986A Fair【图论/BFS】

    [题意]: 有些公司将在Byteland举办公平的会议.Byteland的n个城镇,m条两镇之间的双向道路.当然,你可以使用道路从任一个城镇到达任何城镇. 有k种商品产自Byteland,并且每个城镇 ...

  8. Southern African 2001 框架折叠 (拓扑序列的应用)

    本文链接:http://www.cnblogs.com/Ash-ly/p/5398377.html 题目:考虑五个图片堆叠在一起,比如下面的9 * 8 的矩阵表示的是这些图片的边缘框. 现在上面的图片 ...

  9. [Python Cookbook] Pandas: Indexing of DataFrame

    Selecting a Row df.loc[index] # if index is a string, add ' '; if index is a number, no ' ' or df.il ...

  10. 分层图【p2939】[USACO09FEB]改造路Revamping Trails

    Description 约翰一共有N)个牧场.由M条布满尘埃的小径连接.小径可 以双向通行.每天早上约翰从牧场1出发到牧场N去给奶牛检查身体. 通过每条小径都需要消耗一定的时间.约翰打算升级其中K条小 ...