29网络偷包

摘要:
Fd=套接字(PF_INET,PF_INET IPV4协议SOCK_RAW访问IPPROTO_TCP到原始网络协议:iRet=读取(Fd,sizeof(szBuf));UnsignedshortusOffset:将结构的信息输出到IPHEAD_S*pIpHead=(IPHEAD_S*)szBuf;

偷包,就是在网络传输过程中,截取某一数据包,进行解析获取其发送的数据。

原理与TCP通信类似。只需在创建套接字时,参数不同。

fd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);

PF_INET                      IPV4协议

SOCK_RAW            对原始网络协议访问

IPPROTO_TCP:   TCP 协议

注意:第三参数必须指定协议的类型,不可以是0,只能接受某一种协议的数据,不可以是所有IP数据包。

注意:

char szBuf[1024];

iRet = read(fd, szBuf, sizeof(szBuf));

此时szBuf接受的包是数据,不是字符串,可能是乱码或其他乱七八的东东。

因此,对数据包进行解析:

IP数据报的格式:

(1)一个 IP 数据报由首部和数据两部分组成。

(2)首部的前一部分是固定长度,共 20 字节,是所有 IP 数据报必须具有的。

(3)在首部的固定部分的后面是一些可选字段,其长度是可变的。

29网络偷包第1张

定义IP数据包格式的一个结构体:

typedef struct tagIpHeader

{

      unsigned char ucHeadLen:4;

      unsigned char ucVer:4;

      unsigned char ucTos;

      unsigned short usLen;

      unsigned short usIdent;

      unsigned short usOffset:13;

      unsigned short usFlag:3;

      unsigned char ucTTL;

      unsigned char ucProtocol;

      unsigned short usChkSum;

      unsigned int uiSrcIp;

      unsigned int uiDstIp;

     

      char data[0];

}IPHEAD_S;

再将接收到的szBuf,转换,再将结构体的信息输出

IPHEAD_S *pIpHead = (IPHEAD_S*)szBuf;

TCP 报文段首部的前 20 个字节是固定的,后面有 4n 字节是根据需要而增加的选项 (n 是整数)。

注意:TCP 首部的最小长度是 20 字节。而UDP是28字节。

29网络偷包第2张

定义TIP报文段格式的一个结构体:

typedef struct tagTcpHeader

{

      unsigned short srcPort;

      unsigned short dstPort;

      unsigned int   uiSeq;

      unsigned int   uiSeqQ;

      unsigned short fin:1;

      unsigned short syn:1;

      unsigned short rst:1;

      unsigned short psh:1;

      unsigned short ack:1;

      unsigned short urg:1;

      unsigned short res:6;

      unsigned short usHeadLen:4;

      unsigned short usWinLen;

      unsigned short usChkSum;

      unsigned short usUrgPtr;

      unsigned char  data[0];

}TCPHEAD_S;

例子:

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<string.h>

#define RAW_PORT  8888

//IP数据包格式

typedef struct tagIpHeader

{

      unsigned char ucHeadLen:4;

      unsigned char ucVer:4;

      unsigned char ucTos;

      unsigned short usLen;

      unsigned short usIdent;

      unsigned short usOffset:13;

      unsigned short usFlag:3;

      unsigned char ucTTL;

      unsigned char ucProtocol;

      unsigned short usChkSum;

      unsigned int uiSrcIp;

      unsigned int uiDstIp;

     

      char data[0];

}IPHEAD_S;

//TCP数据报格式

typedef struct tagTcpHeader

{

      unsigned short srcPort;

      unsigned short dstPort;

      unsigned int   uiSeq;

      unsigned int   uiSeqQ;

      unsigned short fin:1;

      unsigned short syn:1;

      unsigned short rst:1;

      unsigned short psh:1;

      unsigned short ack:1;

      unsigned short urg:1;

      unsigned short res:6;

      unsigned short usHeadLen:4;

      unsigned short usWinLen;

      unsigned short usChkSum;

      unsigned short usUrgPtr;

      unsigned char  data[0];

}TCPHEAD_S;

//IP信息

void PrintIpHead(IPHEAD_S *pIpHead)

{

      printf(" --------------- IP_HEAD ------------- ");

      printf("srcPort : %d ", pIpHead->ucVer);

      printf("HeadLen : %d ", pIpHead->ucHeadLen);

      printf("TOS     : %d ", pIpHead->ucTos);

      printf("DataLen : %d ", ntohs(pIpHead->usLen));

      printf("Ident   : %d ", ntohs(pIpHead->usIdent));

      printf("Flag    : %d ", pIpHead->usFlag);

      printf("Offset  : %d ", pIpHead->usOffset);

      printf("TTL     : %d ", pIpHead->ucTTL);

      printf("Protocol: %d ", pIpHead->ucProtocol);

      printf("ChkSum  : %d ", ntohs(pIpHead->usChkSum));

      struct sockaddr_in addr;

      addr.sin_addr.s_addr = pIpHead->uiSrcIp; //s_addr is network-endian

      printf("Src IP  : %s ", inet_ntoa(addr.sin_addr));

     

      addr.sin_addr.s_addr = pIpHead->uiDstIp;

      printf("Dst IP  : %s ", inet_ntoa(addr.sin_addr));

     

      printf(" ------------------------------------- ");

}

