Snorting coke (and packets) by GriYo / 29A ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 Windows 2000 introduces a new concept for Windows users: The possibility of creating raw-sockets. We will use this new Windows capacity to capture network traffic on a net. What to make with captured packets is your decision, some suggestions are: * To capture login/password combinations and use them later to access the corresponding services. * To receive commands from the master. These commands can be sent by means of TCP, UDP or ICMP protocols, or even by a combination of them. As limitation we find that only users with administrator priviledges are allowed to create raw-sockets. First of all, we have to initialize Windows Sockets, by calling WSAStartup. We must tell WSAStartup that we need Winsock version 2.2+, which will only succeed on windows 2000 or XP. ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 invoke WSAStartup,00000202h,addr wsaDATA .if eax != 0 ;Error: WSAStartup jmp ExitApp .endif ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 The second thing is to create a socket to listen at. Its not a bad idea to run this code in a separate thread, so its execution does not disturb the rest of the application. ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 WSA_FLAG_OVERLAPPED equ 00000001h WSockThread proc pParam :DWORD LOCAL s :SOCKET LOCAL if0 :sockaddr_in LOCAL optval :DWORD LOCAL dwBytesRet :DWORD LOCAL dwFlags :DWORD LOCAL wbuf[8] :BYTE invoke WSASocket, AF_INET, SOCK_RAW, IPPROTO_IP, 0, 0, WSA_FLAG_OVERLAPPED .if eax == INVALID_SOCKET ;Error: WSASocket return 0 .endif mov s,eax invoke ZeroFill,addr if0,SIZE sockaddr_in invoke WSockGetInterfase, s, addr if0, 0 .if eax == 0 ;Error: GetInterface return 0 .endif ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 There is a call to a function called WSockGetInterfase in the above code. Dont browse Winsock exported functions looking for it. The code for this function is the next step to code. WSockGetInterfase is used to obtain a list of available network interfases. To get it we will use SIO_ADDRESS_LIST_QUERY Winsock IOCTL: ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 SIO_ADDRESS_LIST_QUERY equ 48000016h WSockGetInterfase proc s :SOCKET, ifx :DWORD, num :DWORD LOCAL BytesRet :DWORD LOCAL if_LIST[2048] :BYTE invoke ZeroFill,addr if_LIST,2048 mov BytesRet,0 invoke WSAIoctl, s, SIO_ADDRESS_LIST_QUERY, NULL, 0, addr if_LIST, 2048, addr BytesRet, NULL, NULL .if eax == SOCKET_ERROR ;Error: WSAIoctl return 0 .endif mov ecx,num lea esi,if_LIST cld lodsd .if eax == 0 ;Error: No interface found return 0 .elseif ecx >= eax ;Error: Device number too high return 0 .endif shl ecx,3 add esi,ecx cld lodsd add eax,sockaddr_in.sin_addr mov esi,eax mov edi,ifx add edi,sockaddr_in.sin_addr cld lodsd stosd return 1 WSockGetInterfase endp ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 We call WSAIoctl with the SIO_ADDRESS_LIST_QUERY to obtain a list of local transport addresses of the socket's protocol family to which the application can bind. The list returned in the output buffer using the following format: ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 SOCKET_ADDRESS_LIST STRUCT iAddressCount dd ? Address dd ? SOCKET_ADDRESS_LIST ENDS ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 WSockGetInterfase uses 3 entry parameters: * A valid socket (s) * A pointer to a sockaddr_in structure that will be filled with information about the selected network interface * The number of the interfase we will bind to. We use 0 here in order to use first detected interface. Once we have created the socket and we have selected the interface we can call bind to asociated them. ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 mov if0.sin_family,AF_INET invoke htons,0 mov if0.sin_port,ax invoke bind, s, addr if0, SIZE sockaddr_in .if eax == SOCKET_ERROR ;Error: bind return 0 .endif ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 The final trick is to set the SIO_RCVALL mode on the socket, by calling WSAIoctl. Lets have a look at what MSDN Library says about this IOCTL: SIO_RCVALL: Enables a socket to receive all IP packets on the network. The socket handle passed to the WSAIoctl function must be of AF_INET address family, SOCK_RAW socket type, and IPPROTO_IP protocol. The socket also must be bound to an explicit local interface, which means that you cannot bind to INADDR_ANY. Once the socket is bound and the IOCTL set, calls to the WSARecv or recv functions return IP datagrams passing through the given interface. Note that you must supply a sufficiently large buffer. Setting this IOCTL requires Administrator privilege on the local machine. SIO_RCVALL is available in Windows 2000 and later versions of Windows. Well, water clear, lets do it. ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 SIO_RCVALL equ 98000001h mov dwBytesRet,0 mov optval,1 invoke WSAIoctl, s, SIO_RCVALL, addr optval, 4, 0, 0, addr dwBytesRet, 0, 0 .if eax == SOCKET_ERROR ;Error: WSAIoctl return 0 .endif ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 Done, now, on result to WSARecv on this socket we will receive IP packets running around the network, lets see an example. ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 lea edi,wbuf cld mov eax,PACKET_BUFFER_SIZE stosd lea eax,pcap_buffer stosd mov dwBytesRet,0 mov dwFlags,0 invoke WSARecv, s, addr wbuf, 1, addr dwBytesRet, addr dwFlags, 0, 0 .if eax == SOCKET_ERROR ;Error: WSARecv return 0 .endif ;Decode IP header! invoke DecodeIpHeader,addr wbuf ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 The DecodeIpHeader function uses a pointer to a WSABUF structure, which contains information about captured network frame. Lets see an example on how to extract the information from it. ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 IP_HEADER STRUCT Version_and_HdrLen db ? ServiceType db ? TotalLen dw ? ID dw ? Flags_and_FragOff dw ? TimeToLive db ? Protocol db ? HdrChksum dw ? SrcAddr dd ? DstAddr dd ? IP_HEADER ENDS DecodeIpHeader proc Buffer :DWORD LOCAL szSrcIp[16] :BYTE mov eax,Buffer mov esi,[eax+4] ;Buffer points to a WSABUF structure mov eax,[esi+IP_HEADER.DstAddr] ;Do something here with destination ip address ;... ;... ;... mov eax,[esi+IP_HEADER.SrcAddr] ;Or do something using source ip address ;... ;... ;... mov al,[esi+IP_HEADER.Protocol] ;You can also check for specific protocols .if al == IPPROTO_TCP ;... ;... ;... .elseif al == IPPROTO_UDP ;... ;... ;... .elseif al == IPPROTO_ICMP ;... ;... ;... .endif ret DecodeIpHeader endp ;緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷緷 Thats all folks, happy snorting! -- GriYo / 29A I'm not in the business... ...I am the business