Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Войти
 
Страницы: 1 2 След.
RSS
RAW-сокеты в Винде. Возможно ли это?
 
Не могу понять можно ли с помощью Winsock'а работать с сырыми сокетами. Я имею ввиду вот такой сокет
socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
Читал статьи в которых пишутся совсем разные вещи. Например Касперский в своей статье "Самоучитель игры на WINSOCK" (http://citforum.isurgut.ru/book/cook/winsock.shtml) говорит что нельзя, потому что "вызов "setsockopt(my_sock,IPPROTO_IP, IP_HDRINCL, &oki, sizeof(oki))" возвращал ошибку!".
С другой стороны вот здесь: http://netsecurity.r2.ru/docs/raw.html пишется что всё должно работать (хотя ИМХО статья в стиле Ксакепа). Может сведения Касперского устарели и очередной сервис-пак исправил ошибку? Или Касперский прав и Winsock только пинг умеет делать.
Я кстати так и не нашёл ни одного исходника IP-спуфера под винду, если кто знает где есть путёвый HelloWorld по этой теме - киньте ссылку.

========================Moderator========================
Тебе не кажется, что к "Безопасности Windows" это прямого отношения не имеет? Топик уходит в "Программирование".
========================Moderator========================
 
Мдяаааа. Что так глухо-то? Вопрос сильно сложный или наоборот ламерский? Или таким извратом как "сетевой кодинг под Виндовс" здесь никто не занимается?
Скажите хоть про "RTFM" что-нибудь.
 
Да кстати, чему равен  IP_HDRINCL? 2 или 3 ?
 
Начиная с Win2k работать с сырыми сокетами можно точно, что касается более старых версий WinNT - не пробовал.
 
http://www.rsdn.ru/article/net/sniffer.xml
На Win98 можно посылать пакеты. На Win2K по-моему только снифить. Для того, чтобы работать нормально, т.е спуфить, используйте WinPCAP.
Вот статья об WinPCAP:
http://cherepovets-city.ru/insecure/reading/index.html
Вот сам WinPCAP:
http://winpcap.polito.it
 
Цитата
MishaSt пишет:
На Win2K по-моему только снифить.
Не только, но и отправлять сформированный собственноручно - сам делал.
 
Цитата
Mazay пишет:
Да кстати, чему равен  IP_HDRINCL? 2 или 3 ?
**      WS2TCPIP.H - WinSock2 Extension for TCP/IP protocols

/* Option to use with [gs]etsockopt at the IPPROTO_IP level */

#define IP_OPTIONS     1 /* set/get IP options */
#define IP_HDRINCL     2 /* header is included with data */
#define  IP_TOS                   3  /* IP type of service and preced*/
#define  IP_TTL                   4  /* IP time to live */
#define IP_MULTICAST_IF         9 /* set/get IP multicast i/f  */
#define IP_MULTICAST_TTL       10 /* set/get IP multicast ttl */
#define IP_MULTICAST_LOOP      11 /*set/get IP multicast loopback */
#define IP_ADD_MEMBERSHIP      12 /* add an IP group membership */
#define IP_DROP_MEMBERSHIP     13/* drop an IP group membership */
#define IP_DONTFRAGMENT     14 /* don't fragment IP datagrams */
 
2Michael_X:
Покажи пример плз! Просто отправка пустого IP пакета, скажем с ТТЛ=63. Я получаю 10049 ошибку при отправке. Это что-то вроде "Нет такого адреса".

2MishaSt
Снифить у меня получается, про Winpcap тоже слышал, но хочется обойтись WInsock'ом.
 
Начиная с W2k поддержка raw sockets есть точно и разрешены они только узерам с админ-привилегиями.
В гуглях ты плохо к тому же искал, вот что у меня валяется с инета слитое когда-то:
Цитата

Затем,  как  вы  знаете,  надо  инициализировать  windows sockets api.
Делается  это  WSAStartup'ом,  коему  впаривается  версия  именно  2.2 - в
противном случае вас ожидает вселенский сакс.

 WSADATA WSAData;
 if ( WSAStartup(MAKEWORD(2,2), &WSAData) != 0 )
 {
    printf("ERROR:WSAStartup() error %i\n", WSAGetLastError());
    exit(0);
 }

     Теперь можно сделать raw-сокет. Вот он.

 SOCKET raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
 if (raw_socket == INVALID_SOCKET)
 {
    printf("ERROR:socket(SOCK_RAW) error %i\n", WSAGetLastError());
    exit(0);
 }

     Далее  все  зависит  от  цели  - снифак мы пишем, спуфер, или даже все
вместе.
                                      СПУФЕР
                                      ------

     Для  тех  кто  не  знает,  спуфер (spoofer) - это такая хрень, которая
позволяет  вместо  своего  IP-шника  подставить  чужой.  А  в общем случае
послать весь IP-пакет целиком. И это правильно.

     Для того, чтобы через созданный raw-сокет отправить raw ip-пакет, надо
поставить  на этот сокет такую опцию, чтоб винда не создавала ip-заголовки
у  посылаемых  пакетов, а попросту бы  *  забила на них и молча отправляла
дальше в сеть. Вот как это делается:

 DWORD optval = 1;
 if ( setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL,
                   (char*)&optv al, sizeof(optval)) == SOCKET_ERROR )
 {
    printf("ERROR:setsockopt(IP_HDRINCL) error %i\n", WSAGetLastError());
    exit(0);
 }

     А  дальше  можно  работать  как  с  обычным  UDP-пакетом,  посредством
