C++程序,客户端和服务器可以正常进行通信收发消息,可否通过网络注入控制服务器执行自己的代码?
正常进行通信收发消息,正常也就没有权限在客户端控制服务器执行自己的代码。
如要非法类型的。首先要得一定权限,也就是说:我们需要提权
https://blog.csdn.net/qq_59942146/article/details/121712670这里好像有部分说明
高级黑客可能有办法找到服务器漏洞,一般这种高危漏洞发现后都会被封掉。最近半年的log4j2就差不多
一种思路是注入脚本,通过请求将脚本代码携带至服务端,例如nodejs脚本或者python脚本等
超级=_=,直接附上注入程序以及dll的代码。
dll 代码很简单只是弹窗,可以根据需要扩充。
注入程序由于是练手,只是随便写了打开计算器的远程注入。
从注入到卸载都包含,在程序执行完毕后扫尾巴
// InjectExample.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
int EnableDebugPriv(const wchar_t *name)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
//打开进程令牌环
if(NULL == OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))
return 1;
//获得进程本地唯一ID
if(!LookupPrivilegeValue(NULL,name,&luid))
return 1;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
//调整权限
if(!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
return 1;
return 0;
}
BOOL InjectDll(const wchar_t* DllFullPath,const DWORD dwRemoteProcessId)
{
HANDLE hRemoteProcess;
EnableDebugPriv(SE_DEBUG_NAME);
//打开远程线程
hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwRemoteProcessId);
if(!hRemoteProcess)
{
printf("OpenProcess Fail,GetLastError: %d",GetLastError());
return FALSE;
}
void *pszLibFileRemote;
//使用VirtualAllocEx 函数在远程进程的内存地址空间分配DLL文件名空间
pszLibFileRemote = VirtualAllocEx(hRemoteProcess,NULL,(wcslen(DllFullPath)+1)*sizeof(wchar_t),MEM_COMMIT,PAGE_READWRITE);
if(!pszLibFileRemote)
{
printf("VirtualAllocEx Fail,GetLastError: %d",GetLastError());
return FALSE;
}
//使用WriteProcessMemory 函数将DLL的路径写入到远程进程的内存空间
DWORD dwReceiveSize;
if(0 == WriteProcessMemory(hRemoteProcess,pszLibFileRemote,(void*)DllFullPath,wcslen(DllFullPath)*sizeof(wchar_t),NULL))
{
printf("WriteProcessMemory Fail,GetLastError: %d",GetLastError());
return FALSE;
}
printf("WriteProcessMem Success!\r\n");
//计算LoadLibrary 的入口地址
PTHREAD_START_ROUTINE pfnStartAddr = NULL;
//#ifdef _UNICODE
pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(::GetModuleHandle(TEXT("Kernel32")),"LoadLibraryW");
//#else
//pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(::GetModuleHandle(TEXT("Kernel32")),"LoadLibraryA");
//#endif
if(NULL == pfnStartAddr)
{
printf("GetProcAddress Fail,GetLastError: %d",GetLastError());
return FALSE;
}
//启动远程线程 LoadLibrary,通过远程线程调用创建新的线程
DWORD dwThreadId=0;
HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,pszLibFileRemote,0,NULL);
if(hRemoteThread == NULL)
{
printf("注入线程失败,ErrorCode: %d\r\n",GetLastError());
return FALSE;
}
printf("Inject Success ,ProcessId : %d\r\n",dwRemoteProcessId);
WaitForSingleObject(hRemoteThread,INFINITE);
GetExitCodeThread(hRemoteThread,&dwThreadId);
//卸载 注入dll
pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"FreeLibrary");
hRemoteThread = CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,(LPVOID)dwThreadId,0,NULL);
//释放远程进程控件
VirtualFreeEx(hRemoteProcess,pszLibFileRemote,wcslen(DllFullPath)*sizeof(wchar_t)+1,MEM_DECOMMIT);
//释放句柄
CloseHandle(hRemoteThread);
CloseHandle(hRemoteProcess);
return TRUE;
}
DWORD GetProcessId()
{
DWORD Pid = -1;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 创建系统快照
//创建系统快照
PROCESSENTRY32 lPrs; //保存进程信息的结构
ZeroMemory(&lPrs,sizeof(PROCESSENTRY32));
lPrs.dwSize = sizeof(lPrs);
wchar_t *targetFile = L"calc.exe";
Process32First(hSnap,&lPrs); //取得系统快照中第一个进程信息
if(wcsstr(targetFile,lPrs.szExeFile)) // 判断进程信息是否为explore.exe
{
Pid = lPrs.th32ProcessID;
return Pid;
}
while(1)
{
ZeroMemory(&lPrs,sizeof(lPrs));
lPrs.dwSize = sizeof(lPrs);
if(!Process32Next(hSnap,&lPrs))
{
Pid=-1;
break;
}
if(wcsstr(targetFile,lPrs.szExeFile))
{
Pid = lPrs.th32ProcessID;
break;
}
}
CloseHandle(hSnap);
return Pid;
}
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t myFILE[MAX_PATH];
GetCurrentDirectory(MAX_PATH,myFILE); //获取当前路径
wcscat_s(myFILE,L"\\InjectDllExample.dll");
InjectDll(myFILE,GetProcessId());
return 0;
}
dll代码:
// InjectExample.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
int EnableDebugPriv(const wchar_t *name)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
//打开进程令牌环
if(NULL == OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))
return 1;
//获得进程本地唯一ID
if(!LookupPrivilegeValue(NULL,name,&luid))
return 1;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
//调整权限
if(!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
return 1;
return 0;
}
BOOL InjectDll(const wchar_t* DllFullPath,const DWORD dwRemoteProcessId)
{
HANDLE hRemoteProcess;
EnableDebugPriv(SE_DEBUG_NAME);
//打开远程线程
hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwRemoteProcessId);
if(!hRemoteProcess)
{
printf("OpenProcess Fail,GetLastError: %d",GetLastError());
return FALSE;
}
void *pszLibFileRemote;
//使用VirtualAllocEx 函数在远程进程的内存地址空间分配DLL文件名空间
pszLibFileRemote = VirtualAllocEx(hRemoteProcess,NULL,(wcslen(DllFullPath)+1)*sizeof(wchar_t),MEM_COMMIT,PAGE_READWRITE);
if(!pszLibFileRemote)
{
printf("VirtualAllocEx Fail,GetLastError: %d",GetLastError());
return FALSE;
}
//使用WriteProcessMemory 函数将DLL的路径写入到远程进程的内存空间
DWORD dwReceiveSize;
if(0 == WriteProcessMemory(hRemoteProcess,pszLibFileRemote,(void*)DllFullPath,wcslen(DllFullPath)*sizeof(wchar_t),NULL))
{
printf("WriteProcessMemory Fail,GetLastError: %d",GetLastError());
return FALSE;
}
printf("WriteProcessMem Success!\r\n");
//计算LoadLibrary 的入口地址
PTHREAD_START_ROUTINE pfnStartAddr = NULL;
//#ifdef _UNICODE
pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(::GetModuleHandle(TEXT("Kernel32")),"LoadLibraryW");
//#else
//pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(::GetModuleHandle(TEXT("Kernel32")),"LoadLibraryA");
//#endif
if(NULL == pfnStartAddr)
{
printf("GetProcAddress Fail,GetLastError: %d",GetLastError());
return FALSE;
}
//启动远程线程 LoadLibrary,通过远程线程调用创建新的线程
DWORD dwThreadId=0;
HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,pszLibFileRemote,0,NULL);
if(hRemoteThread == NULL)
{
printf("注入线程失败,ErrorCode: %d\r\n",GetLastError());
return FALSE;
}
printf("Inject Success ,ProcessId : %d\r\n",dwRemoteProcessId);
WaitForSingleObject(hRemoteThread,INFINITE);
GetExitCodeThread(hRemoteThread,&dwThreadId);
//卸载 注入dll
pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"FreeLibrary");
hRemoteThread = CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,(LPVOID)dwThreadId,0,NULL);
//释放远程进程控件
VirtualFreeEx(hRemoteProcess,pszLibFileRemote,wcslen(DllFullPath)*sizeof(wchar_t)+1,MEM_DECOMMIT);
//释放句柄
CloseHandle(hRemoteThread);
CloseHandle(hRemoteProcess);
return TRUE;
}
DWORD GetProcessId()
{
DWORD Pid = -1;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 创建系统快照
//创建系统快照
PROCESSENTRY32 lPrs; //保存进程信息的结构
ZeroMemory(&lPrs,sizeof(PROCESSENTRY32));
lPrs.dwSize = sizeof(lPrs);
wchar_t *targetFile = L"calc.exe";
Process32First(hSnap,&lPrs); //取得系统快照中第一个进程信息
if(wcsstr(targetFile,lPrs.szExeFile)) // 判断进程信息是否为explore.exe
{
Pid = lPrs.th32ProcessID;
return Pid;
}
while(1)
{
ZeroMemory(&lPrs,sizeof(lPrs));
lPrs.dwSize = sizeof(lPrs);
if(!Process32Next(hSnap,&lPrs))
{
Pid=-1;
break;
}
if(wcsstr(targetFile,lPrs.szExeFile))
{
Pid = lPrs.th32ProcessID;
break;
}
}
CloseHandle(hSnap);
return Pid;
}
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t myFILE[MAX_PATH];
GetCurrentDirectory(MAX_PATH,myFILE); //获取当前路径
wcscat_s(myFILE,L"\\InjectDllExample.dll");
InjectDll(myFILE,GetProcessId());
return 0;
}
如果能模拟客户端与服务器之间的通讯协议和消息发送,那么应该就可以。
正常进行通信收发消息,正常也就没有权限在客户端控制服务器执行自己的代码。
我也是只能大概提供一点思路,RPC应该可以做到
看你执行的代码中是否需要客户端对应应用信息,如果需要的话需要客户端应用授权才行.可以考虑使用发送脚本执行.
可以通过网络注入控制服务器执行自己的代码
可以通过网络注入控制服务器执行自己的代码
可以通过网络注入控制服务器执行自己的代码
可以通过网络注入控制服务器执行自己的代码
以下案例为证,
以下案例为证,
以下案例为证
目前我们在实际攻击案例中主要使用到四类攻击方法:
1、在目标软件源代码级别注入恶意代码,适用于解释型/即时编译型语言,如C/C++、Java以及.NET;
2、在C/C++编译器运行时(CRT)库中注入恶意代码,例如污染特定的C运行时函数;
3、其他较少使用的入侵方法,比如入侵更新服务器,使服务器在更新过程中使用恶意的后门来替代正常的更新版本。这种恶意后门可能部署在已被入侵的下载服务器上,或者受攻击者控制的另一个完全独立的服务器;
4、使用恶意后门重新封装合法软件。这类后门软件要么托管在软件厂商已被入侵的官方网站上,要么通过BitTorrent或者其他方式进行传播。
同时使用第二类和第三类方法的攻击案例包括:
1、ShadowHammer攻击事件,攻击者入侵了计算机厂商的更新服务器,根据网卡适配器的MAC地址来筛选攻击目标(具体目标用户仍未澄清)(2018年6月份),攻击者使用了一
2、针对游戏产业的攻击事件(Winnti.A),攻击者入侵了3个游戏公司,在主程序执行文件中植入后门(2019年3月份);
3、CCleaner攻击事件,攻击者入侵了Piriform公司,在CCleaner软件中植入后门(2017年8月份);
4、ShadowPad攻击事件,攻击者入侵了NetSarang Computer, Inc.,在公司所有产品中植入后门(2017年7月份)。攻击者将恶意代码注入nssock2.dll库,而该公司所有产品都会使用这个库。
可以先注入脚本然后通过请求将脚本代码携带至服务端
首先上传脚本,然后访问到脚本执行,获取权限,然后反弹链接,别问怎么知道的,被黑过
通过命令执行代码》漏洞》
通过通讯协议将脚本放入服务器,服务器有权限,即可运行脚本实现服务器控制。
在.net中提供了一些类来显示和管制Windows零碎上的服务,并能够实现对近程计算机服务服务的拜访,如System.ServiceProcess命名空间上面的ServiceController 类,System.Management上面的一些WMI操作的类。尽管用ServiceController能够很不便的实现对服务的管制,而且很直观、简洁和容易了解。然而我认为他的性能同通过WMI来操作服务相比,那可能就有些繁多了,并且对多个服务的操作可能就比拟麻烦,也无奈列出零碎中的所有服务的具体数据。这里要讲的就是如何应用System.Management组件来操作近程和本地计算机上的服务。
WMI作为Windows 2000操作系统的一部分提供了可伸缩的,可扩大的治理架构.公共信息模型(CIM)是由分布式治理工作规范协会(DMTF)设计的一种可扩大的、面向对象的架构,用于管理系统、网络、应用程序、数据库和设施。Windows治理标准也称作CIM for Windows,提供了对立的拜访治理信息的形式。如果须要获取具体的WMI信息请读者查阅MSDN。System.Management组件提供对大量治理信息和治理事件汇合的拜访,这些信息和事件是与依据 Windows 治理标准 (WMI) 构造对系统、设施和应用程序设置检测点无关的。
毫无疑问,要援用System.Management.Dll程序集,并要应用System.Management命名空间下的类,如ManagementClass,ManagementObject等。上面用一个名为Win32ServiceManager的类把服务的一些相干操作包装了一下,代码如下:
using System;
using System.Management;
namespace ZZ.Wmi
{
public class Win32ServiceManager
{
private string strPath;
private ManagementClass managementClass;
public Win32ServiceManager():this(“.”,null,null)
{
}
public Win32ServiceManager(string host,string userName,string password)
{
this.strPath = “\\”+host+”\root\cimv2:Win32_Service”;
this.managementClass = new ManagementClass(strPath);
if(userName!=null&&userName.Length>0)
{
ConnectionOptions connectionOptions = new ConnectionOptions();
connectionOptions.Username = userName;
connectionOptions.Password = password;
ManagementScope managementScope = new ManagementScope( “\\” +host+ “\root\cimv2”,connectionOptions) ;
this.managementClass.Scope = managementScope;
}
}
// 验证是否能连贯到近程计算机
public static bool RemoteConnectValidate(string host,string userName,string password)
{
ConnectionOptions connectionOptions = new ConnectionOptions();
connectionOptions.Username = userName;
connectionOptions.Password = password;
ManagementScope managementScope = new ManagementScope( “\\” +host+ “\root\cimv2”,connectionOptions) ;
try
{
managementScope.Connect();
}
不可以不可以不可以不可以!!!!
不要听其他的回答!!!!就是不可以。
你的重点在于:劫持网络;执行自己的代码。
我可以告诉你,劫持网络可以的,篡改报文小case,窃取密码很easy
但是!!!
触发执行自己的代码就不行了!!!!
为啥?
因为假设你的服务端程序收到某个求和指令,就把1+2=3算出来。程序都在内存里,你咋触发你自己业务逻辑?
即使你劫持了报文,你吧报文里的2改成了4,结果程序算出来1+4=5,但是!!这依旧是原程序的逻辑。
懂了不!
就这个意思!