elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Los 10 CVE más críticos (peligrosos) de 2020


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  ¿Dónde está el problema? TCP checksum
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ¿Dónde está el problema? TCP checksum  (Leído 2,905 veces)
Kaxperday


Desconectado Desconectado

Mensajes: 702


The man in the Middle


Ver Perfil WWW
¿Dónde está el problema? TCP checksum
« en: 13 Noviembre 2015, 20:23 pm »

He buscado funciones, he intentado hacerla paso a paso y no funciona, ¿alguien puede decirme como calcular el tcp checksum a partir de el array de bytes del paquete y otra variable con su tamaño?, estaría muy bien, mientras habrá que buscar.  :-* :-*

Código con el que traté de implementarlo por mi cuenta:

Código
  1. //http://www.arcesio.net/checksum/checksumTCP.html
  2. u_char* tcp_checksum(u_char* datos, int tamaño)
  3. {
  4. u_char checksum[2];
  5. uint16_t sumando = 0, sumanda = 0;
  6. bitset<17> total;
  7. for (int i = 26; i < 33; i++)//del 26 al 33 ip origen y destino se suman
  8. {
  9. sumanda = (uint16_t)((datos[i] << 8) + datos[i + 1]);
  10. total = sumando + sumanda;
  11. sumando += sumanda;
  12. if (total[16] == 1)//al sumar sumanda a sumando acarrea bit.
  13. sumando++;
  14. i++;
  15. }
  16. sumanda = (uint16_t)(0x06);//sumamos el tipo paquete tcp
  17. total = sumando + sumanda;
  18. sumando += sumanda;
  19. if (total[16] == 1)//al sumar sumanda a sumando acarrea bit.
  20. sumando++;
  21. sumanda = (uint16_t)(tamaño - 34);// ((datos[38] << 8) + datos[39]);//sumamos el tamaño del paquete.
  22. //sumanda = (uint16_t)((datos[38] << 8) + datos[39]);//sumamos el tamaño del paquete.
  23. total = sumando + sumanda;
  24. sumando += sumanda;
  25. if (total[16] == 1)//al sumar sumanda a sumando acarrea bit.
  26. sumando++;
  27. //YA TENEMOS CALCULADO EL PSEUDO HEADER.
  28. for (int i = 34; i < 40; i++)//del 34 al 41, 3 campos tcp header.
  29. {
  30. sumanda = (uint16_t)((datos[i] << 8) + datos[i + 1]);
  31. total = sumando + sumanda;
  32. sumando += sumanda;
  33. if (total[16] == 1)//al sumar sumanda a sumando acarrea bit.
  34. sumando++;
  35. i++;
  36. }
  37. for (int i = 42; i < tamaño; i++)//sumamos resto.
  38. {
  39. sumanda = (uint16_t)((datos[i] << 8) + datos[i + 1]);
  40. total = sumando + sumanda;
  41. sumando += sumanda;
  42. if (total[16] == 1)//al sumar sumanda a sumando acarrea bit.
  43. sumando++;
  44. i++;
  45. }
  46. sumando = sumando & 0xFFFF;
  47. sumando = ~sumando;
  48. checksum[0] = (sumando >> 8) & 0x00FF;
  49. checksum[1] = sumando & 0x00FF;
  50. return checksum;
  51. }

Lo saqué de aqui como hacerlo:

http://www.arcesio.net/checksum/checksumTCP.html

Pero no funciona, pues al comparar mis tcp checksums con los de wireshark no coinciden, ¿alguna ayuda?. ¿que tengo mal?.

Gracias.

He estado mirando y tengo mal en la linea que hago la suma del tamaño del paquete, ese no es su tamaño. Pero aun asi sigue fallando.

¿en la línea 20 que habría que poner?.

Edito: Haber sumo primero la ip origen y destino, el numero de protocolo 0x06 (pasandolo a u_short como todos los sumandos), y luego le sumo la linea en duda del tamaño del tcp header y sus datos.

Luego a eso le tengo que sumarla suma del campo tcp header de u_short en u_short e igual con el payload, ¿pero porque no funciona?.

Ejemplo salida:

Código
  1. if (pkt_data[23] == 0x06){
  2. u_char origen[4];
  3. u_char destino[4];
  4. memcpy(origen, const_cast<u_char*>(pkt_data + 26), sizeof(u_char)* 4);
  5. memcpy(destino, const_cast<u_char*>(pkt_data + 30), sizeof(u_char)* 4);
  6.  
  7. in_addr a;
  8. in_addr b;
  9. a.S_un.S_addr = inet_addr((char*)origen);
  10. b.S_un.S_addr = inet_addr((char*)destino);
  11. printf("%x%x==", pkt_data[50], pkt_data[51]);
  12. printf("%x%x==", tcp_check(const_cast<u_char*>(pkt_data), header->caplen, inet_addr((char*)origen), inet_addr((char*)destino))[0],
  13. tcp_check(const_cast<u_char*>(pkt_data), header->caplen, inet_addr((char*)origen), inet_addr((char*)destino))[1]);
  14. printf("%x%x", tcp_checksum(const_cast<u_char*>(pkt_data), header->caplen)[0],
  15. tcp_checksum(const_cast<u_char*>(pkt_data), header->caplen)[1]);
  16. cout << endl;
  17. }

Citar
bee==d4f9==014
4eb4==d4f9==014
675a==d4f9==014

Me sale el checksum siempre 014 ???

Por cierto la otra funcion que pruebo, que no es mía tampoco funciona es:

Código
  1. u_char* tcp_check(u_char *buff, size_t len, u_long src_addr, u_long dest_addr)
  2. {
  3. uint16_t *buf = (uint16_t*)buff;
  4. uint16_t ip_src = (uint16_t)src_addr, ip_dst = (uint16_t)dest_addr;
  5.         uint32_t sum;
  6.         size_t length = len;
  7.         // Calculate the sum                                            //
  8.         sum = 0;
  9.         while (len > 1)
  10.         {
  11.                 sum += *buf++;
  12.                 if (sum & 0x80000000)
  13.                         sum = (sum & 0xFFFF) + (sum >> 16);
  14.                len -= 2;
  15.        }
  16.  
  17.        if (len & 1)
  18.                // Add the padding if the packet lenght is odd          //
  19.                 sum += *((uint8_t *)buf);
  20.  
  21.        // Add the pseudo-header                                        //
  22.         sum += (ip_src++);
  23.        sum += ip_src;
  24.         sum += (ip_dst++);
  25.         sum += ip_dst;
  26.         sum += htons(IPPROTO_TCP);
  27.        sum += htons(length);
  28.  
  29.         // Add the carries                                              //
  30.         while (sum >> 16)
  31.                 sum = (sum & 0xFFFF) + (sum >> 16);
  32.  
  33. u_char ret[2];
  34.        // Return the one's complement of sum  
  35. ret[0] = ((uint16_t)(~sum) >> 8) & 0x00FF;
  36. ret[1] = (uint16_t)(~sum) & 0x00FF;//
  37.        // return ((uint16_t)(~sum));
  38. return ret;
  39. }
  40. //http://minirighi.sourceforge.net/html/tcp_8c-source.html


« Última modificación: 15 Noviembre 2015, 11:49 am por Kaxperday » En línea

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
rub'n


Desconectado Desconectado

Mensajes: 1.217


(e -> λ("live now")); tatuar -> λ("α");


Ver Perfil WWW
Re: ¿Dónde está el problema? TCP checksum
« Respuesta #1 en: 25 Noviembre 2015, 04:49 am »

pufff y yo que ando con el CCNA. ya que toda la suite tcp/ip es código purito que no vemos  :xD


« Última modificación: 25 Noviembre 2015, 04:57 am por solNegr0; » En línea

rubn0x52.com KNOWLEDGE  SHOULD BE FREE.
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen king
Kaxperday


Desconectado Desconectado

Mensajes: 702


The man in the Middle


Ver Perfil WWW
Re: ¿Dónde está el problema? TCP checksum
« Respuesta #2 en: 28 Noviembre 2015, 16:04 pm »

Buenas, a ver si puedo cerrar el tema por una vez:

http://www.tcpipguide.com/free/t_TCPChecksumCalculationandtheTCPPseudoHeader-2.htm

Lo que tengo que hacer para calcular primero el pseudoheader y sumar todos sus campos como de u_short en u_short (16 bits en 16 bits), ¿luego sumamos toda la cabecera TCP, y luego el payload?

¿Todo de 16 bits en 16 bits?, porque me daba todo unos luego ¿hacía algo mal, no tiene sentido o tenía algún error, o no se calcula así?.

Saludos.
En línea

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
rub'n


Desconectado Desconectado

Mensajes: 1.217


(e -> λ("live now")); tatuar -> λ("α");


Ver Perfil WWW
Re: ¿Dónde está el problema? TCP checksum
« Respuesta #3 en: 28 Noviembre 2015, 16:28 pm »

una pregunta estas haciendo algún proyecto en especial ? o en realidad estas simulando comprobar el crc, del PDU, y luego pasarlo a la capa siguiente en tcp/ip?

todo practicamente manual ??  :huh:
En línea

rubn0x52.com KNOWLEDGE  SHOULD BE FREE.
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen king
Kaxperday


Desconectado Desconectado

