听说不想扯淡的程序猿,不是一只好猿。所以今天来扯扯淡,不贴代码,只讲设计思想。

0x00 起 - 初始设计

我们的目标是设计一枚通用的弱密码扫描器,基本功能是针对不同类型的弱密码,可方便的扩展,比如添加SSH、SVN、phpmyadmin的弱密码扫描功能。我们设定启动方法是命令行,可以通过命令行指定扫描对象,以及扫描哪些弱密码。

既然是要求可扩展,那我们首先来编写一个通用的框架,然后通过添加POC的方法来实现扩展。在这个框架中,我们需要处理的事情包括:

  • 初始化扫描对象(格式化URL、从文件或数据库中读取URL)
  • 载入弱密码扫描脚本(载入一种或者多种扫描脚本)

同时为了易用性,框架还要提供一些额外的功能:

  • 提供一些公用的函数(如端口扫描、URL去格式化以及格式化等)
  • 显示当前可用的POC以及POC的相关信息

我们预期的调用方法应该是这样:

  1. python base.py -p ssh_weak,mysql_weak -t test.txt --run

这样,让我们画个简图:

具体讲解一下:

base.py是扫描器的入口文件

  • poc处理流程:init_poc()将输入 ssh_weak,mysql_weak格式化,通过load_poc()加载到内存中。
  • target处理流程: init_target()将输入 test.txt 内容读取到内存中,同时应该支持直接指定参数,以及从数据库中读取参数。
  • POC管理: show_poc_info()调用load_poc(),载入所有POC,并print poc_info。

poc_base.py是所有POC的父类,POC通过继承poc_base,来实现常用函数的继承,以及POC引擎。

0x10 承 - 功能抽象

通过上述描述,我们得到了一个简单的框架,通过这个框架提供的功能,我们来试着写一个标准的POC:

  1. from poc_base import PocBase
  2.  
  3. class MyPOC(PocBase):
  4. poc_info = {
  5. 'author': 'Friday',
  6. 'title': 'svn_weak',
  7. }
  8.  
  9. def svn_burst(self, url, user, password):
  10. pass
  11.  
  12. def save(): # 向数据库或文件中存储结果
  13. pass
  14.  
  15. def verify(self, target):
  16. count = 0
  17. for url in target:
  18. for user in ['root', 'work']:
  19. for passwd in ['test', '']:
  20. count += 1
  21. if port_open(22) and svn_burst():
  22. print "Success"
  23. save()
  24.  
  25. if count % 10 == 0:
  26. print "当前进度:%d" % count

有几个地方可以优化:

  1. 数据存储模块,每次扫描完存储一次,太浪费资源,有什么解决方法?
  2. 数据存储模块,是否能集成到框架中?
  3. 扫描数量较大的时候,应该有扫描成功的提醒,以及扫描进度的提醒,是否能集成到框架中?

这其实是一个问题,数据定时存储(扫描过程中多次存储)和进度提醒功能,如何集成到框架中?本来的逻辑是,调用一次POC,扫描多个URL,然后直接由POC输出结果。如果想实现数据存储和进度提醒,看起来要把更多的控制权交到框架手中。所以,将POC的功能简化到判断某一个URL是否存在弱密码,返回true or false。将POC的调用权限,交到Poc_Base中,多次调用POC,伪代码如下:

  1. class Poc_Base(object):
  2.  
  3. count = 0
  4. progress = 100 # 进度提醒的单位
  5.  
  6. @ overide
  7. def verify():
  8. pass
  9.  
  10. def run():
  11. for url in url_list:
  12. count += 1
  13.  
  14. if count % progress == 0:
  15. save() # 数据存储
  16. print "progress %d " % (count) # 进度提醒
  17.  
  18. if self.verify():
  19. print "success"