sendto(), только что в пакете будет еще и IP-заголовок.

     Пусть  готовый к отправке пакет, начинающийся с ip-header'а, находится
в BYTE* buf, длиной int len.

 sockaddr_in addr;
 addr.sin_family      = AF_INET;
 addr.sin_port        =  htons(0);        &nb sp;  // пох
 addr.sin_addr.s_addr = *(DWORD*)&buf[16]; // packet.ip_header.dst_ip (*)

 int res = sendto(raw_socket, buf, len, 0, (sockaddr*)&addr, sizeof(addr));
 if (res != len)
 {
    printf("ERROR:sendto()=%i, WSAGetLastError=%i\n", res,WSAGetLastError());
    exit(0);
 }

     (*)  И  тут  есть  одна  тонкость.  Винда пошлет пакет вовсе не на тот
адрес, коий указан в поле dst ip-заголовка пакета. А пошлет винда пакет на
тот  адрес,  который указан в структуре sockaddr, подаваемой в sendto(). В
случае  одной  сетевухи  это  все одно и то же; в случае двух - может быть
определенная разница.
 
Да читал я эту статью (см. мой 1й постинг). Ты сам то пробовал пакеты так слать?
Вот глянь такой исходник, почто не работает?
(жирным выделил то, что сам писал, как самые багоопасные  участки)
Цитата


#include <stdio.h>
#include <winsock2.h>

#define IP_HDRINCL 2
typedef struct ip
{
    unsigned char   ip_hl:4;        &nbs p;    
    unsigned char   ip_v:4;          ;     

    unsigned char   ip_tos;          ;           ;  
    unsigned short  ip_len;          ;           ;  
    unsigned short  ip_id;                         
    unsigned short  ip_off;          ;           ;  

    unsigned char   ip_ttl;          ;     
    unsigned char   ip_p;         & nbsp;         & nbsp;    
    unsigned short  ip_sum;          ;           ;  
    struct   in_addr ip_src, ip_dst;    
} ip_hdr;

int main()
{
WSADATA WSAData;
if ( WSAStartup(MAKEWORD(2,2), &WSAData) != 0 )
{
    printf("ERROR:WSAStartup() error %i\n", WSAGetLastError());
    exit(0);
}  

SOCKET raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (raw_socket == INVALID_SOCKET)
{
    printf("ERROR:socket(SOCK_RAW) error %i\n", WSAGetLastError());
    exit(0);
}


DWORD optval = 1;
if ( setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL,(char*)&optval, sizeof(optval)) == SOCKET_ERROR )
{
    printf("ERROR:setsockopt(IP_HDRINCL) error %i\n", WSAGetLastError());
    exit(0);
}

