TCP switch ---------- This tool allows you to manage tcp connections. For shellcodes creates with "win32 ShellCode Constructor" it is possible to upload/exec some plugins. Using simple commands, you can implement such algorithms as: "listen on ports A and B; wait until connection C1 is made to port A; keep C1 until C2 is connected to port B; then, interlink C1 with C2." or "listen on port A; for each connection C1[i] made to port A, make corresponding C2[i] by connecting to specified ip:port, then interlink C1[i] with C2[i]." or "inject specified file into existing connection C1." Generally, tcpswitch keeps directed graph of links between tcp connections, so you can configure it to work as tcp mapper or make simple tcp chat, or link 2 tcp sessions and then inject your program between'em, while keeping sessions alive, whatever. When started, tcpswitch exec all commands defined in switch2.ini; if .ini file doesn't exists, it listens for commands on 666/tcp. The same commands are valid for both .ini file and control sessions. Control session should operate with "lines" of data, instead of characters; use correct telnet client. switch logic ------------ There exists a set of entries, each entry has unique id. Entry describes established, listening or waiting tcp session. Each entry has its own set of links to other id's, i.e. any entry can point to any set of other entries; All tcpswitch commands operates on these entries and on links between 'em. Each entry can be in one of the following states: STATUS_LISTEN_CTL -- open socket listening for control sessions. created using 'listenctl' command; for each connection to the corresponding port, new entry is created of STATUS_CTL. STATUS_CTL -- established control session. If some data is received in, it is processed as a set of control commands. When some internal switch event occurs, report text is sent to all such sessions. such entry can only be created as a child of STATUS_LISTEN_CTL entry. STATUS_DATA -- established data session. can be created using 'connect' command, or as a child of STATUS_LISTEN_DATA/STATUS_WAITCONN_DATA entries. When some data is received, it is broadcasted to all "linked" data sessions. len = recv(socket[i], data) foreach j if (lnk[i][j]) send(socket[j], data, len) when connection is closed somehow, linked connections behaviour depends on link type. STATUS_WAITCONN_DATA -- created using 'initconn' command; means ip:port (no open socket); used as a parent entry for all automatic connections to the corresponding ip:port. STATUS_LISTEN_DATA -- created using 'listen' command; means open socket listening for data sessions. if somebody connects to this socket, new entry is created of status STATUS_DATA. then, new connections are created (optionally) and some new links are established between entries. Each link between two entries can have one of the following values: 1 SINGLE,KEEP 2 SINGLE,DROP 3 MULTI,KEEP 4 MULTI,DROP "SINGLE" means that link is exclusive, i.e. only one (directed) link of SINGLE type can exists between any two connections; "MULTI" property means that data can be broadcasted to/from multiple connections. "KEEP"/"DROP" properties affects linked entries behaviour when one of them is closed. If some shellcode is connected to the tcpswitch, you can link (type 1) own connection with it, then you can feel free to reconnect, shellcode will not be dropped. Entry linked with others using type 4 will be closed with last closed connection. Lets imagine entry X of type T, which is already connected to entry Y. When such a connection is dropped, the following actions will occur: T=1 X remains open T=2 X is closed T=3 X remains open T=4 X is closed, only if there are no more connections to/from X nb: closing entry X may result in closing other entries connected to it. Available commands are: ---------------------- help -- show quick command syntax listenctl -- listen for "control sessions" on 0.0.0.0: (add new socket to listen on, return id) listen -- listen for "data sessions" on 0.0.0.0: (add new socket to listen on, return id) conn -- immediately connect to ip:port, returns id initconn -- allocate ip:port to connect to, returns id kill id -- close socket/session by id xlink dstid1 dstid2 value -- cross-link two established data sessions by their id's link id1 id2 value -- link/unlink session id1 to id2. all data received from id1 will be sent to id2. show [id] -- show all info about current connections showlinks -- show links table exit -- exit current "control session" die -- exit from memory inject id prefix snippet.bin [text] -- inject code snippet into data session (experimental) [un]mitm m_id1 m_id2 id1 id2 -- set/unset m_id1,2 as man-in-the-middle connections on two connected sockets id1/id2. mitm mode: id1 --> m_id1 --> id2 id1 <-- m_id2 <-- id2 unmitm mode: id1 <==> id2 Macros can be used instead of connection id's: L 1st found connection with specified local port R 1st found connection with specified remote port Usage example ------------- On start: >tcp-switch v2.00 !id=0 status=LISTEN_CTL local=0.0.0.0:666 remote=N/A parent=N/A link:N/A >!id=1 * status=CTL local=127.0.0.1:666 remote=127.0.0.1:xxxx parent=0 link:N/A What do we see here? id=0 is a socket listening for control sessions on port 666 id=1 is current control session, connected to port 666 Now, lets create socket listening for control sessions on port 777: alloc:id=2 >listen:id=2,port=777 !id=0 status=LISTEN_CTL local=0.0.0.0:666 remote=N/A parent=N/A link:N/A >!id=1 * status=CTL local=127.0.0.1:666 remote=127.0.0.1:xxxx parent=0 link:N/A >!id=2 status=LISTEN_CTL local=0.0.0.0:777 remote=N/A parent=1 link:N/A At this step, tcpswitch listens on both ports 666 and 777. To stop listening on port 666, we do the following: kill,id=0 >close:id=0 !id=1 * status=CTL local=127.0.0.1:666 remote=127.0.0.1:xxxx parent=N/A link:N/A >!id=2 status=LISTEN_CTL local=0.0.0.0:777 remote=N/A parent=1 link:N/A Now, we can reconnect to port 777: >tcp-switch v2.00 !id=0 * status=CTL local=127.0.0.1:777 remote=127.0.0.1:xxxx parent=2 link:N/A >!id=2 status=LISTEN_CTL local=0.0.0.0:777 remote=N/A parent=N/A link:N/A Now, lets create two sockets listening for data sessions on ports 1000,1001: alloc:id=1 >listen:id=1,port=1000 alloc:id=3 >listen:id=3,port=1001 !id=0 * status=CTL local=127.0.0.1:777 remote=127.0.0.1:xxxx parent=2 link:N/A >!id=1 status=LISTEN_DATA local=0.0.0.0:1000 remote=N/A parent=0 link:N/A >!id=2 status=LISTEN_CTL local=0.0.0.0:777 remote=N/A parent=N/A link:N/A >!id=3 status=LISTEN_DATA local=0.0.0.0:1001 remote=N/A parent=0 link:N/A id=1 and id=3 are two listening sockets. Now, lets connect (with 2nd and 3rd telnet instances) to ports 1000,1001. in the control session, the following will appear: >(alloc:id=4)(connected:id=4,par=1)(alloc:id=5)(connected:id=5,par=3) then, lets continue in the control session: !id=0 * status=CTL local=127.0.0.1:777 remote=127.0.0.1:xxxx parent=2 link:N/A >!id=1 status=LISTEN_DATA local=0.0.0.0:1000 remote=N/A parent=0 link:N/A >!id=2 status=LISTEN_CTL local=0.0.0.0:777 remote=N/A parent=N/A link:N/A >!id=3 status=LISTEN_DATA local=0.0.0.0:1001 remote=N/A parent=0 link:N/A >!id=4 status=DATA local=127.0.0.1:1000 remote=127.0.0.1:xxxx parent=1 link:N/A >!id=5 status=DATA local=127.0.0.1:1001 remote=127.0.0.1:xxxx parent=3 link:N/A id=4 and id=5 is our new connections. Lets cross-link them using link type 2: lnk[4,5]=lnk[5,4]=2 ... >!id=4 status=DATA local=127.0.0.1:1000 remote=127.0.0.1:xxxx parent=1 link: t2=sd: 5 >!id=5 status=DATA local=127.0.0.1:1001 remote=127.0.0.1:xxxx parent=3 link: t2=sd: 4 Now, data received from one socket will be sent to another one (linked) socket, and vice versa. If you will close connection in 2nd telnet window (corresponding id=4), you will see the following: >(lnk[4,5]=0)(lnk[5,4]=0)(close:id=5) ... >!id=4 status=DATA local=127.0.0.1:1000 remote=127.0.0.1:xxxx parent=1 link:N/A However, connection type were set to 1, i.e. "single/keep", and so link with id=4, i.e. telnet #1 remains connected to tcpswitch. However, link between id=4 & id=5 has been disappeared, and, if telnet #2 is reconnected, you can re-establish it manually, using the same xlink command. But, if in the same situation, connection type is set to 2, i.e. "single/drop", both links will be closed when only one of the connections is dropped. There can be also asymmetric situation - when one of links is of type 1, and another one is of type 2. This could be done using two "link" commands with different types, instead of single "xlink" command. In such a situation, tcpswitch behaviour will differ, depending on which connection is dropped. For automatic session linking, you should setup link id's for "parent" entries, either by "link 1 3 t" plus "link 3 1 t" or using "xlink 1 3 t". Then, all "childs" connecting to ports 1000/1001 will be automatically linked with each other using parent's link type. lnk[1,3]=lnk[3,1]=1 Now, reconnect to tcpswitch in 2nd telnet window, then continue: >(alloc:id=5)(connected:id=5,par=3)(lnk[5,4]=1)(lnk[4,5]=1) !id=0 * status=CTL local=127.0.0.1:777 remote=127.0.0.1:xxxx parent=2 link:N/A >!id=1 status=LISTEN_DATA local=0.0.0.0:1000 remote=N/A parent=0 link: t1=sk: 3 >!id=2 status=LISTEN_CTL local=0.0.0.0:777 remote=N/A parent=N/A link:N/A >!id=3 status=LISTEN_DATA local=0.0.0.0:1001 remote=N/A parent=0 link: t1=sk: 1 >!id=4 status=DATA local=127.0.0.1:1000 remote=127.0.0.1:xxxx parent=1 link: t1=sk: 5 >!id=5 status=DATA local=127.0.0.1:1001 remote=127.0.0.1:xxxx parent=3 link: t1=sk: 4 Now, lets run some shellcode on 127.0.0.1:6666, then, to connect to that shellcode, you should do alloc:id=6 >connect:id=6,127.0.0.1:6666 You can now manually link id=6 with id=4 (id=4 -- 2nd telnet window, port 1000): lnk[4,6]=lnk[6,4]=1 Shell should be now active through telnet window #2. If you now type 'exit' into the shell, connection with id=6 will be closed by shellcode, however telnet window #2 will remain active, since it were connected directly to tcpswitch (using id=4), not to shellcode. To automate connect operation, you should use 'initconn' command: alloc:id=2 >waitconn:id=2,127.0.0.1:6666 !id=0 * status=CTL local=127.0.0.1:777 remote=127.0.0.1:xxxx parent=N/A link:N/A >!id=1 status=LISTEN_DATA local=0.0.0.0:1000 remote=N/A parent=0 link:N/A >!id=2 status=WAITCONN_DATA local=N/A remote=127.0.0.1:6666 parent=0 link:N/A Now, if you will link id=1 (listening on port 1000) to id=2, all future connections to tcpswitch/port 1000 will result in following connections from tcpswitch to 127.0.0.1:6666 and linking sessions with each other: lnk[1,2]=1 !id=0 * status=CTL local=127.0.0.1:777 remote=127.0.0.1:xxxx parent=N/A link:N/A >!id=1 status=LISTEN_DATA local=0.0.0.0:1000 remote=N/A parent=0 link: t1=sk: 2 >!id=2 status=WAITCONN_DATA local=N/A remote=127.0.0.1:6666 parent=0 link: t1=sk: 1 Now, reconnect once again to port 1000, you should see the shell: on connection, in the control window you see: >(alloc:id=3)(connected:id=3,par=1)(alloc:id=4)(connect:id=4,127.0.0.1:6666)(lnk[3,4]=1)(lnk[4,3]=1) then: !id=0 * status=CTL local=127.0.0.1:777 remote=127.0.0.1:xxxx parent=N/A link:N/A >!id=1 status=LISTEN_DATA local=0.0.0.0:1000 remote=N/A parent=0 link: t1=sk: 2 >!id=2 status=WAITCONN_DATA local=N/A remote=127.0.0.1:6666 parent=0 link: t1=sk: 1 >!id=3 status=DATA local=127.0.0.1:1000 remote=127.0.0.1:xxxx parent=1 link: t1=sk: 4 >!id=4 status=DATA local=127.0.0.1:xxxx remote=127.0.0.1:6666 parent=2 link: t1=sk: 3 What do we saw there? Socket with id=1 (with link set to id=2) were listening on port 1000. Entry with id=2 means that child entries should be connected to 127.0.0.1:6666. So, when you have connected to port 1000 (id=3,parent_id=1), socket with (id=4,parent id=2) were created and connection to 127.0.0.1:6666 were made, after that, id=3 were interlinked with id=4, using connection types from parent id's 1 and 2. Now, all the data between 2nd telnet window and shellcode is passed through tcpswitch. To inject shellcode plugins, or "code snippets" into some data session, you can do the following (shellcode listens on 127.0.0.1:6666) >conn 127.0.0.1 6666 >inject 9 #cdsnpt# c:\thahaxor\msgboxt.bin abc and R macros to simplify connections linking: alloc:id=1 >waitconn:id=1,127.0.0.1:6666 alloc:id=2 >listen:id=2,port=1000 lnk[2,1]=lnk[1,2]=2 or, all at once: alloc:id=1 >waitconn:id=1,127.0.0.1:6667 >alloc:id=2 >listen:id=2,port=1000 >lnk[2,1]=lnk[1,2]=2 example above will redirect all connections to local port 1000 to 127.0.0.1:6667. Now, automatic link of two listen incoming connections: alloc:id=1 >listen:id=1,port=2001 >alloc:id=2 >listen:id=2,port=2002 >lnk[1,2]=lnk[2,1]=1 Now, tcpswitch will listen on ports 2001 and 2002 and link all connection pairs to these ports with each other. For example, you can run back-connect shellcode somewhere, then tcpswitch on some unix machine, and then tcpswitch will keep all incoming connections from your shellcode until you connect to tcpswitch; then, it will link you to shellcode. EOF