经过优化之后,POC的基本模式,更简单了:

  1. from poc_base import PocBase
  2.  
  3. class MyPOC(PocBase):
  4. poc_info = {
  5. 'author': 'Friday',
  6. 'title': 'svn_weak',
  7. }
  8.  
  9. def svn_burst(self, url, user, password):
  10. pass
  11.  
  12. def verify(self, url):
  13. for user in ['root', 'work']:
  14. for passwd in ['test', '']:
  15. if port_open(22) and svn_burst():
  16. return True

在beebeeto提交过POC的同学,应该惊呼了“除了结果自动存储的模块,这不和beebeeto的框架一样么!”,是的,在一开始写框架的时候,参考了beebeeto-frame,后来独立编写完成/优化完成后,发现殊途同归了 : )

0x20 转 - 性能提升

在实现基本功能之后,我又开始蠢蠢欲动了。作为一个有尊(xing)严(neng)的框架,怎么能满足于一条线的模式!所以,为了效率,我们要在框架层面添加协程和多进程支持,让多核CPU每个都能跑到100%是我们的目标!

但应该怎么添加进程和协程的支持呢?有之前添加数据存储和进度提醒的经验,实现不难想象。难点在于,在添加进程和协程支持的时候,不影响正常的数据存储和进度提醒。伪代码如下:

  1. class Poc_Base(object):
  2. gevent_num = 100 # 协程数
  3. process_num = 4 # 进程数
  4.  
  5. count = [0] * process_num # 每个进程,单独计数
  6. progress = 100 # 进度提醒的单位
  7.  
  8. @ overide
  9. def verify():
  10. pass
  11.  
  12. def verify_count():
  13. count[progress_number] += 1
  14.  
  15. if count[progress_number] % progress == 0:
  16. save() # 数据存储
  17. print "progress %d " % (count[progress_number]) # 进度提醒
  18.  
  19. if self.verify():
  20. print "success"
  21.  
  22. # 协程调度函数,分配任务到协程
  23. def run_in_gevent(url_list): # url_list 每个进程分配到一定量的url
  24. pool = Pool(self.gevent_num)
  25. for target in url_list:
  26. pool.add(gevent.spawn(self.verify_count, url))
  27.  
  28. pool.join()
  29.  
  30. # 进程调度函数,分配任务到各个进程
  31. def run():
  32. url_each_process = len(url_list)/process_num
  33.  
  34. for process_number in range(process_num):
  35. multiprocessing.Process(target=run_in_gevent, args=(url_list[*:*],)).start()
  36.  
  37. multiprocessing.join()

这样,我们就能在跑POC的时候,用到高端的协程和进程了。

0x30 合

实际运行过程中,协程开了150,进程开了2(8核CPU),可以把两个核的CPU都跑到90+%。

虽然一开始说,不会贴代码,但还是贴了不少伪代码。内容并不深奥,如果你看过beebeeto-frame和beehive的源码,觉得这是简化版的beehive,是高度定制版的beebeeto-frame,我也会觉得很开心: ) ,学习借鉴就是开源软件对于我的意义。

因为涉及公司的一些制度,不方便公开源码,但感兴趣的同学,或者想自己实现一个简单的扫描器的同学,可以参考上文提到的两种开源软件,在github上可以搜到。