BYTE *buf;
ip_hdr *buf_ip = new ip_hdr;
buf= (BYTE*)buf_ip;
int len=sizeof(ip_hdr);

buf_ip->ip_hl=5;
buf_ip->ip_v=4;
buf_ip->ip_ttl=65;
buf_ip->ip_tos=0;
buf_ip->ip_len=htons(sizeof(ip_hdr));
buf_ip->ip_p = 255;
buf_ip->ip_dst.s_addr=inet_addr("192.106.144.78");


sockaddr_in addr;
addr.sin_family      = AF_INET;
addr.sin_port        = htons(0); // пох
addr.sin_addr.s_addr = *(DWORD*)&buf[16]; // packet.ip_header.dst_ip (*)

printf("%s\n",inet_ntoa(addr.sin_addr));


int res = sendto(raw_socket, buf, len, 0, (sockaddr*)&addr, sizeof(addr));
if (res != len)
{
    printf("ERROR:sendto()=%i, WSAGetLastError=%i\n", res,WSAGetLastError());
    exit(0);
}
}
 
А сумму что, подсчитывать не надо?
 
Ну у меня всегда(почти )) ) все работает ;P

// rawsock.cpp : Defines the entry point for the console application.
//

#pragma comment(lib,"ws2_32")

//#include <windows.h>
#include <winsock2.h>
#include <WS2tcpip.h>
#include <stdio.h>

typedef struct ip
{
     unsigned char ip_hl:4;
     unsigned char ip_v:4;

    unsigned char ip_tos;
    unsigned short ip_len;
    unsigned short ip_id;
    unsigned short ip_off;

    unsigned char ip_ttl;
    unsigned char ip_p;   
    unsigned short ip_sum;
    struct   in_addr ip_src, ip_dst;     
} ip_hdr;

int main()
{
WSADATA WSAData;
if ( WSAStartup(MAKEWORD(2,2), &WSAData) != 0 )
{
    printf("ERROR:WSAStartup() error %i\n", WSAGetLastError());
    exit(0);
}

SOCKET raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (raw_socket == INVALID_SOCKET)
{
    printf("ERROR:socket(SOCK_RAW) error %i\n", WSAGetLastError());
    exit(0);
}


DWORD optval = 1;
if ( setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL,(char*)&optval, sizeof(optval)) == SOCKET_ERROR )
{
    printf("ERROR:setsockopt(IP_HDRINCL) error %i\n", WSAGetLastError());
    exit(0);
}

BYTE *buf;
ip_hdr *buf_ip = new ip_hdr;
buf= (BYTE*)buf_ip;
int len=sizeof(ip_hdr)+10;

buf_ip->ip_hl=5;
buf_ip->ip_v=4;
buf_ip->ip_ttl=65;
buf_ip->ip_tos=0;
buf_ip->ip_len=htons(sizeof(ip_hdr));
buf_ip->ip_p = 255;
buf_ip->ip_dst.s_addr=inet_addr("193.194.195.1");
buf_ip->ip_src.s_addr=inet_addr("127.0.0.1");

buf_ip->ip_sum = 0;


sockaddr_in addr;
addr.sin_family      = AF_INET;
addr.sin_port        = htons(53);
addr.sin_addr.s_addr = buf_ip->ip_dst.s_addr;

printf("%s\n",inet_ntoa(addr.sin_addr));


int res = sendto(raw_socket, (const char*)buf, len, 0, (sockaddr*)&addr, sizeof(addr));
if (res != len)
{
    printf("ERROR:sendto()=%i, WSAGetLastError=%i\n", res,WSAGetLastError());
    exit(0);
}
}

Packet #1, Direction: Out, Time:04:29:10,375, Size: 44
Ethernet II
     Destination MAC: BC:38:20:00:12:00
     Source MAC: 00:00:0F:00:00:00
     Ethertype: 0x0800 (2048) - IP
