首页
论坛
课程
招聘
[原创]runas自动输入密码(使用api hook实现)
2014-3-10 14:38 11978

[原创]runas自动输入密码(使用api hook实现)

2014-3-10 14:38
11978
最近需要在程序中以管理员身份运行某程序,尝试了发现下面几种方法
1、系统自带命令runas,无法实现自动输入密码
2、sanur第三方小工具通过管道和runas交互实现自动输入密码,在Win7和Window2008上无法正常工作
3、自己通过编程实现runas的功能,短时间开发并调试完成较困难

最终用使用Detours hook runas的ReadConsole、CreateProcessWithLogonW实现
代码如下:
/*runasdll源码*/
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <stdio.h>
#include "detours.h"
#pragma comment(lib, "detours.lib")

typedef BOOL (WINAPI *pfnReadConsole)(
            __in          HANDLE hConsoleInput,
            __out         LPVOID lpBuffer,
            __in          DWORD nNumberOfCharsToRead,
            __out         LPDWORD lpNumberOfCharsRead,
            __in_opt      LPVOID pInputControl
            );


typedef BOOL (WINAPI *pfnCreateProcessWithLogonW)(
                  __in          LPCWSTR lpUsername,
                  __in          LPCWSTR lpDomain,
                  __in          LPCWSTR lpPassword,
                  __in          DWORD dwLogonFlags,
                  __in          LPCWSTR lpApplicationName,
                  __in          LPWSTR lpCommandLine,
                  __in          DWORD dwCreationFlags,
                  __in          LPVOID lpEnvironment,
                  __in          LPCWSTR lpCurrentDirectory,
                  __in          LPSTARTUPINFOW lpStartupInfo,
                  __out         LPPROCESS_INFORMATION lpProcessInfo
                  );




BOOL WINAPI MyReadConsole(
                    __in          HANDLE hConsoleInput,
                    __out         LPVOID lpBuffer,
                    __in          DWORD nNumberOfCharsToRead,
                    __out         LPDWORD lpNumberOfCharsRead,
                    __in_opt      LPVOID pInputControl
                    );


BOOL WINAPI MyCreateProcessWithLogonW(
  __in          LPCWSTR lpUsername,
  __in          LPCWSTR lpDomain,
  __in          LPCWSTR lpPassword,
  __in          DWORD dwLogonFlags,
  __in          LPCWSTR lpApplicationName,
  __in          LPWSTR lpCommandLine,
  __in          DWORD dwCreationFlags,
  __in          LPVOID lpEnvironment,
  __in          LPCWSTR lpCurrentDirectory,
  __in          LPSTARTUPINFOW lpStartupInfo,
  __out         LPPROCESS_INFORMATION lpProcessInfo
  );

BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize);


pfnReadConsole realReadConsole = (pfnReadConsole)GetProcAddress(LoadLibrary("Kernel32.dll"), "ReadConsoleW");
pfnCreateProcessWithLogonW realCreateProcessWithLogonW = (pfnCreateProcessWithLogonW)GetProcAddress(LoadLibrary("Advapi32.dll"), "CreateProcessWithLogonW");


HANDLE g_hDLL = NULL;


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
           )
{
  char szModuleName[MAX_PATH] = {0};
  char szExe[MAX_PATH] = {0};
  switch (ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH:

    g_hDLL = hModule;

    GetModuleFileName(NULL, szModuleName, MAX_PATH-1);    
    strcpy(szExe, strrchr(szModuleName, '\\')+1);

    if (strcmpi(szExe, "RUNAS.EXE"))
    {    
      return TRUE;
    }
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach((PVOID*)&realReadConsole, MyReadConsole);
    DetourAttach((PVOID*)&realCreateProcessWithLogonW, MyCreateProcessWithLogonW);
    DetourTransactionCommit();
    break;
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
  case DLL_PROCESS_DETACH:
    break;
  }
  return TRUE;
}


BOOL WINAPI MyReadConsole(
              __in          HANDLE hConsoleInput,
              __out         LPVOID lpBuffer,
              __in          DWORD nNumberOfCharsToRead,
              __out         LPDWORD lpNumberOfCharsRead,
              __in_opt      LPVOID pInputControl
              )
{
  *((char*)lpBuffer) = 0x0d;
  *lpNumberOfCharsRead = 1;
  return FALSE;
}


