这是做者的系列网络安全自学教程,主要是关于网安工具和实践操做的在线笔记,特分享出来与博友共勉,但愿您们喜欢,一块儿进步。前文分享了Python网络攻防相关基础知识,包括正则表达式、Web编程和套接字通讯,本文将继续分析Python攻防之多线程、C段扫描和数据库编程。本文参考了爱春秋ADO老师的课程内容,这里也推荐你们观看他Bilibili和ichunqiu的课程,同时也结合了做者以前的经验进行讲解。html
做者做为网络安全的小白,分享一些自学基础教程给你们,但愿大家喜欢。同时,更但愿你能与我一块儿操做深刻进步,后续也将深刻学习网络安全和系统安全知识并分享相关实验。总之,但愿该系列文章对博友有所帮助,写文不容易,大神请飘过,不喜勿喷,谢谢!python
下载地址:https://github.com/eastmountyxz/NetworkSecuritySelf-study
百度网盘:https://pan.baidu.com/s/1dsunH8EmOB_tlHYXXguOeA 提取码:izebgit
前文学习:
[网络安全自学篇] 一.入门笔记之看雪Web安全学习及异或解密示例
[网络安全自学篇] 二.Chrome浏览器保留密码功能渗透解析及登陆加密入门笔记
[网络安全自学篇] 三.Burp Suite工具安装配置、Proxy基础用法及暴库示例
[网络安全自学篇] 四.实验吧CTF实战之WEB渗透和隐写术解密
[网络安全自学篇] 五.IDA Pro反汇编工具初识及逆向工程解密实战
[网络安全自学篇] 六.OllyDbg动态分析工具基础用法及Crakeme逆向破解
[网络安全自学篇] 七.快手视频下载之Chrome浏览器Network分析及Python爬虫探讨
[网络安全自学篇] 八.Web漏洞及端口扫描之Nmap、ThreatScan和DirBuster工具
[网络安全自学篇] 九.社会工程学之基础概念、IP获取、IP物理定位、文件属性
[网络安全自学篇] 十.论文之基于机器学习算法的主机恶意代码
[网络安全自学篇] 十一.虚拟机VMware+Kali安装入门及Sqlmap基本用法
[网络安全自学篇] 十二.Wireshark安装入门及抓取网站用户名密码(一)
[网络安全自学篇] 十三.Wireshark抓包原理(ARP劫持、MAC泛洪)及数据流追踪和图像抓取(二)
[网络安全自学篇] 十四.Python攻防之基础常识、正则表达式、Web编程和套接字通讯(一)github
前文欣赏:
[渗透&攻防] 一.从数据库原理学习网络攻防及防止SQL注入
[渗透&攻防] 二.SQL MAP工具从零解读数据库及基础用法
[渗透&攻防] 三.数据库之差别备份及Caidao利器
[渗透&攻防] 四.详解MySQL数据库攻防及Fiddler神器分析数据包web
[python] 专题七.网络编程之套接字Socket、TCP和UDP通讯实例
[python] 专题八.多线程编程之thread和threading
[python] 专题九.Mysql数据库编程基础知识正则表达式
参考文献:
《安全之路Web渗透技术及实战案例解析》陈小兵老师
《Wireshark数据包分析实战》第二版 Chris Sanders
《TCP/IP协议栈详解卷一》 W.Richard Stevens算法
《Wireshark协议分析从入门到精通》-51cto老师
https://www.bilibili.com/video/av29479068
2019 Python黑客编程:安全工具开发 - bilibili 白帽黑客教程
http://www.heibanke.com/lesson/crawler_ex00/
python subprocess模块使用总结sql
声明:本人坚定反对利用社会工程学方法进行犯罪的行为,一切犯罪行为必将受到严惩,绿色网络须要咱们共同维护,更推荐你们了解它们背后的原理,更好地进行防御。shell
进程: 是程序的一次执行,每一个进程都有本身的地址空间、内存、数据栈及其余记录运行轨迹的辅助数据。
线程: 全部的线程都运行在同一个进程当中,共享相同的运行环境。线程有开始、顺序执行和结束三个部分。数据库
因为单线程效率低,这里引入了多线程编程。
计算机的核心是CPU,它承担了全部的计算任务,它就像一座工厂,时刻运行着。假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其余车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。
进程就比如工厂的车间,它表明CPU所能处理的单个任务。任一时刻,CPU老是运行一个进程,其余进程处于非运行状态。一个车间里,能够有不少工人。他们协同完成一个任务。线程就比如车间里的工人,一个进程能够包括多个线程。
Python thread模块能够调用下述函数实现多线程开启。它将产生一个新线程,在新的线程中用指定的参数和可选的kwargs来调用这个函数。
start_new_thread(function, args kwargs=None)
注意:使用这个方法时,必定要加time.sleep()函数,不然每一个线程均可能不执行。此方法还有一个缺点,遇到较复杂的问题时,线程数不易控制。
# -*- coding: utf-8 -*- # By:CSDN Eastmount 2019-10-05 import thread import time def fun1(): print "hello world %s" % time.ctime() #多线程 def main(): thread.start_new_thread(fun1, ()) #无参数 thread.start_new_thread(fun1, ()) time.sleep(2) print "over" #程序成功在同一时刻运行两个函数 if __name__ == '__main__': main()
输出结果以下图所示:
上面的代码简单讲述了thread模块的多线程使用。但实际应用中这种例子遇到比较少,而哪种状况比较多呢?假如说全部C段的地址ping探测其是否存活,代码以下。
# -*- coding: utf-8 -*- # By:CSDN Eastmount 2019-10-05 import thread import time from subprocess import Popen, PIPE def ping_check(): #check = Popen(['/bin/bash', '-c', 'ping -c 2 ' + '127.0.0.1'], stdin=PIPE, stdout=PIPE) ip = '127.0.0.1' #ping指定次数后中止ping 但报错访问被拒绝,选项 -c 须要具备管理权限。 #check = Popen("ping -c 3 {0} \n".format(ip), stdin=PIPE, stdout=PIPE, shell=True) check = Popen("ping {0} \n".format(ip), stdin=PIPE, stdout=PIPE, shell=True) data = check.stdout.read() #数据 print data #程序成功在同一时刻运行两个函数 if __name__ == '__main__': ping_check()
若是输入的ip地址为本机127.0.0.1,则输出正常连通结果,以下所示。
若是输入的ip地址为本机220.0.0.1,则提示超时,以下图所示。
接着思考:如何对一个C段网址进行ping探测呢?
设计一个循环,若是主机不存在,返回的是timeout;若是主机存在,则包含TTL字样,这里以TTL为判断标准,从而判断存活的数据。
# -*- coding: utf-8 -*- # By:CSDN Eastmount 2019-10-05 import thread import time from subprocess import Popen, PIPE def ping_check(): ip = '127.0.0.1' check = Popen("ping {0} \n".format(ip), stdin=PIPE, stdout=PIPE, shell=True) data = check.stdout.read() #数据 if 'TTL' in data: #存活 print 'UP' #程序成功在同一时刻运行两个函数 if __name__ == '__main__': ping_check()
输出结果为“UP”。
接下来咱们尝试检测ichunqiu网站的ip地址存活状况。首先,调用ping命令检测该网站的ip地址,即:1.31.128.240。
这里将ping_check()函数设置一个传递参数,对应ip地址,对它进行探测;经过thread线程实现ip地址存活性探测,能探测到不少存活的主机。
# -*- coding: utf-8 -*- # By:CSDN Eastmount 2019-10-05 import thread import time from subprocess import Popen, PIPE def ping_check(ip): check = Popen("ping {0} \n".format(ip), stdin=PIPE, stdout=PIPE, shell=True) data = check.stdout.read() #数据 if 'TTL' in data: #存活 print '%s is UP' % ip #主函数 if __name__ == '__main__': #寻找目标 ichunqiu 1.31.128.240 for i in range(1,255): ip = '1.31.128.' + str(i) #多线程方法 thread.start_new_thread(ping_check, (ip, )) time.sleep(0.1)
输出结果以下图所示:
问题:
在多线程编程中,几个线程是同时启动,因此输出也是输出在一行,那怎么才能换行输出呢?这里使用系统输出。
# -*- coding: utf-8 -*- # By:CSDN Eastmount 2019-10-05 import thread import time from subprocess import Popen, PIPE import sys def ping_check(ip): check = Popen("ping {0} \n".format(ip), stdin=PIPE, stdout=PIPE, shell=True) data = check.stdout.read() #数据 if 'TTL' in data: #存活 sys.stdout.write('%s is UP \n' % ip) #主函数 if __name__ == '__main__': #寻找目标 ichunqiu 1.31.128.240 for i in range(1,255): ip = '1.31.128.' + str(i) #多线程方法 thread.start_new_thread(ping_check, (ip, )) time.sleep(0.1)
按行输出结果,以下图所示:
thread模块存在一些缺点,尤为是线程数不能被控制。下面使用threading解决线程数可控制的问题。
# -*- coding: utf-8 -*- import threading import time import sys def fun1(key): sys.stdout.write('hello %s:%s \n'%(key, time.ctime())) def main(): threads = [] keys = ['a', 'b', 'c'] #线程数 threads_count = len(keys) for i in range(threads_count): t = threading.Thread(target=fun1, args=(keys[i],)) threads.append(t) for i in range(threads_count): threads[i].start() for i in range(threads_count): threads[i].join() if __name__ == '__main__': main()
输出结果以下图所示,三个线程同时发生。
多线程threading方法实现了咱们想要的功能,可以控制线程数,例如想写成requests模块,获取网站的status_code状态码。
# -*- coding: utf-8 -*- import threading import time import requests import sys def fun1(): time_start = time.time() r = requests.get(url="http://www.eastmountyxz.com/") times = time.time() - time_start #print('Status:%s--%s--%s'%(r.status_code, times, time.strftime('%H:%M:%S'))) sys.stdout.write('Status:%s--%s--%s\n'%(r.status_code, times, time.strftime('%H:%M:%S'))) def main(): threads = [] #线程数 网页访问10次 threads_count = 10 for i in range(threads_count): t = threading.Thread(target=fun1, args=()) threads.append(t) for i in range(threads_count): threads[i].start() for i in range(threads_count): threads[i].join() if __name__ == '__main__': main()
输出结果以下图所示:
生产者-消费者问题和Queue模块:
虽然threading解决了线程数可控问题,可是面对复杂问题的时候,好比生产者和消费者问题,仍然不能很好地解决。
生产者和消费者问题
生产者生产货物,将货物放到队列数据中,生产者在生产这些货物时,它的时间是不肯定的;当生存着将货物交给消费者,消耗的时间也是不肯定的;因为两个时间都不肯定,多线程编程存在必定问题。
这里引入Queue模块解决该问题。
import Queue queue = Queue.Queue() for i in range(10): queue.put(i) print(queue.empty()) print(queue.qsize()) #取数据 get依次取出里面的数据 print(queue.get()) print(queue.get())
输出结果以下所示:
生产者利用Queue将全部数据货物按顺序放入Queue,接着消费者依次取出Queue中的数据。接着实现C段扫描。
# -*- coding: utf-8 -*- # By:CSDN Eastmount 2019-10-05 import threading import Queue import sys from subprocess import Popen, PIPE #定义一个类 传入参数queue class DoRun(threading.Thread): def __init__(self, queue): threading.Thread.__init__(self) self._queue = queue def run(self): #非空取数据 while not self._queue.empty(): ip = self._queue.get() #print ip check_ping = Popen("ping {0} \n".format(ip), stdin=PIPE, stdout=PIPE, shell=True) data = check_ping.stdout.read() if 'TTL' in data: sys.stdout.write(ip+' is UP.\n') def main(): threads = [] threads_count = 100 queue = Queue.Queue() #放入ip地址 for i in range(1, 255): queue.put('1.31.128.' + str(i)) for i in range(threads_count): threads.append(DoRun(queue)) for i in threads: i.start() for i in threads: i.join() if __name__ == '__main__': main()
最终输出结果以下图所示,经过该代码能够实现检测某网站ip段的存活状况。
Python数据库编程,这里直接引入核心代码便可,更多参考前文:[python] 专题九.Mysql数据库编程基础知识
早期每一个数据库和Python创建链接时,都须要有对应的接口程序,这样致使数据库比较混乱,须要学习不少新的接口程序并修改大量代码。
后来为了解决该问题,咱们定义了相关的接口规范,全部数据库接入其中便可编程。咱们只要学会Python DB API,就能实现对不一样版本数据库的操做,这样更加方便快捷,更改的代码较少。
Python访问数据库的基本流程以下图所示:
Python调用MsSQL须要导入MySQLdb库,以下:
import MySQLdb
connect()函数
主要使用的方法是connect对象。connect()方法生成一个connect对象,用于访问数据库,其参数以下:
user:Username
password:Password
host:Hostname
database:DatabaseName
dsn:Data source name
注意并不是全部的接口程序都严格按照这种格式,如MySQLdb。
import MySQLdb conn = MySQLdb.connect(host='localhost', db='test01', user='root', passwd='123456', port=3306, charset='utf8')
connect()对象方法以下:
lose():关闭数据库链接,或者关闭游标对象
commit():提交当前事务
rollback():取消当前事务
cursor():建立游标或类游标对象
errorhandler(cxn,errcls,errval):做为已给游标的句柄
注意,执行close()方法则上述的链接对象方法不能再使用,不然发生异常。commit()、rollback()、cursor()或许更对于支持事务的数据库更有意义。数据库事务(Database Transaction) ,是指做为单个逻辑工做单元执行的一系列操做,要么完整地执行,要么彻底地不执行。 一旦你完成了数据库链接,关闭了游标对象,而后在执行commit()提交你的操做,而后关闭链接。
游标对象
上面说了connect()方法用于提供链接数据库的接口,若是要对数据库操做那么还须要使用游标对象。游标对象的属性和方法:
fetchone():能够看做fetch(取出) one(一个),也就是获得结果集的下一行(一行)。
fetchmany(size):能够看做fetch(取出)many(多个),这里的参数是界限,获得结果集的下几行(几行)
fetchall():顾名思义,取得全部。
execute(sql):执行数据库操做,参数为sql语句。
close():不须要游标时尽量的关闭
下面是一个获取MySQL数据库版本的代码,它覆盖了Python连接数据库的基本过程。
# -*- coding: utf-8 -*- import MySQLdb #创建链接 conn = MySQLdb.connect( host = '127.0.0.1', port = 3306, user = 'root', passwd = '123456' ) #执行最简单的语句 cus = conn.cursor() #查看MySQL的版本 sql = 'select version()' cus.execute(sql) #查看返回结果 print(cus.fetchone()) #关闭链接和对象 cus.close() conn.close()
输出结果以下图所示:
Python网络爬虫和MySQL数据库结合的文章参考做者前文:
[python爬虫] 招聘信息定时系统 (一).BeautifulSoup爬取信息并存储MySQL
[python爬虫] Selenium爬取内容并存储至MySQL数据库
但愿这篇文章对你有所帮助,这是Python网络攻防很是基础的一篇博客,后续做者也将继续深刻学习,制做一些经常使用的小工具供你们交流。
下午经过CSDN认识了一位计算机视觉方向的博友,咱们相约博士毕业回各自的家乡教书,虽天各一方,而且不认识,但已经是朋友,祝好。
晚上终于看懂了第一篇恶意代码检测的论文,溯源和扫描还须要多学习,多实验。同时,看了几篇讲梵高的文章,挺不错的。分享一段:
梵高的生活较为落魄和不堪,但他的做品里永远是明亮的,美好的,纯真的,积极的。1889年,他在精神病院里画出了《星空》,那大概是梵高心里最纯洁的颜色,罗纳河上的星空,让处于压迫的心里仍闪烁着点点星光。善良淳朴的人性之美,和坚持纯粹的艺术之美交合着。这大概就是为何他的做品特别能打动人的缘由!
晚安,女神,我也准备学学油画
(By:Eastmount 2019-10-05 晚上11点 http://blog.csdn.net/eastmount/ )