NiceLeeのBlog 用爱发电 bilibili~

DNS污染、解决方案以及自动化

2020-05-23
nIceLee

阅读:


最近在捣鼓逆向的同时沉迷于Github Workflow,总想利用它来整点骚东西,遂有此文。

前言

以Windows系统为例,让我们来看一下,假设不换DNS查询服务器,当要访问的一个网站被DNS污染的时候,我们是如何人工解决的。

  • 第一步,找一个海外的机器,尝试DNS解析得出ip
    举例,最简单的一个做法,找个工具站ping域名就行。
    • 打开站长工具
    • 输入域名,仅勾选海外即可
    • 查询即可得出结果
  • 第二步,更改本机hosts
    编辑C:\Windows\System32\drivers\etc\hosts

  • 第三步,刷新缓存
    • win+R键打开运行
    • 输入cmd,回车
    • 输入ipconfig /flushdns,回车

问题与思路

当我有很多域名,每个域名都这么执行第一步,其实也挺麻烦的,该如何实现python的自动化批量操作呢?

  1. 直接DNS查询
    先安装库:
    pip install dnspython
    

    然后直接上码:

     import dns.resolver
    
    
     def get_ip(domain):
         ip_list = []
         try:
             cn = dns.resolver.query(domain, 'CNAME')
             for i in cn.response.answer:
                 for j in i.items:
                     cname_domain = j.to_text() 
         except:
             pass
         else:
             A = dns.resolver.query(cname_domain.rstrip('.'), 'A')
             for i in A.response.answer:
                 for j in i.items:
                     ip_list.append(j.address)
                 
         try:
             A = dns.resolver.query(domain, 'A')
             for i in A.response.answer:
                 for j in i.items:
                     print(j)
                     ip_list.append(j.address)
         except:
             pass
            
         if ip_list == []:
             return None
         else:
             return ip_list[0]        
            
     if __name__ == '__main__':
         ip = get_ip('www.baidu.com')
         print(ip)
    

    缺点是需要额外安装库,同时由于DNS查询是UDP发包,单次很容易就抛出异常。

  2. 直接ping
    调用系统的ping命令,然后从回复获取ip

     import subprocess
     import re
     import locale
     import platform
    
    
     def ping(domain):
         ip = []
         if platform.system() == "Windows":
             cmd = u"ping %s -n 1" % domain
         else:
             cmd = u"ping %s -c 1" % domain
                
         p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            
         line = p.stdout.readline().decode(locale.getpreferredencoding())
         while len(line) > 0:
             line = p.stdout.readline().decode(locale.getpreferredencoding())
             if ip == []:
                 ip = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', line)
         if ip == []:
             return None
         else:
             return ip[0]     
            
     if __name__ == '__main__':
         ip = ping('www.baidu.com')
         print(ip)
    

    缺点是系统可能没有ping工具,而安装可能又没有权限。例如github的workflow的Ubuntu虚拟机冇这个功能,安装报错…

     apt-get install iputils-ping
    
  3. 巧妙利用socket转换
    直接上码

     #!/usr/bin/env python
     # coding:utf-8
         
     import socket       
            
     if __name__ == '__main__':
         ip = socket.gethostbyname('www.baidu.com')
         print(ip)
    

部署与实现

  • 如何将workflow的运行结果呈现出来,这里有几种思路。
    放到工程本身、放到issue,以及放到release。
    放到工程里面,每次提交都会产生commit,影响正常的数据统计;放到release里面也感觉怪怪的;感觉issue区是个交流展示的好地方。

  • 如何触发workflow的工作流,这里有几种思路。
    • 周期性触发
    • 通过PUSH/PR来人工触发event X
      (PUSH需要权限,而PR感觉麻烦,还要fork什么的
    • 打开issue
      正好结果直接回复到相应issue中
  • 周期性关闭已打开的有label的issue,并新建issue打上标签

      name: CreateIssue
    
      on:
         schedule: 
             - cron: '1 0 1,16 * *'
    
      jobs:
        build:
    
          runs-on: ubuntu-latest
               
          steps:
          - uses: actions/checkout@v2
                   
          - name: Set up Python 3.8
            uses: actions/setup-python@v1
            with:
              python-version: 3.8
                
          - name: Generate github hosts
            run: |
              python socket_query.py
              cat hosts.txt
         
            
          - name: Close issues of hosts label
            uses: actions/github-script@0.4.0
            with:
              github-token: $
              script: |
                let response = await github.issues.listForRepo({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  labels: ['host'],
                  state: 'open'
                });
                let data = response['data'];
                  
                data.forEach(function(issue){
                  var id = issue['number'];
                  github.issues.update({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: id,
                    state: 'closed'
                  });
                });
                  
          - name: Create issue to show hosts
            uses: actions/github-script@0.4.0
            with:
              github-token: $
              script: |
                const date = new Date();
                const year = date.getFullYear().toString();
                const month = (date.getMonth() + 1).toString();
                const day = date.getDate().toString();
                const title = year + '-' + month + '-' + day + ' github hosts';
                var fs = require("fs");
                fs.readFile("hosts.txt", 'utf-8', (err, data) => {
                  github.issues.create({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      labels: ['host'],
                      title: title,
                      body: data
                  });
                });
    
  • 用户新建issue后,自动查询并回复

      name: ReplyIssueCreate
    
      on:
        issues:
          types: [opened]
    
      jobs:
        permission:
          name: permission check
          runs-on: ubuntu-latest
          if: github.actor != 'github-actions[bot]'
          steps:
          - name: check permission
            run: |
              echo $
              echo permission pass
              
              
        build:
          runs-on: ubuntu-latest
          needs: permission
          steps:
          - uses: actions/checkout@v2
                   
          - name: Set up Python 3.8
            uses: actions/setup-python@v1
            with:
              python-version: 3.8
            
          - name: Generate github hosts
            run: |
              python socket_query.py
                
          - uses: actions/github-script@0.4.0
            with:
              github-token: $
              script: |
                var fs = require("fs");
                fs.readFile("hosts.txt", 'utf-8', (err, data) => {
                  github.issues.createComment({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      body: data
                  });
                });
    

后续


内容
隐藏