BOOL WINAPI MyCreateProcessWithLogonW(
                    __in          LPCWSTR lpUsername,
                    __in          LPCWSTR lpDomain,
                    __in          LPCWSTR lpPassword,
                    __in          DWORD dwLogonFlags,
                    __in          LPCWSTR lpApplicationName,
                    __in          LPWSTR lpCommandLine,
                    __in          DWORD dwCreationFlags,
                    __in          LPVOID lpEnvironment,
                    __in          LPCWSTR lpCurrentDirectory,
                    __in          LPSTARTUPINFOW lpStartupInfo,
                    __out         LPPROCESS_INFORMATION lpProcessInfo
                    )
{  

  WCHAR wcsPassword[128] = {0};  
  char szPassword[128] = {0};
  char szIniFile[MAX_PATH] = {0};  
  
  GetModuleFileName((HMODULE)g_hDLL, szIniFile, MAX_PATH);
  strcpy(strrchr(szIniFile, '\\')+1, "MyRunas.ini");
  GetPrivateProfileString("Setting", "password", "", szPassword, 128, szIniFile);

  if (!strlen(szPassword))
  {
    printf("读取密码文件%s失败,请检查设置是否正确!\n", szIniFile);
    MessageBox(NULL, "读取密码文件失败,请检查设置是否正确!", "", NULL);
  }
  else
  {
    MByteToWChar(szPassword, wcsPassword, sizeof(wcsPassword)/sizeof(wcsPassword[0]));
  }

  return realCreateProcessWithLogonW(lpUsername,
                     lpDomain,
                     wcsPassword,
                     dwLogonFlags,
                     lpApplicationName,
                     lpCommandLine,
                     dwCreationFlags,
                     lpEnvironment,
                     lpCurrentDirectory,
                     lpStartupInfo,
                     lpProcessInfo);
}


BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize)
{
  // Get the required size of the buffer that receives the Unicode 
  // string. 
  DWORD dwMinSize;
  dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);

  if(dwSize < dwMinSize)
  {
    return FALSE;
  }

  // Convert headers from ASCII to Unicode.
  MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);  
  return TRUE;
}



//detours需要dll导出任意一个函数
VOID test()
{
}


/*MyRunas源码*/
// myrunas.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include "detours.h"

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

int _tmain(int argc, _TCHAR* argv[])
{
  
  if (argc==1)
  {
    char szInfo[1024] = {0};
    wsprintf(szInfo, "%s", "MyRunas只是一个外壳,在启动runas时修改了它的某些代码,使其支持自动输入密码,其中密码是在MyRunas.ini文件中设置的,除此之外MyRunas用法和runas命令完全相同。"
      "在XP、Win7、Win2008下测试通过。\n\nMyRunas v1.0 2014/3\nby YangFan\nEmail:522419441@qq.com", "MyRunas");
    MessageBox(GetForegroundWindow(), szInfo, "MyRunas", MB_ICONINFORMATION);
    return -1;
  }

  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  si.cb = sizeof(si);
  memset(&si, 0, sizeof(si) );  
  memset( &pi,0, sizeof(pi) );

  char szMyRunasCMDLine[1024] = {0};
  char szRunasCMDLine[1024] = {0};
  strcpy(szMyRunasCMDLine, GetCommandLine());
  strcpy(szRunasCMDLine, "runas ");
  strcat(szRunasCMDLine, strstr(szMyRunasCMDLine+strlen(__argv[0]), __argv[1]));

  char szDLL[MAX_PATH] = {0};
  GetModuleFileName(NULL, szDLL, 1024);
  strcpy(strrchr(szDLL, '\\')+1, "runasdll.dll");///runasdll.dll必须要导出函数,否则会报错
  // Start the child process. 
  if( !DetourCreateProcessWithDll( NULL,   // No module name (use command line)
    szRunasCMDLine,        // Command line
    NULL,           // Process handle not inheritable
    NULL,           // Thread handle not inheritable
    FALSE,          // Set handle inheritance to FALSE
    0,              // No creation flags
    NULL,           // Use parent's environment block
    NULL,           // Use parent's starting directory 
    &si,            // Pointer to STARTUPINFO structure
    &pi, 
    szDLL,
    NULL)
    ) 
  {
    printf( "CreateProcess failed (%d)\n", GetLastError() );
    return -1;
  }

  // Wait until child process exits.
  WaitForSingleObject( pi.hProcess, INFINITE );

  // Close process and thread handles. 
  CloseHandle( pi.hProcess );
  CloseHandle( pi.hThread );


  
  return 0;
}



2021 KCTF 秋季赛 防守篇-征题倒计时(11月14日截止)!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (5)
雪    币: 209
活跃值: 活跃值 (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
shilyx 活跃值 2014-3-10 14:43
2
0
可能是没理解,不过既然有密码为什么不用密码登陆后获得令牌然后CreateProcessAsUser
雪    币: 671
活跃值: 活跃值 (86)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
瀚海云烟 活跃值 1 2014-3-11 09:21
3
0
对啊对啊,既然有密码了,为什么不直接调用CreateProcessWithLogonW呢
雪    币: 199
活跃值: 活跃值 (744)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
appview 活跃值 2014-3-11 14:52
4
0




原因有两个:
1、使用系统API的方法实现runas类似的全部功能工作量太大
2、为了方便在批处理等脚本中调用
雪    币: 201
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
绝笔十三 活跃值 2014-7-17 20:20
5
0
非常感谢,解决了我的大问题。
雪    币: 69
活跃值: 活跃值 (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
hulucc 活跃值 2014-7-18 12:13
6
0
bat的管道命令无法自动么0 0
游客
登录 | 注册 方可回帖
返回