• Linux C/C++下收集指定域名的子域名信息(类似dnsmap实现)


    我们知道dnsmap是一个工具,主要用于收集指定域名的子域名信息。它对于渗透测试人员在基础结构安全评估的信息收集和枚举阶段非常有用,可以帮助他们发现目标公司的IP网络地址段、域名等信息。

    dnsmap的操作原理

    dnsmap(DNS Mapping)是一种将域名解析为特定 IP 地址的技术。其操作原理是通过修改本地 DNS 服务器的配置,将特定的域名解析为固定的 IP 地址。当用户访问这个域名时,本地 DNS 服务器会返回预设的 IP 地址,从而实现跳过原网站、访问特定内容的目的。

    DNSMAP 操作的具体步骤如下:

    • 1.修改本地 DNS 服务器配置:在 DNS 服务器上,为需要映射的域名添加一条新的 PTR(Pointer)记录,将该域名指向特定的 IP 地址。这样,当用户查询该域名时,DNS 服务器会返回这个 IP 地址。

    • 2.客户端查询 DNS:当用户访问需要通过 DNSMAP 进行映射的域名时,客户端会向本地 DNS 服务器发起域名查询请求。

    • 3.本地 DNS 服务器响应:本地 DNS 服务器在接收到查询请求后,会在其缓存中查找与该域名相关的 PTR 记录。如果找到了相应的 PTR 记录,本地 DNS 服务器就会返回该记录对应的 IP 地址。如果没有找到相应的记录,本地 DNS 服务器会向上级 DNS
      服务器发起递归查询,直到获取到结果。

    • 4.客户端获取 IP 地址:客户端收到本地 DNS 服务器返回的 IP 地址后,会使用该 IP 地址进行网络请求,从而实现访问特定内容的目的。

    Linux下dnsmap的使用

    以下是dnsmap在Linux环境下的使用介绍,使用方法:

    dnsmap <指定域名>[选项]-w 后加字典文件
        -r 指定结果用常规格式输出文件
        -c 指定结果用csv去输出
        -d 设置延迟
        -i 设置忽略ip (当你遇到一个虚假ip时很有用)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过设置dnsmap的选项,可以为其指定子域名的字典、指定保存信息的文件、指定dns请求的间隔时间以及指定忽略结果中的某些信息等。例如:

    dnsmap baidu.com -w wordlist.txt
    
    • 1

    上指令表示使用自定义的wordlist.txt作为dnsmap穷举子域名的字典。如果不使用-w选项,则使用默认的字典。

    通过指定保存信息的文件有两种方式,常规方式和csv方式。

    dnsmap baidu.com -w wordlist.txt -c reportfile.csv
    
    • 1

    常规方式:选项-r表示用常规方式保存dnsmap得到的子域信息,常规方式也就是将dnsmap输出的信息原封不动的进行保存。使用-c选项表示以csv方式保存信息。

    -r 指定一个目录,将扫描到的结果保存到这个指定的目录中,并以当前时间戳命名。例如:

    dnsmap baidu.com -r /tmp/ -d 600
    
    • 1

    使用-d选项指定一个正整数,使得 dnsmap 在暴力扫面的时候能够周期性的休眠,这样不会占用系统带宽。单位是秒。

    使用 dnsmap的优缺点

    使用 dnsmap的优缺点如下:
    优点:

    • 方便快捷:dnsmap可以直接将域名解析为特定 IP 地址,省去了手动修改 hosts 文件或使用代理软件的步骤,操作更加简便。
    • 灵活性:dnsmap可以针对特定的域名进行映射,可以根据需求灵活配置。
    • 易于管理:dnsmap可以通过修改本地 DNS服务器配置实现,便于管理和维护。

    缺点:

    • 安全风险:dnsmap可能会绕过网站的正常访问控制,使用户访问到未经授权的内容,存在一定的安全风险。
    • 稳定性问题:dnsmap依赖于本地 DNS 服务器的缓存,如果缓存更新不及时,可能会导致查询结果不准确。
    • 适用范围有限:dnsmap只能在使用同一本地 DNS 服务器的用户之间实现域名映射,不适用于跨区域、跨网络的用户。

    Linux C/C++下收集指定域名的子域名信息

    struct dns_discovery_args {
        FILE * reg_report;
        FILE * csv_report;
        char * domain;
        int nthreads;
        struct addrinfo * wildcard;
    };
    ...
    FILE *parse_args(int argc, char ** argv)
    {
    ...
        while ((c = getopt(argc, argv, "r:w:t:c:")) != -1)
            switch (c) 
            {
                case 'w':
                    ptr_wl = optarg;
                    break;
                case 't':
                    SAY("THREADS: %s\n", optarg);
                    dd_args.nthreads = atoi(optarg);
      	        break;
                case 'r':
                    SAY("REGULAR REPORT: %s\n", optarg);
                    dd_args.reg_report = ck_fopen(optarg, "w");
                    break;
                case 'c':
                    SAY("CSV REPORT: %s\n", optarg);
                    dd_args.csv_report = ck_fopen(optarg, "w");
                    break;
                default:
                    if (optopt == 'r' || optopt == 'w' || optopt == 't' || optopt == 'c') {
                        fprintf(stderr, "Option -%c requires an argument.\n", optopt);
    	            exit(EXIT_FAILURE);
                    }
                    usage();
            }
    
    ...
    
        return wordlist;
    }
    void *dns_discovery_thread(void * args);
    void dns_discovery(FILE * file, const char * domain);
    void resolve_lookup(const char * hostname);
    void print_resolve_lookup(const char * hostname, struct addrinfo * res);
    void wildcard_detect();
    bool compare_hosts(struct addrinfo * host1, struct addrinfo * host2);
    bool compare_ai_addr(struct addrinfo * host1, struct addrinfo * host2);
    ...
    int main(int argc, char ** argv) 
    {
    ...
    
        if (atexit(cleanup) != 0) 
        {
            fprintf(stderr, "Cannot set exit function\n");
            return EXIT_FAILURE;
        }
    
        wordlist = parse_args(argc, argv);   
        wildcard_detect();
    
        if (dd_args.wildcard) 
        {
            snprintf(hostname, sizeof hostname, "*.%s", dd_args.domain);
            print_resolve_lookup(hostname, dd_args.wildcard);
        }
    
        threads = (pthread_t *) ck_malloc(dd_args.nthreads * sizeof(pthread_t)); 
     
        for (i = 0; i < dd_args.nthreads; i++) 
        {
            if (pthread_create(&threads[i], NULL, dns_discovery_thread, (void *)wordlist) != 0)
                error("pthread_create");
        }
        
        for (i = 0; i < dd_args.nthreads; i++) 
        {
            pthread_join(threads[i], NULL);
        }
      
    ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    运行结果:


    If you need the complete source code, please add the WeChat number (c17865354792)

    DNS发现是一个多线程子域生成器,用于测试的初始阶段。它使用一个与给定域连接的单词列表来搜索子域。

    DNS发现解析并显示IPv4和IPv6。它类似于其他工具,如dnsmap,但是多线程的。

    总结

    DNSMAP(DNS Mapping)是一种将域名解析为 IP 地址,同时将 IP 地址映射回域名的技术。

    实现 DNSMAP 库需要掌握 C 语言基础、域名解析、DNS 协议、错误处理、线程/异步编程、网络编程以及编译和调试等知识点。

    Welcome to follow WeChat official account【程序猿编码

  • 相关阅读:
    .NET应用如何防止被反编译
    scrcpy macos 编译安装最新版 1.2.4
    Prometheus系列(二)Grafana可视化部署
    使用tkinter开发GUI程序3 -- tkinter常见控件的特征属性(第一部分)
    企业上半年净利润下降近8成,企业如何应对?
    洛谷题单 【入门1】顺序结构
    恒驰Q&A | 我们到底是做什么的?和恒大恒驰有什么关系?
    文盘 Rust -- tokio 绑定 cpu 实践
    亚马逊云科技多项新功能与服务,助力各种规模的组织拥抱生成式 AI
    聚合聊天,一人管理多个微信
  • 原文地址:https://blog.csdn.net/chen1415886044/article/details/133282064