//TCP信息

void PrintTcpHead(TCPHEAD_S *pTcpHead)

{

      printf(" --------------- TCP_HEAD ------------- ");

      printf("srcPort : %d ", htons(pTcpHead->srcPort));

      printf("dstPort : %d ", pTcpHead->dstPort);

      printf("uiSeq   : %d ", pTcpHead->uiSeq);

      printf("uiSeqQ : %d ",  htons(pTcpHead->uiSeqQ));

      printf("fin:%d syn:%d tst:%d psh:%d ack:%d urg:%d res:%d:%d ",

                 pTcpHead->fin,pTcpHead->syn,pTcpHead->rst,

                 pTcpHead->psh,pTcpHead->ack,pTcpHead->urg,pTcpHead->res);

      printf("usHeadLen: %d ", pTcpHead->usHeadLen);

      printf("usWinLen  : %d ", htons(pTcpHead->usWinLen));

      printf("usChkSum  : %d ", htons(pTcpHead->usChkSum));

      printf("usUrgPtr: %d ", htons(pTcpHead->usUrgPtr));

      printf("ChkSum  : %d ", htons(pTcpHead->usChkSum));

      printf(" ------------------------------------- ");

}

void CaptureData()

{

      int fd;

      int iRet;

      struct sockaddr_in addr;

      socklen_t  addrlen = sizeof(addr);

     

      fd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP); //capture TCP data-packet

      //fd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); //capture TCP data-packet

      if (fd < 0)

      {

           perror("Fail to socket!");

           return;

      }

     

      addr.sin_family = AF_INET;

      addr.sin_port   = htonl(RAW_PORT);

      addr.sin_addr.s_addr = htonl(INADDR_ANY);

      iRet = bind(fd, (struct sockaddr*)&addr, addrlen);

      if (iRet)

      {

           perror("Fail to bind!");

           close(fd);

           return;

      }

      char szBuf[1024];

      while(1)

      {

           memset(szBuf, 0, sizeof(szBuf));

           iRet = read(fd, szBuf, sizeof(szBuf));

           if (iRet < 0)

           {

                 perror("Fail to read!");

                 break;

           }

           //解析数据包

           IPHEAD_S *pIpHead = (IPHEAD_S*)szBuf;

           PrintIpHead(pIpHead);

           //解析TCP报文的数据

           TCPHEAD_S *pTcpHead=(TCPHEAD_S *)pIpHead;

           printf("data: %s ", pTcpHead->data);

           //printf("Recv:%s ", szBuf);

          

      }

      close(fd);

      return; 

}

int main()

{

      CaptureData();

      return 0;

}

大小序问题:

在数据包格式中看到,版本在前,首部长度在后。但是在结构体中,首部长度在前,版本在后。

解析:因此char是一个字节,而在数据包中,版本+首部长度=1字节。并且是大字节序,接受到后在内存中是小字节序。此时首部长度将被放在高位,版本被放在地位。因此进行调换。

DataLen和 Ident   的转换也是如此。

      printf("DataLen : %d ", ntohs(pIpHead->usLen));

      printf("Ident   : %d ", ntohs(pIpHead->usIdent));

免责声明:文章转载自《29网络偷包》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇iview组件DatePicker type="datetimerange绑定初始默认时间值JAVAPMS是JAVA门户管理系统下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Prommetheus 插件监控 ES

转载自:https://blog.csdn.net/u010453363/article/details/76689435/ 用prometheus主要是监控elk中的elasticsearch和logstash prometheus的clicent收集数据,并提供http服务,由prometheus server主动pull数据。   1.1 elast...

layui 时间插件laydate中动态设置改变min和max值

<div class="layui-inline"> <label class="layui-form-label">申请时间</label> <div class="layui-input-inline"> <input...

eslint 错误提示

“Missing semicolon.” : “缺少分号.”, “Use the function form of ”use strict”.” : “使用标准化定义function.”, “Unexpected space after ‘-’.” : “在’-'后面不应出现空格.”, “Expected a JSON value.” : “请传入一个js...

分解uber依赖注入库dig-使用篇

golang的依赖注入库非常的少,好用的更是少之又少,比较好用的目前有两个 谷歌出的wire,这个是用抽象语法树在编译时实现的。 uber出的dig,在运行时,用返射实现的,并基于dig库,写了一个依赖框架fx 本系列分几部分,先对dig进行分析,第一篇介绍dig的使用,第二篇再从源码来剖析他是如何通过返射实现的的依赖注入的,后续会介绍fx 的使用和...

滚动效果--marquee的使用

1. <marquee></marquee>标签,默认从最右侧往左滚动; 2. marquee 支持的属性    (1)behavior设置滚动方式: <marquee behavior="alternate">我是来回滚动</marquee><marquee behavior="scroll">...

IDEA 常用的基本设置 2019.3版本

一、字体设置 (1)非编辑框内的字体设置 Settings--->Appearance & Behavior--->Appearance--->选择Use custom font (2)编辑框的字体设置 Settings--->Editor--->Color Scheme--->Color Scheme Font...