基于Python+协程+多进程的通用弱密码扫描器的更多相关文章

  1. day-5 python协程与I/O编程深入浅出

    基于python编程语言环境,重新学习了一遍操作系统IO编程基本知识,同时也学习了什么是协程,通过实际编程,了解进程+协程的优势. 一.python协程编程实现 1.  什么是协程(以下内容来自维基百 ...

  2. Python核心技术与实战——十六|Python协程

    我们在上一章将生成器的时候最后写了,在Python2中生成器还扮演了一个重要的角色——实现Python的协程.那什么是协程呢? 协程 协程是实现并发编程的一种方式.提到并发,肯很多人都会想到多线程/多 ...

  3. Python 协程总结

    Python 协程总结 理解 协程,又称为微线程,看上去像是子程序,但是它和子程序又不太一样,它在执行的过程中,可以在中断当前的子程序后去执行别的子程序,再返回来执行之前的子程序,但是它的相关信息还是 ...

  4. [转载] Python协程从零开始到放弃

    Python协程从零开始到放弃 Web安全 作者:美丽联合安全MLSRC   2017-10-09  3,973   Author: lightless@Meili-inc Date: 2017100 ...

  5. Python协程与Go协程的区别二

    写在前面 世界是复杂的,每一种思想都是为了解决某些现实问题而简化成的模型,想解决就得先面对,面对就需要选择角度,角度决定了模型的质量, 喜欢此UP主汤质看本质的哲学科普,其中简洁又不失细节的介绍了人类 ...

  6. python 协程与go协程的区别

    进程.线程和协程 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定义: 操作系统能够进行运算调度的最小单位.它被包含在进 ...

  7. Python协程与JavaScript协程的对比

    前言 以前没怎么接触前端对JavaScript 的异步操作不了解,现在有了点了解一查,发现 python 和 JavaScript 的协程发展史简直就是一毛一样! 这里大致做下横向对比和总结,便于对这 ...

  8. 终结python协程----从yield到actor模型的实现

    把应用程序的代码分为多个代码块,正常情况代码自上而下顺序执行.如果代码块A运行过程中,能够切换执行代码块B,又能够从代码块B再切换回去继续执行代码块A,这就实现了协程 我们知道线程的调度(线程上下文切 ...

  9. 从yield 到yield from再到python协程

    yield 关键字 def fib(): a, b = 0, 1 while 1: yield b a, b = b, a+b yield 是在:PEP 255 -- Simple Generator ...

随机推荐

  1. Eclipse输入任意字母或指定字符出现提示框

    Eclipse默认是输入"."的时候会有提示框提示对应的API. 如果想更方便的输入任意字母或者指定的符号出现提示框设置如下: 打开Eclipse,选中“Window”->& ...

  2. android 获取IMEI号

    android 获取 imei号码 核心代码: Imei = ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).getDeviceId( ...

  3. PhotoShop—剪贴蒙版

    工作中发现剪贴蒙版方便好用,所以简单分享下~ 一.剪贴蒙版有什么作用 1.文字上色 2.裁剪图片 3.添加背景 等 二.剪贴蒙版怎么使用 1.新建层,打上字如图 2.文字上面再建层加上效果如渐变 3. ...

  4. SparkSQL之数据源

    准备json文件: cat /root/1.json {"name":"Michael"} {"name":"Andy" ...

  5. 第一次知道Winform的窗体之间传值怎么写,分享给小白~

    之前为了这事,百度了一天也没找到,最终使用了静态变量了. 窗体Form1: private void button1_Click(object sender, EventArgs e) { var f ...

  6. Remoting的入门教程

    注:<网摘自http://www.codesky.net/article/200411/48322.html> 基本原理 当客户端创建远程RemotableClass的一个实例,.NET框 ...

  7. SignalR 2.0 系列:SignalR的服务器广播

    英文渣水平,大伙凑合着看吧…… 这是微软官方SignalR 2.0教程Getting Started with ASP.NET SignalR 2.0系列的翻译,这里是第八篇:SignalR的服务器广 ...

  8. C#抽象工厂简单实现类

    曾经参与开发过的的项目,一般都是采用MVC模式进行开发,大概框架图如下: web界面层调用BLL业务层,BLL通过抽象工厂DALFactory动态生成继承了IDAL的数据库操作层实例,以进行对数据库的 ...

  9. javascript笔记——工作笔记

    1.防止普通用户缓存静态文件,每次修改之后给静态文件的应用后面加上参数后缀[项目文件较多时最好使用前端构建工具] 比如: <script src="$!webPath/resource ...

  10. javascript 基础API

    Math.random() 取值范围[0,1)  大于等于0小于1,包括0,不包括1 Math.floor() 向下取整  Math.ceil() 向上取整 第一题:一组数的规则如下:1.1.2.3. ...