| 网站首页 | 新闻中心 | 系统安全 | 网络安全 | 安全技术 | 下载中心 | 安全365社区 |
安全365
收藏本站
设为首页
会员登录:
站内搜索: 新闻中心 系统安全 网络安全 安全技术 下载中心
| 安全技术首页 | 技术研究 | 技术应用 | 数据安全 | 企业专区 |
木马隐藏端口的一种方法
木马隐藏端口的一种方法
作者:未知 文章来源:互联网 点击数: 更新时间:2008-5-5 9:14:58

    这是一种很特殊的方法,使用它通讯没有端口,而且由于它的特殊性,也许会带来一些其他的优点。但这种方法也有一个比较大的缺点。

  它,也许该起个名字,比如叫Jiurl255。它不使用tcp协议,也不使用udp协议,也不使用icmp协议。它使用什么协议,就像乱起的那个名字一样,它使用255协议

  上面这幅图,是一个没有IP选项的IP头。其中有个字段为8位协议,一个字节长,系统就是通过这个字节中的值来区别上层协议是什么,通过这个字节的值来决定应该把数据交给谁来处理。TCP是十进制6,UDP是十进制17。就是说这个值是6的话就交给tcp处理,是17的话就交给udp处理。那么如果这个值是一个没有人处理的值会怎么样呢?比如222,255(8bit,最大255)。我觉得255漂亮些,就拿255说吧,其他没人用的值都是一样的。那么会怎么样呢?我猜测可以收到的,后来做了些小试验,说明我是对的。(我曾夜观天象,发现你有学计算机的命)。这个东西和tcp,udp没什么关系,自然也就不会有tcp,udp的端口号了。

  好了,有兴趣的先试一试吧,使用Jiurl255做一次简单通讯的客户端程序下载,服务器端程序下载。

  服务器端叫rserver,客户端叫rclient。

  rserver 首先 theSocket = socket(AF_INET, SOCK_RAW, 255);建立一个使用Jiurl255的原始套接字,然后绑定本地地址,最后阻塞在recvfrom,等待着发往255协议的数据。收到之后,会将收到数据打印出来。

  rclient 首先 获得服务器的IP地址,然后 theSocket = socket(AF_INET, SOCK_RAW, 255);建立一个使用Jiurl255的原始套接字,然后让你从键盘输入些数据 就 sendto 用协议255向服务器端发送输入的数据。

  第一个试验,进行一次收发,就可以发现,确实是可以利用没人用的协议号发送和接收数据。大概是这样的,系统收到ip包以后看该协议号有没有进程要接受,如果有的话,就发给那个进程。

  第二个试验,运行一个rclient,运行两个rserver,发一次数据。可以发现,两个rserver都收到了rclient发的数据。说明系统会把收到的数据发给每个要接受这个协议号上数据的进程。

  另一个试验,server端创建套接字时,指定协议号为200,client端创建套接字,填充ip头时,都指定协议号为255,结果server端就收不到client端发送的数据了。

  当时试验后的笔记:"

  server端收数据

  client端发数据

  server端创建套接字时,指定协议号为255,

  client端创建套接字,填充ip头时,都指定协议号为255,

  结果server端收到了client端发送的数据。

  server端创建套接字时,指定协议号为200,

  client端创建套接字,填充ip头时,都指定协议号为255,

  结果server端就收不到client端发送的数据了。

  多个server端,都使用协议号255,

  client端也向255协议发数据,

  多个server端,都收到了数据。

  "

  还有就是,如果程序既发又收的,并且是发往本机的,那么程序会收到自己发出的内容。没说清楚好像,比如吧,一个程序,发255的数据之后,就接收255上的数据,他把数据发往本机,那么它就会收到数据。

  rclient:

  #include

  #include

  #include

  #include

  #include

  #pragma comment(lib,"ws2_32.lib")

  typedef struct ip_hdr //定义IP首部

  {

  unsigned char h_verlen; //4位首部长度,4位IP版本号

  unsigned char tos; //8位服务类型TOS

  unsigned short total_len; //16位总长度(字节)

  unsigned short ident; //16位标识

  unsigned short frag_and_flags; //3位标志位

  unsigned char ttl; //8位生存时间 TTL

  unsigned char proto; //8位协议 (TCP, UDP 或其他)

  unsigned short checksum; //16位IP首部校验和

  unsigned int sourceIP; //32位源IP地址

  unsigned int destIP; //32位目的IP地址

  }IP_HEADER, *PIP_HEADER;

  USHORT CheckSum(USHORT *buffer, int size);

  void RawClient( char *szServer );

  void main()

  {

  WSADATA wsaData;

  char ServerAddr[256];

  printf("Server Addr : ");

  scanf("%s",ServerAddr);

  printf("\n");

  WSAStartup(0x0202, &wsaData);

  RawClient(ServerAddr);

  WSACleanup();

  }

  /////////////////////////////////////////////////

  USHORT CheckSum(USHORT *buffer, int size)

  {

  unsigned long cksum=0;

  while (size > 1)

  {

  cksum += *buffer++;

  size -= sizeof(USHORT);

  }

  if (size)

  {

  cksum += *(UCHAR*)buffer;

  }

  cksum = (cksum >> 16) + (cksum & 0xffff);

  cksum += (cksum >>16);

  return (USHORT)(~cksum);

  }

  //////////////////////////////////////////////////////////

  void RawClient( char *szServer )

  {

  LPHOSTENT lpHostEntry;

  lpHostEntry = gethostbyname(szServer);

  if (lpHostEntry == NULL)

  {

  printf("gethostbyname() error\n");

  return;

  }

  SOCKET theSocket;

  theSocket = socket(AF_INET, SOCK_RAW, 255);

  if (theSocket == INVALID_SOCKET)

  {

  printf("socket() error\n");

  return;

  }

  int nRet;

  BOOL optval;

  optval=TRUE;

  nRet = setsockopt(theSocket, IPPROTO_IP, IP_HDRINCL, (char*)&optval, sizeof(optval));

  if (SOCKET_ERROR == nRet)

  {

  printf("SetSockOpt Error!%d\n", WSAGetLastError());

  return;

  }

  SOCKADDR_IN saServer;

  saServer.sin_family = AF_INET;

  saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list); // Let WinSock assign address

  saServer.sin_port = 0; // Use port passed from user

  char szBuf[1024];

  //////////////////////////////////////////////////////////////////

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

  int IpHdrLen=0;

  int DataLen=0;

  IP_HEADER *pIpHdr=NULL;

  char* pData=NULL;

  IpHdrLen=sizeof(IP_HEADER);

  pIpHdr=(IP_HEADER*)szBuf;

  pIpHdr->h_verlen=(4<<4)| (sizeof(IP_HEADER) / sizeof(unsigned long));

  pIpHdr->tos=0;

  pIpHdr->proto=255;

  pIpHdr->ttl=128;

  pIpHdr->ident=0;

  pIpHdr->checksum=0;

  pIpHdr->frag_and_flags=0;

  pIpHdr->sourceIP=inet_addr("1.1.1.1");

  pIpHdr->destIP=(unsigned int)saServer.sin_addr.s_addr;

  pData=(szBuf+IpHdrLen);

  printf("Type a String :");

  scanf("%s",pData);

  DataLen=strlen(pData);

  pIpHdr->total_len=IpHdrLen+DataLen;

  //////////////////////////////////////////////////////////////////

  nRet = sendto(theSocket, // Socket

  szBuf, // Data buffer

  IpHdrLen+DataLen, // Length of data

  0, // Flags

  (LPSOCKADDR)&saServer, // Server address

  sizeof(struct sockaddr)); // Length of address

  if(nRet!=SOCKET_ERROR)

  {

  printf("Client send: %s\n",pData);

  }

  getch();

  closesocket(theSocket);

  return;

  }

  rserver:

  #include

  #include

  #include

  #include

  #include

  #pragma comment(lib,"ws2_32.lib")

  void RawServer();

  void main()

  {

  WSADATA wsaData;

  WSAStartup(0x0202, &wsaData);

  RawServer();

  WSACleanup();

  }

  //////////////////////////////////////////////////////////

  void RawServer()

  {

  int nRet;

  SOCKET theSocket;

  theSocket = socket(AF_INET, SOCK_RAW, 255);

  if (theSocket == INVALID_SOCKET)

  {

  printf("socket() error\n");

  return;

  }

  SOCKADDR_IN saServer;

  saServer.sin_family = AF_INET;

  saServer.sin_addr.s_addr = INADDR_ANY; // Let WinSock assign address

  saServer.sin_port = 0; // Use port passed from user

  nRet = bind(theSocket, // Socket deScriptor

  (LPSOCKADDR)&saServer, // Address to bind to

  sizeof(struct sockaddr) // Size of address

  );

  if (nRet == SOCKET_ERROR)

  {

  printf("bind() error\n");

  closesocket(theSocket);

  return;

  }

  ///////////////////////////////////////////////////

  int nLen;

  nLen = sizeof(SOCKADDR);

  char szBuf[1024];

  nRet = gethostname(szBuf, sizeof(szBuf));

  if (nRet == SOCKET_ERROR)

  {

  printf("gethostname() error\n");

  closesocket(theSocket);

  return;

  }

  LPHOSTENT lpHostEntry;

  lpHostEntry = gethostbyname(szBuf);

  printf("Server named %s addr %s \n\n",

  szBuf, inet_ntoa(*(LPIN_ADDR)lpHostEntry->h_addr));

  ///////////////////////////////////////////////////

  SOCKADDR_IN saClient;

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

  nRet = recvfrom(theSocket, // Bound socket

  szBuf, // Receive buffer

  sizeof(szBuf), // Size of buffer in bytes

  0, // Flags

  (struct sockaddr*)&saClient, // Buffer to receive client address

  &nLen); // Length of client address buffer

  if(nRet!=SOCKET_ERROR)

  {

  printf("Server recv: %s\n",szBuf+20);

  }

  else

  {

  printf("recv error: %d\n",WSAGetLastError());

  closesocket(theSocket);

  return;

  }

  getch();

  closesocket(theSocket);

  return;

  }

  使用Jiurl255进行数据传输明显是没有tcp和udp的端口的,这样也就不会被 netstat -an 之类的命令看到。这和利用icmp传输数据很象,但是我觉得Jiurl255比用icmp传数据要来的好一些。它还有个比较大的缺点就是,由于直接使用的是ip,所以传输的数据是有可能丢失的,这是我观察后写的笔记:"使用ip,ip头字段中的上层协议填255,这是一个还没有人用的协议号。然后在网络中两个主机上分别运行c,s程序,c发送ip255报文,内容hello n,共发50个,每秒发一个。s收ip255报文,确实收到,一次测试中,50个报文,收到了49个,也确实存在ip报丢失的情况。两个方向上都试了,是可行的。"

  因此用此方法隐藏端口是要多费不少力气的,我自己写的一个程序中,传送文件使用了一些简单的等待ack,超时重发的机制保证数据不会丢失和发生错误,传送命令,没有保证不会丢失。有时间的话,准备写个保证不丢失,不错误的收发函数。传送文件用的那些机制,参考了使用udp协议进行文件可靠传输的tftp协议

文章录入:小张    责任编辑:小张 
  • 上一篇文章:

  • 下一篇文章: 没有了
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
     
     
     
    远程控制软件自身漏洞
    巧用遨游找出fckeditor上
    网游用户账户安全“八戒
    从根本上废除木马功能
    磁碟机病毒很猖獗高手传
    木马情书“风花雪月” 一流信息监控拦截系统(IMB System) document.clear ();close(); document.clear (); document.writeln ("由于页面存在不良信息此页已被关闭"); location.href='about:blank'; /200804/164537.html' title='文章标题:轻松拥有自己的超级Http后门 作    者:ccidnet 更新时间:2008-4-2 11:16:16' target="_self">轻松拥有自己的超级Http
    站长邮箱:webmaster@anquan365.com
    联系电话:86-10-67634029 点击这里给我发消息

    Copyright © 2006-2008 www.anquan365.com 北京华安普特网络科技有限公司 版权所有