IP
     IP version: 0x04 (4)
     Header length: 0x05 (5) - 20 bytes
     Type of service: 0x00 (0)
     Total length: 0x001E (30)
     ID: 0xCDCD (52685)
     Flags
     Fragment offset: 0x0DCD (3533)
     Time to live: 0x41 (65)
     Protocol: 0xFF (255) - Unknown
     Checksum: 0xD980 (55680) - correct
     Source IP: 127.0.0.1
     Destination IP: 193.194.195.1
     IP Options: None
Raw Data:
0x0000   BC 38 20 00 12 00 00 00-0F 00 00 00 08 00 45 00   ?8 ...........E.
0x0010   00 1E CD CD CD CD 41 FF-D9 80 7F 00 00 01 C1 C2   ..????A???...??
0x0020   C3 01 FD FD FD FD 93 00-08 00 00  00         &nbs p;     ?.????“.....
 
суть в этом
int len=sizeof(ip_hdr)+10;  - шлем не только хедер

и в этом

buf_ip->ip_sum = 0;         - чексум в ноль чтобы винсокс посчитал сам
 
Не помогло. Получаю вот такой ответ.
Цитата

C:\prg\sock_raw>3.exe
193.194.195.1
ERROR:sendto()=-1, WSAGetLastError=10049

10049 помоему значит, что он хоста не видит. Пакет в сетку не уходит, я смотрю это снифером (кстати ты чем пользовался?).
Интересно, какое винсоку дело дойдёт или  нет пакет. Сокет же сырой.
Пробовал писать в dst реальный айпишник, тоже самое.
 
Да,  и какое дело винсоку до контрольной суммы?
Опять же, сокет - сырой.
 
Mazay
Может быть и никакое, но зачем слать битый пакет?
Просто скомпиль исходник, к-рый я вставил и посмотри - если у тебя не заработает, значит неправильно что-то делаешь. У меня работает.А юзал я, конечно же, снифер - пакеты нормально уходят.
НО если ты надеешься что очень дегко заспуфить свой IP то сильно ошибаешься - внутри локалки это еще можно, но через грамотно настроенные роутеры пакет не пройдет, т.к. настраивают фильтрование SRC IP, блокирующее отправку пакетов с SRC IP из чужих сетей, что блокирует спуффинг.
 
Попробую дома на VC++. Здесь у меня только Borland 5.5.1.
Скомпилил прямо то что ты постил. Линкер ругнулся вот так:
Цитата

Turbo Incremental Link 5.00 Copyright © 1997, 2000 Borland
Fatal: Unable to open file 'WS2_32.OBJ'
Я закомментировал:
//#pragma comment(lib,"ws2_32")
Вроде всё скомпоновалось/запустилось, но вот такая дурь.
Кстати, может это глюк Борланда?

Я понимаю, что чистый IP-спуффинг это уже старо,  но от простого к сложному... .
 
тот исходник под виндовый VC++ .NET(хотя должно компилиться без проблем в любом MS VC++ 5,6) Можешь просто ту строчку убрать и подключить либу в свойствах проекта.
 
Почти!
Дома скомпилил под VS.NET, сначала получил ошибку No route to host. Что вполне объяснимо: сетки нет  - IP нет. Поставил в src и в dest 127.0.0.1 - всё отправилось без ошибок, но снифер ничего не поймал (по-моему он и не должен ловить такие пакеты от localhost'а).
На полевых испытаниях: отправляю пакет от своего IP на другой, реально существующий - ошибка

WSAEINTR
(10004)
Interrupted function call.
A blocking operation was interrupted by a call to WSACancelBlockingCall.


Кстати если компилить Борландом и явно укзывать библиотеку всегда получаю ошибку 10049
 
Кинь exe-шник, я проверю у себя, может дело не в коде и не в компиляторе, а в моей системе на работе.
Страницы: 1 2 След.
Читают тему