Mensajes: 702


The man in the Middle


Ver Perfil WWW
Re: ¿Dónde está el problema? TCP checksum
« Respuesta #4 en: 28 Noviembre 2015, 17:17 pm »

Si pertenece a un proyecto y es necesario para que pueda rodar en sí, pero no es lo que piensas, lo que trato de hacer es modificar paquetes TCP tanto de origen y destino, pero si el checksum no queda actualizado el paquete se descarta, el checksum ip si que lo conseguí calcular bien, pero este no.

Mí código que hice para calcularlo es sencillo, suma bien de 16 bits en 16 y controlando el acarreo de bit, el problema es más teórico. Necesito algo de ayuda.

Un saludo.

Os dejo el código que tengo, solo necesito calcular bien el tcp len para poder comprobar si funciona lo demás:

Código
  1. //http://www.arcesio.net/checksum/checksumTCP.html
  2. u_char* tcp_checksum(u_char* datos, int tamaño)
  3. {
  4. u_char *checksum = new u_char[2]();
  5. uint16_t sumando = 0;
  6. bitset<17> total;
  7.  
  8. //sumo ip origen e ip destino
  9. for (int i = 26; i < 33; i++){
  10. total = sumando + (uint16_t)((datos[i] << 8) + datos[i + 1]);
  11. sumando += (uint16_t)((datos[i] << 8) + datos[i + 1]);
  12. if (total[16] == 1)
  13. sumando++;
  14. i++;
  15. }
  16.  
  17. //sumo el byte de ceros y el numero de protocolo TCP
  18. total = sumando + (uint16_t)(0x06);
  19. sumando += (uint16_t)(0x06);
  20. if (total[16] == 1)
  21. sumando++;
  22.  
  23. //aqui sumaría el tcp len no se calcular aún.
  24. //[IP Total Length] - (([IP IHL] + [TCP Data offset]) * 4)
  25. //Aquí sumaríamos el TCP len ¿cuanto es?.
  26. /*total = sumando + (uint16_t)((datos[38] << 8) + datos[39]);
  27. sumando += (uint16_t)((datos[38] << 8) + datos[39]);
  28. if (total[16] == 1)
  29. sumando++;*/
  30.  
  31. //sumo todo el campo de cabecera con el checksum a cero
  32. for (int i = 34; i < 54; i++){
  33. if (i != 50){
  34. total = sumando + (uint16_t)((datos[i] << 8) + datos[i + 1]);
  35. sumando += (uint16_t)((datos[i] << 8) + datos[i + 1]);
  36. if (total[16] == 1)
  37. sumando++;
  38. }
  39. i++;
  40. }
  41.  
  42. //sumo todo el campo de datos a lo que teníamos.
  43. for (int i = 55; i < tamaño - 1; i++){
  44. total = sumando + (uint16_t)((datos[i] << 8) + datos[i + 1]);
  45. sumando += (uint16_t)((datos[i] << 8) + datos[i + 1]);
  46. if (total[16] == 1)
  47. sumando++;
  48. i++;
  49. }
  50.  
  51. //invertimos y pasamos a dos bytes el resultado.
  52. sumando = sumando & 0xFFFF;
  53. sumando = ~sumando;
  54. checksum[0] = (sumando >> 8) & 0x00FF;
  55. checksum[1] = sumando & 0x00FF;
  56. return checksum;
  57. }

Edito:

Finalmente, para calcular el TCP checksum hay que tener crear un array de u_short formado por la concatenación del pseudoheader, cabecera tcp, y tcp payload (datos tcp).

Yo no formo el array paso directamente a sumar sus partes. Sumo primero las ips, luego sumo  el numero protocolo y el tcp len que son 96 bits.

Depués sigo sumando al resultado toda la cabecera casi siempre son 20 bytes, que sumamos de 16 bits en 16 bits cada par.

Después sumo los datos TCP de 16 bits en 16 bits como siempre.

Una vez está todo sumado, invierto el u_short y lo divido en 2 bytes (u_char).

¿Es el método correcto? ¿Por qué falla?.

El tcp len no es el único problema (ya que no lo sé calcular), pues con wireshark compruebo que hay paquetes que lo llevan a cero, y aún así no coinciden los checksums.

Saludos y gracias.
« Última modificación: 28 Noviembre 2015, 17:45 pm por Kaxperday » En línea

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
¿Donde està?
Foro Libre
GARROTE 7 4,468 Último mensaje 2 Enero 2013, 05:21 am
por OmarHack
Dónde se supone que está el enlace de descarga de esta app para Ubuntu
GNU/Linux
okik 8 4,921 Último mensaje 1 Julio 2015, 18:13 pm
por Gh057
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines