ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Программирование Raw сокетов на языке Си
  #1  
Старый 09.05.2006, 20:24
Аватар для t0x1n
t0x1n
Новичок
Регистрация: 08.05.2006
Сообщений: 6
Провел на форуме:
13259

Репутация: 1
Отправить сообщение для t0x1n с помощью ICQ
По умолчанию Программирование Raw сокетов на языке Си

t0x1n
http://www.security.e-gloryon.com
security@shamkir.net

Сокеты бывают трех типов:
SOCK_DGRAM датаграмные сокеты - сокеты которые отсылаются в сеть без запроса на соединение (к ним относятся UDP сокеты)
SOCK_STREAM потоковые сокеты - сокеты требующие соединение (TCP сокеты)
SOCK_RAW сырые сокеты - то что хотим, т.е. пишем сокеты с нуля.
В этой статье нас будут интересовать RAW (сырые) сокеты.

В качестве примера я напишу программу которая посылает обычный UDP пакет.
Если вы пользуетесь операционной системой Linux то код программы нужно компилировать с параметром
-D_BSD_SOURCE т.к. мы будет использовать бсдешные сокеты. Также компилировать и запускать
код программы необходимо с правами root (суперпользователя). Для этого достаточно ввести команду
su root.

Начнем...

Для начала функции нужные нам для работы:

Открытие RAW сокета:
int sock;
sock=socket(PF_INET, SOCKET_RAW, протокол);
Закрытие сокета:
close (sock);
Указание порта отправителя и получателя:
htons(порт);
Указание IP адреса отправителя и получателя:
inet_addr ("IP адрес");

Теперь покажу как устроен заголовок UDP на Си т.к. мы будем писать прогрумму посылающую UDP пакет.
UDP:
uh_sport Порт отправителя
uh_dport Порт получателя
uh_ulen Длина заголовка
uh_sum Контрольная сумма

Сообщения об ошибках:
Чтобы в случае ошибки программа нам выдала сообщение о ней
необходимо написать такую конструкцию:
Код:
int sock;
socket(PF_INET, SOCK_RAW, IPPROTO_UDP); //Создаем сокет
if ((sock)<0) //Если sock<0 тогда
{
perror ("socket"); //выдать сообщение об ошибке
} else { //Если нет то
printf ("socket ok"); //Выдать сообщение socket ok
}

А вот код программы посылающий UDP пакет:
#include 
#include 
#include 

main()
{
    int sock;
    sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP); //Открываем сокет
    if ((sock)<0){
    perror ("socket");
    } else {
    printf ("socket ok\n");
    }
    char buf[9999];

    /* Структуры*/
    struct sockaddr_in sin;
    struct udphdr *udph=(struct udphdr*)buf;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1"); //IP адрес получателя
    /***********/    

    /*UDP заголовок */
    udph->uh_sport=htons(21); //Порт отправителя
    udph->uh_dport=htons(22); //Порт получателя
    udph->uh_ulen=0; //Длина заголовка
    udph->uh_sum=0; //Контрольная сумма
    /***************/
    
    /*Посылаем пакет*/
    if((sendto(sock, &udph, sizeof(udph), 0, (struct sockaddr*)&sin, sizeof(sin)))<0){
    perror ("sendto");
    } else {
    printf ("sendto ok\n");
    }
    close (sock); //Закрываем сокет
}

Теперь компилируем и запускаем код с правами рута. Чтобы вполне убедиться, что программ работает
можете запустить tcpdump и посмотреть отослался пакет или нет.

[t0x1n@t0x1n~]$ su root
[root@t0x1n~]$ gcc -D_BSD_SOURCE udp.c -udp
[root@t0x1n~]$ ./udp
socket ok
sendto ok
[root@t0x1n~]$
Ну вот думаю и все! Желаю удач в сетевом кодинге

Последний раз редактировалось Green_Bear; 10.06.2006 в 10:14.. Причина: тег код для придурков создали
 
Ответить с цитированием

  #2  
Старый 09.05.2006, 21:10
Аватар для nerezus
nerezus
Pagan Heart
Регистрация: 12.08.2004
Сообщений: 3,791
Провел на форуме:
6490435

Репутация: 2290


Отправить сообщение для nerezus с помощью ICQ
По умолчанию

А файрвол пропускает провайдерский?
 
Ответить с цитированием

  #3  
Старый 09.05.2006, 21:36
Аватар для Xex
Xex
Banned
Регистрация: 10.07.2005
Сообщений: 224
Провел на форуме:
1062041

Репутация: 50
По умолчанию

И чем она отличается от статей типа:"Кодим по сетевому для чайников"?
Это больше похоже на инструкцию про программингу примитивнейшей сетевой проги.
 
Ответить с цитированием

  #4  
Старый 09.05.2006, 23:37
Аватар для t0x1n
t0x1n
Новичок
Регистрация: 08.05.2006
Сообщений: 6
Провел на форуме:
13259

Репутация: 1
Отправить сообщение для t0x1n с помощью ICQ
По умолчанию

Да, это что то вроде инструкции по программированию сырых сокетов для самых маленьких.
 
Ответить с цитированием

  #5  
Старый 09.05.2006, 23:39
Аватар для t0x1n
t0x1n
Новичок
Регистрация: 08.05.2006
Сообщений: 6
Провел на форуме:
13259

Репутация: 1
Отправить сообщение для t0x1n с помощью ICQ
По умолчанию

Должен пропускать
 
Ответить с цитированием

  #6  
Старый 21.05.2006, 07:35
Аватар для lexa
lexa
Участник форума
Регистрация: 14.01.2005
Сообщений: 169
Провел на форуме:
427901

Репутация: 23
Отправить сообщение для lexa с помощью ICQ
По умолчанию

а вот мне это интерестно ! спасибо t0x1n
 
Ответить с цитированием

  #7  
Старый 10.06.2006, 02:42
Аватар для faust45
faust45
Познающий
Регистрация: 02.03.2006
Сообщений: 43
Провел на форуме:
132146

Репутация: 0
По умолчанию

Ну мне честно говоря премер с ROW Socket совсем не понятен
где ты заголовок IP формируеш ? Вот я нашёл в инете крутой пример лови

Код:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>

unsigned short ip_cksum(unsigned char * buff, int len)
{
        unsigned long sum = 0;
        if (len > 3)
        {
                __asm__("clc\n"
                "1:\t"
                "lodsl\n\t"
                "adcl %%eax, %%ebx\n\t"
                "loop 1b\n\t"
                "adcl $0, %%ebx\n\t"
                "movl %%ebx, %%eax\n\t"
                "shrl $16, %%eax\n\t"
                "addw %%ax, %%bx\n\t"
                "adcw $0, %%bx"
                : "=b" (sum) , "=S" (buff)
                : "0" (sum), "c" (len >> 2) ,"1" (buff)
                : "ax", "cx", "si", "bx" );
        }
        if (len & 2)
        {
                __asm__("lodsw\n\t"
                "addw %%ax, %%bx\n\t"
                "adcw $0, %%bx"
                : "=b" (sum), "=S" (buff)
                : "0" (sum), "1" (buff)
                : "bx", "ax", "si");
        }
        if (len & 1)
        {
                __asm__("lodsb\n\t"
                "movb $0, %%ah\n\t"
                "addw %%ax, %%bx\n\t"
                "adcw $0, %%bx"
                : "=b" (sum), "=S" (buff)
                : "0" (sum), "1" (buff)
                : "bx", "ax", "si");
        }
        sum =~sum;
        return(sum & 0xffff);
}

unsigned short tcp_check(struct tcphdr *th, int len,
          unsigned long saddr, unsigned long daddr)
{
        unsigned long sum;
        __asm__("
            addl %%ecx, %%ebx
            adcl %%edx, %%ebx
            adcl $0, %%ebx
            "
        : "=b"(sum)
        : "0"(daddr), "c"(saddr), "d"((ntohs(len) << 16) + IPPROTO_TCP*256)
        : "bx", "cx", "dx" );
        __asm__("
            movl %%ecx, %%edx
            cld
            cmpl $32, %%ecx
            jb 2f
            shrl $5, %%ecx
            clc
1:          lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            loop 1b
            adcl $0, %%ebx
            movl %%edx, %%ecx
2:          andl $28, %%ecx
            je 4f
            shrl $2, %%ecx
            clc
3:          lodsl
            adcl %%eax, %%ebx
            loop 3b
            adcl $0, %%ebx
4:          movl $0, %%eax
            testw $2, %%dx
            je 5f
            lodsw
            addl %%eax, %%ebx
            adcl $0, %%ebx
            movw $0, %%ax
5:          test $1, %%edx
            je 6f
            lodsb
            addl %%eax, %%ebx
            adcl $0, %%ebx
6:          movl %%ebx, %%eax
            shrl $16, %%eax
            addw %%ax, %%bx
            adcw $0, %%bx
            "
        : "=b"(sum)
        : "0"(sum), "c"(len), "S"(th)
        : "ax", "bx", "cx", "dx", "si" );

        /* We only want the bottom 16 bits, but we never cleared the top 16. */

        return((~sum) & 0xffff);
}

void resolve_address(struct sockaddr *addr, char *hostname, u_short port) {
struct sockaddr_in *address;
struct hostent *host;

address = (struct sockaddr_in *)addr;
(void) bzero((char *)address, sizeof(struct sockaddr_in));
address->sin_family = AF_INET;
address->sin_port = htons(port);
address->sin_addr.s_addr = inet_addr(hostname);
if ((int)address->sin_addr.s_addr == -1) {
  host = gethostbyname(hostname);
  if (host) {
   bcopy( host->h_addr, (char *)&address->sin_addr, host->h_length);
  }
  else {
   puts("Couldn't resolve address!!!");
   exit(-1);
  }
 }
}

char *create_ip(u_long source, u_long dest, u_char protocol, u_char ttl, 
        u_short id, char *data, int data_len)
{
 char *ip_datagram;
 struct iphdr *ip_header; 
 ip_datagram = malloc(sizeof(struct iphdr) + data_len);
 ip_header = ip_datagram;
 ip_header->version   = 4;
 ip_header->tos       = 0;
 ip_header->frag_off  = 0;
 ip_header->check     = 0;
 ip_header->saddr     = source;
 ip_header->daddr     = dest;
 ip_header->protocol  = protocol;
 ip_header->ttl       = ttl;
 ip_header->id        = htons(id);
 ip_header->ihl       = 5;
 ip_header->tot_len   = htons(sizeof(struct iphdr) + data_len); 
 ip_header->check = htons(ip_cksum(ip_datagram,sizeof(struct iphdr)));
 bcopy(data,ip_datagram+sizeof(struct iphdr),data_len);
 return ip_datagram;
}

char *create_tcp(u_long source, u_long dest, u_short sport, u_short dport, 
        u_long seqnum, u_long acknum, u_char flags, char *data, int datalen) 
{
 char *wewt;
 struct tcphdr *tcp_header;
 wewt = malloc(sizeof(struct tcphdr) + datalen);
 tcp_header = wewt;
 tcp_header->th_sport = sport;
 tcp_header->th_dport = dport;
 tcp_header->th_seq   = seqnum;
 tcp_header->th_ack   = acknum;
 tcp_header->th_flags = flags;
 tcp_header->th_sum   = 0;
 tcp_header->th_sum = htons(tcp_check(tcp_header, sizeof(struct tcphdr), 
    source, dest));
 bcopy(data,wewt+sizeof(struct tcphdr),datalen);
 return wewt;
}

void sendpack(char *fromhost, int fromport, char *tohost, int toport) {
 char *packet;
 char *tcppacket;
 char *sendme;
 static struct sockaddr_in local, remote;
 static int sock = 0;
 if (!sock) {
   resolve_address((struct sockaddr *)&local, fromhost, fromport);
   resolve_address((struct sockaddr *)&remote, tohost, toport);
   sock = socket(AF_INET, SOCK_RAW, 255);
   if (sock == -1) { perror("Getting raw socket"); exit(-1); }
  }
   tcppacket = create_tcp(&local.sin_addr, &remote.sin_addr, 
        local.sin_port, remote.sin_port, 795930600, 0, TH_SYN,
        NULL, 0);
   packet = create_ip(&local.sin_addr, &remote.sin_addr,
        6, 24, 4, NULL, 0);
   sendme = (struct iphdr *)packet;
   bcopy(tcppacket, sendme+sizeof(struct iphdr), sizeof(tcppacket));
   printf("the ip header is %d bytes long.\n", sizeof(struct iphdr));
   printf("the tcp header is %d bytes long.\n", sizeof(struct tcphdr));
   printf("the ip packet is %d bytes long.\n", sizeof(packet));
   printf("the tcp packet is %d bytes long.\n", sizeof(tcppacket));
   printf("the final packet is %d bytes long.\n", sizeof(sendme));
  {
   int result;

   result = sendto(sock, packet, sizeof(packet), 0,
        (struct sockaddr *)&remote, sizeof(remote));
   if (result != sizeof(packet)) { perror("sending packet"); }
  }
}

main(int argc, char **argv) {
if (argc!=5) {
 printf("usage: %s <from host> <from port> <to host> <to port>\n", argv[0]);
 exit(-1);
}
 printf("forging packet from %s.%d to %s.%d\n", argv[1], atoi(argv[2]), 
        argv[3], atoi(argv[4]));
 sendpack(argv[1], atoi(argv[2]), argv[3], atoi(argv[4]));
}

Последний раз редактировалось Green_Bear; 10.06.2006 в 10:13.. Причина: тег код для придурков создали
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